port: H5 localises to one element, and the rotation rule that explained 14 of 16 is refuted

check-all's four remaining red rows. What I established, and two hypotheses that
died on the way -- the second is the one worth reading.

 build_12 / build_15 are ONE ELEMENT. All 951 differing pixels lie inside
pgloading_loop5 (pgloading_ring.png, 333x276 at [1,444]) and the diff's own bbox
x 69..301 y 478..710 sits entirely within it. That also answers, with no rule at
all, why build_00 and build_01 AGREE: the port's own draw log says they draw 7
elements to build_12's 10, and pgloading_loop5 is one of the three they never
draw. The loading screens that agree are the ones that never draw the element
the disagreement is in.

🔴 REFUTED, and it looked strong. ui_layout.rs:86 states in its own words that
"rotation_deg is decoded but NOT rendered", and the port does render it. A
census over all sixteen exported screens gave: every screen with a non-zero rest
rotation DIFFERS, every screen without agrees -- 6 of 6 both ways, including
both legacy rows. Widening it to any rotating element (rest rotation OR a
two-keyframe 360 spinner at any depth) breaks it: build_00 and build_01 carry
two spinners each, the port draws both, and they agree with the reference.

A rule that holds on 14 of 16 and fails on the two cases nobody had looked at is
a rule fitted to the rows it was built from. Recorded rather than deleted,
because the ui_layout.rs:86 comment is exactly what the next reader will find.

🟡 main_menu_jp / extras_jp carry the same sweep leaves -- ptloop01/pteff03 at
rot 30, ptloop02/pteff03a at rot -45 -- whose phase residual is the reason
already named for `title`, and their means (0.79, 0.66) sit with title's 0.44
rather than their EN twins' 3.94 and 6.74. Consistent with, not established:
nobody has isolated those leaves on those screens.

🔴 And an asymmetry this exposed, now DECLARED rather than left silent.
main_menu_jp contains exactly the six elements main_menu marks additive, and
extras_jp all nine of extras'. The map is keyed by screen name and the Decoder's
RB_BLENDCONTROL0 log was taken on the ENGLISH screens, so the port draws them
additive on EN and alpha-over on JP -- asserting by omission that the JP build
blends differently, which is the LESS likely possibility.

Both options assert something unmeasured; only one of them was visible. The map
is NOT extended (that would extrapolate a measurement onto a build nobody drove
to) and the claim is instead written into authored/rendering.json's
additive_elements_why, plus a low-priority ask H6 that says out loud it may not
be worth a boot -- MISSION §7 puts JP out of scope and it costs two rows.

check-all stays red on the same four. Nothing was excused.

Not settled: why the two renderers disagree on pgloading_loop5 specifically; the
JP blend question; H1 (key repeat); whether the splashes tick at the title's rate.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018AHUQvXGyNcKonSEWsgWcX
This commit is contained in:
Sylpheed port agent
2026-09-01 17:20:33 +00:00
parent 26cf6ecac5
commit 0a9bf4e16a
3 changed files with 114 additions and 3 deletions

View File

@@ -222,6 +222,30 @@
"being ONE means the fixed-function stage multiplies the SHADER's output by 1,",
"and the shader has not been read. The port's alpha-over path measures 0.92-1.31x",
"the frame mean on `ptbase`/`pteff05`, so it is not visibly wrong. Nothing here",
"changes it."
"changes it.",
"",
"🔴 2026-09-01 — THE JP SCREENS ARE NOT IN THIS MAP, AND THAT IS AN UNMEASURED",
"CLAIM THIS FILE IS MAKING BY OMISSION. Declared here rather than left silent.",
"",
"`main_menu_jp` contains exactly the elements `main_menu` marks additive --",
"ptloop01, ptloop02, ptframe1, ptframe2, pteff10, pteff12 -- and `extras_jp`",
"contains all nine of `extras`'. This map is keyed by SCREEN NAME, and the",
"Decoder's RB_BLENDCONTROL0 log was taken by driving the game to the ENGLISH",
"screens. So the port draws these elements additive on the EN screens and",
"alpha-over on the JP ones, and nothing measured says the game does that.",
"",
"The port is therefore asserting, by omission, that the JP build blends the same",
"elements differently from the EN build -- which is the LESS likely of the two",
"possibilities. Extending the map would extrapolate a measurement onto a build",
"nobody drove to, which is not the port's to do. Both options assert something",
"unmeasured; only one of them is visible. This paragraph is how the quieter one",
"is made visible. Asked in docs/port/BLOCKED.md.",
"",
"⚠️ It does not affect the deliverable: PORT-MISSION §7 puts localisation beyond",
"English out of scope and the JP screens are not in the boot path. It affects",
"`tools/port/verify-screen`, where main_menu_jp and extras_jp DIFFER by 0.79 and",
"0.66 -- magnitudes that sit with `title`'s 0.44 sweep-phase residual rather than",
"with their own EN twins' 3.94 and 6.74, which is consistent with the JP rows",
"carrying no additive contribution at all. Consistent with, not established."
]
}

