# Scene/Event VM Goal

이 문서는 `/goal` 장기 작업을 다시 시작할 때 사용할 기준이다. 1차 opcode 사전, `map1_01a` trace, selected scene/text root consumer, producer/hotspot 정적 검토, runtime watchpoint 시도는 이미 진행됐다. 다음 목표는 남은 `scene/event VM` 흐름 중 정적으로 더 확정 가능한 부분을 승격하고, 런타임 없이는 불가능한 항목을 명확히 분리하는 것이다.

## Goal Prompt

아래 문장을 `/goal` 목표로 사용한다.

> 환세취호전 `Hwanse2.exe`의 scene/event VM에서 selected scene/text root, branch, flag, prompt sequence 흐름을 정적으로 최대한 해석한다.  
> 목표는 map/scene이 어떤 text root와 선택지/분기/트리거를 소비하는지 추적 가능한 수준까지 승격하는 것이다.  
> 이미 확정된 opcode dictionary, `map1_01a` trace, selected root consumer, producer/hotspot review, runtime watchpoint blocked 결과를 출발점으로 삼는다.  
> 런타임 없이는 확정 불가능한 항목은 억지 추정하지 말고 `blocked`로 분리하며, 새로 해석된 opcode/consumer/producer/flag 근거는 문서와 웹 리뷰에 반영한다.

짧게 입력해야 할 때는 이렇게 쓴다.

```text
docs/SCENE_EVENT_VM_GOAL.md 기준으로 scene/event VM의 selected text root, branch, flag, prompt sequence 흐름을 정적으로 해석하고 확정/blocked를 분리한다.
```

## Current Grounded Artifacts

현재 기준점으로 삼을 파일:

- `docs/SCENE_EVENT_VM_REFERENCE.md`: 현재까지 확정/부분확정된 scene/event VM 구조.
- `web/scene_event_vm_review.html`: opcode dictionary와 VM 검토 홈.
- `web/scene_event_vm_execution_route_review.html`: 실행 루트 gap 검토.
- `web/selected_scene_text_root_consumer_review.html`: selected pointer consumer 구조.
- `web/scene_event_vm_branch_flag_review.html`: branch/flag read-write 및 route proof blocked 구조.
- `web/scene_event_vm_prompt_sequence_review.html`: prompt/choice/branch-call boundary 분리.
- `web/scene_event_vm_choice_target_review.html`: `0x004bfdb4` 공통 표시 스트림과 `0x16 -> 0x59e2a0 -> 0x18` choice target 흐름 분리.
- `web/scene_event_vm_random_gate_review.html`: `0x59db1f`를 선택 인덱스가 아닌 random gate 성공 카운터로 분리.
- `web/scene_event_runtime_evidence_handoff.html`: 정적 frontier 포화 이후 필요한 watchpoint/trace 증거 handoff.
- `out/scene_event_vm_opcode_dictionary.{json,html}`
- `out/map1_01a_scene_trace.{json,md}`
- `out/selected_scene_text_root_consumer_review.{json,html}`
- `out/scene_event_vm_branch_flag_review.{json,md,html}`
- `out/scene_event_vm_prompt_sequence_review.{json,html}`
- `out/scene_event_vm_choice_target_review.{json,html}`
- `out/scene_event_vm_random_gate_review.{json,html}`
- `out/scene_event_runtime_evidence_handoff.{json,html}`

## Scope

이번 goal에서 다룰 것:

- selected scene/text root가 어디서 설정되고 어디서 소비되는지 추가 추적.
- branch/flag read-write 관계를 opcode/handler/operand 근거로 분리.
- scene command sequence와 prompt sequence가 실제 대사 흐름으로 이어지는지 검토.
- 선택지 표시, 선택 결과, 다음 prompt 연결의 command boundary 찾기.
- `map1_01a`처럼 짧고 이미 관찰된 흐름을 proof sample로 사용.
- 확정 가능한 opcode/consumer/producer/flag는 `grounded` 이상으로 승격.
- 반복 정적 스캔으로 더 이상 안 되는 것은 `blocked`로 문서화.

이번 goal에서 다루지 않을 것:

- 전체 시나리오 대본 완성.
- 모든 map transition 연결.
- savedata route proof 재개.
- 런타임 gdbstub 안정화 자체에 매몰.
- 전투, 오디오, CNS rect, 스프라이트 보정.
- 게임 플레이 구현 또는 UI polish.

## Evidence Levels

작업 결과는 반드시 아래 중 하나로 분류한다.

- `confirmed`: EXE 근거와 실제 화면/사용자 관찰 흐름이 모두 맞는다.
- `grounded`: EXE handler/operand/consumer 근거가 강하지만 전체 런타임 검증은 없다.
- `partial`: 일부 샘플은 맞지만 조건, flag, branch, length가 남아 있다.
- `candidate`: 패턴 후보일 뿐이며 기본 화면에 확정처럼 보이면 안 된다.
- `blocked`: 현재 정적/런타임 수단으로는 더 못 올라간다.
- `rejected`: 오탐 또는 폐기된 가설.

