Takes the port branch up to77320d5e-- the state the human play-tested on 2026-09-02 -- for SOURCE paths only. Not a branch merge: `auto/port-p6-audio` is 366 commits and 938 files, and most of that must not land. WHAT COMES IN (76 files, all human-confirmed working): * the logo splash animation.08ed3dd1found it: `pose_at` ASSIGNED the settle instant instead of clamping to it, so the splash never animated at all -- and the same bug manufactured a passing harness result, because the harness photographed t past the settle. Confirmed by play-test: "cannot notice any obvious difference from the actual game." * gamepad input -- (A)/(B) bound additively (`ui_accept` ships with NO joypad binding), stick latched with hysteresis at the game's own 61% digitise threshold. This is what made (A), video-skip and Extras work at all. * menu navigation and flow, menu audio, the exporter, the authored declarations, and 23 verification tools under tools/port/. WHAT IS DELIBERATELY LEFT ON THE BRANCH: * everything afterc0ae460a-- the F5/F6 title-timing investigation, whose own tip commit calls itself a "hand-off for one-minute human checks". Unchecked by definition; it goes through the new review gate like anything else. * the OPTIONS menu work of 2026-09-03. Real, probably good, NOT play-tested. * the F1 repeat mechanism, which its own commit calls "deliberately inert". WHAT MUST NOT LAND, AND WHY THE .gitignore CHANGED: 545 MB of extracted game content was committed on that branch -- 850 sprite, audio and transcoded video files under `export-probe/` and `export-probe2/`, plus 246 MB of loose .wav and .tsv at the repo root. This repository's own rule, in this file, is "never game content". The rule was not missing. It was written, and it was tightened on that very branch, with a careful comment explaining why BOTH `export/` and `data/base/` had to be listed -- while the exporter was writing to a third name that nobody had thought to list. Enumerating names is the thing that failed. So the ignore rules now describe the SHAPE: any top-level `export*/`, game media by extension, and loose capture output at the root. Verified both ways -- it catches all four offenders and ignores nothing currently tracked. Verified: `cargo check --workspace` clean; all nine GDScript files parse in project context, with a positive control (an injected syntax error is detected, 3 lines) so the clean result means something. `tools/port/check-all` was NOT run -- it needs the container, the export tree and a display.
229 lines
11 KiB
Markdown
229 lines
11 KiB
Markdown
# The blend map is deleted — and adopting the decoded field found a counter-example
|
||
|
||
**Status:** ✅ **adopted.** ❌ **My counter-example failed — the bit is right and the
|
||
regression is a metric artefact.** See the last two sections.
|
||
Port at `7dd754f` + this commit; formats pinned at `formats-pin-2026-09-01`;
|
||
HANDOFF on this branch answers `9ca1eb5`.
|
||
|
||
`PORT-MISSION` §3: *"When the RE agent later decodes something you had authored,
|
||
delete the authored entry and let the exporter emit it. That deletion is the
|
||
measure of progress."* This is that deletion.
|
||
|
||
## What changed
|
||
|
||
| | before | after |
|
||
|---|---|---|
|
||
| source | `authored/rendering.json` → `additive_elements`, keyed by **screen name** | `blend_additive` per element, emitted by the exporter |
|
||
| origin | transcribed from the Decoder's per-draw `RB_BLENDCONTROL0` log | **decoded** — `T8aD +0x04` bit `0x02` |
|
||
| reach | three screens somebody drove the game to | every screen on the disc |
|
||
|
||
The pin bump is its own commit (`7dd754f`). The exporter emits `blend_additive`
|
||
on `Element` **and** on nested focus/leaf elements — both spellings of the
|
||
accessor are needed, because a button's focused variant is reached through
|
||
`focus_link` and `ptbtn00f.t32` is in `build.sprites` while no element carries it
|
||
as `sprite`. `ptbtn00f` is exactly the sharp case: the plate is alpha-over and
|
||
its own glow is additive, on one screen in adjacent draws.
|
||
|
||
## The check before the swap — the map was a subset, not the answer
|
||
|
||
Over `main_menu`, `extras`, `press_start` and `title`:
|
||
|
||
| | count |
|
||
|---|---|
|
||
| map says additive **and** the disc agrees | **15** |
|
||
| map says additive and the disc does **not** | **0** — no contradictions |
|
||
| disc says additive and the map did not | **17** |
|
||
|
||
Nothing transcribed was wrong. It was **incomplete and was being read as
|
||
complete**. The 17 include:
|
||
|
||
* `pteff03` / `pteff03a` — the sweep **leaves**. `draw_leaf_for` means those are
|
||
what actually reach the screen while the map listed their parents
|
||
`ptloop01`/`ptloop02`. (Both parent and leaf carry the bit, so this one turned
|
||
out to change nothing — established below, not assumed.)
|
||
* **twelve on `title`**, where the map was deliberately empty. The port has been
|
||
drawing every title effect alpha-over.
|
||
|
||
**And it answers `BLOCKED.md` H6 with no capture at all.** The JP asymmetry — the
|
||
port drawing `main_menu` additive and `main_menu_jp` alpha-over, asserting by
|
||
omission that the JP build differs — was an artefact of a name-keyed map. The bit
|
||
is on the disc for every screen at once.
|
||
|
||
## 🔴 The regression, which is one element
|
||
|
||
Scored against the oracle captures, on the GPU, before and after:
|
||
|
||
| screen | before | after | Δ |
|
||
|---|---|---|---|
|
||
| **`main_menu`** | 10.88 | **13.02** | **+2.14** |
|
||
| **`main_menu_options`** | 11.56 | **13.57** | **+2.01** |
|
||
| `extras` | 13.10 | 13.10 | — |
|
||
| `title` | 14.11 | 14.11 | — |
|
||
| `title_plate`, `title_band`, both splashes | unchanged | unchanged | — |
|
||
|
||
**The scores are deterministic** — two further runs gave 13.02 / 13.10 / 13.57
|
||
to the digit — so this is a real change, not sampling noise.
|
||
|
||
### It is `pteff10`, isolated
|
||
|
||
* `main_menu`'s only newly-additive **top-level** element is `pteff10`.
|
||
* `extras` has **no** newly-additive top-level element, and its score did not
|
||
move. That is the control: the same change applied to a screen with nothing new
|
||
moves nothing.
|
||
* The leaf rule was tested separately by disabling it — `main_menu` stayed at
|
||
13.02, so `pteff03`/`pteff03a` are **not** the cause. That prediction of mine
|
||
failed and the rule was restored, being provably neutral here.
|
||
|
||
`title` did not move despite twelve newly-additive elements, which is consistent:
|
||
`verify-capture` poses at settle `t=198`, and the title's effect quads —
|
||
`ptlogo_back2eff1…5`, `ptlogoall_eff`, `pteff01` — are transparent there.
|
||
|
||
### 🔴 WHY I THOUGHT THIS WAS A COUNTER-EXAMPLE — and it was not. Kept because the premise-check is the lesson
|
||
|
||
**Their own map lists `pteff10` as additive on `extras` and not on `main_menu`,
|
||
and they logged both screens.** So either their per-draw log shows `main_menu`'s
|
||
`pteff10` drawn alpha-over — a direct contradiction between a capture and the
|
||
disc bit, on one element — or it was not drawn during that capture. The oracle
|
||
comparison independently prefers alpha-over there.
|
||
|
||
❌ **Wrong, and the premise was the failure.** The oracle *does* measure it
|
||
additive on `main_menu` — three sessions, every frame. What I read was a stale
|
||
coverage table of theirs sitting upstream of its own correction. **I inferred
|
||
"their log does not cover this" from a table, and called it a contradiction with
|
||
a capture.** The lesson is not that the map was stale; it is that I treated a
|
||
summary as the log. See the resolution at the foot of this page.
|
||
|
||
## Why the change ships anyway, stated rather than assumed
|
||
|
||
1. `main_menu` carries a **±3.78 capture-phase term** in the harness's own note —
|
||
the capture caught the free-running sweep at an unknown phase. **+2.14 is
|
||
inside that stated uncertainty** and cannot adjudicate a disc fact.
|
||
`main_menu_options` is a sub-region of the same screen and inherits the same
|
||
sweep.
|
||
2. The decoded source is far better evidenced than the comparison that moved, and
|
||
it **fixes two known defects** — twelve title effects drawn with the wrong
|
||
blend, and a JP/EN asymmetry the port was asserting by omission.
|
||
3. Fitting an exception for `pteff10` would put an authored entry back to make one
|
||
number smaller. That is the move this project keeps having to undo.
|
||
|
||
🔴 **This was a known regression shipped deliberately, not an unnoticed one** —
|
||
and the decision was right for a *stronger* reason than the one I used. Not only
|
||
is +2.14 inside the ±3.78 phase term: the oracle had already adjudicated this
|
||
element, so the metric is the thing disagreeing, not the render.
|
||
|
||
## What this does not claim
|
||
|
||
* That the bit is wrong. One element, inside a stated uncertainty, against a
|
||
disc-wide check with an out-of-sample prediction.
|
||
* That `pteff10` on `main_menu` and on `extras` are the same sprite. Not checked.
|
||
* That the leaf rule is right — only that it is **neutral here**, so nothing in
|
||
this page rests on it.
|
||
|
||
|
||
---
|
||
|
||
# ❌ The counter-example failed, and the regression is RMSE's area-weighting
|
||
|
||
## The oracle had already adjudicated `pteff10`
|
||
|
||
`blend-bit-vs-oracle.txt` carries it on **both** screens — entry 5 (main menu)
|
||
and entry 6 (extras), `+0x04 = 0x8832`, bit set, both labels read out of the
|
||
guest command stream — and HANDOFF records it *"additive, in all three menu
|
||
sessions, every frame."*
|
||
|
||
**My premise was a stale coverage table**, not a reading of the log. The
|
||
correction existed; the wrong table was still visible upstream of it. So the
|
||
adversarial attempt lands as **survived**: the claim is stronger for having been
|
||
challenged, and the challenge cost one message.
|
||
|
||
⚠️ **And the regression was flagged on this exact element before I adopted it** —
|
||
🟡 in HANDOFF: nearly exact under alpha-over in our render, additive in the game,
|
||
*"the one row here your renderer does not independently corroborate."*
|
||
|
||
## But their explanation makes a prediction, so I checked it
|
||
|
||
If additive and alpha-over *nearly coincide* on a dim glow (max alpha 130) over a
|
||
dark background, the score should barely move. **Mine moved 20 %.** That is a
|
||
real tension and it was worth one measurement.
|
||
|
||
Diffing the two port renders — the only change between them is `pteff10`'s blend:
|
||
|
||
| | |
|
||
|---|---|
|
||
| pixels identical | 373 588 (**40.5 %**) |
|
||
| pixels differing by > 3 | 330 794 (**35.9 %**) |
|
||
| **maximum difference, anywhere** | **32 levels** |
|
||
| pixels differing by ≥ 60 | **0** |
|
||
| bounding box | x 288–993, full height |
|
||
|
||
**Their explanation holds and my scepticism does not.** No pixel moves by more
|
||
than 32/255 — 12.5 % — which is "nearly coincide" measured rather than asserted.
|
||
What moved the RMSE is **area**: a third of the frame shifting slightly.
|
||
|
||
## The thing worth keeping: RMSE cannot tell broad-and-shallow from narrow-and-deep
|
||
|
||
`raw-rmse` is area-weighted, so **a shallow change over a third of the frame
|
||
moves it far more than a deep change over a few hundred pixels** — and the number
|
||
alone does not say which you have. 10.88 → 13.02 reads like a serious regression
|
||
and is a difference invisible to an eye.
|
||
|
||
This bears on every `verify-capture` number in the corpus, not just this one. A
|
||
row that moves should be asked *"broad or deep?"* before it is called a
|
||
regression, and that costs one histogram.
|
||
|
||
## What I did NOT do: exclude the element
|
||
|
||
The Decoder suggested considering `pteff10` excluded from the metric with the
|
||
reason stated, rather than letting 13.02 sit as debt. **I have not**, and the
|
||
measurement above is why: max-32 over a wide area is a *characterised* difference,
|
||
not an unscoreable one. Excluding it would remove the only signal that would fire
|
||
if the bit were ever wrong on some other screen — and the reason to exclude
|
||
("the metric can't distinguish these") is now known to be false; it distinguishes
|
||
them fine, it just weights them by area.
|
||
|
||
**The 13.02 stands, with its explanation attached.** That is cheaper than an
|
||
exclusion nobody will revisit.
|
||
|
||
|
||
---
|
||
|
||
# 🔴 Provenance: the oracle behind this adoption had a container-only instrument
|
||
|
||
Recorded 2026-09-01 at shutdown, from the Decoder's own audit of their `/canary`
|
||
checkout, not from anything visible on this side.
|
||
|
||
This page deleted an authored map on the strength of `ui-blend-mode-decoded.md` —
|
||
35 elements against `RB_BLENDCONTROL0` read out of the guest command stream, zero
|
||
errors both ways, plus an out-of-sample prediction. **That evidence was not
|
||
reproducible by anyone who cloned this repository.** The Canary logger commit
|
||
that emits `blend=` per draw lived only in their container; without it a draw log
|
||
records **no blend state at all**, so the oracle could not be re-derived at all —
|
||
not approximately, not at reduced confidence. Not at all.
|
||
|
||
It is reproducible now: four container-only logger commits are exported as
|
||
patches under `tools/canary-patches/` **on `auto/frame-blend-draw-path`**, with a
|
||
rebuild recipe. ⚠️ Named without a resolvable path on purpose — that directory is
|
||
not in this checkout, and citing it as one would be the exact defect
|
||
`check-citations` exists to catch.
|
||
|
||
## What this does and does not change
|
||
|
||
* **It does not weaken the adoption.** The measurement was real when made and is
|
||
now reproducible. Nothing here is retracted.
|
||
* **It does change what "decoded" was resting on.** For the window between the
|
||
adoption and the export, this port had deleted an authored entry in favour of a
|
||
field whose supporting oracle no one else could regenerate. The map was the
|
||
*worse* of the two — a screen-name table that could not answer for a screen
|
||
nobody drove to — so the trade was still right. But it was a trade made against
|
||
an instrument, and the instrument's reach was smaller than the finding's.
|
||
|
||
📌 **The generalisation, and it is theirs:** a finding is only as portable as the
|
||
tool that produced it, and a reproduce recipe that reads as complete is the
|
||
dangerous kind. Theirs *looked* complete — it named shas — which is why four
|
||
commits sat unexported while one was noticed.
|
||
|
||
⚠️ And the port cannot check this class from here. `check-citations` scans repo
|
||
paths; an instrument living in another container is not a path at all. **The only
|
||
defence available on this side is asking what produced a number before adopting
|
||
it**, which is not a check and does not run.
|