# Scene/Event VM Reference

이 문서는 `docs/SCENE_EVENT_VM_GOAL.md` 1차 목표에서 승격 가능한 부분만 정리한다. 전체 scene route 실행은 아직 확정하지 않았으므로, 아래 항목은 opcode/handler 근거 중심의 `grounded` 범위다.

## Current Status

- opcode dictionary: `out/scene_event_vm_opcode_dictionary.json`
- review page: `web/scene_event_vm_review.html`
- command stream candidate review: `web/scene_event_vm_command_stream_candidates.html`
- command stream candidate artifact: `out/scene_event_vm_command_stream_candidates.json`
- execution route review: `web/scene_event_vm_execution_route_review.html`
- execution route artifact: `out/scene_event_vm_execution_route_review.json`
- event record structure review: `out/event_record_structure_review.html`
- event record structure artifact: `out/event_record_structure_review.json`
- coordinate semantics review: `web/scene_event_coordinate_semantics_review.html`
- coordinate semantics artifact: `out/scene_event_coordinate_semantics_review.json`
- conditional map route review: `web/scene_event_conditional_map_route_review.html`
- conditional map route artifact: `out/scene_event_conditional_map_route_review.json`
- selected root consumer review: `web/selected_scene_text_root_consumer_review.html`
- selected root consumer artifact: `out/selected_scene_text_root_consumer_review.json`
- branch/flag review: `web/scene_event_vm_branch_flag_review.html`
- branch/flag artifact: `out/scene_event_vm_branch_flag_review.json`
- global flag candidate review: `web/scene_event_global_flag_candidate_review.html`
- global flag candidate artifact: `out/scene_event_global_flag_candidate_review.json`
- text consumer trace review: `web/scene_event_text_consumer_trace_review.html`
- text consumer trace artifact: `out/scene_event_text_consumer_trace_review.json`
- scene-seq/resource link review: `web/scene_seq_resource_record_link_review.html`
- scene-seq/resource link artifact: `out/scene_seq_resource_record_link_review.json`
- selector-root structure review: `web/selector_root_structure_review.html`
- selector-root structure artifact: `out/selector_root_structure_review.json`
- resource loader consumer trace review: `web/resource_loader_consumer_trace_review.html`
- resource loader consumer trace artifact: `out/resource_loader_consumer_trace_review.json`
- prompt sequence review: `web/scene_event_vm_prompt_sequence_review.html`
- prompt sequence artifact: `out/scene_event_vm_prompt_sequence_review.json`
- choice target review: `web/scene_event_vm_choice_target_review.html`
- choice target artifact: `out/scene_event_vm_choice_target_review.json`
- random gate review: `web/scene_event_vm_random_gate_review.html`
- random gate artifact: `out/scene_event_vm_random_gate_review.json`
- runtime evidence handoff: `web/scene_event_runtime_evidence_handoff.html`
- runtime evidence handoff artifact: `out/scene_event_runtime_evidence_handoff.json`
- map1 trace candidate: `out/map1_01a_scene_trace.md`
- gap list: `out/scene_event_vm_gap_list.md`
- grounded opcode count: 15
- route-linked event VM execution: gap
- `map1_01a` first scene binding: partial, `selector-root-range-candidate`
- `map1_01a` command trace rows shown: 160

## map1_01a Execution Route Classification

`map1_01a` has three relevant scene records at this stage:

| record | classification |
| --- | --- |
| `0x0043e798` | manifest/resource record only. It lists resources for `map1_01a`, but no strict event record or selector execution reference is attached. |
| `0x005032d8` | grounded incoming entry context. It is strict event-linked from `map1_02b` into `map1_01a`, but it is not the first field-scene execution root. The linked transition record is now split as target-linked / coordinate-unverified / condition-undecoded, so its reviewed coordinates must not be promoted to original trigger proof. |
| `0x00542b44` | selector scene-list/resource adjacency. It is adjacent to `map2_02d` selector data, but this is blocked from promotion because no strict source hotspot, coordinate table, or runtime execution proof is attached. |

`out/event_record_structure_review.*` separates each transition/event record into source map ownership, target resource linkage, raw point table, reviewed spawn metadata, and condition payload state. For `map1_02b@0x00503350`, the target linkage to `map1_01a` is grounded by payload resources, but the reviewed `11,12`/`11,13` coordinates remain `coordinate-unverified` because the actor uses a bottom 3x1 footprint and no decoded trigger consumer proves those tiles.

`out/scene_event_coordinate_semantics_review.*` reclassifies every raw point-table coordinate under the bottom 3x1 footprint rule. Across 11 event records and 228 point rows, no source-trigger proof is promoted. The common point table signature is reused across multiple records, so rows such as `map1_02b@0x00503350` are split into `manual-target-spawn-review`, `target-spawn-candidate-unproven`, or `object-or-camera-point-candidate` instead of being treated as route triggers. This keeps `11,12`/`11,13` from being over-promoted while preserving their manual spawn metadata for later runtime/consumer proof.

`out/scene_event_conditional_map_route_review.*` checks whether map name strings are clustered with other target map strings, target scene ids, resources, and condition-like scalar values. The static pattern is strong: 11 transition records contain 53 condition choices, and 10 records fan out to multiple target maps. 43 choices have a target map string followed by the target map's scene id. This is still `conditional-map-route-pattern-static-only`: no condition consumer, scenario flag meaning, source trigger, or runtime branch path is proven. The scalar values are therefore retained as `sentinel`, `packed-shape-scalar`, or `small-scalar-candidate`, not promoted to named flags.

`out/scene_event_vm_command_stream_candidates.*` separates command-like storage blocks from transition payload records. It currently finds 47 command-like blocks with prompt/text, wait, branch/call, object-position, and display/cursor opcode surfaces, but `routeLinkedBlockCount=0`. The transition/event records remain target/resource payload evidence only; they are not promoted to map-transition command opcodes or full scene command lists.

The current best first text-flow candidate is still `scene-text-group-029` / `scene-seq-029-01`, rooted at `0x00501808`. It matches the observed early Ataho cave text, but remains `partial` because direct `scene record -> executed VM stream` proof is missing.

`out/scene_event_global_flag_candidate_review.*` scans x86 absolute-memory reads, compares, and writes in `.text` and aggregates `.data` targets as global flag candidates. The strongest static candidates include the known active flag block around `0x00457744` and runtime branch-state globals around `0x0059e33e`, but the review remains `global-flag-candidates-static-only`: it does not prove which entrance/scene condition consumes those globals until an executed scene/event record path reaches the relevant handler.

`out/scene_event_text_consumer_trace_review.*` separates individual story text pointers from the VM text consumer path. For selected `scene-text-group-029` / `scene-seq-029-01`, 42 `textVa` refs are entry-table refs and none are direct `.text` refs. The consumer path itself is grounded at the opcode layer: `0x0d` can set `context+0x28` from the stream and `0x0b` consumes `context+0x28` through text routine `0x0041b579`. This upgrades the text-consumer evidence, but not the route binding: `scene/event record -> selected root -> prompt stream` remains blocked.

