port: on_cancel half measured, and a MEASURED stamp removed from the other half

The Decoder measured B on the main menu -> title (86a8ce7): delivery-confirmed,
<= 0.4 s, no loading screen. main_menu/on_cancel moves from 'likely but UNPROVEN'
to MEASURED -- and it is the LATENCY that settles it, not the destination: my own
why had named the confound that the title also auto-returns after ~8-10 s idle,
and 0.4 s is twenty times faster than that.

The other half is a fault in my tree. title/on_cancel_why read 'MEASURED,
HANDOFF Q5'; the source's evidence cell for that clause reads 'none'. HANDOFF Q5
prefixes a six-clause row with one **measured** and my authored tree copied the
word. The value stays null either way, so no pixel moves -- what is removed is a
false provenance.

Auditing the rest of that row rather than only the clause I was handed: the
up/down cell is ALSO empty. It splits -- one-item-per-press is carried indirectly
by the wrap montage's count, no-auto-repeat is not. The port already behaved this
way without stating it (edge-triggered _input), so navigation.auto_repeat is now
explicit and marked a choice.

34 MEASURED stamps audited; six cite a HANDOFF row alone, one of which was wrong.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N7FiFFFwbvG2uxdcEh8HyF
This commit is contained in:
Sylpheed port agent
2026-08-30 11:09:25 +00:00
parent 71243bcc60
commit ec93d7d946
3 changed files with 315 additions and 219 deletions

View File

@@ -735,3 +735,30 @@ wrap rather than infer one; their 45 s hold ended at 17 M against a `loop_end` o
maximum adjacent-sample step of **212** against a 99.9th percentile of **3 737**,
so the join is not a click. **It does not discriminate the two readings** — a cut
near a zero crossing is smooth wherever it falls.
### Ⓑ on the title — what happens, actually measured
**Derived from HANDOFF `9ca1eb5`; Decoder branch `86a8ce7`.**
`authored/flow.json` holds `title/on_cancel: null` and previously stamped it
`MEASURED, HANDOFF Q5`. That stamp is now removed: the source table's evidence
cell reads `none`, and the Decoder states their 2026-08-30 run cannot be counted
because the second Ⓑ arrived during the title's build-in.
**The ask:** a run that presses Ⓑ *after the title has settled*. They have
already named this as the shape a valid run needs, so this is a pointer, not a
request for a method.
**What it changes if the answer is "something":** `null` is currently the safe
default and the port ships it either way, so nothing is blocked — this is a
provenance repair, not a stall.
### Auto-repeat on a held direction
**Derived from HANDOFF `9ca1eb5`; Decoder branch `86a8ce7`.**
Q5's `up / down` cell is empty in the source. *One item per press* is fine — the
wrap montage's count carries it. *No auto-repeat* is not evidenced, and the
source hedges with "at the durations tried". The port holds `auto_repeat: false`
as a stated choice. **The ask:** hold a direction for ~2 s and say whether the
cursor moves more than once.

View File

@@ -9,7 +9,7 @@ dies, which is what this file is for.
<!-- INDEX: generated by tools/port/index-decisions -- do not hand-edit -->
143 sections. Search this before re-deriving anything.
144 sections. Search this before re-deriving anything.
* [P0 — the exporter, 2026-08-28](#p0--the-exporter-2026-08-28)
* [P1 — Godot draws the screen, 2026-08-28](#p1--godot-draws-the-screen-2026-08-28)
@@ -154,6 +154,7 @@ dies, which is what this file is for.
* [A refuted-claim register, because the audit found what the audit found](#a-refuted-claim-register-because-the-audit-found-what-the-audit-found)
* [State of the port, and a claim I built on for a week without checking](#state-of-the-port-and-a-claim-i-built-on-for-a-week-without-checking)
* [Identifying their submenu capture: edges where intensity could not](#identifying-their-submenu-capture-edges-where-intensity-could-not)
* [`on_cancel`: one half measured, and a MEASURED stamp removed from the other](#on_cancel-one-half-measured-and-a-measured-stamp-removed-from-the-other)
<!-- /INDEX -->
## P0 — the exporter, 2026-08-28
@@ -8319,3 +8320,69 @@ the same thing about the build-within-archive question. **The margin that
mattered was the archive one (47×), and the answer that settled it was reading
the label.** Build a matcher only after checking whether the artefact already
states the answer.
## `on_cancel`: one half measured, and a MEASURED stamp removed from the other
The Decoder measured **Ⓑ on the main menu → the title** (their `86a8ce7`,
`docs/re/data/b-on-main-menu.txt`): delivery-confirmed, 73.5 % of pixels changed,
both captures naming themselves, **≤ 0.4 s**, and **no loading screen** on the
path despite the disc carrying four.
`authored/flow.json` `main_menu/on_cancel` moves from *"likely but UNPROVEN"*
to **MEASURED**. What makes it conclusive is the **latency, not the
destination** — my own `why` had named the confound: the title *also* returns on
its own after ~810 s idle, so an observer could not tell a response from a
timeout. ≤ 0.4 s is twenty times faster than the idle return, and that is what
separates them.
### 🔴 The other half: my tree stamped MEASURED on a claim with no evidence
`title/on_cancel_why` read **`"MEASURED, HANDOFF Q5: Ⓑ on the title does
nothing."`** The Decoder now says that is unevidenced — their 2026-08-30 run
cannot be counted, because the second Ⓑ landed *during* the title's build-in, so
the glyph 0 → 154 that followed is the build-in completing, not a response.
I did not invent the stamp, and that is the point worth recording. **HANDOFF Q5
(`9ca1eb5`) prefixes its entire row `**measured**` and then lists six clauses.**
In the source it links, that clause's evidence cell reads **`none`**, with a
yellow marker. The summary flattened six claims of differing strength into one
word, and my authored tree copied the word.
⚠️ **The value does not change — `null` either way.** Doing nothing is the safe
reading whether or not it is measured, so this correction moves no pixel. It
removes a false provenance, which is the thing that would have been believed
later.
### The same row has a second empty cell, which nobody flagged
Auditing the rest of Q5 rather than only the clause I was handed: the **`up /
down`** row — *"one item per press, no auto-repeat at the durations tried"*
also has an **empty evidence cell**, and my `navigation` block cites that same
row.
✅ It splits cleanly, and only one half is exposed:
* **one item per press** is evidenced *indirectly and well* — the wrap montage's
count only comes out if each press moves one (4 presses from `EXTRAS` landing
on `OPTIONS`). Keep it.
* **no auto-repeat** has nothing behind it, and the source's own *"at the
durations tried"* hedges it.
🔴 Worse, the port already behaved this way **without stating it**: `boot.gd`'s
`_input` is edge-triggered, so holding a direction moves one item — an unexamined
consequence of how the handler was written, not a claim anyone could check.
`navigation.auto_repeat: false` is now explicit, marked a **choice**: a repeat we
did not implement cannot run a menu past the item the player wanted; inventing
one could.
### Audit of every MEASURED stamp in `authored/`
34 stamps. **Six cite a HANDOFF row and nothing else** — the laundering path
above. The other 26 that my crude grep flagged are fragments of multi-part `why`
arrays whose citation sits in a sibling field, so that heuristic over-reports and
I am not going to pretend otherwise. Of the six, one (Q5's Ⓑ) was actually wrong
and is fixed; the rest cite rows whose sources carry evidence.
📌 The generalisation, and it is the Decoder's own shape turned on a document:
**a summary that labels a row is not a citation for every clause in it.** A
bundled `**measured**` is exactly as strong as its weakest cell.