View File

@@ -134,7 +134,8 @@ submitted per frame.
| # | ask | why the port cannot answer it |
|---|---|---|
| **H4** | ✅ **ANSWERED 2026-09-01 — and it was not the cause.** The game blends in the **encoded** space: `RB_COLOR_INFO.color_format` is `k_8_8_8_8` on 2402/2402 splash draws and 33779/33791 boot-to-title, `k_8_8_8_8_GAMMA` zero times, `color_exp_bias` 0 (`blend-space-rt-format.txt`). | 🔴 **My premise was wrong and the answer exonerates everybody.** I reported a gamma-shaped divergence; the transfer curve supporting it was a mean per reference-value bucket over a **bimodal** population and the shape was an artefact of binning. Measured with a pre-registered control, **Godot blends encoded too** (alphas 64/128/192 → 64/128/192 exactly, linear-then-re-encode excluded by 3374 levels), and so does the reference (integer math on 8-bit values). All three agree; no change needed anywhere. **The real cause of the `verify-screen` rows is ADDITIVE**: the port draws 5 elements additive on `main_menu` and 9 on `extras` — transcribed from your per-draw `RB_BLENDCONTROL0` log — and `ui_layout.rs` has no additive path at all. The divergence tracks the set size (9 → 6.74, 5 → 3.94, 0 → ~0.7). See [`verify-screen-blend-divergence.md`](verify-screen-blend-divergence.md). |
| **H5** | **Four `verify-screen` rows have no diagnosis**: `main_menu_jp` (mean 0.79), `extras_jp` (0.66), `build_12` and `build_15` (both exactly 0.0368, over3 462, diff bbox `464x266+60+454`). None is in the additive map. `build_12` and `build_15` producing **byte-identical statistics** points at one shared element rather than two coincidences. | Not blocking — `check-all` is **left red** on these four and the allowance was not widened to cover them. It is now *derived* from `authored/rendering.json`'s additive set plus the two legacy rows, so a screen is excused because it has additive elements the reference cannot draw, and one that differs without them still fails. Port `HEAD` `da7864e`; HANDOFF `9ca1eb5`. |
| **H5** | 🟡 **PARTLY DIAGNOSED 2026-09-01, and two hypotheses of mine died getting there.** `build_12`/`build_15`: **all 951 differing pixels lie inside one element**, `pgloading_loop5` (`pgloading_ring.png`, 333×276 at `[1,444]`), diff bbox `x 69..301, y 478..710` entirely within it. That also explains why `build_00`/`build_01` **agree** — the port's draw log shows they draw 7 elements to `build_12`'s 10, and `pgloading_loop5` is one of the three they never draw. `main_menu_jp`/`extras_jp` carry the same sweep leaves (`ptloop01/pteff03` rot 30, `ptloop02/pteff03a` rot 45) whose phase residual is the named reason for `title`, and their means (0.79, 0.66) sit with `title`'s 0.44 rather than their EN twins' 3.94/6.74 — consistent, not established. | 🔴 **Refuted on the way, and recorded so the next reader does not repeat it:** `ui_layout.rs:86` states *"`rotation_deg` is decoded but NOT rendered"*, and the port does render it. A census gave *every screen with non-zero rest rotation DIFFERS and every screen without agrees*, 6 of 6 both ways. **It is still wrong**`build_00`/`build_01` carry two 360° spinners each, the port draws both, and they agree. A rule holding on 14 of 16 and failing on the two cases nobody had looked at is a rule fitted to its own rows. **Ask:** why the two renderers disagree on `pgloading_loop5` specifically — its top-level keyframes hold `a=0x7f` around `rest.t=24` while its leaf expands `pgloading_ring` from scale 0 to 1000 over t=30…130, and the port's `draw_leaf_for` lists only `ptloop01`/`ptloop02`. Not blocking; `check-all` stays red on these four. |
| **H6** | **Does the JP build draw the same elements additive as the EN build?** Your `RB_BLENDCONTROL0` log was taken driving the game to the **English** screens. `main_menu_jp` contains exactly the six elements `main_menu` marks additive and `extras_jp` all nine of `extras`'. | The port's map is keyed by screen name, so it currently draws them additive on EN and **alpha-over on JP** — asserting by omission that the JP build differs, which is the *less* likely possibility. Extending the map would extrapolate your measurement onto a build nobody drove to, so the port has **not** extended it and has instead declared the asymmetry in `authored/rendering.json`'s `additive_elements_why`. ⚠️ **Low priority and say so if it is not worth a boot**: PORT-MISSION §7 puts localisation beyond English out of scope and the JP screens are not in the boot path. It costs the port only two `verify-screen` rows. Port `HEAD` `26cf6ec`; HANDOFF `9ca1eb5`. |
## Still open — these block work

