port: print the capture-phase term beside the numbers it qualifies

Their closing point -- the thread lived in messages and docs/re/, which by our own
rule means it was not delivered -- applies to my side. The capture-phase term was
in DECISIONS.md, but verify-capture is what prints the numbers it qualifies and it
said nothing: a reader saw title 14.16 with no sign that +/-5.56 is inherited from
where the shutter fell.

Now printed per row: title +/-5.56 regression only, main_menu +/-3.78, extras
+/-3.73, and both splashes marked as carrying no free-running element and meaning
what they say. Header records that --leaf-time=0 is a convention, not the game's
phase.

Also names a gap their own update exposes: they landed the leaf facts in HANDOFF,
correctly, but HANDOFF as I read it contains none of them -- their work is on
auto/build-ordinal-audit and origin/main is 145 commits behind. So the facts reach
me only through messages, the channel the rule says does not count. Writing it in
the contract is necessary and not sufficient when the contract lives on an
unmerged branch. My BLOCKED.md and DECISIONS.md carry the status sourced to their
sha so my tree does not depend on a HANDOFF I cannot see.

Second structural consequence of main being stale, after the Cargo.toml pin.

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 17:11:57 +00:00
parent 857930a1ac
commit 51c85ed691
2 changed files with 67 additions and 3 deletions

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 -->
188 sections. Search this before re-deriving anything.
189 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)
@@ -199,6 +199,7 @@ dies, which is what this file is for.
* [The off-edge splash residual is **not** tonal — and I was comparing it to the wrong floor](#the-off-edge-splash-residual-is-not-tonal--and-i-was-comparing-it-to-the-wrong-floor)
* [Their linearity gate, applied to my side of the ratio — and an inversion](#their-linearity-gate-applied-to-my-side-of-the-ratio--and-an-inversion)
* [The leaf thread, closed — one export value verified against the game, one self-check abandoned](#the-leaf-thread-closed--one-export-value-verified-against-the-game-one-self-check-abandoned)
* [Delivering the phase term where the numbers are, not where I found them](#delivering-the-phase-term-where-the-numbers-are-not-where-i-found-them)
<!-- /INDEX -->
## P0 — the exporter, 2026-08-28
@@ -10674,3 +10675,47 @@ self-check as inconclusive is the end state**, not a step toward another attempt
⚠️ Still open and now parked: whether the port's leaf advance is wrong at all. Four
models refuted means the input to my 1.87× table is known to be *not* frame-locked
and *not* simple wall-clock, and nothing more.
## Delivering the phase term where the numbers are, not where I found them
Their point closing the leaf thread — *it lived in messages and `docs/re/`, which
by our own rule means it wasn't delivered* — applies to my side, and I had the
same gap. The capture-phase term was written up in `DECISIONS.md`. But
**`verify-capture` is what prints the numbers it qualifies**, and it said nothing:
a reader saw `title 14.16 / 0.21 %` with no indication that ±5.56 of it is
inherited from where the shutter fell.
✅ Now printed per row, in the tool's own metric:
```
main_menu 13.21 0.06% rendered with authored initial focus; +/-3.78 capture-phase term
title 14.16 0.21% settle t=198; +/-5.56 capture-phase term -- regression only
publisher_logo 2.17 0.01% no free-running element -- absolute, means what it says
developer_logos 3.05 0.01% no free-running element -- absolute, means what it says
```
Plus a header block recording that `--leaf-time=0` is a **convention, not the
game's phase**, and that these rows are usable for regression at a fixed pin and
**not** as absolutes against anything measured differently.
### ⚠️ A gap in the delivery rule that their own update exposes
They landed the leaf facts in **HANDOFF**, which is right — it is the contract,
and the standing instruction has me read it every iteration. **It is not in my
checkout.** Their work is on `auto/build-ordinal-audit`; `origin/main` is 145
commits behind and still the stale era. So:
* `docs/port/HANDOFF.md` as I read it contains **none** of it — no "the leaves are
drawn and free-run", no "undecodable with reach".
* The facts reach me only through messages, which is exactly the channel the rule
says does not count as delivery.
📌 **"Write it in the contract" is necessary and not sufficient when the contract
lives on an unmerged branch.** Nothing is wrong with what either of us did; the
gap is structural and belongs to the merge, which is a human's. What I can do is
name it, and keep the facts locally where my own work reads them —
`BLOCKED.md` and `DECISIONS.md` carry the leaf-clock status and the phase term,
sourced to their sha, so my tree does not depend on a HANDOFF I cannot see.
⚠️ This is the second structural consequence of `main` being stale, after the
`Cargo.toml` pin being load-bearing. Both are recorded rather than worked around.

View File

@@ -215,9 +215,28 @@ for row in "${MAP[@]}"; do
raw=$(convert "$OUT/$name.crop.png" "$cap" -metric RMSE -compare -format "%[distortion]" info: 2>&1 | tail -1)
raw=$(python3 -c "print('%.2f' % (float('$raw')*255))" 2>/dev/null || echo "?")
note=""
# 🔴 EVERY ROW WITH A SWEEPING LEAF CARRIES A CAPTURE-PHASE TERM, AND THIS
# TOOL USED TO PRINT THE NUMBER WITHOUT IT.
#
# `ptloop01`/`ptloop02` free-run on a settled screen -- a settled screen is not
# a static screen -- so a capture froze them wherever the shutter fell, and the
# render is pinned at `--leaf-time=0` by CONVENTION, not because 0 is the
# game's phase. Measured by sweeping the phase against each capture:
#
# title 5.56 main_menu 3.78 extras 3.73 splashes 0.00
#
# Those are RMSE, in this tool's own metric, and larger than most margins
# anyone has quoted from these rows. So: usable for REGRESSION at a fixed pin,
# run to run; NOT usable as an absolute against anything measured differently.
#
# ✅ The two splash rows carry no free-running element at all. They are the
# only absolutes here that mean what they say.
case "$name" in
main_menu|extras) note="rendered with authored initial focus" ;;
title) note="settle t=198; residual is the SWEEP PHASE -- see DECISIONS.md" ;;
title) note="settle t=198; +/-5.56 capture-phase term -- regression only" ;;
title_jp) note="+/-5.6 capture-phase term (same leaves as build 4)" ;;
main_menu) note="rendered with authored initial focus; +/-3.78 capture-phase term" ;;
extras) note="rendered with authored initial focus; +/-3.73 capture-phase term" ;;
publisher_logo|developer_logos) note="no free-running element -- absolute, means what it says" ;;
esac
# Where the difference lives. This comes FIRST because it is what the gamma
# sweep has to be protected from.