A snapshot of the non-game files as of0148cb8("port: F5/F6 hand-off -- one-minute human checks, and a refutation attempt that survived", 2026-09-04), the tip of auto/port-p6-audio. The branch was deleted from the server on 2026-09-17 during the consolidation cleanup; issue #7 asks for this work as a reviewable PR, so it is recovered here before the commits are garbage collected. Contents: the 84 files the branch changed relative to its fork pointb305aa4, which is this commit's parent. The tree is therefore 0148cb8's tree with the 854 exported game assets left out -- export-probe/, export-probe2/, three .wav renders of game audio and adv-v2-screenlog.tsv. Game data stays out of git; the exporter regenerates those from the disc. docs/port/DECISIONS.md still refers to them by name. Not recovered: the branch's own 366 commits. Keeping them would make those assets reachable again, so this is one snapshot instead. The original commits stay unreferenced in the server's object store, and in this clone under the local branch archive/port-p6-audio, until either is garbage collected. Refs #7. The OPTIONS work that issue #6 asks for is a subset of this branch, also recovered as recover/options-menu. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
25 KiB
H3 — the PRESS Ⓐ plate: which half the lateness is in
Status: ✅ both halves answered, and TWO of my own conclusions on this page
were refuted within the hour — the 5 units/frame reading and the claim that
clock: "shared" collapses. Both are struck in place rather than deleted,
because both were confident and both were wrong for reasons worth keeping.
The answers are the Decoder's h3-units-per-frame-measured.md,
origin/auto/frame-blend-draw-path at a482d9a.
Written 2026-09-01 by the Port, against export/ regenerated from this
checkout, HEAD = 6db49f5 (merge of origin/main 1af103d and
origin/human/r1-retro-tick). HANDOFF on this branch answers 9ca1eb5.
The play-test finding 3 says the plate
arrives late and names three candidate causes: the unit→seconds constant
(the Decoder's), the clock origin and rest.t (both ours). The brief
asks which half it is, and how that was established. This page is the answer.
Short version, after the answer landed.
rest.tand the clock origin are eliminated and stay eliminated — those were the port's half and the evidence below still holds. Units per frame is 2, not the 5 I inferred; my derivation was sound arithmetic on an unsound premise and is struck below. The anchor is t=160, as I suspected. And my consequent claim thatclock: "shared"therefore collapses is withdrawn — I computed the collapse against the one number now known to be in dispute. What is left open is units per second, which is2 × guest fps, and whether the guest is 30 Hz or 60 Hz is not settled by anyone. At 60 Hz the plate lands at 1.97 s instead of 3.93 s, which is the size of what the human reported.
What the export actually declares
export/screens/title/press_start.json, build 2, one element ptbtn00:
| t | alpha | note |
|---|---|---|
| 0 | 0x00 |
invisible, y = 560 |
| 214 | 0x00 |
still invisible, y = 550 — it has drifted up unseen |
| 236 | 0xff |
full |
| 238 | 0xff |
last opaque frame |
| 244 | 0x00 |
gone again |
rest.t = 236. settle_window = [214, 236, 225].
🔴 The corpus says the plate reaches a=255 at t=238. It reaches it at
t=236. 238 is the last frame at full alpha, not the arrival. Every
derivation quoting 238 − 118 = 120 units = 2.000 s is really 236 − 118 = 118 units = 1.967 s. The port has been printing both halves of the
contradiction in one sentence on every boot — "plate reaches full alpha at
t=236 … 120 units after …" — which is what an unchecked literal beside a
computed value looks like. Corrected in boot.gd and in authored/flow.json.
It moves the reconciliation by 0.033 s and overturns nothing.
Candidate 1 — rest.t. Eliminated.
rest.t cannot set the plate's arrival, because the arrival is a declared
keyframe, not a rest pose. ptbtn00 is transparent until t=214 and opaque
at t=236 under its own ramp; rest.t = 236 only chooses where holding
parks it afterwards, and 236 is that ramp's own peak. Setting rest.t to any
other value moves where the plate stops, never when it starts.
Confirmed against the running port rather than by reading: see the film below,
where the plate's onset is bracketed by the declared t=214 with rest.t
untouched.
⚠️ This does not rehabilitate rest.t generally. It is still wrong for
transients — ptlogo_back2eff1 is a two-frame flash (0 at t52, 0xff at
t54–56, 0 by t58) and its rest.t = 54 is the flash peak, so rest() leaves
five of these burning at once. It is simply not in this defect's causal path.
Candidate 2 — the clock origin. Eliminated, and measured.
Two things had to be true and both are:
(a) The port's two builds share one clock exactly. _advance sets
view.time_units = 0.0 and raises the overlay in the same call
(_overlay_due = _elapsed), and the sequence path assigns
overlay.time_units = view.time_units outright rather than integrating a second
delta. Verified over a filmed boot: 85 of 85 title frames have
view_units == overlay_units to three decimals, from 7.812 to 679.182. There
is no drift and no offset to find.
(b) The title step begins when the previous step ends. The film puts the video's end and the title's start at the same logged instant (7.86 s / 7.92 s across two runs), with no black hold between them.
Candidate 3 — the unit→seconds constant. NOT eliminated. It is the live one.
🔴 This section said "eliminated by sign" and that was wrong. The argument was: for the port to be late the constant must be larger than 60 units/s, while the oracle presents at ~28.1 fps and the corpus measured the idle title at 28.5 fps — both slower than nominal, so the game's units run slower, not faster.
That conflates two different quantities. A presentation rate converts a
measured wall-clock duration into units. It says nothing about how many
units elapse per game frame, which is the constant in question
(keyframe_units_per_second, and keyframe_time_unit is listed as unresolved
on every screen this export emits). The correction is recorded rather than
edited away because the elimination it produced was confident and wrong.
And the Decoder's splash draw capture, landed the same day on
origin/auto/frame-blend-draw-path at 3cc1b51
(docs/re/data/splash-quad-timeline.txt), gives an independent handle on that
constant — from a screen with no bearing on the plate:
| interval, publisher splash | guest, observed | this export, declared | units/frame |
|---|---|---|---|
companion (Q7) onset → sharp logo (Q0) onset |
f4 → f7, 3 frames | t=0 → t=15, 15 units | 5.0 |
| companion onset → its own peak | f4 → f7 (a=240), 3 frames | t=0 → t=15 (a=255), 15 units | 5.0 |
| sharp logo onset → full alpha | f7 → f10, 3 frames | t=15 → t=30, 15 units | 5.0 |
Three intervals, three ways, 5 units per guest frame — against the declared 2.
🔴 STRUCK. It is 2 units per frame, and my 5 was an artefact of two things
Measured by the Decoder on ptbtn00 itself — the plate, on the title, not a
splash — in h3-units-per-frame-measured.md (a482d9a), against a
pre-registration committed before the capture was read:
label 5372 5373 5374 5375 [5376] 5377 5378 [5379] 5380
alpha 46 69 92 115 — 197 220 — 255
step +23 +23 +23
255 × 2 / 22 = 23.18, and the plate's declared ramp is t=214 → 236, i.e.
T = 22. Three consecutive gap-free steps of exactly 23 is 2.0 units per
frame on the nose. Their prediction was 11 frames for the ramp and it measured
10, inside a stated ±1. My 4.4-frame prediction is excluded by more than 2×.
Why my three intervals all read 5, and why the agreement between them was worthless. Two independent errors, both mine to have made:
- An alpha step is not a clock rate. For a linear segment,
Δα per frame = 255 × (units per frame) / T. Two elements with different declared segment lengthsTshow differentΔαat an identical clock. Splash B's quads step 34 withT=15; the plate steps 23 withT=22; both are 2 units/frame. Reading a step as a rate is what produced the 2.7×. - My "onsets" were not onsets. I took each quad's first submission as its
α = 0time. On splash A,Q7andQ0are both already at α = 85 when first submitted. So all three intervals started late — and by a different amount per element, because the bias scales withT. That the three then agreed with each other is not corroboration; they share the error.
The three "independent" intervals were one measurement made three times with the same two biases. That is the shape I should have checked for and did not.
⚠️ The Decoder records the published splash-quad-timeline.txt having no T
column as their own defect, now fixed. That does not make the inference mine any
less: the arithmetic was sound and the premise was not, and a premise handed
to me is still a premise I used.
⚠️ Two caveats, and they are why this is asked rather than acted on. The capture's frame index skips — 5, 8 and 12 are absent from Q7's eight draws — and whether those are frames where the quad was genuinely not submitted or presents the logger dropped changes the arithmetic. And the present rate during a splash is not established.
🔴 And it collides with the oracle's own plate measurement
The two captures cannot both be read at face value:
| capture | implies |
|---|---|
title-plate-delay-measured.md — 118 units in 2.135 s |
~55 units/s |
splash-quad-timeline.txt — 15 units in 3 frames |
~150 units/s at 30 fps |
A factor of 2.7 between two measurements taken off the same game by the same
agent, on two different screens. Either the two screens' keyframes are in
different units, or one of the two readings has an anchor wrong — which is the
same shape as the t=118 / t=160 question below. Both are oracle
measurements and neither is the port's to resolve. Asked in
BLOCKED.md H3.
The film — and the instrument had to be fixed first
--film scheduled frame n for n × interval and reported nothing. One
1280×720 save_png under llvmpipe costs ~0.24 s, so a request for 0.05 s
delivered 247 frames in 60 s where 1 200 were asked for — an achieved 4.1 fps
against a requested 20 — and the deficit accumulated silently into the frame
index. f_071.png still looked exactly like the frame that was meant to be
3.55 s in.
TEMPORAL-VERIFICATION.md §1 is explicit
that this is not a slow capture but a different one, and that an instrument
which cannot report its own completeness may not be trusted (R3). So --film
now writes <film>_frames.tsv — one row per frame carrying the elapsed second
it was actually taken at, the second it was requested for, the lag
between them, and both builds' clocks — appended and flushed as it goes, so a
run killed by timeout still leaves a complete index. It prints the achieved
rate against the requested one every 40 frames. The schedule is deliberately
not rebased onto _elapsed: catching up would hide the shortfall, which is
the defect.
The run this page rests on: requested 20 fps, achieved 15.9 fps for the first
120 frames and 11.3 fps by frame 200, lag reaching 8.7 s. Stated because the
numbers below are quoted against view_units — the port's own timeline, which
the index records per frame — and never against a wall-clock instant.
Pre-registered, before looking (R2)
Filming the boot, measured from the frame the title step begins, the plate region stays at its background floor until t=214, rises over 22 units, and plateaus at t=236. Accept ±2 frames at each end.
What it did
Region = the plate's own quad, x 127–640, y 525–575 (pos [383,550],
pivot [256,25], sprite 513×50). Mean of the crop, one row per filmed frame:
view_units |
region mean | |
|---|---|---|
| 7.8 → 143.8 | 0.13765, flat to 5 decimals | nothing there |
| 151.9 → 207.8 | 0.13773 → 0.14341 | a slow 4 % drift, build 4's own |
| 207.8 → 215.3 | 0.14341 → 0.15348 | ⬅ the step; brackets the declared 214 |
| 215.3 → 239.8 | → 0.21254 | the ramp |
| 239.8 → 279.3 | → 0.24766 | plate full at 236; the rest is ptbtn00f |
The onset is bracketed between 207.8 and 215.3 at a frame spacing of ~7.5 units,
i.e. within one frame of the declared 214, and rest.t was never touched.
Prediction held.
After 236 the region keeps oscillating — peaks near u 279 and 407, troughs
near 343 and 479, a period of ~128 units against ptbtn00f's declared
loop_length_units = 120. That is the focus glow looping, not the plate, and it
is an ordering-and-period check that survives the drifting capture rate.
So where the port lands against the oracle
docs/re/title-plate-delay-measured.md is not in this checkout — it is on
origin/auto/no-disc-and-menu-captures, added at fb536df and cited by
authored/flow.json at 5b0a6e6. Read there:
| run 1 | run 2 | the port | |
|---|---|---|---|
| settled → plate | 2.138 s | 2.132 s | 1.967 s (118 units at 60/s) |
| first drawn → plate | 3.781 s | 4.263 s | 3.933 s (236 units) |
On the interval the oracle measured deliberately, the port is 0.17 s early. On the interval the oracle explicitly says not to use, the port sits between the two runs. No number anyone has taken makes this port's plate late.
The human watched both and says late, and that observation stands. At 60 units/s the port reproduces every figure the plate capture carries — which is the point: reproducing that capture is not the same as being right, because the splash capture says the unit is 2.5× off and would put the port 2.4 s late. The two cannot both hold. The human's eye agrees with the splash capture.
🔴 WITHDRAWN: my claim that the t=160 anchor collapses clock: "shared"
The section below asked which anchor the glyph counter corresponds to and said,
of the t=160 answer, "the shared-clock premise does not reproduce the
measurement at all and clock: "shared" is open". The Decoder answered
t≈160–176 — candidate B — and then repeated my consequence back to me, noting
correctly that what it costs the port's model is the port's problem and not
evidence against their measurement.
They were right to report it and I was wrong to have claimed it. I computed the collapse by comparing the declared 76 units against 2.135 s, and 2.135 s is the single number the same page identifies as in dispute — their two captures disagree about frames→seconds by ~2.9×. Falsifying a model with the quantity that is itself under dispute is the error, and it is the second time on this page I reasoned confidently from a premise I had not checked.
Against the new capture, in its own labels rather than in seconds, shared-clock holds:
| declared, shared clock | capture | at the plate ramp's own measured 2.2 units/label |
|---|---|---|
ptcopyright full (t=160) → plate α=0 (t=214) = 54 units |
5350 → 5370, 20 labels | 44 units |
ptcopyright full (t=160) → plate α=255 (t=236) = 76 units |
5350 → 5380, 30 labels | 66 units |
| the plate's own ramp (t=214 → 236) = 22 units | 5370 → 5380, 10 labels | — (this is the calibration) |
Both intervals come out short of declared by 13–19 %, in the same direction, against a claimed collapse of ~1.7×. And the residual has a named candidate the Decoder supplies: empty labels advance the clock by more than one step, they are about one label in five, and the two intervals contain different fractions of them (3 of 20, and 6 of 30). Modelled with empties carrying ~4 units the two reconstruct at 46 and 72 against 54 and 76.
So clock: "shared" is not falsified and the port keeps it. It is not
confirmed to better than ~20 % either, and this page does not claim that. What
it is no longer is "collapsed on the port's own account".
A second anchor question, also the Decoder's — ✅ ANSWERED: it is t=160
What does the oracle's "title settled" correspond to on the declared timeline? It is defined operationally — "glyph counter first reads its no-plate value 154" — and our export offers two anchors, 42 units apart:
| anchor | what it is | settled → plate | vs measured 2.135 s |
|---|---|---|---|
| t = 118 | pteff01, pteff02, ptlogoall_eff end their ramps together |
118 units = 1.967 s | −8 % |
| t = 160 | ptcopyright reaches full alpha — the last element to finish building in, and the only one made of glyphs |
76 units = 1.267 s | −41 % |
The port's reconciliation picked 118. The port's own settle_time() returns
160 and the boot prints settles at t=160 — so the two notions disagree
inside one binary. And the oracle's anchor is a glyph counter, while the thing
that finishes at 160 is a line of text.
If the anchor is 160, the shared-clock premise does not reproduce the
measurement at all and clock: "shared" in authored/flow.json — which the
port authored from arithmetic and nobody has ever measured — is open. If it is
118, the reconciliation stands and H3 is not a timing defect.
Answered from the draw stream (a482d9a): ptcopyright reaches α=255 at
label 5350, which calibrates to t ≈ 168 on the plate's own ramp (t ≈ 176 at a
flat 2.0/label). Candidate B is 8–16 units away; candidate A is 50–58. It is B.
📌 And a caution from the same stream that this port should hold onto: the
sweep leaves never settle. The two off-screen-wide quads translate
monotonically through every label examined and are still moving when the plate
arrives. "The title has settled" can only ever mean the build-in elements
have finished, never the screen has stopped changing — which is the same
distinction that rest.t keeps getting wrong.
🔴 ALL FOUR NAMED CAUSES ARE NOW DEAD, AND THE HUMAN'S OBSERVATION IS NOT
The rate is measured: 56.8 units per guest second (units-per-second-measured.md,
control passing at 1.15 %, two elements agreeing at one clock — ptbtn00 at
657.9 α/s and ptcopyright at 650.4 α/s, which puts ptcopyright's segment at
T = 22.25, a round declared length nobody fitted). 30 and 120 are both
excluded.
At 56.8 units/s the plate's t = 236 lands at 4.15 s after clock zero,
against the port's 3.93 s. The port is fractionally early. So:
| candidate | verdict |
|---|---|
rest.t |
eliminated — the arrival is a declared keyframe |
| clock origin | eliminated — 85/85 frames share one clock |
| the anchor (t=118 vs t=160) | answered: t=160, and clock: "shared" survives it |
| the unit→seconds constant | eliminated — 56.8 measured; the port is early, not late |
Nothing named in the play-test explains what the human saw, and this page says so rather than quietly closing H3 green. The observation stands and is now unattributed. Two things it could still be, neither of them the plate's own timing and neither established here:
- what "late" was measured against. Every number above is relative to the
title's clock zero. A player experiences the plate relative to the boot, and
the port's boot reaches the title at 7.86 s only because
--skip-atpresses Ⓐ. 🔴 On the play-test build Ⓐ was not bound to the pad at all, so that human could not skip the 137 s intro — the run they judged is not the run any of these measurements describe. - the splash dwells. The rate's reach is the title. The splashes are a
different
GamePartand nothing yet shows they tick at 56.8; the Decoder has reading theirToff the disc as a next item.
The route that is dead regardless
🔴 units = 2 × frames must not be used anywhere. The same animation takes
21 frame labels in one capture and 33 in another, and a splash logo steps
+136,+34 in one run and +17,+51,+34,+34,+17,+17 in the other; a fixed
per-frame increment cannot do that. The 2 was one run's frame pacing.
✅ Audited, and the port never did this. boot.gd advances
time_units += delta * units_per_second off delta time. The retirement cost this
port a justification in authored/timing.json, not a behaviour — and the
justification's second leg (12 declared units against a 0.14–0.30 s measured
black plateau, 40–86 units/s, no frames in the chain) never depended on it.
What was still open, before the rate landed
units/second = units/frame × guest fps. The first factor is now 2. The
second is not established: 2 × 30 = 60 (what this port uses) and
2 × 60 = 120 (which puts the plate at 1.97 s instead of 3.93 s — the size
of what the human reported). The Decoder's capture ran at 27.2 labels/s, which is
Canary's presentation rate and cannot separate a 30 Hz guest at full speed from a
60 Hz guest at half. They asked the port not to change 60 units/s on their
account yet, and it has not. Asked in BLOCKED.md H3.
Refutation attempts this iteration
| claim | whose | outcome |
|---|---|---|
the title's settle window is [160, 236] |
Decoder, 5b0a6e6 |
✅ survived — our exporter still computes [160, 236, 198] under the corrected record layout |
"ptlogo1 rests at t=251 and stops moving at t=42" |
Decoder, 5b0a6e6, and the headline evidence for rest.t ≠ settle |
❌ refuted on its evidence — in the current export ptlogo1.rest.t is 42, equal to when it stops moving. The record-layout fix repaired exactly this element. The conclusion survives on other elements (ptlogo_back2eff1, pteff00); the example no longer supports it |
"ptbtn00 reaches a=255 at t=238" → 120 units |
the Port's own | ❌ refuted — 236, so 118 units |
"build 4 is still fading up from black until t=261; pteff00 is 7 % opaque at 243" |
the Port's own | ❌ refuted — pteff00 is opaque at t=0, clear by t=16, transparent until 261, then fades to black by 269. At t=243 it is 0 % opaque. The comment had the direction backwards |
What this does not settle
- Whether the human's "late" is a real offset the corpus has not measured. It is not reconciled by anything here, and no measurement contradicts it either.
- The
t=118/t=160anchor. Asked, not guessed. - Whether the plate pulses after arrival. The port holds it; the corpus
measures a ~2.24 s pulse. Filed already in
flow.json'sno_pulse_why. - Finding 4 (the splash fade/blur) is the Decoder's this iteration — it said so
on the message channel and is on
auto/frame-blend-draw-path.
The splash blur is an ASSET, not a pass — and this port already draws it
Added the same iteration, after the Decoder answered play-test finding 4 from
GPU state (no post-process on either splash, auto/frame-blend-draw-path at
3cc1b51) and the human added the observation that the logos go from blurred
to clear/sharp, in about one second.
Those two are not in tension. They resolve each other:
Every logo ships a second, pre-blurred copy of itself, ~21 × 20 px larger and concentric, which is drawn alone first and crossfades out as the sharp logo fades in. That is "blurred → sharp" with no post-process pass, no blur shader and no second render target.
Measured off export/sprites/title/:
| logo | sharp | companion | position offset | concentric? |
|---|---|---|---|---|
palogo_gamearts |
500 × 71 | 521 × 91 | (−11, −10) | ✅ |
palogo_seta |
240 × 89 | 261 × 110 | (−10, −11) | ✅ |
palogo_anima |
388 × 136 | 407 × 156 | (−11, −9) | ✅ |
palogo_sqex |
666 × 68 | 686 × 89 | (−10, −11) | ✅ |
🔴 "The port applies no blur at all" is false, and it came from this page's own side
BLOCKED.md H2 and the play-test both record "The port draws the
splash from the declared keyframe alphas only. It applies no blur at all."
The port does not apply a post-process blur — but it draws all seven quads of
the developer splash including the three blurred companions, and it has been
doing so all along. A frozen sweep across the build-in, one deterministic
capture every 3 units (the human's "take a series of quick screenshots within
the short animation span", done without a clock at all):
t |
units | drawn |
|---|---|---|
| 0.00 s | 0 | background only |
| 0.05 – 0.25 s | 3 – 15 | background + the three blurred companions alone |
| 0.30 – 0.70 s | 18 – 42 | all seven — the crossfade |
| 0.75 – 0.80 s | 45 – 48 | background + the three sharp logos |
Blurred first, then both, then sharp. The mechanism is reproduced. The claim that it was not came from describing the renderer instead of running it.
Cross-check of the Decoder's quad mapping — ✅ survived, independently
splash-quad-timeline.txt names its quads by NDC rectangle off the guest's
vertex stream. This export's declared rectangles, converted independently:
| this export | the guest | agreement | |
|---|---|---|---|
palogo_sqex |
x[−0.517, +0.523] y[−0.106, +0.083] | Q0 x[−0.520, +0.520] y[−0.100, +0.080] |
~2 px |
palogo_sqex_eff |
x[−0.533, +0.539] y[−0.133, +0.114] | Q7 x[−0.530, +0.540] y[−0.130, +0.120] |
~4 px |
Two decoders, two paths — a .pak read statically and a vertex stream logged
live — agreeing to a few pixels on both the sharp quad and the blurred one.
That is corroboration of the mapping and of Q7 being the companion.
What is still open on the splash
- The extent. The rectangles agree; the alphas are where the 5-units-per- frame discrepancy above came from, and until that is settled it is not possible to say whether the game holds the blurred copy longer than we do. That is the same question as H3 and is asked once, there.
- Whether
palogo_eff0(kind0x10, a full-screen quad, like the title'spteff00) is the splash's fade veil. Not examined this iteration.