# ✅ What appends to the trigger queue — built-in 25, not the engine [`structures/isl-builtins.md`](structures/isl-builtins.md) took the trigger queue at `phase+272` a long way — its layout, its live count at `+272+20`, and the generic appender `sub_8226EAB8` — and stopped at: *"What actually appends a node is still unidentified."* Its suggested next step was a **gdb watchpoint** on a running emulator. It is a static question after all. ## The search that works `sub_8226EAB8` is a shared list helper with 16 callers, so it cannot be identified by name. But the corpus records that the trigger container **embeds its inner list at `+12`**, so the caller must hand it `container + 12`. Two of the 16 do: ``` 0x8226E208 addi r3, r30, 12 0x8226A2B4 addi r3, r29, 12 ``` and in the second, `r29` is set 34 instructions earlier: ``` 8226A22C addi r29, r24, 272 ; r24 = the ScriptPhase 8226A2B4 addi r3, r29, 12 ; -> phase + 272 + 12 bl 0x8226EAB8 ; the generic append ``` `phase + 272 + 12` is exactly the inner list whose count the corpus watched at `phase + 272 + 20`. **`sub_8226A0D8` is the appender.** ## 🔑 And it is a BUILT-IN, so the script appends its own triggers `sub_8226A0D8` is **ScriptPhase vtable slot 28**, and slot 28 is what **built-in 25**'s stub tail-calls. Its entry is the standard built-in shape — `r3` = the phase, `r4` = the `local[]` base, `[phase+324]` indexed by `local[4]`. **There are ZERO real `bl 0x8226A0D8` instructions in the image.** It is reached only through the vtable, i.e. only as a built-in. So the queue is populated by the **script**, not by the engine — which retires the residual "the engine moves records into the phase's queue each frame" reading that `isl-builtins.md` already flagged as unsupported by its call site. Built-in 25's argument shape agrees with the corpus's independently measured tables: it is in `UNIT_ARG` (a unit at `local[4]`) and in `SYM1_SLOTS[12]` (a symbol-table-1 name — a route, message or objective — at `local[12]`). ## 🔴 REFUTED: this does not explain the unreachable routines The attractive next step was that built-in 25 carries the coroutine entry a trigger fires, which would have seeded the 389 routines reachable from no static entry. It does not. At Stage 02's built-in 25 sites, taking each staged operand as a code offset from the phase base: | staged slot | values | landing on an instruction boundary | |---|---|---| | 0 | 2 | **0 — 0 %** | | 4 | 2 | **0 — 0 %** | | 8 | 2 | **0 — 0 %** | | 12 | 2 | **0 — 0 %** | | *control:* an arbitrary 4-aligned offset | — | **38.7 %** | Nothing scores even at chance. And the scale is wrong anyway: built-in 25 has **only 2 call sites in Stage 02** — far too few to account for ~15 % of the code being unreachable. So the trigger queue is now identified, but **what starts the unreachable routines remains open**, and it is not this. ## 🟡 Not settled * **What a trigger node contains**, and what consumes it. The append is located; the node's own layout is not read. * **The other `+12` caller**, `0x8226E208` in `sub_8226E160`, appends to some other embedded list — not shown to be the trigger queue. * **Built-in 25 is still unnamed.** "Appends to the trigger container" is what it does mechanically; what the trigger *means* needs the consumer.