`out/scene_seq_resource_record_link_review.*` connects the already extracted `scene-seq-*` text-flow candidates with selector/root resource bundles and scene manifest resource records. It currently groups 40 scene text groups / 64 sequences: 37 are `selector-root` range candidates and 3 are nearest scene/resource proximity candidates. 24 selector-root groups also link to field-map manifest records, while 13 are resource-only selector roots such as battle/cinematic/minigame-style bundles. This is useful as a "scene unit" candidate layer, but remains `scene-seq-resource-link-candidate-direct-root-blocked`: no direct event root has been proven to execute both the resource record and the linked text sequence.

`out/selector_root_structure_review.*` decomposes 93 unique selector roots from 94 selector rows into CNS/resource refs, field-map refs, text-entry table spans, local-pointer clusters, and control-pointer candidate spans. 37 roots have scene-seq text groups, and all 37 also contain resource structure under the same scanned root range; 66 roots contain CNS refs overall, and 2025 text-entry rows are inside root ranges. The selector rows split into 63 selector groups, including 14 multi-slot groups. The four `0x4f` mode1 cross-writers are now exposed here as same-group `slot 1 -> slot 0` alias normalization candidates (`13:1 -> 13:0`, `4:1 -> 4:0`, `19:1 -> 19:0`, `3:1 -> 3:0`), not route producers. This strengthens selector-root as a scene package candidate, but remains `selector-root-structure-decomposed-candidate`: direct execution proof and command opcode proof are both false.

`out/active_object_prompt_residual_duplicate_slot_audit.*` closes one residual ambiguity inside the plain-descriptor active-object prompt layer. Selectors `48:9` and `48:13` share the same row pointer, selected root `0x00500000`, field-map list, linked CNS list, and selected-root first dwords; their selected-pointer cells are only `0x10` bytes apart and both resolve to the same root. No direct text refs distinguish the slot cells, row pointer, or root. Treat them as alias-equivalent at the selected-root layer, not as independent prompt producer roots. The still-missing piece is the outer scene/event scheduler or condition that chooses group 48 slot 9 versus slot 13 before both converge.

`out/active_object_selector30_bridge_gap_audit.*` closes the matching negative check for residual selector `30:0`. The selector directory row is real: directory cell `0x00442dad` resolves to row `0x00524060`, and that row resolves to selected root `0x00524350` / script `0x005266fc`. Because the selector directory base is `0x00442d95`, the corresponding stream selector byte would be `0x06`. EXE raw scan finds zero `0x00000662` materializer commands, zero `0x00000663` remover commands, zero `0x62 0x06` fragments, and zero reachable selector-6 rows in the known active-object graph. Therefore `30:0` remains a real residual prompt root, but it is not materialized through the opcode `0x62` selector route that explains `24:0`; an alternate outer scheduler/producer is still required.

`out/active_object_selector48_bridge_gap_audit.*` performs the same negative check for the alias-equivalent residual pair `48:9`/`48:13`. Directory cell `0x00442df5` resolves to row `0x004e7238`, and row slots 9 and 13 both resolve to selected root `0x00500000` / script `0x005006a4`. The directory-derived stream selector byte would be `0x18`, but EXE raw scan finds zero `0x00001862` materializer commands, zero `0x00001863` remover commands, zero `0x62 0x18` or `0x63 0x18` fragments, and zero reachable selector-0x18 rows. This keeps the selected-root alias claim, while preserving the missing outer condition/scheduler that chooses slot 9 versus slot 13.

`out/active_object_selector45_frontier_gap_audit.*` fixes the current tail frontier around selector `45:0`. This root is not a plain residual: selector directory cell `0x00442de9` resolves to row `0x0044dcc4`, selected root `0x0044dd5c`, `scene-text-group-007`, and `zs_maoh.cns`. Under that root, `opcode2f_prompt_stream_owner_audit` already grounds 15 prompt script rows, 15 opcode `0x2f` prompt commands, and 35 tagged `0x0307` initializer refs. The negative side is equally explicit: selector byte `0x15` has zero `0x00001562` materializer commands, zero `0x00001563` remover commands, zero `0x62 0x15` fragments, and zero reachable selector-0x15 rows. Therefore the event prompt root and its internal scripts are real, but the upper scene/event scheduler that selects `45:0` and activates one concrete initializer remains the unresolved boundary.

`out/selector45_to22_downstream_bridge_audit.*` separates the next internal bridge from that unresolved boundary. Selector `45:0` has 20 root packet runs and exactly 4 runs that post-run into selector `22:0`'s prompt stream `0x00459e8c`; 3 are prompt-linked and 1 remains object-packet consumer-unproven. The selector22 frontier reports the same 4 incoming rows, and the `0x00459e8c` continuation prologue is grounded. The bridge addresses have zero external `.text` references, so this promotes the internal `45:0 -> 22:0` continuation bridge only. It still does not prove the normal-play scheduler that first enters selector `45:0`.

`out/selector45_outer_entry_inventory_audit.*` collects the remaining outer-entry surfaces for selector `45:0` in one place. Direct dword refs to the selector directory cell, row pointer, root, prompt streams, first prompt commands, downstream stream, and `zs_maoh.cns` string all have zero external `.text` refs. Selector-byte `0x15` has zero reachable materializer/remover opcode rows and zero `.text` pattern hits. The only new useful signal is data-only: selector `45:0` appears in one nearby `0x000b` group-list row and one derived record-boundary row, but those rows still have no proven code consumer. Therefore this page keeps `45:0` as `selector45-outer-entry-inventory-exhausted-static-route-producer-blocked`: the group-list is a candidate surface, not a selected-root producer.

`out/selector_group_list_header_target_audit.*` resolves the header fields of those group-list records. The selector `45:0` group-list record at `0x0044dc44` has list start `0x0044dc60`, but its primary header target is `0x00449613`, which falls inside selector root `13:1` (`map5_14i`, `map5_13i`, `map5_11i`, `map5_12i`, `map5_15i`, `map5_16i`, `map5_17i`, `map5_18i`, `map5_19i`, `map5_20i`, `scene-text-group-005`). This makes the row a cross-root adjacency/dependency clue rather than a direct selector `45:0` producer. Promotion remains blocked until a code consumer is found that reads the record/list and writes the selected-root state.

`out/selector_group_list_owner_dependency_audit.*` flips the same data into owner/member form. There are six unique group-list records; five have owner header targets, and four unique owner records contain group `45` as a member. For selector `45:0`, those owners are `13:1`, `29:0`, `42:0`, and `49:0`, while all header-target `.text` refs remain zero. This keeps the group-list surface as an owner dependency/member-list structure, not a normal-play producer for selector `45:0`.

`out/selector13_route_owner_entry_frontier_audit.*` follows the strongest owner/member lead into selector `13:1`. It grounds owner root `0x00444a44`, selector pointer row `0x00443770` / slot `0x00443774`, the local self handoff at `0x00444aa8`, 24 owner prompt scripts, two route-like prompt scripts (`0x00446604`, `0x0044667c`), and the shared script-pointer previous dword tag `0x0000ec03` for all owner prompt scripts. The direct route-entry `.text` ref count is still `0`, so this narrows the frontier but does not promote the outer scheduler/consumer.

