port: the contract I read is 3185 lines shorter than the contract
docs/port/HANDOFF.md on main is 926 lines, last touched9ca1eb5on 2026-08-29. The live one is 4111 lines at27938aa, +3930/-745 across 96 commits I have never read, several of them addressed to the port by name. The Decoder writes HANDOFF on origin/auto/no-disc-and-menu-captures; main is a hundred-odd commits behind it; I open main's copy every iteration as instructed. So the rule meant to prevent this cannot detect it. tools/port/blocked-provenance recovers each row's derivation from history rather than memory -- git log -S on the row's key phrase -- and all 27 open rows derive from9ca1eb5, because HANDOFF-on-main has not moved. A constant cannot separate a fresh row from a rotten one. Withdrawn in BLOCKED.md: 'HANDOFF has not moved in four milestones' was missing the qualifier that carried its meaning. The tool's first version silently missed its own known positive: P6 looping vs712cac8, whose 9.44 s answer this port already ships. 'looping' did not stem to 'loop', 'menu' was stoplisted, and a >=2-shared-words threshold dropped the rest. The threshold was the defect -- two common words outscored one rare one -- so ranking is now by log(N/df) with no cutoff at all, and the control passes at rank 1 of 7 without touching the stoplist. Every discard is counted: struck rows, sub-rank pairs, stoplisted words. Same rule applied to check-claims, which now reports the 40 occurrences it suppresses; the Decoder reached it the same day from the opposite failure, a silent suppression path making a clean run unfalsifiable. The reading list found two open rows already answered: the plate's pulse period (120, not 105) and the main menu having no idle self-return, which refutes the B row's own reasoning. Refutation attempted on '+0x08 is the loop length', the claim the port was about to build on. It survives: their falsifier re-run on my own read of the disc gives 0 violations in 1781 records, and on the eight records this port animates their table reproduces cell for cell. Adopted -- screen.rs exports loop_length_units and ScreenView._loop_period prefers it, announcing any disagreement rather than silently resolving it. The value does not change: authored/timing.json already had 120 from a wall-clock measurement, so a disc field and an emulator stopwatch agree while sharing no instrument. Two asks filed: the field is exposed in no public API on any ref, so the port reads four bytes it should not own; and eleven focus records declare the same 120-unit cycle while only the plate is authored to animate, which is behavioural and not mine to infer. Every asserting check passes; oracle RMSEs unchanged, as 120 == 120 predicts. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01N7FiFFFwbvG2uxdcEh8HyF
This commit is contained in:
@@ -91,9 +91,19 @@ git log -1 --format=%h -- docs/port/HANDOFF.md # newer than 9ca1eb5? re-reconc
|
||||
⚠️ Rows are **not** being back-dated: nobody knows when most were written, and inventing a sha would be worse than admitting there is none. New rows carry one. This table was last audited **2026-08-30** against a running port.
|
||||
|
||||
|
||||
🔴 **"HANDOFF has not moved in four milestones" [refuted] — WITHDRAWN 2026-08-30,
|
||||
and the missing qualifier carried the whole meaning.** HANDOFF has moved **96
|
||||
times**. It has not moved *on `main`*, which is the copy this port opens. The
|
||||
live document is 4 111 lines at `27938aa`; `main`'s is **926** at `9ca1eb5`, a
|
||||
gap of +3 930/−745, and several of those commits are addressed to the port by
|
||||
name. Run `tools/port/blocked-provenance`: every row below derives from
|
||||
`9ca1eb5`, so **the derivation sha this file demands cannot separate a fresh row
|
||||
from a rotten one** — it is constant by construction. The rot is not that rows
|
||||
are old; it is that the document they derive from is frozen while the thing it
|
||||
copies moves. See `DECISIONS.md`.
|
||||
|
||||
**Re-checked at the voice export**, `HEAD` = `3a4c6ac` (merged with `origin/main`
|
||||
at `1b1a4df`). `git log -1 --format=%h -- docs/port/HANDOFF.md` still answers
|
||||
**`9ca1eb5`** — HANDOFF has not moved in four milestones. The second-half check,
|
||||
at `1b1a4df`). The second-half check,
|
||||
`git log --oneline 9ca1eb5..HEAD -- docs/re/`, lists four commits, of which
|
||||
`3491d30` (*"the disc ships movies in TWO audio profiles, and 28 of them are
|
||||
5.1"*) is the one this iteration used and `7eeae30` is still unfolded into
|
||||
@@ -115,7 +125,7 @@ HANDOFF.
|
||||
| P6 looping | where a menu loop restarts | Q10 | ❔ **still open, and the port shipped the ugly answer on purpose.** No loop-point field has been identified in any bank — `BGM_001` is the one characterised end to end (fades out at 167.663 s into 6.15 s of silence) and nothing suggests `BGM_103` differs in kind. `authored/audio.json` sets `loop: "restart"` — replay from sample 0 — so the listener hears the fade-out and the trailing silence at the seam. **Trimming to the fade would sound better and be worse**: it would invent a loop point, and an invented one is indistinguishable from a decoded one a month later. What settles it: a loop-point field, or a capture of the real menu looping. ⚠️ **The cost is now measured, 2026-08-30.** The bed loops at 87.8 s against the track's own 87.7 — `loop: "restart"` behaves exactly as authored — and the seam is **36 consecutive near-silent 50 ms windows, 84.40–87.80 s**: about **3.4 seconds of silence** after a fade from RMS 2057 to 431. Long enough to read as the music having stopped rather than looped. That does **not** license trimming to the fade, which would still invent a loop point; it is recorded so the missing field's price is a number rather than an adjective. |
|
||||
| ~~P5 focus marker~~ | ~~the focus ring's spin PERIOD, and whether it loops~~ | Q1 + *"groups hold"* | ✅ **answered 2026-08-29, and NOT ON `main` YET.** The Decoder pointed at it over the message channel and the pointer resolves: branch `auto/no-disc-and-menu-captures`, commit **`4fa3099`** (branch head `66e74d4`), file `docs/re/focus-ring-spin-measured.md`, frames under `docs/re/captures/focus-ring/`. **The ring spins continuously — period 2.177 s wall-clock, eight evenly spaced autocorrelation peaks over nine revolutions**, with no angle estimated anywhere (both angle estimators failed their own controls and were not used). It also reconciles with the declared `t=120` without a new constant: 120 units = 60 rendered frames, which is 2.00 s at a true 30 Hz and 2.08–2.17 s at the 27.6–28.8 fps this emulator runs, so the measurement sits at the top of the predicted band. 🟡 The Decoder is explicit that this is *consistency, not closure* — the guest frame rate was not measured in the same run. ⚠️ **Do not read `captures/focus-ring/ring-20s-mean-uniform.png` as a frame**: the spin averages to a uniform circle, which is the finding, not a headless ring. **The port has not implemented this yet** — it still draws 0°, which the same corpus says is a pose the game never shows. That is next iteration's work and it is no longer blocked. |
|
||||
| ~~P3/P5 — the title screen~~ | ~~does the idle post-boot title show the `PRESS Ⓐ` plate?~~ | Q2 | ✅ **STALE — struck 2026-08-30, and it had been wrong for weeks.** Every factual claim in it is now false: the boot does **not** end on a plateless build 4, `press_start` is **not** unused, and the port **has** drawn two builds at once since the plate-delay work. Verified this iteration — `boot ends on title + press_start`, `overlay press_start … drew 1: ptbtn00`, plate region mean **95.70** against 33.6 for the bare title. 🔴 The row directly below it was already marked *answered and TAKEN* for the same question: two rows on one question, one struck and one live claiming the opposite, and the live one was the stale one. That is this page's own documented failure mode, caught by auditing it rather than by reading it. ⚠️ What remains open is a **different** question and has its own row: whether the plate *stays up* after its 8-unit window. |
|
||||
| P5 — Ⓑ on the main menu | **is Ⓑ what returns to the title, or the idle timer?** | Q5 | 🟡 stated in HANDOFF, no capture behind it. The title self-returns after ~8–10 s idle, so one unrecorded observation cannot separate them. `authored/flow.json` implements it and marks it *authored — likely but UNPROVEN*. **Not blocking** — P5 shipped with it — but it is the only navigation rule on that screen with nothing under it. Settled by one run that presses Ⓑ well inside the idle window, timestamped. |
|
||||
| P5 — Ⓑ on the main menu | ~~is Ⓑ what returns to the title, or the idle timer?~~ **how long does Ⓑ take?** | Q5 | 🟡 **the ORDERING is answered, the latency is not — and this row's own argument is refuted, 2026-08-30.** It reasoned that *"the title self-returns after ~8–10 s idle, so one unrecorded observation cannot separate them"*. HANDOFF `27938aa` measures the main menu as **not self-returning for ≥ 60 s untouched**, and places the ~8–10 s idle on the **title**, not the menu — so the confound the row was built on does not exist. Ⓑ is delivered (Canary logs `vk=5801`) and is the only input in ≥ 100 s before the return: **the ordering is measured**. What stays open is only the latency, from a backlogged run. `authored/flow.json` already implements the ordering and is now under-claiming rather than over-claiming. Surfaced by `blocked-provenance` at score 10.6 against `9a10258`, unread for a day. |
|
||||
|
||||
| ~~P6 BGM — the sub-wave count~~ | ~~is a music bank's LEADING REGION a stem, or a decoder artefact?~~ | Q10 | ✅ **CLOSED 2026-08-29 — the census was right and the port was summing a bank header into the music.** Decoded and timed, sub-wave 0 of `BGM_103`, `BGM_102` and `BGM_001` is identical: **10 300 B → 0.009 s, peak −inf**, i.e. digitally silent. 10 300 B is the 10 240-byte bank header (the Decoder's disc-wide census) plus a 60-byte RIFF wrapper. So it is not a stem, and `export_bgm` had been counting it in the divisor — putting every real stem at 1/3 instead of 1/2, **3.52 dB of attenuation on all menu music shipped since P6**. Dropping a *silent* input is arithmetic, not a decoding decision, so this closed on the port's side; measured after the fix, `main_menu.ogg` goes −7.69 → **−4.20 dBFS**, +3.49 dB against 3.52 predicted. Corroborates the Decoder's `c1f3608` from the other direction. The export now reports 2 sub-waves and the manifest warning is gone. |
|
||||
| ~~P3 — the plate's ONSET~~ | ~~visible 2.13 s after settle, or group starts then?~~ | Q2 | ✅ **resolved 2026-08-29, and the answer is AUTHOR NOTHING.** The port's refutation held and produced a better answer than either option it offered. Correction at `5b0a6e6` on `auto/no-disc-and-menu-captures`: **both builds run on one clock, started together**, and the plate arrives at its own declared `t=238`. Checked against this export rather than taken on trust — build 4's visible build-in ends at `t=118` (`pteff01`, `pteff02`, `ptlogoall_eff` finish together), `ptbtn00` reaches alpha 255 at `t=238`, difference **120 units = 2.000 s**, against a measured 2.138 / 2.132 s at an emulator presenting 28.1 fps rather than 30. The 2.13 s constant is **deleted**. |
|
||||
@@ -124,7 +134,7 @@ HANDOFF.
|
||||
| ~~P4/P7 — `S00A` as a second asset~~ | ~~does a structurally different movie also put dialogue in FC?~~ | — | 🔴 **NOT OBTAINABLE IN THIS CONTAINER — closed as a route finding, 2026-08-29.** The drive works end to end (main menu +0.999, `newgame-difficulty` +0.999, `newgame-selectdata-crash` +0.997, with the focus detector validated live against a known transition) and then **the guest throws at `PC: 0x82307128` ×349**; no `S00A` stream ever decodes. ⚠️ It also refines `title-crash-stl-tree.md` rather than confirming it: the mechanism survives but the container it names, `aab216c3`, is **complete here** — the throw is on `1b556564`, which holds one file plus a stray `.tmp`. **So the new-game path builds a different cache container, and the documented remedy does not transfer** — it restores a *previously complete* cache, and no complete `1b556564` has ever existed here. **Consequence for the port: the centre-channel result rests on `ADV` alone.** `S00A` was wanted precisely because its second stream is digital silence where `ADV`'s is a 0.60× copy. That corroboration is behind a crash outside menu-port scope and neither agent is chasing it. |
|
||||
| ~~P3/P5 — the title plate~~ | ~~does the idle title show `PRESS Ⓐ`~~ | Q2 | ✅ **answered and TAKEN at this iteration.** `auto/no-disc-and-menu-captures` at `fb536df`, `docs/re/title-plate-delay-measured.md`, traces in `docs/re/data/plate-timing-run{1,2}.tsv`. It is the third case: build 4 alone, then the plate composited over it. ⚠️ The delay is timed from where build 4 **stops animating**, not from where it first appears — measured the other way the two runs differ by 0.48 s against 6 ms. `ScreenView` now draws two builds at once, as a second `ScreenView` in the same `SubViewport` rather than a subordinate screen inside one. The onset question above is what is left. |
|
||||
|
||||
| P3 — the plate's PULSE | **does the plate's focus record loop, and with what period?** | Q2 | ❔ **open, and the port's earlier reading of it was wrong.** The port had looked for the pulse in `ptbtn00`'s own group; `5b0a6e6` identifies it as the plate's **focus record** `ptbtn00f` — a glow ramping alpha `0x00`→`0x50` and back, t=6…105. Measured on the running game at 2.12 / 2.19 / 2.34 / 2.31 s, mean **2.24 s**. 🟡 **The port has not taken it.** Looping that record needs a period, and its group is 105 timed units plus the **authored** 24-unit exit ramp = 129 units = 2.15 s — composing an authored constant with a loop assumption to land on a measured number is tuning, not measuring. Separately: the port draws no focus record on `press_start` at all, because the screen has no `buttons` and nothing is focused, so *whether the game always draws it* is its own question. |
|
||||
| ~~P3 — the plate's PULSE~~ | ~~does the plate's focus record loop, and with what period?~~ | Q2 | ✅ **ANSWERED, and it had been answered for a day in a document this port was not reading.** HANDOFF `27938aa` (delivered at `07e93ce`): a nested record is its own RATC bundle and the header's **`+0x08` is the loop length**, so `ptbtn00f` ramps 0→80→0 over 105 units inside a **120**-unit cycle and rests dark for 15. Found by `tools/port/blocked-provenance`, which ranked that commit against this row at **14.0, the highest score in the file** — not by an experiment. ✅ **Refutation attempted and it survived**: their falsifier (`+0x08 < max t` must never occur) re-run on my own read of the disc gives **0 of 1 781**, and on the eight records this port animates, 7 exact and `ptbtn00f` the lone hold — their table cell for cell (`cargo run -p sylpheed-export --example record_loop_control`). ⚠️ The port never shipped 105: `authored/timing.json` already had 120 from a **wall-clock measurement**, so the disc and an emulator stopwatch agree while sharing no instrument. The exporter now derives it (`focus.loop_length_units`) and the authored value becomes the second witness. 🔴 **New ask below** — the field is in an example, not in the crate's API. |
|
||||
| ~~P5 focus ring — implementation~~ | ~~the ring's spin period~~ | Q1 | ✅ **implemented 2026-08-29.** `ScreenView.spin_period_units` drives it: one turn per the element's own declared `t`, looping, from the screen clock. The period comes off the **disc**; what the RE agent supplied is that the turn repeats rather than stopping. Verified on the port's own render — the ring is bit-identical one period apart across the whole frame, differs by 3.6/255 inside its box at quarter-period steps, and conserves box luminance to **0.027 %** over eight phases, which is the same observable the RE agent used to separate rotation from a pulse. 🟡 **Direction is not measured** — the port turns 0°→+360°, which is the sign the disc declares, but the RE agent's angle estimators failed their controls and no signed angle was ever taken. 🟡 **Phase across a focus change is not measured** either: the port drives the ring off the screen clock, so it does not reset when focus moves. Settled by two frames straddling a focus change. |
|
||||
|
||||
| P7 / naming — the four unnamed builds | **which locale and variant is each of `GP_TITLE` entries 0, 1, 12, 15?** | — | 🟢 **found by the port, not blocking, and handed over.** All four are **loading screens**: every element in all four is named `pgloading_*` (`pgloading_processing.png`, `pgloading_circle1`, `pgloading_delta`, `pgloading_ring`), and `LOADING` is one of the three screen names the Decoder read out of `sub_821C6458`. They export today as `build_00`, `build_01`, `build_12`, `build_15`. Two variants: 0/1 carry 7 elements, 12/15 carry 10 (adding `pgloading_eff00`, `pgloading_loop5`, `pgloading_baseeff`). The archive's own pairing — adjacent for 2/3, `+3` for 4…9 and 10/13, 11/14 — suggests 0 is the twin of 1 and 12 the twin of 15, but **which member is which locale is an inference and the port has not named them on it**. Naming is cheap for the Decoder and a guess for the port. |
|
||||
@@ -137,6 +147,13 @@ HANDOFF.
|
||||
| ~~P1–P7 — the keyframe record layout~~ | ~~adopt the corrected pose/time pairing~~ | — | ✅ **ADOPTED 2026-08-29 by pinning `formats-pin-2026-08-29c`.** This row was wrong twice: it said the change *"cannot be taken yet"* and that it *"reaches the port only when that branch lands on `main`"*. **It arrives when the tag is pinned**, which is what MISSION §2's tagging rule exists for. ⚠️ And the knob I tested first, `SYLPHEED_KF_TIME_SHIFT`, is a **retired partial fix** that left pose 0 untimed — the real correction is the tagged crate's default, with the old reading behind `SYLPHEED_KF_TIME_LEGACY=1`. **The blast radius was far smaller than this row predicted**: under the correction *every pose is timed* (866 keyframes, 0 untimed), so `pose_at`'s synthetic-exit branch became dead code rather than wrong code and nothing needed re-deriving. Oracle: `publisher_logo` 1.00 %→**0.75 %**, `developer_logos` 0.39 %→**0.33 %**, `extras`' differing region collapsing from 736×525 to **398×295 at the sweep position**. 🔴 Open cost: `sylpheed-cli` builds from the workspace crate, so `verify-screen` compares two decoder eras until the tag reaches `main`. Revert to the path dependency then. |
|
||||
| ~~P7 / naming — the four unnamed builds~~ | ~~which locale and variant is each of entries 0, 1, 12, 15?~~ | — | ✅ **answered 2026-08-29** (`docs/re/ui-title-build-map.md`): all four are the loading screen, two variants — plain (7 elements) and dressed (10) — decoded from their own `pgloading_*` element names. ⚠️ **Not adopted as names yet, for two reasons the RE agent gave and one the port found.** Theirs: the executable names exactly two, and *which* bundle takes which name is 🟡 undecided, so `LOADING`/`LOADING2` must not go in an asset path; and locale is 🟡 — the English member of a pair is the one in the first half of `GP_TITLE.p00`, 8/8 structurally but only 3/3 where a capture can check, and the three pairs that matter are the three no capture can check. Mine: **the message gives the bundles as "0/1 and 10/11", which is the `is_build` ordinal, and `authored/screen_names.json` is keyed by PAK ENTRY** — in entry space 10 and 11 are `palogo_sqex` and `palogo_gamearts`, the splashes. See the refutation section in `DECISIONS.md`. |
|
||||
|
||||
## New ask, 2026-08-30 — derived from HANDOFF `27938aa`, at port `HEAD` `f33aeca`
|
||||
|
||||
| Milestone | Needs | HANDOFF | State |
|
||||
|---|---|---|---|
|
||||
| P3/P5 — the record loop length | **expose `+0x08` in `sylpheed_formats`' public API** | `27938aa` | 🔴 **the port cannot obey the instruction with anything published.** HANDOFF says *"stop shipping 105"*, which presumes the port can read the loop length. It is decoded in `examples/record_loop_length.rs`, asserted in `tests/ui_record_loop_length_disc.rs`, written up in `docs/re/structures/ui-record-loop-length.md` — and exposed in the crate's API **on no ref at all** (checked against every ref touching `crates/sylpheed-formats/src/`). `screen.rs` reads the four bytes itself, guarded on the `RATC` magic, because `parse_build` publishes each record's `(offset, size)`. That works and it is **the port holding a format detail it should not own**: one `pub` field on the record type takes it back where it belongs, and the exporter's helper is documented to be deleted the day it appears. Not blocking — the value is shipping. |
|
||||
| P3/P5 — the other focus records | **do `ptbtn01f…05f` and `ptbtn11f…13f` animate while focused?** | `27938aa` | ❔ **open, and deliberately not inferred.** The export shows all eleven declaring the same 120-unit cycle, and `looping_focus_records` names only the plate. A declared cycle is not evidence that the game runs it — `authored/timing.json` already argues the pulse rule matches 82 of 212 elements and would make the copyright notice pulse. Whether a focused menu button glows is **behavioural**: outside my role, asking. |
|
||||
|
||||
## Answered since this file was last written — no longer blocking
|
||||
|
||||
Q1 (keyframe time unit — linear ramp, 2 units per rendered frame, 1 unit = 1/60 s
|
||||
|
||||
@@ -9,7 +9,7 @@ dies, which is what this file is for.
|
||||
|
||||
<!-- INDEX: generated by tools/port/index-decisions -- do not hand-edit -->
|
||||
|
||||
233 sections. Search this before re-deriving anything.
|
||||
235 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)
|
||||
@@ -244,6 +244,8 @@ dies, which is what this file is for.
|
||||
* [Full regression after a session of edits — and the phase term moving two published rows](#full-regression-after-a-session-of-edits--and-the-phase-term-moving-two-published-rows)
|
||||
* [Narrowing my own hook — 33 was a measurement of the regex](#narrowing-my-own-hook--33-was-a-measurement-of-the-regex)
|
||||
* [Their Q10 correction checked, and the register's cost is per-*mention*, not per-correction](#their-q10-correction-checked-and-the-registers-cost-is-per-mention-not-per-correction)
|
||||
* [The contract I read every iteration is 3 185 lines shorter than the contract](#the-contract-i-read-every-iteration-is-3-185-lines-shorter-than-the-contract)
|
||||
* [A refutation attempt on `+0x08 is the loop length` — it survives, and the port adopts it](#a-refutation-attempt-on-0x08-is-the-loop-length--it-survives-and-the-port-adopts-it)
|
||||
|
||||
<!-- /INDEX -->
|
||||
## P0 — the exporter, 2026-08-28
|
||||
@@ -12194,3 +12196,149 @@ new occurrence needing the token, including in the sentence explaining that this
|
||||
happens. **Four instances, each inside text about the mechanism.** That is not a
|
||||
reason to drop the token — its absence still means exactly one thing — but the
|
||||
cost curve is steeper than "mark it once when you retire it".
|
||||
|
||||
## The contract I read every iteration is 3 185 lines shorter than the contract
|
||||
|
||||
📌 **`docs/port/HANDOFF.md` on `main`: 926 lines, last touched `9ca1eb5`, 2026-08-29.
|
||||
The live one: 4 111 lines, `27938aa`, today. 96 commits I have never read,
|
||||
+3 930/−745.** The mission tells me to read HANDOFF every iteration and I have.
|
||||
I have been reading `main`'s copy. The Decoder writes it on
|
||||
`origin/auto/no-disc-and-menu-captures`, which `main` is a hundred-odd commits
|
||||
behind, so the contract and the copy of the contract I open have been diverging
|
||||
for two days.
|
||||
|
||||
Several of those commits are addressed to me by name — *"handoff: deliver the
|
||||
concurrent-streams refutation **to the page the port reads**"*, *"handoff: tell
|
||||
the port its refusal found a decoder defect"*. They were delivered to the page I
|
||||
read. The page I read is not the page they were delivered to.
|
||||
|
||||
### 🔴 The instruction that was supposed to prevent this cannot detect it
|
||||
|
||||
`BLOCKED.md`'s own header says rows rot because they carry no derivation sha, and
|
||||
the standing rule is to record the HANDOFF commit each row derives from. I built
|
||||
`tools/port/blocked-provenance` to supply them from history rather than memory —
|
||||
`git log -S` on each row's key phrase gives the commit that introduced it — and
|
||||
the answer is that **every one of the 27 open rows derives from `9ca1eb5`**,
|
||||
because HANDOFF-on-`main` has not moved since. A constant cannot discriminate.
|
||||
|
||||
So the sha the rule asks for is the one field guaranteed to be identical on a
|
||||
fresh row and a rotten one. **The rot is not that rows are old. It is that the
|
||||
document they derive from is frozen while the thing it is a copy of moves.**
|
||||
|
||||
⚠️ And my own `BLOCKED.md` asserts *"HANDOFF has not moved in four milestones"*.
|
||||
**That is withdrawn.** HANDOFF has moved 96 times. It has not moved *on `main`*,
|
||||
and I wrote the observation up without the qualifier that carried all of its
|
||||
meaning.
|
||||
|
||||
### What the tool measures instead, and the control that caught it lying
|
||||
|
||||
Counted against every ref rather than my own ancestry, each row has **196 unread
|
||||
`docs/re/` commits** behind it — again identical for every row, because none of
|
||||
that branch is my ancestor. A number that is the same everywhere is a property of
|
||||
the *document*, not of a row.
|
||||
|
||||
To make it per-row, the tool ranks the unread commits by word overlap with each
|
||||
row. **The first version silently missed its own known positive.** `P6 looping`
|
||||
asks where the menu loop restarts; `712cac8` measures it at 9.44 s and this port
|
||||
has shipped that value since. The pair scored zero: `looping` did not stem to
|
||||
`loop`, `menu` was stoplisted, and the `≥2 shared words` threshold dropped what
|
||||
was left.
|
||||
|
||||
The threshold was the defect, not the constant. **Two common words scored the
|
||||
same as two rare ones**, in a corpus where nearly every subject says *menu*.
|
||||
Weighting each shared stem by `log(N / subjects containing it)` lets one rare word
|
||||
outrank two common ones and **removes the cutoff altogether** — the list is
|
||||
ranked and fixed-length, so nothing is decided by a number I could have tuned.
|
||||
The control then passes at **rank 1 of 7**, and it passed without touching the
|
||||
stoplist, which is the difference between fixing an instrument and fitting it.
|
||||
|
||||
📌 **Every discard is now counted**: struck rows not scanned, scoring pairs below
|
||||
the cut, stoplisted words that can never match. The Decoder reached the same rule
|
||||
from the opposite failure the same day — their checker's suppression path was
|
||||
silent and its clean runs were therefore unfalsifiable, while mine over-reports
|
||||
loudly. **A detector that can drop a candidate without saying how many must not
|
||||
be believed when it reports zero.**
|
||||
|
||||
### It immediately found two open rows whose answers were already written
|
||||
|
||||
| row | unread commit | |
|
||||
|---|---|---|
|
||||
| `P3 — the plate's PULSE` | `07e93ce` (score 14.0) | the period is **120, not 105** |
|
||||
| `P5 — Ⓑ on the main menu` | `9a10258` (score 10.6) | the menu has **no idle self-return** — the row's own reasoning is refuted |
|
||||
|
||||
Both had sat unread for a day. Neither needed an experiment; they needed the
|
||||
document to be looked at.
|
||||
|
||||
## A refutation attempt on `+0x08 is the loop length` — it survives, and the port adopts it
|
||||
|
||||
The claim the port was about to build on, so the one to attack (PROTOCOL:
|
||||
*refutation is cheapest where the other agent is most confident*). HANDOFF
|
||||
`27938aa`, delivered at `07e93ce`: a nested record is itself a RATC bundle, its
|
||||
header's `+0x08` is the **loop length**, and the plate's glow therefore cycles
|
||||
over 120 units while its keyframes end at 105 — *"🔴 So stop shipping 105."*
|
||||
|
||||
I re-ran **their own two controls** on my own reading of the disc rather than
|
||||
taking the census —
|
||||
`cargo run -p sylpheed-export --example record_loop_control`:
|
||||
|
||||
| | disc-wide | |
|
||||
|---|---|---|
|
||||
| timed nested records | 1 781 | |
|
||||
| `+0x08 == max t` | 1 643 | 92.3 % |
|
||||
| `+0x08 > max t` (a hold) | 138 | 7.7 % |
|
||||
| **`+0x08 < max t`** | **0** | **0.00 % — the falsifier never fires** |
|
||||
|
||||
Identical to their figures. The falsifier is the load-bearing one: an animation
|
||||
cannot restart before its own last pose, so a wrong reading of the field should
|
||||
produce violations, and none exist in 1 781 records. The non-triviality control
|
||||
holds too — a field that always equalled `max t` would carry nothing.
|
||||
|
||||
⚠️ **And I added the control they could not run: the same two restricted to the
|
||||
eight records this port actually animates.** A disc-wide 0.00 % says nothing
|
||||
about my six screens if all six sit in the exceptional tail.
|
||||
|
||||
```
|
||||
record +0x08 max t slack
|
||||
ptbtn00f 120 105 15
|
||||
ptbtn01f…05f 120 120 0
|
||||
ptloop01/02 600/720 600/720 0
|
||||
shipped: 7 exact, 1 hold, 0 falsified
|
||||
```
|
||||
|
||||
Their table, cell for cell. ⚠️ Note how narrowly non-trivial it is **here**:
|
||||
across the disc 7.7 % of records hold, but on my shipped set exactly **one of
|
||||
eight** does. The claim survives on my data; it is not richly confirmed by it.
|
||||
|
||||
### 🔴 The instruction cannot be complied with using anything they published
|
||||
|
||||
*"Stop shipping 105"* presumes the port can read the field. `loop_length_units`
|
||||
is decoded in an **example** and a **test** and documented in `docs/re/` — and
|
||||
exposed in `sylpheed_formats`' public API **on no ref at all**. I checked every
|
||||
ref that touches the crate's `src/`.
|
||||
|
||||
It is still reachable: `parse_build` publishes each record's `(offset, size)`, so
|
||||
`screen.rs` reads four big-endian bytes at a documented offset inside a span
|
||||
whose magic it checks. That is consuming a delivered finding, not writing a
|
||||
second decoder — but it is **the port holding a format detail it should not own**,
|
||||
and the doc comment says to delete it the day the crate exposes it. Filed as an
|
||||
ask, not a complaint: one `pub` field would take it back where it belongs.
|
||||
|
||||
### The value does not change. Its provenance does.
|
||||
|
||||
`authored/timing.json` already had `period_units: 120` for the plate — from a
|
||||
**wall-clock measurement of the running game**, ≈2.37 s. The disc declares
|
||||
**120**. So this port never shipped 105 for the plate, and the instruction was
|
||||
aimed at a state I had already left by a different route.
|
||||
|
||||
📌 **That is the result worth keeping.** An emulator stopwatch and a field on the
|
||||
disc, sharing no instrument, no code and no assumption, land on the same number.
|
||||
`ScreenView._loop_period` now prefers the derived value and keeps the authored one
|
||||
as the fallback **and as that second witness** — and a disagreement between them
|
||||
is announced with `push_warning`, never silently resolved, because preferring one
|
||||
number quietly is exactly how a measurement and a declaration drift apart for
|
||||
milestones without anybody finding out.
|
||||
|
||||
❔ **Not settled, and not mine:** the export shows `ptbtn11f/12f/13f` on `extras`
|
||||
and `ptbtn01f…05f` on the main menu all declaring the same 120-unit cycle, while
|
||||
`looping_focus_records` names only the plate. Whether those records *animate*
|
||||
while focused is behavioural — an ask, not an inference from the header.
|
||||
|
||||
Reference in New Issue
Block a user