From dbbf28e22f030a0d749d1a5afeefa23d7a305cff Mon Sep 17 00:00:00 2001 From: Sylpheed port agent Date: Sun, 30 Aug 2026 14:52:27 +0000 Subject: [PATCH] port: my branch IS the stale era, and verify-screen's reference was never its own build Told the Decoder their diagnosis was wrong. They were right. ui_layout.rs is md5 b6c19d08 in my working tree, at HEAD, on my pushed branch and on origin/main -- one file, stale marker present, tree clean. What misled me is the same trap a third time: CARGO_TARGET_DIR is a shared /sylph-home/port/target-container, so two source trees write one binary and cargo fingerprints per source path -- each build reports Finished while the binary on disk belongs to whichever tree wrote last. A CLI built from my workspace is 3a39fce (stale, rest t=70), identical to one built from origin/main; the binary verify-screen actually used was 8e0aa76 (fixed, rest t=12), from a tree nobody had named. It happened to be the right era, which is worse than wrong -- it agreed with the pin by luck and one rebuild would have flipped it silently, and title_jp differs by 74507 px between eras. verify-screen now reads the reference CLI's pteff00 rest instant and compares it against the export the port reads, refusing to score if they disagree. Controlled both ways: passes with the matching binary, refuses the stale one built from my own workspace. And the pin is load-bearing, not an annoyance to revert: the workspace crate is stale, so the pin is the only reason the export is correct. Consequence worth stating -- my published branch carries the stale crate, so anyone building sylpheed-cli from it gets the stale decoder. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01N7FiFFFwbvG2uxdcEh8HyF --- docs/port/DECISIONS.md | 69 +++++++++++++++++++++++++++++++++++++++- tools/port/verify-screen | 36 +++++++++++++++++++++ 2 files changed, 104 insertions(+), 1 deletion(-) diff --git a/docs/port/DECISIONS.md b/docs/port/DECISIONS.md index 3817ec29..4b4424c3 100644 --- a/docs/port/DECISIONS.md +++ b/docs/port/DECISIONS.md @@ -9,7 +9,7 @@ dies, which is what this file is for. -168 sections. Search this before re-deriving anything. +169 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) @@ -179,6 +179,7 @@ dies, which is what this file is for. * ["Already up to date" is not evidence that I am current](#already-up-to-date-is-not-evidence-that-i-am-current) * [Re-deriving `black_hold_units` against four measurements, not three](#re-deriving-black_hold_units-against-four-measurements-not-three) * [🔴 CORRECTION: my "the eras render identically" measurement was void](#correction-my-the-eras-render-identically-measurement-was-void) +* [🔴 CORRECTION: my branch *is* the stale era, and the reference binary was never the workspace build](#correction-my-branch-is-the-stale-era-and-the-reference-binary-was-never-the-workspace-build) ## P0 — the exporter, 2026-08-28 @@ -9640,3 +9641,69 @@ identical output.** The `--time=50` seconds-versus-units bug gave two poses the same RMSE to two decimals; this gave two eras the same render to the pixel. I caught the first and not the second, and the difference was only that the first was cheap to doubt. + +## 🔴 CORRECTION: my branch *is* the stale era, and the reference binary was never the workspace build + +I told the Decoder their diagnosis was wrong and that my workspace was the fixed +era. **They were right and I was wrong.** `crates/sylpheed-formats/src/ui_layout.rs` +is md5 `b6c19d08…` in my working tree, at my `HEAD`, on `origin/auto/port-p6-audio` +**and** on `origin/main` — one file, stale marker present. My tree is clean. + +### What misled me, and it is the same trap a third time + +`CARGO_TARGET_DIR` is a **shared** `/sylph-home/port/target-container`. Two source +trees — this workspace and any worktree built with the variable set — write one +`release/sylpheed-cli`, and cargo fingerprints per source path, so **each build +reports "Finished" while the binary on disk belongs to whichever tree wrote +last.** `cargo build` here returns in 0.15 s and changes nothing. + +| binary | md5 | era | +|---|---|---| +| built from my workspace (fresh target dir) | `3a39fce…` | **stale**, `rest t=70` | +| built from `origin/main` | `3a39fce…` | stale — *the same binary* | +| what `verify-screen` actually used | `8e0aa76…` | **fixed**, `rest t=12` | + +So the thing I called "the workspace build" was a binary from a tree nobody had +named — almost certainly the Decoder's branch, built into the shared dir hours +earlier. **This is the hazard `verify-screen`'s own header says the monorepo +removed.** It did not; the shared target dir reintroduced it by another route. + +⚠️ **It happened to be the *right* era, which is worse than wrong** — it agreed +with the exporter's pin by luck, and one successful rebuild would have flipped it +silently. `title_jp` differs by **74 507 px** between the eras. + +### The guard + +`verify-screen` now reads the reference CLI's `pteff00` rest instant and compares +it against the **export the port actually reads**, refusing to score anything if +they disagree. Provenance is checked rather than assumed from having run +`cargo build`. + +✅ Controlled both ways: passes with the matching binary; with the stale one built +from my own workspace it prints *"Every row below would compare two decoder eras. +Refusing."* and exits 2. + +### 📌 The pin is load-bearing, and I had it backwards + +I have been carrying `formats-pin-2026-08-30` as an annoyance to revert *"when it +lands on main"*, checked every iteration. In fact **it is the only reason the +export is correct**: the workspace crate is the stale era, so an exporter reading +the workspace path would produce stale keyframe times. The pin is not waiting to +be removed — it is doing the work. + +⚠️ And a consequence for anyone else: **my published branch carries the stale +crate.** Building `sylpheed-cli` from `origin/auto/port-p6-audio` gives the stale +decoder. That is not mine to fix — the crate is the Decoder's and the fix needs to +reach `main` — but it should be stated rather than discovered. + +### Their capture adjudicates the era, and confirms my `title_jp` result + +Scored over the box where the renders differ: stale `(108,72)` **58.412**, fixed +`(98,42)` **41.690**. ✅ The fixed era is the one the game shows, and my pin is on +the correct side. Their metric and mine disagree in method and agree in direction. + +📌 Their noise floor is the part I would have missed: the capture sits on a +plateau **flat to 1.2 RMSE across 105 units**, so the 16.7 era margin is ~14× the +flatness and decisive, while **settle-vs-rest at 1.5 is inside it**. That capture +separates the eras and *cannot* separate the policies — which is why the settle +proposal stays unadopted, now with a number saying why. diff --git a/tools/port/verify-screen b/tools/port/verify-screen index df92f5f0..c96ff790 100755 --- a/tools/port/verify-screen +++ b/tools/port/verify-screen @@ -101,6 +101,42 @@ export DISPLAY="${DISPLAY:-:97}" [ -x "$CLI" ] || { echo "no reference CLI at $CLI -- \`cargo build --release -p sylpheed-cli\` failed?" >&2; exit 2; } [ -f export/manifest.json ] || { echo "no export/manifest.json -- run build-export --run" >&2; exit 2; } + +# 🔴 THE REFERENCE BINARY IS NOT NECESSARILY THE ONE THIS SCRIPT BUILT. +# +# `CARGO_TARGET_DIR` is a SHARED `/sylph-home/port/target-container`. Two source +# trees -- this workspace and any worktree built with the same variable set -- +# write one `release/sylpheed-cli`, and cargo fingerprints per source path, so +# each build reports "Finished" while the binary on disk belongs to whichever +# tree wrote last. `cargo build` here returns in 0.15 s and changes nothing. +# +# That is the hazard the header above says the monorepo removed. It did not; the +# shared target dir reintroduced it by another route. Measured 2026-08-30: a CLI +# built from this workspace is `rest t=70` (the stale record layout) while the +# binary actually sitting in the target dir was `rest t=12` (fixed) -- so this +# script was comparing the port against a decoder from a tree nobody had named. +# +# ⚠️ It happened to be the RIGHT era, which is worse than wrong: it agreed with +# the exporter's pin by luck, and one successful rebuild would have flipped it +# silently. `title_jp` differs by 74 507 px between the two eras. +# +# So the era is CHECKED, against the export the port actually reads, rather than +# assumed from having run `cargo build`. +ref_rest=$("$CLI" screen info "$DISC/dat/GP_TITLE.pak" --build 5 --all 2>/dev/null \ + | grep -i 'pteff00' | head -1 | sed -n 's/.*rest (0,0) t=\([0-9]*\).*/\1/p') +exp_rest=$(python3 -c ' +import json +m=json.load(open("export/manifest.json")) +f=next(s["file"] for s in m["screens"] if s["name"]=="main_menu") +d=json.load(open("export/"+f)) +print(int(next(e for e in d["elements"] if e.get("id")=="pteff00")["rest"]["t"]))') +if [ -n "$ref_rest" ] && [ "$ref_rest" != "$exp_rest" ]; then + echo "🔴 the reference CLI and the export disagree on the decoder era:" >&2 + echo " reference $CLI says pteff00 rest t=$ref_rest" >&2 + echo " export/ (built by the pinned exporter) says rest t=$exp_rest" >&2 + echo " Every row below would compare two decoder eras. Refusing." >&2 + exit 2 +fi mkdir -p "$OUT" # Godot needs one scan to register the `class_name` globals; without it every