traps: rows 51 to 53, the museum's missing rows and a BACK with no box under it

The reproduction, the three surveys and the before/after for the rung-10 Pewter stall, with the
ROM-gated run's table. Rows 51 (UNKNOWN's two states), 52 (a building with no row on the map
graph) and 53 (a frontier excluded by a window that lapses) each with their tests.
This commit is contained in:
acamilo 2026-09-22 13:14:47 +00:00
parent e9f5d693bb
commit d5a21e9a5d
2 changed files with 82 additions and 0 deletions

View file

@ -1941,3 +1941,81 @@ checkpoint's own half-finished conversation plus the one `NO` that answered the
- `infra/tests/lint.sh`: all checks passed, de-PII guard included. - `infra/tests/lint.sh`: all checks passed, de-PII guard included.
- `--print-compatibility`: **648 bytes, sha256 `0d9bfde7...707fa`** -- byte-identical to v0.4.1 - `--print-compatibility`: **648 bytes, sha256 `0d9bfde7...707fa`** -- byte-identical to v0.4.1
through v0.4.4. Decoder, reward catalog, adapter version and roles untouched. through v0.4.4. Decoder, reward catalog, adapter version and roles untouched.
## 2026-09-22, rows 51 to 53: the road the museum had no row for, and a `BACK` with no box under it
Flagged live by the watchdog within the hour of v0.4.5 going out: rank 10 (PEWTER CITY) for five
and a half hours, the objective rung 11's BOULDER BADGE whose place is the gym leader in map
`0x36`, and since the 11:30 restart the macro starts were `GO FRONTIER` **1,235**, `BACK` **678**,
`GO OBJECTIVE` 267, `GO OUT` 242, `YES` 169. Between 11:46 and 12:17 the ratchet fired **two**
"Stuck: rolled back to PEWTER CITY" recoveries, attempts 0 -> 2. The fly was on map 52, the Pewter
museum's ground floor. This is the residual the row-41 review named: `BACK` 189 times "in a text
box" on map `0x02`, surrounded by `GO OBJECTIVE` and `GO FRONTIER`, with `GO FRONTIER` runs of 112.
`docs/design/macros.md` sections 12.13 to 12.16 are the design; this is the reproduction, the
surveys and the before/after.
### Where the fly was standing
`examples/scene_probe.rs` from the live checkpoint:
- map `0x34` (52), **20x8**, the player at **(10, 7)** facing up -- standing on the museum's own
front doormat, one of four `LAST_MAP` warps on the south wall;
- the scene reads **`Unknown`**, not `Dialog`: `font=0x00` and **no text box at all**
(`corners=(0x10,0x10,0x10,0x10)`), with `flags5=0x24` -- the cartridge holding the joypad. The
pad is **`NEXT`, `BACK`**;
- the objective is map `0x36` and `next_hop(Region { map: 52 }, 0x36)` answers **`None`**, because
`neighbours(52)` is **empty**: the museum has no row on the map graph. So
`objective_goals` is `[]`, `GO OBJECTIVE` is off the pad, and so are `GO SHOP` and `GO HEAL`;
- the map grid decodes: **98 walkable tiles, 62 reachable from the door, 39 never stood on** --
and `frontier_aims` offers **40** of them, almost all behind the admission desk on the east side.
### The three mechanisms, and none of them is the text box
1. **`BACK` was never in a text box.** It is on no overworld pad and on no dialog pad, so every one
of the 678 was dealt by `Scene::Unknown` -- which is two states under one name. A screen this
crate cannot name (the Pokedex, the trainer card, OPTION) is one, and the hunt's own attribution
counts `unknown` frames as "a text box" (`dialog_map`), which is what made the residual read the
way it did. The other is a frame of the **overworld** with the cartridge driving: `detect`'s
overworld branch needs `controllable`, and a warp in flight, a scripted push-back or a guide
walking the fly through a door all fail it. `NEXT` and `BACK` there are an A and a B pressed into
somebody else's script.
2. **The museum is not on the map graph**, which the row-41 review named as a residual and left:
"adding the row would give the fly the road to the gym from indoors". Both rows come from the
cartridge's own warp table rather than from counting: Pewter City names `0x34` at (14, 7) and at
(19, 5) -- the museum's two doors -- and `0x34` names `0x35` at (7, 7), the staircase.
3. **The museum's frontier is unreachable and the blocked ledger is a window.** A `GO FRONTIER`
that can reach none of its goals refuses `no route` and writes all forty tiles to the ledger;
ten brain minutes later they are candidates again and it refuses again, once per hold.
And the ratchet's two rollbacks were the ratchet working to contract: its stall window is restarted
by *exploration*, and two museum floors and a town the run had already covered earn none. Entering
a map for the first time does count -- a new map is a map's worth of tiles nobody has stood on --
which is the half of the 2026-09-17 rule that already held and is now pinned by a test of its own.
| # | trap | trigger | test | fix, or why it is left |
| ---: | --- | --- | --- | --- |
| 51 | `Scene::Unknown` deals `NEXT` and `BACK` on a frame of the overworld the cartridge is driving, where an A and a B press are presses into a script | every warp, every scripted push-back, every guide that walks the fly somewhere -- `BACK` 678 starts in 47 live minutes, 189 of them on map `0x02` | `an_unknown_frame_with_no_box_on_it_deals_nothing`, `an_unknown_scene_is_dialog_with_advance_only`, `the_fly_reaches_the_pewter_gym_from_the_rung_ten_checkpoint` (ROM-gated: `BACK` in a box 0, unknown pads with no box 0) | **fixed**: the pad is dealt on whether a box is drawn. A scripted overworld frame is an empty pad the fly waits out, and it is the one empty pad that ends itself -- the cartridge gives the buttons back within a few frames |
| 52 | a building with no row on the map graph has no neighbours, so from inside it there is no road to the objective and no errand either | the whole rung-10 stall: `GO OBJECTIVE`, `GO SHOP` and `GO HEAL` all off the pad on maps `0x34` and `0x35` | `the_museums_two_floors_know_the_road_to_the_gym`, `the_hop_count_is_the_road_measured_rather_than_named`, the ROM run below | **fixed**: two rows, both surveyed from the cartridge's warp table. The upper floor has no *area* -- no front door of its own, like a bedroom -- so it offers no errand, and its road out is the staircase |
| 53 | a frontier the route search cannot reach is excluded by a ten brain minute window, so it comes back every ten minutes for ever | `GO FRONTIER` 1,235 starts in 47 minutes over two museum floors and a covered town; 39 unstood tiles on map `0x34`, almost all behind the admission desk | `a_frontier_no_walk_can_reach_takes_go_frontier_off_the_pad_and_keeps_it_off`, `a_frontier_mark_is_the_stood_ledgers_to_clear`, `standing_on_new_ground_is_what_clears_a_maps_frontier_mark` | **fixed**: the refusal is remembered per map with no window, beside the pushed-tile ledger of row 37, and cleared by the fly standing on ground of that map it had not stood on before -- the only event that can change which tiles it can reach |
### The ROM-gated run, from the live checkpoint
`FLY_PEWTER_CHECKPOINT`, macros mode, the stub rotation, 200,000 frames (55.8 brain minutes):
| measure | value |
| --- | --- |
| the checkpoint's map | `0x34`, the museum's ground floor, on its doormat |
| reached **map `0x36`**, the gym's interior | **frame 2,423, on 15 macros** |
| `TALK` on the pad inside the gym | yes -- and 15 `TALK` starts on map `0x36` |
| `GO OBJECTIVE` bound on the gym's own pad | yes |
| `BACK` on a `dialog` or `unknown` frame | **0** (189 in the before hunt, on map `0x02` alone) |
| pads dealt on an `unknown` frame with nothing drawn | **0** |
| `GO FRONTIER` starts on the museum's two floors | **0** (1,235 live over those floors and the town) |
| `GO FRONTIER` starts overall | 1,247 -- 649 of them in Pewter City itself |
| route | `0x34` -> Pewter City -> the gym, then the town's shops and houses |
The fly is out of the museum and into the gym in the first minute, and then spends the run in
Pewter City's buildings: the town's errands are session state and the 11:30 restart re-armed both,
so `GO OBJECTIVE` aims at the mart and the centre before the leader (section 13, and `BUY
ANTIDOTE` 3, `BUY BALL` 2, `HEAL` 1 in the same run say it was paid).

View file

@ -210,6 +210,10 @@ impl Ratchet {
/// ///
/// Nothing in this module knows what the signal means, which is the same bargain `coverage` /// Nothing in this module knows what the signal means, which is the same bargain `coverage`
/// is: the ladder, the map graph and the objective all belong to the adapter. /// is: the ladder, the map graph and the objective all belong to the adapter.
// One argument past clippy's seven, and the argument is the point: this is the whole of one
// sample. A struct for it would be a type that exists only to be destructured at the one
// call site the sim loop has, which is the same idiom `decoder.rs` and `lif.rs` take here.
#[allow(clippy::too_many_arguments)]
pub fn observe_with_progress<F>( pub fn observe_with_progress<F>(
&mut self, &mut self,
safe: bool, safe: bool,