View File

@@ -119,7 +119,93 @@ which Canary applies a gamma↔linear conversion.
**All three agree. Blend space is not a difference between anybody here**, and
the port needs no change for it.
## Still open — why `check-all` stays red
## The other four rows — localised, and two hypotheses died getting there
`check-all` still fails on these four, and the allowance was not widened to
cover them. What follows is where they are, not yet why.
### 🔴 Hypothesis 1, refuted: a blend-space divergence
Covered above. Killed by a control on my own renderer.
### 🔴 Hypothesis 2, refuted: the port renders `rotation_deg` and the reference does not
This one looked strong. `ui_layout.rs:86` says so in its own words —
*"`rotation_deg` is decoded but NOT rendered"* — and the port does render it. A
census over all sixteen exported screens gave:
> **Every screen with a non-zero rotation at rest DIFFERS, and every screen with
> none agrees** — 6 of 6 either way, including both legacy rows.
**It is still wrong.** Widening the rule to *any* rotating element — a non-zero
rest rotation **or** a two-keyframe 360° spinner at any depth — breaks it:
`build_00` and `build_01` carry two spinners each and **agree** with the
reference. Asked directly, the port's own draw log says it draws both spinners
on those screens. So rotation is present, rendered, and produces no difference.
A rule that holds on 14 of 16 and fails on the two cases nobody had looked at is
the shape of a rule fitted to the rows it was built from. Recorded because the
next person will find the `ui_layout.rs:86` comment and reach for it too.
### ✅ What is actually established: `build_12` and `build_15` are ONE element
All **951** differing pixels lie inside `pgloading_loop5`
(`pgloading_ring.png`, 333×276 at `[1,444]`), and the diff's own bounding box —
`x 69..301, y 478..710` — sits entirely within it. No other element's rectangle
contains a differing pixel that this one does not.
And that closes the `build_00` / `build_01` question without any rule about
rotation: the port's draw log shows those two screens draw **7** elements and
`build_12` draws **10**. `pgloading_loop5` is one of the three extra. The
loading screens that agree are the ones that never draw the element the
disagreement is in.
Why the two renderers disagree *on that element* is not settled. It is small —
max 17, mean 0.0368 — and the element is unusual: its top-level keyframes hold
`a=0x7f` for eight units around `rest.t = 24`, while its **leaf** record
expands `pgloading_ring` from `scale 0` to `1000` over t=30…130. The port's
`draw_leaf_for` lists only `ptloop01` and `ptloop02`, so the port draws the
element and not that leaf. Whether the reference does the same is the open half.
### 🟡 `main_menu_jp` and `extras_jp` — consistent with the sweep leaves, not established
Both carry `ptloop01/pteff03` (rot 30, at x=1521) and `ptloop02/pteff03a`
(rot 45, at x=839) — the **same sweep leaves** whose phase residual is the
already-named reason for `title`. Their means sit with `title`'s and nowhere
near their own EN twins':
| | mean |
|---|---|
| `title` (sweep residual, named since P1) | 0.4431 |
| `extras_jp` | 0.6592 |
| `main_menu_jp` | 0.7885 |
| `main_menu` (5 additive) | 3.9363 |
| `extras` (9 additive) | 6.7422 |
That is consistent with the JP rows being the sweep residual alone, with no
additive contribution — which is what the port's own map implies, since it lists
no additive set for them. **Consistent with, not established:** nobody has
isolated the sweep leaves on those two screens.
## 🔴 An asymmetry this exposed, and it is the port's to declare
`main_menu_jp` contains **exactly the elements** `main_menu` marks additive —
`ptloop01 ptloop02 ptframe1 ptframe2 pteff10 pteff12` — and `extras_jp` contains
all nine of `extras`'. The port draws them **alpha-over** on the JP screens and
**additive** on the EN ones, purely because `authored/rendering.json` is keyed by
screen name and the Decoder's `RB_BLENDCONTROL0` log was taken on the EN screens.
**The port is therefore asserting, by omission, that the JP build blends the same
elements differently — and that is the less likely of the two possibilities.**
Extending the map would extrapolate a measurement onto a build nobody drove to,
which is not the port's to do; leaving it silent asserts the surprising thing by
default. So it is made explicit in `authored/rendering.json` and asked in
`BLOCKED.md`, and the map is **not** extended.
⚠️ It does not affect the deliverable: MISSION §7 puts localisation beyond
English out of scope, and the JP screens are not in the boot path.
## Why `check-all` stays red
Four rows are **not** explained by the additive set: