diff options
Diffstat (limited to 'docs/research/003-live-rules.md')
| -rw-r--r-- | docs/research/003-live-rules.md | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/docs/research/003-live-rules.md b/docs/research/003-live-rules.md new file mode 100644 index 0000000..b7c0349 --- /dev/null +++ b/docs/research/003-live-rules.md @@ -0,0 +1,139 @@ +# Pure 연구 보고서 003: 실행 중 규칙을 바꾸고 이유를 확인하기 + +작성일: 2026-09-22 +상태: **구현 검증 완료. 사용자 피드백 반영: 개발 경험 평가에는 부적합.** + +사용자는 이 Dino를 직접 개발하지 않았으므로 개발 경험을 평가할 수 없다고 지적했다. +이 데모로 확인한 범위는 정해진 규칙 변경·상태 보존·판정 표시다. +아래 기존 검사와 수치는 그 범위의 기록으로 보존한다. +새 동작을 직접 작성하는 평가는 [별도 제작 실험 004](004-authoring.md)로 옮겼다. + +## 먼저 직접 해볼 일 + +공룡이 점프하는 작은 연습 장면을 만들었다. 공중에서 두 번째 점프가 거절되면, +그 자리에서 규칙을 **두 번 점프**로 바꾸고 다시 시도할 수 있다. +규칙을 적용해도 위치·속도·진행 상태는 유지된다. 부딪혀도 연습은 계속된다. + +[실행 안내](../../prototypes/live-rules/README.md)에 따라 화면을 열고 다음을 확인하면 된다. + +1. 점프한 뒤 공중에서 다시 점프해, 거절 이유를 찾는다. +2. 공중에서 일시정지하고 **두 번 점프**로 바꿔 **규칙 적용**을 누른다. +3. 위치와 진행 상태가 유지되는지 보고 다시 점프한다. +4. 점프를 비활성화한 뒤, 무엇 때문에 입력이 거절됐는지 확인한다. + +시간을 맞추기 어려우면 정지 상태에서 점프하고 한 프레임씩 진행해도 된다. +정지 중에도 입력은 판정하지만 위치는 프레임을 진행할 때 움직인다. +**처음부터**는 규칙과 진행 상태를 함께 초기화한다. + +사용자가 알려줄 것은 “하려던 일 / 실제로 일어난 일 / 기대했던 일”이다. +예를 들어 “규칙을 바꿨는데 여전히 거절 표시가 보여 적용 실패로 생각했다”는 관찰이면 +충분하다. 그 원인을 재현하고, 화면과 실행 의미 중 무엇을 고칠지 분석하는 일은 Codex가 맡는다. + +## 무엇을 구현했는가 + +Zig로 작성한 코어가 점프 판정, 물리, 규칙 변경, 진행 상태와 사건 기록을 담당한다. +이를 WebAssembly로 빌드해 브라우저와 터미널에서 사용한다. 두 어댑터는 같은 Wasm 파일을 +각자의 인스턴스로 실행한다. 현재 두 화면의 진행 상태를 실시간으로 공유하는 기능은 없다. + +판정은 입력 요청·활성 여부·접지 여부·남은 점프 수를 읽고, 조건을 선택해 합류하는 +**고정된 여섯 노드 그래프**다. 화면에서 보는 노드 값은 코어가 실제 판정에 사용한 값이다. +바꿀 수 있는 것은 점프 조건·힘·활성화 세 항목이며, 모두 검증한 뒤 함께 적용한다. +지원하지 않는 값은 기존 규칙과 상태를 유지한 채 거절한다. + +연산이나 연결을 자유롭게 추가하는 편집기, 임의 프로그램의 상태 이전은 아직 구현하지 않았다. +이번에는 앞선 계산 사슬과 별도의 상호작용 모델에서 편집과 관찰의 의미를 확인했다. +새로운 알고리즘이나 일반 런타임의 성능 우월성을 입증한 결과는 아니다. + +## 규칙을 바꿨는데 왜 이전 판정이 남는가 + +판정 화면은 **마지막 입력을 처리하기 직전의 상태와 그때 사용한 규칙 버전**을 보여준다. +규칙을 수정했다고 과거의 입력이 새 규칙으로 처리된 것은 아니므로, 이 기록도 그대로 둔다. +다음 입력이 들어오면 새 규칙으로 판정하고 화면의 기록을 교체한다. + +따라서 현재 규칙이 버전 2이고 마지막 판정이 버전 1인 상태는 정상이다. +사용자가 이 차이를 이해할 수 있는지는 실제 조작으로 확인해야 한다. +기록을 더 보관하는 것만으로 설명이 쉬워진다고 가정하지 않는다. + +## 보관 공간에서 확인한 사실 + +아래 값은 Zig의 `@sizeOf`로 얻은 **선언된 자료 구조의 크기**다. + +| 항목 | 바이트 | 포함하는 정보 | +|---|---:|---| +| 규칙 | 16 | 조건·힘·활성화·버전 | +| 진행 상태 | 68 | 위치·속도·장애물·횟수 등 | +| 마지막 판정 | 24 | 판정 당시 상태·버전·여섯 노드 값 | +| 사건 기록 | 264 | 최근 사건 16개와 기록 위치 | +| 코어 구조체 | 372 | 위 네 항목을 포함한 크기 | +| 그래프 정의 | 24 | 여섯 노드의 고정 정의 | +| 선언 크기 합계 | **396** | 코어 구조체 + 그래프 정의 | + +마지막 판정과 사건 기록은 합쳐서 288바이트다. 이 작은 모델에서는 전체 선언 크기 +396바이트 중 약 72.7%를 차지한다. **사용자에게 실행 이유를 보여주기 위한 정보도 +따로 계산해야 한다**는 구체적인 사례다. 다른 앱에서도 같은 비중이라는 뜻은 아니다. + +이 합계는 실제 RAM 사용량이 아니다. 그래프 상수는 컴파일러가 명령어로 접을 수 있고, +Wasm 엔진과 화면에도 별도 비용이 있다. 코어 구조체는 앞의 네 항목을 포함하므로 +표의 모든 행을 더하면 중복 계산이 된다. + +실제 Wasm 선형 메모리의 용량은 **65,536바이트(64 KiB)**로, 초기값과 최대값이 같다. +코어 데이터와 예약한 16 KiB 스택은 이 공간 안에 포함된다. +선언 크기나 스택을 64 KiB에 다시 더하지 않는다. +빌드된 Wasm 파일은 **32,544바이트**이며, 파일 크기와 메모리 용량도 서로 다른 값이다. +브라우저·Node 엔진, DOM·렌더러, 실행 코드와 프로세스 전체 메모리는 이번 수치에 포함하지 않았다. + +최근 사건 16개를 넘으면 오래된 사건을 덮어쓴다. 이것은 완전한 실행 재생 로그가 아니다. +별도의 정해진 명령열로 재생 검사를 수행하며, 메모리에 모든 과거 상태를 보관하지 않는다. + +## 검증과 증거 + +- 네이티브 Zig 검사 **11개**를 통과했다. 규칙 변경 시 상태 보존, 잘못된 변경의 거절, + 정지·한 프레임 진행, 두 번 점프, 그래프 판정, 기록 한도, 재생 일치와 카운터 처리를 검사했다. +- 실제 Wasm을 사용하는 어댑터 검사 **6개**를 통과했다. 같은 입력 의미, 실행 중 변경, + 잘못된 숫자 입력, 반복 실행 후의 기록·메모리 한도와 재생 결과를 확인했다. +- 별도 코드 검토에서 코어와 어댑터의 수정 원자성, 범위 검사, 공간 집계 표현을 확인했다. + 터미널에 소수·범위를 넘는 정수·음수·지수 표기를 넣었을 때 거절되고 기존 상태가 유지되는지도 확인했다. + +검사를 통과했다는 것은 다룬 시나리오의 결과이며 모든 가능한 실행의 정확성 증명은 아니다. +검증 환경은 Linux aarch64, Zig 0.15.2와 Node 24다. **M3 macOS 측정은 수행하지 않았다.** +처리 속도, 사용자 입력 지연과 전체 앱 메모리를 비교하는 벤치마크도 수행하지 않았다. + +재현 명령은 [실행·검증 안내](../../prototypes/live-rules/README.md)에 있다. +소스·Wasm 해시, 구조체 크기와 명령별 상태를 담는 +[실행 기록](../../prototypes/live-rules/results/2026-09-22-linux-aarch64/storage-and-replay.json)은 +최종 소스와 대조해 저장했다. 이번 기록에는 네이티브 검사 결과와 빌드 정보도 포함한다. +향후 재실행에서 빌드 기록이 없으면 컴파일러 출처를 확인한 것으로 취급하지 않는다. + +## 실제 브라우저 조작 검증 + +Chromium 151과 Playwright CLI 0.1.21에서 실제 컨트롤을 조작해 **23개 확인 항목**을 통과했다. +JavaScript로 코어 상태를 직접 바꾸는 방식 대신 버튼·키보드·폼을 사용했고, +읽기 전용 관찰 함수로 결과를 확인했다. + +- 정지·실행·한 프레임 진행, 키보드와 버튼 입력, 키 반복과 중복 입력 방지를 확인했다. +- 초안은 적용 전까지 실행에 영향을 주지 않았고, 적용 시점의 높이 60.20px, 속도 5.60px/틱, + 진행 거리 32px, 처리 단계 8이 모두 그대로 유지됐다. 다음 점프는 새 규칙으로 허용됐다. +- 이전 버전 판정 표시, 세 번째 점프와 비활성화된 점프의 거절, 명시적 초기화를 확인했다. +- 최대 세기의 두 번 점프가 화면 밖으로 사라지지 않았다. 390px 폭에서 가로 넘침 없이 + 컨트롤을 조작했고, 공룡이 너무 작아 보이는 초기 표시를 확대해 확인했다. +- Wasm 파일을 불러오지 못할 때 실행 명령 안내와 비활성화된 컨트롤을 확인했다. + +최종 소스·Wasm 해시와 상태 전후 값은 +[브라우저 검증 기록](../../prototypes/live-rules/results/2026-09-22-linux-aarch64/browser-checks.json)에 있다. +[데스크톱 화면](../../prototypes/live-rules/results/2026-09-22-linux-aarch64/desktop.png)과 +[좁은 화면](../../prototypes/live-rules/results/2026-09-22-linux-aarch64/mobile.png)도 보관했다. +좁은 화면 검사는 데스크톱 브라우저의 뷰포트 검사이며 실제 휴대폰이나 터치 센서 검증은 아니다. +이 검증은 동작과 표시를 확인한 것이며, 사용자가 쉽게 이해하는지에 대한 평가를 대신하지 않는다. + +## 다음에 판단할 질문 + +아래는 당시의 후속 질문이다. 이후 사용자 피드백으로 **빈 작업물에서 직접 만드는 과정**을 +먼저 확보하기로 바꿨다. 이 데모의 평가를 다시 요구하지 않는다. + +먼저 사용자가 “왜 입력이 거절됐는지”와 “변경이 언제 적용됐는지”를 이 화면에서 +설명할 수 있는지 확인한다. 찾기 어렵다면 어떤 정보나 표현이 부족한지 재현한다. + +그다음 이 작은 모델에서 288바이트를 쓰는 판정·사건 기록 중 **항상 남겨야 할 정보와 +필요할 때 다시 계산할 수 있는 정보**를 나눈다. 이전 판정을 정확히 다시 설명하려면 +당시 상태와 규칙의 어떤 부분이 필요한지부터 확인해야 한다. +사용자가 실제로 찾는 정보와 정확성을 유지하는 조건이 정해진 뒤 보관·재계산 방식을 비교한다. |
