1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
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바이트를 쓰는 판정·사건 기록 중 **항상 남겨야 할 정보와
필요할 때 다시 계산할 수 있는 정보**를 나눈다. 이전 판정을 정확히 다시 설명하려면
당시 상태와 규칙의 어떤 부분이 필요한지부터 확인해야 한다.
사용자가 실제로 찾는 정보와 정확성을 유지하는 조건이 정해진 뒤 보관·재계산 방식을 비교한다.
|