Files
Sylpheed/authored/timing.json
Sylpheed port agent ace071dd7b port: delete exit_ramp_units, invert the format's own rule, and guard a scale-0 leaf
FOUR THINGS, and the first is what MISSION section 3 calls the measure of
progress.

DELETED `exit_ramp_units` AND `exit_ramp_seconds`. They were authored because the
disc had no time slot on a group's final keyframe, so the ramp into it was the
one unknown duration per screen. Under the corrected record layout that keyframe
does not exist -- a group is an 8-byte header then frames x {u32 time; 36-byte
pose} and every pose is timed. VERIFIED DEAD BEFORE DELETING: setting it to 9999
(166 s) moved the boot's transitions by 0.04 s, which is wall-clock jitter, and
both uses in ScreenView are gated on a condition that no longer fires on any of
the export's 866 keyframes.

INVERTED THE FORMAT'S OWN RULE. `check.rs` enforced "the final keyframe has no
`t`; the disc has no time slot there" and FORMAT.md stated it. Both are now
backwards, and the validator fired 150 times on a re-export. I had not run
`check` between pinning the tag and measuring against the oracle -- the pixel
harness was green while the format validator was failing on every screen with a
multi-keyframe group. A correctness harness does not replace a format one; they
fail at different layers.

GUARDED A SCALE-0 LEAF, which the Decoder hit in its own renderer: its leaf
branch marked the element drawn unconditionally while the blit returned early on
zero scale, so a scale-0 leaf suppressed its parent and blanked the element --
live on all four loading screens. This port did not have the bug only because
authored/rendering.json happens not to list pgloading_loop5. That is an accident
of a gate written for another reason, not a defence, so `_draw_leaf` now reports
whether it drew and `_draw` falls back to the parent.

ISOLATED THE PACING QUESTION rather than leaving it as a suspected regression.
Legacy association: publisher 4.70 agrees, developer 3.92 DIFFERS. Corrected:
publisher 4.26 DIFFERS, developer 3.62 agrees. Both misses are ~0.03 s outside a
composite bound. The association traded which screen is marginally out; it did
not regress the pacing.

Bumped the pin c -> d for the parser and audio changes. Its headline renderer
change does not reach this port: sylpheed-cli builds from the workspace crate.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N7FiFFFwbvG2uxdcEh8HyF
2026-08-29 19:19:46 +00:00

120 lines
6.2 KiB
JSON