## Promotion Rules

승격 가능한 경우:

- 동일 opcode가 여러 command에서 같은 operand 구조와 효과를 보인다.
- handler VA가 명확하고, handler 내부 참조가 scene/text/resource/flag와 연결된다.
- selected pointer/root가 특정 producer에서 설정되고 특정 consumer에서 읽히는 경로가 이어진다.
- branch/flag의 read와 write가 같은 flag storage 또는 같은 state slot으로 연결된다.
- command sequence가 사용자가 알려준 실제 prompt/choice 흐름과 같은 순서로 맞는다.
- 웹 리뷰에서 후보와 확정이 분리되어 재검토 가능하다.

승격 금지:

- 메모리 근접성만으로 scene order라고 판단.
- resource list에 있다는 이유만으로 actor action 또는 prompt 연결 확정.
- manual exit marker와 비슷하다는 이유만으로 transition opcode 확정.
- 한 샘플만 맞는 opcode를 전체 의미로 확정.
- runtime watchpoint가 실패했는데 성공한 것처럼 해석.

## Work Slices

### Slice 1: Selected Root Producer Extension

목표:

- `0x0059de30` selected pointer에 값을 쓰는 producer 후보를 더 찾는다.
- current root `0x00540714`와 route root/range가 실제 producer에 닿는지 본다.
- 기존 producer/hotspot review에서 막힌 이유를 유지하며, 새 증거가 있는 경우에만 갱신한다.

중단 기준:

- 새 producer가 current root/range와 연결되지 않으면 `blocked` 유지.

### Slice 2: Branch/Flag Read-Write

목표:

- branch-like opcode가 읽는 flag/state slot을 찾는다.
- 같은 storage에 쓰는 opcode가 있는지 추적한다.
- 선택지 결과, scene state, map state, resource state를 구분한다.

중단 기준:

- flag storage가 동적 계산으로만 나오고 producer가 없으면 `partial` 또는 `blocked`.

### Slice 3: Prompt Sequence Boundary

목표:

- prompt, choice, wait, branch, next-prompt command boundary를 분리한다.
- 선택지와 선택 후 대사가 하나로 뭉친 review 데이터를 분리할 수 있는 근거를 찾는다.
- `map1_01a` 초반 대사 흐름을 작은 proof sample로 사용한다.

중단 기준:

- prompt root는 알지만 선택 결과 branch가 불명확하면 prompt sequence만 `grounded`, branch는 `partial`.

### Slice 4: Consumer/Execution Route Gap

목표:

- selected root consumer `0x0040adfe` 주변의 control/data flow를 더 추적한다.
- runtime watchpoint blocked 결과를 전제로, 정적 route proof가 가능한지 다시 본다.
- 실행 root가 record list인지 실제 interpreter entry인지 구분한다.

중단 기준:

- qemu/gdbstub watchpoint 실패 반복 금지. 새 수단 없으면 정적 분석만 수행.

### Slice 5: Review Cleanup

목표:

- 새로 승격한 항목만 `web/index.html`과 VM 관련 review에 노출한다.
- 후보는 접힘 영역 또는 별도 gap 목록에 둔다.
- 오래된 후보/폐기 가설이 확정 항목처럼 보이지 않게 정리한다.

## Anti-Rabbit-Hole Rules

다음 상황이면 멈추고 문서화한다.

- 하나의 opcode 또는 하나의 map transition에 30분 이상 묶인다.
- savedata, 전투, 오디오, 스프라이트로 작업 범위가 새기 시작한다.
- 런타임 없이는 확인 불가능한 branch를 정적으로 단정한다.
- 이미 blocked된 watchpoint 방식을 같은 조건으로 반복한다.
- 후보를 사용자용 페이지에 확정처럼 노출한다.

멈출 때 남길 내용:

- 본 opcode/VA/file.
- 확인된 근거.
- 막힌 이유.
- 다음에 필요한 외부 힌트 또는 런타임 조건.

## Done Criteria

이번 goal은 아래 중 충분한 진전이 있으면 1차 완료로 본다.

- selected root producer 또는 branch/flag read-write 중 하나 이상이 새로 `grounded` 이상으로 승격된다.
- prompt/choice/next-prompt boundary가 기존보다 명확해진다.
- `blocked` 항목이 반복 후보가 아니라 명확한 근거와 함께 분리된다.
- `docs/SCENE_EVENT_VM_REFERENCE.md`와 관련 웹 리뷰가 최신 상태다.
- `python3 tools/verify_web_assets.py`와 `python3 tools/verify_runtime_http.py --base http://127.0.0.1:8013`가 통과한다.

## Non-Completion Criteria

아래는 이번 goal 완료 조건이 아니다.

- 전체 시나리오 완성.
- 모든 선택지 분기 완성.
- 모든 맵 이동 구현.
- 모든 NPC 이동 구현.
- 런타임 watchpoint 성공.
- 실제 플레이 가능한 전체 게임 구현.