`out/selector13_034b_packet_context_audit.*` narrows the same selector `13:1` root through the grounded `0x034b -> 0x0307` packet/list layer. Owner root `0x00444a44` has 23 packet runs, 125 packet entries, six scene-choice runs, and 80 prompt-linked entries. This packet context covers 20 of the 24 selector13 frontier prompt scripts, while also linking adjacent owner-root prompt scripts such as selector `4:1`; that mixed-owner result is important negative evidence. It strengthens local object/prompt ownership, but it is still not the outer scene/event scheduler that chooses the concrete run or prompt.

`out/selector13_missing_frontier_initializer_audit.*` resolves the four selector `13:1` frontier prompt scripts that were missing from the selector13-owned packet context. All four have tagged initializer evidence: three scripts (`0x00447980`, `0x00447a6c`, `0x00447b78`) belong to a cross-root `0x034b -> 0x0307` packet owned by selector `58:0` / root `0x00443400`, and one script (`0x00447c7c`) is grounded by a standalone `0x0307` tagged initializer inside selector `13:1`. This closes the missing-frontier coverage gap, but it is still classified as `selector13-missing-frontier-initializers-grounded-cross-root-scheduler-blocked` because no scheduler/condition has proven why selector `58:0` or the standalone initializer is activated with selector `13:1`.

`out/selector58_to13_postrun_handoff_audit.*` narrows the cross-root half of that finding. It identifies 9 selector `58:0` `0x034b` packet runs / 44 entries that end with `postRunDword=0x00000004` and `postRunNext=0x00444b0c`, where `0x00444b0c` is owned by selector `13:1` and decodes into a grounded prompt/control continuation. Those 9 runs include 23 unique prompt scripts and cover all 3 cross-root missing-frontier scripts. This is promoted only to `selector58-to13-postrun-handoff-grounded-scheduler-blocked`: the handoff itself is grounded, but the upper scene/event scheduler or condition that selects selector `58:0` remains unproven.

`out/selector58_outer_scheduler_frontier_audit.*` tests that remaining upper frontier directly. It scans selector `58:0` row pointer `0x00443308`, root `0x00443400`, selector13 continuation `0x00444b0c`, and sample packet addresses for direct `.text` references. All focus `.text` reference counts are `0`; selector `58:0` is not present in the selected-root writer binding and has no opcode4f mode1 self-setter. The adjacency from selector `56:0` to `58:0` to `13:0`/`13:1` is real data structure evidence, but still not an instruction-bound scheduler. The audit therefore closes this pass as `selector58-outer-scheduler-frontier-data-only-blocked`.

`out/resource_loader_consumer_trace_review.*` traces the next boundary after selector-root resource packaging. It finds 1081 `.cns` strings and 2216 `.cns` pointer refs, all in `.data`; 2158 of those refs fall inside selector-root ranges, and 370 unique CNS names are present under selector-root ranges. The executable also has grounded file/archive loader boundaries: 74 file API call sites and 24 loader/path candidate functions, including `0x00423dce..0x00423f15` with inline `FLDF` magic at `0x00423e3d`. The follow-up bridge scan finds 11 direct calls into loader candidates and 7 loader candidates with callers, but selector-root start/range/row-pointer `.text` refs are all 0, and direct `.text` refs to individual `.cns` string pointers are also 0. This is deliberately kept at `resource-loader-consumer-static-boundary-route-blocked`: selector-root resource packages and file loader boundaries are both real, but the data-flow from selected scene root to loader consumer remains unproven.

The route-relevant selector roots are also now explicitly separated from execution proof:

- selector `0:0` root `0x00501808`: contains `map1_01a`/`map1_02b`, source-side only.
- selector `1:0` root `0x00478364`: contains target-side `map2_*` maps including `map2_02d`, target-side only.
- selector `2:0` root `0x00540714`: contains both `map1_01a` and `map2_02d`, but its row/root references are selector-table-only.

All three route-relevant selector roots currently have `0` `.text` dword refs and no predecessor-to-current root ref, so selector membership does not prove route order or execution.

## Selected Root Consumer

The selected scene/text root consumer is now grounded separately from the full route proof.

- selected pointer global: `0x0059de30`
- current selector/root under review: `2:0` / `0x00540714`
- consumer handler: opcode `0x08` at `0x0040adc9`
- zero-check/read/context switch: `0x0040add6` / `0x0040adfe` / `0x0040ae06`

The byte-verified behavior is:

- opcode `0x07`: writes an indexed pointer into `0x0059de30`
- opcode `0x08`: advances the current stream, checks `0x0059de30`, pushes the return stream, then sets `context+0x40 = 0x0059de30`
- opcode `0x09`: writes either the current stream or an operand pointer into `0x0059de30`
- save loader: writes `selectorGroupTable[save[0x0002]][save[0x0003]]` into `0x0059de30`

This proves the consumer mechanism, not the route. The review now exposes an explicit route-bridge gate list: selected-root external proof is false, real selector `2:0` saves are `0`, source/current bridge hits are `0`, predecessor/current bridge hits are `0`, forward merge bridge hits are `0`, producer/hotspot proof is false, and runtime consumer/watchpoint hits are `0`. Source/predecessor roots currently have 162 opcode `0x08` activators but 0 current-root/current-range producers, so route promotion still requires runtime proof that `0x0059de30 == 0x00540714` at opcode `0x0040adfe`, a captured selector `2:0` save, or a strict `map1_01a` producer/hotspot.

## Selected Pointer Table Xrefs

`out/scene_034b_selected_pointer_table_xref_audit.*` now separates three claims that used to be easy to conflate:

- `0x81` writer role: grounded. All `57` executable dword refs to the `11` selected-pointer tables are real `0x81 index, table` inline operands. They are therefore selected-pointer global writer commands, not arbitrary data refs.
- selected target role: grounded as a decoded bridge. The `57` writer refs expand to `37` selected targets; `19` targets contain prompt commands, and `24` contain nested selected-pointer family opcodes.
- route scheduler: still blocked. The writer commands are VM command-boundary evidence, but the outer scene/event scheduler or condition that reaches each writer remains unproven.

The same audit also imports the slot0 bootstrap selected-pointer handoff from `out/global_object_table_slot_audit.*`, but keeps it separate from the `0x034b` table-ref counts. Slot0 runs `0x81` at `0x0047e664`, writes `0x0059de30` from table `0x004a2cb0[0] = 0x004a2d38`, then `0x82` transfers control through the selected pointer global with return continuation `0x0047e670`. Nearby strings (`middata.mlk`, `compile.cns`, `aaa.cns`, `logo_00.cns`, `title.cns`, `map_k1.cns`, `map_k2.cns`, `btl_k1.cns`, `btl_k2.cns`) classify this as a startup/intro resource root, not a story prompt route producer.

`out/selected_root_setter_operand_boundary_audit.*` folds the selected-root
setter row evidence into one boundary page.  The generic operand/source layer is
now grounded: `57` opcode `0x81` commands write `0x0059de30 =
inlineTable[index]`, all are followed by opcode `0x05`, `15` opcode `0x80`
rows are descriptor slot-cache writes, and `2` opcode `0x82` rows are
selected-root activators/consumers.  The same page keeps the `0x4f` route-owner
self-selector evidence visible (`3` in-root self commands, `1` route selector
without such a command), but explicitly leaves route promotion blocked.  The
remaining missing evidence is still the outer scene/event scheduler that enters
one concrete writer under normal route conditions.

`out/selected_root_writer_owner_root_xref_audit.*` adds the next boundary above
those `0x81` writer commands.  The `57` writers belong to `21` unique owner
roots.  Each owner root has exactly one direct dword reference, every reference
is in `.data`, and no owner root has a direct `.text` reference.  This rejects
the simpler model where normal code jumps directly to a writer owner root by an
immediate pointer.  The remaining producer search should therefore follow the
consumer of those `.data` rows or selector directories, not the writer roots
themselves.

`out/selected_root_writer_owner_data_row_shape_audit.*` classifies those `21`
`.data` rows.  All are resource-like rows: `11` include `middata.mlk` plus
map CNS resources, and `10` include battle/object CNS resources.  This does not
prove the route producer, but it narrows the next static target to the consumer
of resource-row directories that select one of these rows before opcode `0x81`
writes `0x0059de30`.

`out/selected_root_writer_selector_directory_binding_audit.*` then binds those
rows back to `save_scene_selectors.json`.  All `21` writer owner roots match the
selector row `selectedPointerHex`; `18` row pointers match exactly, and the
remaining `3` point to a containing selector row with the owner root at an
internal offset.  This grounds the selector-directory binding layer.  The
remaining missing edge is still the runtime producer of the selector
group/slot, or the scheduler path that chooses one selector row for the current
scene/event.

`out/selected_root_writer_selector_setter_command_audit.*` cross-checks those
`21` writer selector keys against all opcode `0x4f mode=1` selector handoff
commands.  `11` writer selectors have an in-root self-setter, `12` mode=1
commands touch writer bindings when the `19:1 -> 19:0` alias row is included,
and `10` writer selectors have no mode=1 setter command.  Every touched command
still has the common `0x31 00 78 02` flag-clear prologue and common
`0x6d 0:0` + `0x05` return tail.  This is useful coverage, but remains
post-entry evidence; it does not prove the outer scene/event producer.

`out/selected_root_writer_no_mode1_alternative_writer_audit.*` closes the
immediate gap for the `10` writer selectors that have no opcode `0x4f mode=1`
self-setter.  All `10` are covered by opcode `0x81` selected-pointer writer
rows (`23` writer rows total), including prompt-bearing and nested-router
targets.  This means the no-mode1 selectors are not invalid selector entries;
they are explained by another selected-root writer mechanism.  The remaining
missing edge is still the scheduler/resource consumer that reaches those
`0x81` commands.

`out/selected_root_no_mode1_local_fanout_audit.*` expands the only no-mode1
selector with direct refs, `46:0`.  Its two direct refs are not semantic
choice/flag branches; both are local pointer-table overlaps inside a compact
fanout area.  The table points to `7` opcode `0x81` endpoint commands, `6` of
which point at prompt-bearing roots.  This is useful local fanout evidence, but
it still does not prove the outer scheduler because the consumer that indexes
the local pointer table has not been identified.  The apparent low bytes
`0x20/0x38/0x50/0x5c/0x68` are endpoint-pointer low bytes, not promoted VM
opcode starts.

`out/selected_root_no_mode1_local_pointer_table_consumer_audit.*` separates
adjacent tables that were easy to conflate.  The old local fanout table at
`0x004a6df8` is now understood as entries `1..7` of the full opcode `0x0a`
inline fanout table that begins at `0x004a6df4`.  The cell at `0x004a6df4`
is branch index `0`, not a separately proven fallback writer.  The nearby
selected-record table at `0x004a6c8c` is consumed by `8` opcode `0x81` table
operands, covers indices `0..7`, and all eight selected records point at the
common owner root `0x004a6d38`.  This grounds the nested selected-record table
reached after selected-root writer execution.

`out/opcode0a_inline_fanout_pattern_audit.*` scans aligned `.data` dwords whose
low byte is `0x0a` and whose following dwords form a VA pointer run.  There are
`811` such low-byte candidates and `292` pointer-run candidates.  The focus
packet `0x004a6df0` (`0x0008580a`) is the only pointer-run candidate whose
entire run decodes as opcode `0x81` selected-root writer targets: `8` pointers,
all plausible commands, all opcode `0x81`, with cells starting at
`0x004a6df4` and covering the local fanout table cells.  The opcode `0x0a`
handler at `0x0040288a` is grounded: it reads `stream[1]` as a context byte
offset, reads `stream[2]` as the branch count, clamps the byte at
`context[stream[1]]` to `count-1`, and replaces the VM cursor with
`dword[oldCursor + 4 + selectedIndex*4]`.  For the focus packet this means
`context[0x58]` selects one of the eight opcode `0x81` selected-root writer
targets.  Therefore the local inline fanout consumer is promoted.  The writer
of `context[0x58]` and the outer scene/event route producer that enters
`0x004a6df0` remain blocked.

`out/opcode10_context58_producer_audit.*` grounds the local writer immediately
before that fanout.  The unique command `0x004a6de8: 10 b0 58 00` is handled by
opcode `0x10` at `0x00402d2e`; byte checks show this mode copies
`byte(context+a8[0])` into `context[0x58]`.  The following local command
`0x004a6df0: 0a 58 08 00` then consumes that byte as the eight-way inline
fanout index.  This promotes the local index producer/consumer pair, but it
still does not identify the outer scene/event scheduler that enters
`0x004a6de8` or initializes `context+a8[0]`.

`out/opcode10_stateblock0_entry_stub_audit.*` grounds the local initializer for
that `context+a8[0]` source.  Eight entry stubs at `0x004a6cb8 + index*0x10`
have the exact shape `43 00 00 00 ; 10 c0 00 index ; 03 00 00 00 38 6d 4a 00`.
Opcode `0x43` selects state block `0x004576d8` as `context+a8`; opcode `0x10`
mode `0xc0` writes the immediate `index` to `stateBlock[0]`; opcode `0x03`
jumps to common root `0x004a6d38`.  Combined with the context[0x58] producer
above, the local `entry stub -> stateBlock[0] -> context[0x58] -> opcode0a`
chain is grounded.  The scheduler or event record that chooses one of those
eight entry-stub addresses is still blocked.

`out/opcode81_entry_stub_table_writer_audit.*` grounds the selected-pointer
writer layer immediately before those entry stubs.  The table at `0x004a6c8c`
contains the eight entry-stub addresses `0x004a6cb8 + index*0x10`, and all
eight direct refs to that table are inline operands of opcode `0x81` commands:
`81 index 00 00 8c 6c 4a 00`.  The opcode `0x81` handler at `0x0040ad9b` is
byte-checked to read `stream[1]` as the table index, read `dword[stream+4]` as
the table pointer, store `dword[table + index*4]` into selected pointer global
`0x0059de30`, and advance the cursor by eight bytes.  This proves
`opcode81 -> selected pointer global -> entry stub table` for indices `0..7`;
it still does not prove the outer scene/event scheduler that reaches a
concrete opcode `0x81` command site.

`out/opcode81_entry_stub_writer_context_audit.*` grounds the local owner/root
context for those same eight writer commands.  All eight writer sites decode on
command boundaries inside packet-owned selector roots:
`22:0`, `9:0`, `18:0`, `50:0`, `14:0`, `0:0`, `34:0`, and `5:0`.
Five of the eight have a prompt command in the nearby before-window, and all
eight are immediately followed by opcode `0x05`.  This upgrades the local stream
context from raw byte windows to owner-root command context, but it still does
not prove the upstream scheduler or scenario condition that enters those roots.

`out/opcode81_entry_stub_self_setter_span_audit.*` narrows the six
map-midi-resource entry-stub writers whose owner roots also contain a local
opcode `0x4f` mode-1 self-selector setter before the opcode `0x81` writer.
All six setters precede their writers, so the local ordering is grounded.
However, the setter-to-writer spans contain substantial intervening stream
content: 218 prompt commands, 28 selected-pointer opcodes, 1446 branch-like
commands, and one span with 9126 commands between setter and writer.  This
therefore remains local owner-root context only and must not be promoted to the
outer scene/event scheduler or a route-specific producer.

## 0x034b / 0x0307 Execution Model

`out/scene_034b_0307_list_execution_model_audit.*` grounds the visible `0x034b -> 0x0307,target...` rows as sequential byte-VM commands, not a hidden variable-length list consumer. `0x034b` is `opcode 0x4b mode 3`, while every `0x0307,target` row is `opcode 0x07 mode 3` with an 8-byte command width. The `0x07` handler byte checks prove that it allocates a child context, stores the dword operand into child `+0x40`, stores the child pointer into parent `+0x58`, and advances the parent cursor by 8.

This rejects the model where the engine picks one `0x0307` row directly as the selected option. Choice selection analysis should instead stay on child script branch flow: `scene_choice_handler_semantics_review.*` and `scene_034b_child_branch_target_audit.*` ground choice-result compare branches through opcode `0x13`/context `+0x3a`. `scene_choice_option_value_base_audit.*` further grounds the selected result value itself as zero-based: the `0x18` handler clamps/wraps against `optionCount - 1`, and all `119` opcode13 choice branches fall inside a matching `0..N-1` marker range, including `31` value-0 branches. The global displayed-text label binding still remains partial because some prompt entries contain nested/merged choice menus at the same result offset; the route scheduler also remains blocked.

`out/scene_034b_prearg_scalar_false_positive_audit.*` closes a misleading xref split in the same layer. The real `0x5a <preArg> 0x034b` descriptor shape has `370` runs and `882` direct preArg refs, all in `.data` with `0` `.text` refs. The only preArg `.text` refs in the broader scan are non-`0x5a` scalar values `0x6d` and `0x84` (`7 + 25` refs), not pointer-like descriptor/list roots. These refs are therefore false positives for a route-specific scheduler or list consumer.

`out/scene_0307_active_object_runtime_bridge_review.*` now mirrors the compound wrapper closure directly: the `31` choice-adjacent `0x0307` targets split into `29` strict active-object initializers plus `2` wrapper targets whose tagged child initializers resolve to text/prompt active scripts. `out/scene_choice_0307_spatial_initializer_audit.*` keeps that distinction visible as `29` strict spatial initializers, `2` compound-explained candidates, and `0` remaining unmatched targets after compound wrapping. Structurally all `31` targets are explainable, but the selected option order and the outer route-specific scheduler remain unproven.

## Selected Root Producer/Hotspot Review

The producer/hotspot side is separately blocked.