{
"format": "sylpheed.timing/1",
"keyframe_units_per_second": 60,
"why": [
"HANDOFF Q1. The disc says a keyframe is at `t=30`; it does not say what a",
"`t` is. The unit was MEASURED off the running game, not decoded: a declared",
"15-unit fade lands on round(255*k/15) for all seven of its samples with k",
"stepping 2,4,6,8,10,12,14 on seven consecutive submitted frames -- so 2",
"units per rendered frame -- and the idle title presents at 28.3-28.8 fps,",
"a 30 Hz game, giving 60 units per second. A second line agrees: the",
"transition quad is declared black for 12 units, and a capture measured the",
"pure-black plateau at 0.17-0.23 s, where 12/60 = 0.20 s.",
"",
"Expressed as units-per-second rather than seconds-per-unit so the value is",
"exact rather than a repeating decimal a reader has to recognise.",
"",
"DELETE THIS FILE when a field on the disc is found that states the unit.",
"Nothing here is on the disc."
],
"kind": "measured",
"source": "/reborn docs/port/HANDOFF.md Q1, docs/re/ui-keyframe-time-unit.md",
"ramp": "linear",
"ramp_why": [
"Also HANDOFF Q1, and part of the same measurement: the fade lands on the",
"linear value at every one of the seven sampled frames, so there is no ease."
],
"dwell_seconds": null,
"dwell_why": [
"NOT SET, and not needed. A screen's dwell is its OWN keyframe group: the",
"publisher wordmark reaches its hold at t=235 (3.92 s) and the developer logos",
"at t=190 (3.17 s), both read from the disc. Adding a hold on top of that would",
"be inventing a number nobody measured, so the sequencer holds for zero extra",
"time and the pacing you see is the disc's own.",
"",
"If a capture ever times the real boot, this is where that number goes."
],
"looping_focus_records": {
"_": [
"WHICH focus records the port draws unconditionally, and loops. CHOSEN, and",
"deliberately a LOOKUP rather than a rule -- delete an entry the day the disc",
"or a capture states it.",
"",
"THE PRESS (A) PLATE GLOWS AND PULSES. Measured on the running game:",
"`ptbtn00f`, the plate's focus record, ramps alpha 0x00->0x50 and back, and",
"its period was timed four times at 2.12 / 2.19 / 2.34 / 2.31 s. You cannot",
"measure a period unless the thing repeats, so THAT IT LOOPS IS MEASURED. The",
"port drew nothing at all here, because press_start has no `buttons` and",
"nothing is focused.",
"",
"WHY A LOOKUP AND NOT A RULE, which is the part worth keeping. The spinning",
"ring is a RULE in the renderer (`spin_period_units`) because it has a",
"disc-wide check: 16 of 212 elements match its shape and all 16 are focus",
"rings, zero false positives. The obvious rule for a pulse -- a group whose",
"keyframes vary only in alpha and whose first and last alpha are equal -- was",
"CENSUSED BEFORE BEING WRITTEN and it fails: 82 OF 212 ELEMENTS MATCH,",
"including ptcopyright, palogo_sqex, ptmsg and every _eff fade-in. A renderer",
"rule on that shape would make the copyright notice pulse.",
"",
"Narrowing to focus records leaves exactly ONE distinct element (ptbtn00f,",
"plus its JP twin), and a rule justified by n=1 is a special case wearing a",
"rule's clothes. So it is written here, per element, by name."
],
"press_start/ptbtn00": {
"record_element": "ptbtn00f",
"period_units": 129,
"kind": "chosen",
"why": [
"129 units = the element's own group under the port's existing timing model:",
"its last timed keyframe is t=105 and the final untimed keyframe is reached",
"`exit_ramp_units` (24) later. NO NEW CONSTANT is introduced -- 24 is the",
"same authored value every other element's exit already uses.",
"",
"129 units is 2.150 s at 60 units/s, and 2.295 s at the ~28.1 fps that",
"emulator presents (56.2 units/s), against measurements of 2.12 / 2.19 /",
"2.34 / 2.31 s. It sits inside that spread at either rate.",
"",
"IT IS A CHOICE, and here is the alternative the data CANNOT rule out: the",
"cycle could restart at the group's first keyframe (t=6) rather than at 0,",
"giving 123 units = 2.050 s / 2.189 s at emulator rate. That ALSO sits",
"inside the measured spread. Nothing available separates them, so t=0 is",
"taken because it is where every other group in this port starts -- which is",
"consistency, not evidence.",
"",
"A fifth reading exists and is NOT averaged in: the Decoder re-picked its",
"troughs and got 2.628 s, having previously reported 2.369 from the same",
"run. It withdrew the estimate as too weak to resolve better than ~7%, so it",
"is recorded here and not used.",
"",
"WHAT DELETES THIS ENTRY: a capture that times the pulse against a landmark",
"in the same frame, or a loop flag decoded on the disc."
]
}
},
"exit_ramp_deleted_why": [
"DELETED 2026-08-29, and the deletion is the point.",
"",
"`exit_ramp_seconds` (~0.4 s) and `exit_ramp_units` (24) were AUTHORED because",
"the disc had no time slot on a group's final keyframe, so the ramp into it was",
"the one unknown duration per screen. Under the corrected record layout",
"(formats-pin-2026-08-29c onward) there IS no untimed keyframe -- a group is an",
"8-byte header then frames x {u32 time; 36-byte pose}, so every pose is timed",
"including the last. The unknown the constant stood in for does not exist.",
"",
"MISSION section 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.'",
"",
"VERIFIED DEAD BEFORE DELETING, not assumed: setting it to 9999 (166 seconds)",
"changed the boot's transitions by 0.04 s -- wall-clock jitter, not a 166 s",
"ramp. Both of its uses in ScreenView were gated on `not last_frame.has('t')`,",
"which no longer fires on any of the export's 866 keyframes.",
"",
"The measurement it recorded is not lost: HANDOFF Q7's ~0.4 s fade-out and the",
"0.17-0.23 s black hold are still measured facts, and the hold is still used --",
"`tools/port/verify-dwell` compares a transition INTERVAL against the oracle's",
"visible SPAN plus that hold. What is deleted is the port's need to invent a",
"duration the disc now states."
]
}