- source/target under review: `map1_01a -> map2_02d`
- selector/root under review: `2:0` / `0x00540714`
- source/predecessor opcode `0x08` activators: `162`
- source/predecessor current-root/current-range producers: `0` / `0`
- opcode `0x4f` mode1 selector writers: `27` total, `23` self-writers, `4` cross-writers, `0` external-to-current selector `2:0` writers
- opcode `0x4f` mode1 is not a universal root-entry prologue: only `23` of `94` selector roots contain a mode1 row, while `71` selector rows have no such row.
- the `4` cross-writers target slot `0` from slot `1` roots (`13:1 -> 13:0`, `4:1 -> 4:0`, `19:1 -> 19:0`, `3:1 -> 3:0`), so they are classified as slot-alias normalization candidates rather than route producers.
- route-relevant opcode `0x4f` rows (`0:0`, `1:0`, `2:0`, `10:0`, `17:0`) are all root-local self-writers and therefore do not promote a pre-entry producer
- opcode `0x4f` mode1 continuation is now grounded: after writing selector bytes it switches to stream `0x004dc514`, whose first save-selector opcode is `0x08` handled by `0x0040adc9`, the selected-root consumer. Mode0 starts at `0x004dc518`, exactly `mode1+4`, so it skips that first consumer opcode. This proves the selector-byte-write -> selected-root-consumer continuation mechanism, but still does not prove who entered a root-local self-writer.
- `out/selector_root_preentry_ref_review.*` checks direct references to the route-relevant root starts and root-local `0x4f` self-writer rows. All four route root-start refs are selector-table selected-pointer cells, exact self-writer dword refs are `0`, exact root `.text` refs are `0`, and source/predecessor -> current `2:0` range refs are `0`. It exposes `75` aligned refs from address-predecessor selector `10:0` into current `2:0`, but the bridge is fully classified as data/child-subentry structure rather than route execution proof: `1` selector-table current root cell, `20` opcode04-to-object-script entries, `9` descriptor `0x5a -> 0x034b` current-range entries, `33` tagged `0x0307` entries, `9` opcode04 display continuations, `2` actual-dispatcher flag branches, and `1` actual-dispatcher flag write. The `0x31`/`0x32` rows must be interpreted through the actual byte dispatcher table at `0x00440538`; the older local-base `0x00440720` interpretation is rejected because that address is actual opcode `0x7a`, not a second dispatcher base.
- `out/selector_root_address_predecessor_bridge_audit.*` follows that `10:0 -> 2:0` bridge one level deeper. The 75 bridge rows resolve to `48` unique targets: `42` rows are descriptor/`0x0307` data entries, and `33` command-like rows walk to local object/flag/stop/current-root self-writer flows. The walk reaches `1` local prompt, `0` selected-root commands, `0` map-loader refs, and `0` route proofs, so this bridge is now classified as a current-root data/subentry bridge rather than a pre-entry selected-root producer.
- `out/scene_flag_01f5_selected_pointer_route_audit.*` grounds one selected-pointer `0x32` flag branch on flag word `0x01f5`: both branch arms write selected pointers, and three generic VM flag writer candidates (`0x0045a0a4`, `0x0045a160`, `0x0045a21c`) belong to selector `22:0` with maps `map7_09k..map7_12k`. These writers are prompt-linked to hell-bottom return/escape contexts, and selector `22:0` has `12` runs / `47` entries with `9` same-root post-run continuations containing writer command-boundary hits. This is `grounded-context` for the flag lifecycle, not route promotion: the normal-play scheduler path that enters selector `22:0` and executes the writer/branch sequence is still blocked.
- `out/save_selector_target_alias_bridges.*` classifies that `10:0 -> 2:0` bridge candidate. The target-side alias set is `1:0`, `10:0`, `17:0`; all `75` forward hits come from address-adjacent `10:0`, while logical/public target alias `1:0` and alias `17:0` have `0` forward hits. The sole exact current-root hit is selector-row metadata, not executable data. The `10:0` data hits include `65` pre-writer-script-range hits and `9` leaf-table-window hits, with `2/2` corrected/effective leaf-reader hits, but all traces to the current writer/reader/scene records remain `0/0/0`. Therefore the bridge is classified as `address-adjacent-alias-data-only`, not execution proof.
- `out/save_selector_mapset_aliases.*` shows why the alias scan still matters: current selector `2:0` equals the target-side map set plus `map1_01a`, and `10:0` is address-adjacent to `2:0`. This supports selector list recomposition/aliasing, but address contiguity explicitly does not prove execution.
- `out/save_selector_target_alias_state_effects.*` narrows the branch-state value side only. If `1:0` or `10:0` executed and its `0x00000210` fill persisted into current `2:0`, the current writer/reader gate would pass for all modeled starts. That conditional is still unproven: actual alias execution, state persistence, gated control path to `0x00542b0c`, and strict map1_01a source hotspot remain missing.
- `out/save_selector_selected_root_execution_gap.*` keeps selected-root execution blocked for `2:0` / `0x00540714`. The save-loader path has no real selector `2:0` sample, the `0x00440720` dispatch slice is still static-slice evidence, direct current-root refs are table-only, global opcode `0x07`/`0x08`/`0x09` paths find no non-current current-root/range producer, and runtime/public probes do not observe `0x0059de30` reaching `0x00540714`. The patched public selector `2:0` route hit is explicitly diagnostic-only and excluded, so the report remains `selected-root-no-real-selector-no-execution-ref-diagnostic-excluded`.
- `out/save_selector_route_pair_index_source_gap.*` keeps the higher-level route-pair index source blocked. Route-pair entries `6` and `8` and negative wrapper entry `-12` have no code-backed direct source refs: their direct refs are opcode `0x5a` mode0 fallthrough words with non-code low-byte handlers, descriptor refs are leaf-table cells, child refs are descriptor child words, encoded entry anchors stay raw/non-promoting, and opcode `0x07` selects no leaf-table/current/wrapper/frontier slot.
- `out/selected_root_execution_external_proof_packet.*` is the broader accepted-evidence checklist for selected-root execution. It keeps `selectedRootExternalProofFound=False`: real selector `2:0` save evidence is missing, normal runtime selected-pointer proof is missing, non-current current-root producer proof is missing, and entry/wrapper normal selection proof is missing. Savedata-derived proof remains parked, so the save-loader subgate currently records `real=0`.
- `out/save_selector_merge_execution_gap.*` classifies selector `2:0` as merge-shaped but not executed. It is the only selector containing the route pair and can be described as target-side predecessor `1:0` plus `map1_01a`, but source/current bridge hits are `0/0`, predecessor/current forward bridge hits are `0`, encoded merge execution is false, and the `10:0` alias bridge remains address-adjacent data only.
- `out/save_selector_predecessor_route_order.*` and `out/save_selector_predecessor_persistence_gap.*` narrow the inherited-state candidate. Selector `1:0` is immediately before `2:0`, no intermediate selector exists, predecessor fill `0x00000210` would pass the current reader, and the current root has no known before-frontier overwrite. This is still not route proof because `1:0` is target-side only, the confirmed source-side route overlaps selector `0:0`, and `0:0 -> 2:0` merge order is unproven.
- `out/save_selector_secondary_global_reset_gap.*` closes the obvious static reset shapes for `secondaryBranchState`: there are no direct global secondary writers, no overlapping block-write reset, no valid current before-frontier fill, and no predecessor tail reset. The remaining reset uncertainty is runtime order or an untraced VM/helper path, not a visible static reset.
- `out/save_selector_predecessor_descriptor_bridge_gap.*` and `out/save_selector_predecessor_fill_execution_order_gap.*` close the obvious predecessor bridge attempts. The predecessor fill fragment at `0x004844d0/0x004844d8` is a real local stream fragment, but fixed traversal from the predecessor root does not reach it, descriptor closures do not bridge to the fill/current reader, encoded scalar matches are non-promoting, and runtime fill observation is absent.
- `out/save_selector_route_pair_entry_execution_gap.*` and `out/save_selector_wrapper_execution_gap.*` close the leaf-table corrected-reader question. Current selector `2:0` has route-pair entries `6` and `8`, and opcode `0x2c` corrected traces from both entries reach reader `0x00542b0c`. This is explicitly classified as `corrected-trace-not-normal-selection-proof`: opcode `0x07` does not select those entries, source/predecessor opcode `0x08`/`0x09` paths do not produce the current root/range, direct entry-pointer refs are non-code opcode `0x5a` fallthrough words, and the reader-bearing wrapper is negative entry `-12` outside the current root run.
- `out/current_leaf_wrapper_external_proof_packet.*` summarizes the accepted evidence boundary. It keeps `currentLeafWrapperExternalProofFound=False`: selected-root execution, higher-level entry index source, wrapper execution, current selector leaf execution, and strict source hotspot are all still missing. Corrected route-pair traces are not accepted as route execution proof until a normal-route selected-root/index/wrapper path is proven.
- strict hotspot candidates: `4`, all external-review only
- frontier reader branch: partial only. The same `secondaryBranchState[selectionBuffer[0x20]]` slot is preserved from writer to reader, but runtime state value and control path are not proven.

This keeps the current static selected-root producer and map1 strict-hotspot scans exhausted until new evidence appears: a runtime watchpoint, a captured selector `2:0` save, a strict source hotspot/event row, or a deeper VM proof that reaches `0x00542b0c` with the required branch state.

## Active Object Allocator Callsites

`out/active_object_allocator_callsite_audit.*` classifies all direct calls to the active-object allocator `0x00435b5b`.

- direct allocator calls: `85`
- all calls classified: `true`
- generic child-runner update function: `0x00402321`
- generic child-runner calls: `82`
- opcode07 child-spawn call: `1`
- event-object dispatcher calls: `2`
- specialized active-object update call: `1`

The opcode07 handler at `0x00402549` reads the mode byte from `stream+1`, passes it dynamically via `push eax`, pushes update function `0x00402321`, and calls the allocator. This grounds `0x0307` rows as child object creation commands, not as a hidden variable-length list consumer.

The allocator audit closes a separate ambiguity from the `0x034b/0x0307` layer: object creation roles are now known, but allocation itself still does not prove why a specific child object or prompt stream was selected. The route-specific scheduler remains blocked upstream of the allocator.

## Generic Child Runner Contexts

`out/generic_child_runner_context_audit.*` splits the 82 generic child runner (`0x00402321`) allocations by caller context.

- all generic child-runner calls classified: `true`
- context+0x40 opcode07 child spawn: `1`
- event `context+0xb0` child spawns: `3`
- visible-record script spawn: `1`
- battle/effect helper calls: `66`
- UI/menu layer calls: `6`
- system script bridge calls: `3`

This narrows the remaining blocker.  The event `+0xb0` and opcode07 paths prove child/substream handoff semantics, while the UI and battle clusters are now separated from scene/event routing.  None of these caller contexts is promoted as the normal selected-root route producer; that owner remains upstream of child-runner allocation.

`out/generic_child_runner_upstream_owner_audit.*` follows the nine non-battle/non-UI owner candidates one step farther upward.

- audited owner candidates: `9`
- direct script wrapper: `0x004022f0`, caller `0x00411426`
- script pointer global: `0x0047e358`
- global runner object table: `0x0059dd70`
- event object constructor: `0x0041b622`, callers `0x00405ca9`, `0x0041d599`
- visible-record script spawn: `0x00428410`, caller `0x00405d8d`
- rows touching selected-root or map-loader refs: `0`

The direct wrapper is a runtime global script/object table path, and the event `+0xb0` rows still hand control to child runners rather than proving the owning scene/event scheduler.  This audit therefore keeps the route-specific selected-root producer blocked, but rules out these nine child-runner owners as direct selected-root/map-loader producers.

## Active Object Non-Prompt Scripts

`out/active_object_nonprompt_script_taxonomy.*` classifies the remaining active-object scripts whose inventory classification was `script-no-text-no-map-proof`.

- non-prompt scripts: `150`
- all non-prompt scripts classified: `true`
- action/evaluate then stop scripts: `109`
- group-slot state scripts: `26`
- action/evaluate control scripts: `12`
- one-off control scripts: `flag-branch-control-script` `1`, `generic-control-entry-script` `1`, `stop-only-script` `1`

This report keeps object interaction/state helpers visible without over-promoting them.  The dominant pattern is an object-local `0x24` action/evaluate command followed by stop, while the `0x6d` group-slot scripts show stateful object flow.  None of the 150 rows is promoted as a route-specific selected-root producer.

`out/active_object_group_slot_state_audit.*` follows the `26` non-prompt `0x6d/0x6e` group-slot scripts through local branch and attach targets.

- walked group-slot scripts: `26`
- prompt commands reached through local flow: `24`
- selected-root family commands reached: `0`
- map-loader refs reached: `0`
- route proof count: `0`
- attach-script targets: `5`
- state writes: `1`

This closes the group-slot layer as object-local state/prompt-adjacent flow for now.  It is useful evidence for object interaction scripts, but not a route-specific selected-root producer.

`out/active_object_action_control_audit.*` follows the `12` non-prompt `0x24 action/evaluate` scripts that do more than immediately stop.

- action-control scripts: `12`
- continuation targets: `0x00451ad0` `9`, `0x00451b4c` `3`
- prompt commands reached: `0`
- selected-root family commands reached: `0`
- map-loader refs reached: `0`
- route proof count: `0`

These scripts are now classified as local object action/evaluate flows ending in opcode `0x76` continuations, not scene route producers.

`out/active_object_residual_control_audit.*` closes the last `3` non-prompt control rows.

- residual scripts: `3`
- classes: `flag-branch-control-script` `1`, `generic-control-entry-script` `1`, `stop-only-script` `1`
- prompt commands reached: `1`
- selected-root family commands reached: `0`
- map-loader refs reached: `0`
- route proof count: `0`

The one flag-branch residual can show a local prompt, but none of the residual rows reaches selected-root or map-loader route evidence.

## Branch/Flag Review

The branch/flag side is now split into grounded values and blocked route proof.

- active-selection flag: `0x00457744`
- static/startup default: `0x01`
- save override offset: `0x006c`
- writer/reader pair under review: opcode `0x12` at `0x005428bc` -> opcode `0x11` at `0x00542b0c`
- shared table/slot: `secondaryBranchState[selectionBuffer[0x20]]`
- known opcodes between writer and reader preserve the same slot: true
- predecessor-fill narrowing: selector `1:0`, fill `0x00000210`, all starts pass under that hypothesis
- event/object writer candidates linked to current route: `0`
- selected-pointer route flag `0x01f5`: branch and writer lifecycle grounded in selector `22:0`, but route-specific producer remains blocked

This promotes the active flag default and the writer/reader slot equation to grounded/partial review evidence. It still does not promote the route because the selected branch-state value, normal control path to `0x00542b0c`, predecessor execution/persistence, strict source hotspot, and real selector `2:0` runtime/save state are not proven.

## Runtime Watchpoint Attempt

`tools/probe_runtime_selected_root_consumer_watchpoint.py` targets the exact selected-root consumer path:

- selected pointer global `0x0059de30` -> runtime `0x002bde30`
- consumer read `0x0040adfe` -> runtime `0x0012adfe`
- current root `0x00540714` -> runtime `0x00260714`

The probe currently remains blocked. qemu/gdbstub can set breakpoints, but the relocated addresses are not mapped at the initial stop, the remote connection closes before a real consumer hit, and hardware watchpoint insertion fails. Therefore it records `consumerHitProbeCount=0`, `routeValueProbeCount=0`, and does not promote the route.

## Grounded Opcodes

| opcode | handler | length | role |
| --- | --- | --- | --- |
| `0x02` | `0x0041b771` | `0x4` | display cursor update |
| `0x03` | `0x0041b7bb` | `0x4` | display state update |
| `0x04` | `0x0041b7ed` | `0x4` | display timer setup |
| `0x06` | `0x0041b8ee` | `0x4` | input/wait latch |
| `0x07` | `0x0041b956` | `0x8` | object position |
| `0x08` | `0x0041b9a0` | variable | display style/palette |
| `0x09` | `0x0041bac6` | `0x8` | control-flow call |
| `0x0a` | `0x0041bb15` | stack-pop | control-flow return |
| `0x0b` | `0x0041bb4c` | `0x4` | text source |
| `0x0c` | `0x0041bb99` | `0x14` | text/object source child allocation |
| `0x0d` | `0x0041bca4` | `0x8` | text source index/cursor seed |
| `0x0e` | `0x0041bd4f` | `0x8` | cursor relative move |
| `0x15` | `0x0041d476` | `0x8` | cursor origin relative move |
| `0x1b` | `0x0041d89d` | `0x4` | data bank select |
| `0x37` | `0x00420028` | `0x4` | global timer setup |

## map1_01a First Scene Trace

`scene-text-group-029` / `scene-seq-029-01` is the current best candidate for the first `map1_01a` text flow. It starts with:

- `여긴 호랑이권법가 / 아타호가 사는 곳!`
- `아타호는 동굴에서 / 한가롭게 지내고 있다`
- early choice: `한가한 게 좋지, 잠이나 잘까` / `한가한데 쇼핑이나 할까`

This sequence is useful for review, but it is not promoted to `confirmed` because the current evidence is selector-root range evidence rather than direct normal field-scene execution proof.

## Prompt Sequence / Choice Boundary Review

`scene-text-group-029` / `scene-seq-029-01` is now split into prompt rows, command boundary rows, and choice boundary rows:

- review page: `web/scene_event_vm_prompt_sequence_review.html`
- artifact: `out/scene_event_vm_prompt_sequence_review.json`
- selected root range: `0x00501808` .. `0x00503480`
- prompts shown: `32` of `128`
- choices shown: `4` of `8`
- command rows shown: `160`
- visible boundary opcodes: `0x0b` render, `0x06` wait, `0x18` choice marker, `0x09` branch-call, `0x35` literal/control payload, `0x00` end/clear

The prompt render/wait boundary is grounded within the candidate trace, and several choice rows show nearby `0x18` choice markers plus `0x09` branch-calls. The `0x18` choice marker in this trace is a 4-byte record such as `40 18 3a 02`; the following `40 00 00 00` is the next command and must not be absorbed as an inline target. This improves reviewability but does not prove the selected option target. The sequence must still be treated as `partial`/`blocked` around choice branches, because direct scene record -> prompt root binding and selected choice -> next prompt edges are still missing.

The `map1_01a` trace is also explicitly mixed-quality review data:

- command rows shown: `160`
- grounded command rows: `24`
- candidate command rows: `136`
- default-handler rows: `111`, currently opcodes `0x00` and `0x01`

The default handler at `0x0040239f` only advances `context+0x40` by 4 bytes and returns. Therefore `0x00`/`0x01` rows in this trace are useful as boundary/context clues, but they are not promoted to route execution proof without command-start binding.

## Choice Target Review

`0x004bfdb4` is now reclassified as a common display/menu stream, not as a selected option -> next prompt target.

- review page: `web/scene_event_vm_choice_target_review.html`
- artifact: `out/scene_event_vm_choice_target_review.json`
- common stream: `0x004bfdb4`
- common stream block: `event-dialogue-block-021`
- common stream classification: `system-text-like`
- sample text: `처음부터`, `이어서하기`, `시나리오 선택`, `미니게임`, `아타호의 집`, `되돌아감`

The choice-target handler cluster is now separated from the prompt trace, but it is **not** proven to be the selected prompt-choice edge:

- `script_handler_table` opcode `0x16` handler `0x0040ba3f`: reads `stream+0x04`, writes selected target global `0x0059e2a0`, advances by 8.
- `script_handler_table` opcode `0x18` handler `0x0040bab2`: advances by 4, compares `0x0059db1e` and `0x0059db1f`, checks active flag `0x00457749`, and when active sets `context+0x40 = [0x0059e2a0]`.
- Prompt trace marker `40 18 3a NN` is also 4 bytes, but the prompt trace does not prove that it dispatches through the `script_handler_table` `0x18` handler.
- The selected `map1_01a` prompt trace currently shows `0` opcode `0x16` producer rows.

Therefore the selected option -> next prompt edge remains blocked. The remaining proof is either a binding from the prompt trace to the `0x16 -> 0x59e2a0 -> 0x18` handler cluster, or a different producer path for the actual user choice cursor/confirm result.

The global prompt choice marker argument scan currently sees `267` `40 18 3a NN` rows:

- exact visible line-count matches: `129`
- low-6-bit visible line-count matches: `172`
- high-bit marker rows: `125`

This partially characterizes `NN`: plain low values often equal the visible choice count, but high-bit values appear to carry menu/layout/flag context or merged-menu state. It is not a next-target pointer.

## Random Gate Review

`0x0059db1f` is no longer treated as a user-selected choice index. It is grounded as a random-gate success counter.

- review page: `web/scene_event_vm_random_gate_review.html`
- artifact: `out/scene_event_vm_random_gate_review.json`
- internal random function: `0x00427730`
- random gate tick: `0x004330e0`
- success threshold: `0x0059db1c`
- required success count: `0x0059db1e`
- success counter: `0x0059db1f`

The gate formula is:

- `rand16_mod`: `seed = seed * 0x41c64e6d + 0x3039; result = ((seed >> 16) & 0xffff) % arg`
- `gate tick`: if `rand16_mod(10000) < [0x59db1c]`, increment `[0x59db1f]`
- `script_handler_table` opcode `0x18`: if `[0x59db1e] <= [0x59db1f]` and active flag `0x00457749` is nonzero, jump to `[0x0059e2a0]`

This improves the handler-cluster analysis by excluding a false route: `0x59db1f` is a probabilistic gate counter, not a selected option number.

## Prompt Producer Frontier

The current selected-root / prompt-producer goal is frozen in the compact
handoff artifact:

- runtime evidence handoff page: `web/scene_event_runtime_evidence_handoff.html`
- runtime evidence handoff artifact: `out/scene_event_runtime_evidence_handoff.json`

The grounded pieces are:

- selected root consumer and generic selected-root global writer are verified.
- selector byte writer is generic and grounded.
- route-like local prompt pipeline is grounded for selectors `13:1`, `14:0`, `18:0`, and `34:0`.
- `0x034b` / `0x0307` packet walking, child runner lifecycle, descriptor stack add/remove, and pointer-run consumer paths are grounded as generic mechanisms.
- selector `58:0 -> 13:*` post-run handoff is grounded as data/control adjacency.

The latest negative checks are equally important:

- `34:0` expected selector command bytes `4f 01 22 00` have no exact opcode `0x4f` mode1 command hit.
- direct `.text` refs to route-specific roots, terminal values, and selector group-list record cells are zero for the currently tested route-like frontiers.
- group-list code-pattern and tag-literal consumer scans found no instruction-bound consumer for the route-like focus rows.
- runtime-index writer opcodes `0x62` and `0x63` are generic active-object add/remove handlers, not route-specific producers.

Therefore the current completion audit intentionally reports `do-not-call-update-goal`. The remaining missing proof is the upper scene/event scheduler or condition producer that chooses one concrete selector/root before the generic selected-root consumer runs. The next useful evidence is one of:

- a runtime watchpoint/trace for writes to `0x004576da`, `0x004576db`, or `0x0059de30`;
- a runtime trace of descriptor-run order/count values around `0x004576e8` / `0x004576e9`;
- a newly identified instruction-bound scheduler/list consumer that is outside the exhausted direct xref, terminal closure, selector-pair, runtime-index, and group-list scans.

## Gap Policy

The following stay as gaps instead of being forced into a route model:

- route-linked event VM execution proof
- full instruction length/operand layout for non-target opcodes
- direct `map1_01a` scene dispatch root binding
- direct scene-to-prompt pointer reference

When continuing, only decode additional partial opcodes if they appear in the current target trace. Do not expand into all route transitions or savedata proof from this goal.
