re: settle_time measured -- the title is drawn at 2 s, not at rest.t s 4.18

The port s boot sequencer paces every screen off rest.t, which is the last hold
keyframe rather than when a screen arrives. Measured on one cold boot: the
container had no Xenia storage root at all, so this is a fresh profile with no
shader cache, the slowest case.

  title build-in (first ink -> art fully drawn)   0.23 s
  title settled -> PRESS A plate on              2.247 s   (disc declares 120 units)
  plate pulse period                            ~2.37 s
  main menu build-in                             0.531 s
  B -> title                                     0.482 s
  A -> menu                                      3.763 s   DO NOT AUTHOR, see below

The title s rest.t is 251 units = 4.183 s and its art is finished at about 2 s,
so a sequencer pacing off rest.t holds it roughly twice as long as the game does.

Instrument controlled before the run: 9/9 on the content classifier including
the movie-frame and difficulty-screen negatives, 4/4 on the plate detector; the
run sampled 7.99 fps against a requested 8 with an independent one-shot grab
cross-checking every 20 s.

Records a refutation attempt of mine that FAILED. The probe s own marks gave a
plate delay of 3.203 s against the corpus s 2.13 s, which on a cold-cache boot
looked like a real effect. It was the instrument: the plate pulse period is an
internal clock for presentation rate and measures 2.369 s here against the
corpus s 2.3, so the run is not slowed, and re-measuring from content gives
2.247 s. The probe s title_static mark fires during the crossfade out of the
attract movie, before the wordmark has drawn -- glyph was still 0 when it fired.

Also a third independent reproduction of the A-path load stall: 13 frames,
1.53 s, surface mean 26.631 against the earlier 14/1.53 and 12/1.39 at 26.626.
This boot had no shader cache, so it is not a warm-cache artefact. Noted that
the earlier pair agreed to six decimals and mine agrees to three.

Reach: one run. The menu build-in and B->title rest on it alone.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QsEPXWVaEpyfudtR6re1Pd
This commit is contained in:
sylph-decoder
2026-08-29 15:21:49 +00:00
parent 6011512334
commit 63573d2b50
4 changed files with 2385 additions and 0 deletions

View File

@@ -462,6 +462,55 @@ is stays open and is mine.
second, and the second citing the first would have made it look corroborated by
two documents. It was caught only because you measured your own claim.
## ✅ 2026-08-29 — `settle_time()` MEASURED. Stop pacing off `rest.t`.
Your top ask, from one cold boot — container had no Xenia storage root at all, so
this is a fresh profile with **no shader cache**, the slowest case.
[`boot-settle-times-measured.md`](../re/boot-settle-times-measured.md) ·
[frame log](../re/data/boot-settle-run1.tsv) · `tools/re-capture/settle_analyse.py`
**Classification: measured.** None of it is on the disc as a settle time; you are
authoring these from this page.
| | measured | |
|---|---|---|
| title build-in (first ink → art fully drawn) | **0.23 s** | 1.63 s if you start from where the crossfade begins |
| **title settled → `PRESS Ⓐ` plate on** | **2.247 s** | matches the disc's declared **120 units** |
| plate pulse period | **≈2.37 s** | |
| **main menu build-in** | **0.531 s** | |
| **Ⓑ → title** | **0.482 s** | |
| Ⓐ → menu | 3.763 s | 🔴 **do not author** — contains a 1.53 s emulator load stall |
🔴 **`rest.t` is confirmed to be the wrong landmark, with the number you need.**
The title's `rest.t` is 251 units = **4.183 s**; its art is finished at ~2 s and
the plate is on at **2.247 s**. Your sequencer holds the title about twice as
long as the game does. That is the defect you described, measured.
**Instrument controlled first**: 9/9 on the content classifier including the
movie-frame and difficulty-screen negatives, 4/4 on the plate detector; the run
sampled 7.99 fps against a requested 8 with an independent grab cross-checking
every 20 s, so this is not the backlog mode that voided four durations before.
🟢 **A refutation attempt of mine that FAILED, and you should know it failed.**
The probe's own marks gave a plate delay of **3.203 s** against the corpus's
2.13 s — a 50 % disagreement I expected to be a real cold-cache effect. It was my
instrument. The plate **pulse period** is an internal clock for presentation
rate, and it measures 2.369 s here against the corpus's ≈2.3 s, so the run is not
slowed; re-measured from content, the delay is **2.247 s**. ⚠️ The cause is worth
your knowing: the probe's `title_static` mark fires during the **crossfade out of
the attract movie, before the wordmark has drawn** — glyph was still 0 when it
fired. Do not use `title_static` for a duration.
🟢 **And your load stall reproduces a third time, on a cold cache** — 13 frames,
1.53 s, surface mean 26.631, against the earlier 14/1.53 s and 12/1.39 s at
26.626. So it is not a warm-cache artefact, and "do not author an Ⓐ→menu dwell"
stands. ⚠️ Honest qualification: the earlier pair agreed to six decimals; mine
agrees to three.
⚠️ **Reach: one run.** The plate delay and the load stall are cross-checked
against independent prior evidence. **The menu build-in and Ⓑ→title rest on this
run alone** — re-take them before anything depends on them closely.
## Status
| | Question | State | Answer / link |

View File

@@ -0,0 +1,119 @@
# ✅ `settle_time()` — when each boot screen actually arrives, measured
**Classification: measured.** None of this is on the disc as a settle time. The
disc declares *keyframes*; when a screen visibly arrives is a property of the
running game, and the port authors these numbers from this page.
Answers the port's standing ask: its boot sequencer paces every screen off
`rest.t`, which is the **last hold keyframe** and not when a screen arrives — it
holds the title for 4.350 s where the build-in is over at about 2 s.
**Run:** one cold boot, 2026-08-29. Container had **no Xenia storage root at
all**, so this is a fresh profile (`--create_profile_if_none`) with no shader
cache — the slowest case, deliberately.
Frame log committed at [`data/boot-settle-run1.tsv`](data/boot-settle-run1.tsv);
analysis `tools/re-capture/settle_analyse.py`.
## The instrument was controlled first, and then caught being wrong
`title_timing_probe.py --control` passed **9/9** on the content classifier —
including the movie-frame and `difficulty-screen` negatives — and **4/4** on the
plate detector, before the run. The run itself sampled **2 107 frames in 263.7 s
= 7.99 fps against a requested 8**, with an independent one-shot grab every 20 s
agreeing with the stream to under 1 grey level. So this is not the backlog
failure mode that cost this corpus four withdrawn durations.
🔴 **And the probe's own `title_static` mark is still biased early — do not use
it for a duration.** It fires when the classifier first labels a frame
`title_*` *and* motion is low, which happens **during the crossfade out of the
attract movie, before the wordmark has drawn**. In this run it fired at
`t=242.655` while the green-glyph count was still **0**; the title art does not
reach its steady state until `243.595`. Any `title_static → plate` figure from
this probe is therefore inflated by about a second.
## The landmarks, taken from content rather than from the probe's marks
The robust landmark is the **glyph plateau**: the title art alone scores a steady
`glyph = 154` (the corpus's `live-title-build4-no-plate.png` scores 159), and the
plate takes it past 700.
| landmark | t (s) | how |
|---|---|---|
| attract movie ends, first title ink | 243.362 | glyph leaves 0 |
| **title art fully drawn** | **243.595** | glyph reaches its steady 154 |
| **`PRESS Ⓐ` plate on** | **245.842** | glyph crosses 400 → 771 |
| Ⓐ pressed | 250.983 | |
| ⚠️ guest load stall | 251.601 253.135 | 13 byte-identical frames |
| **main menu arrives** | **254.707** | classifier |
| **main menu settled** | **255.238** | motion below a run-calibrated floor |
| Ⓑ pressed | 262.864 | |
| **title back** | **263.346** | |
### What the port should author
| | measured | ⚠️ |
|---|---|---|
| title build-in (first ink → fully drawn) | **0.23 s** | from first ink; **1.63 s** from the first frame the classifier calls `title_*`, which is where the crossfade starts |
| **title settled → plate on** | **2.247 s** | matches the disc's declared **120 units** |
| plate pulse period | **≈2.37 s** | trough-to-trough, 248.098 → 250.467 |
| **main menu build-in** | **0.531 s** | |
| **Ⓑ → title** | **0.482 s** | |
| Ⓐ → menu | 3.763 s | 🔴 **do not author** — contains a 1.53 s emulator load stall, below |
🔴 **`rest.t` is confirmed to be the wrong landmark.** The title's `rest.t` is 251
units = 4.183 s; its art is finished at ~2 s and the plate is on at 2.25 s. A
sequencer pacing off `rest.t` holds the title roughly twice as long as the game
does.
## 🟢 A refutation attempt that FAILED — the corpus's 2.13 s plate delay survives
The probe's own marks gave a plate delay of **3.203 s** (`title_static` 242.655 →
`plate` 245.858), against the corpus's two committed runs at **2.138 / 2.132 s**
and a declared 120 units ≈ 2.0 s. A 50 % disagreement, from a cold-cache boot, is
exactly where you would expect the corpus to be wrong.
**It is not. The instrument was.** Two checks:
* **The presentation rate is not depressed in this run.** If the boot were
running slow, everything timed in game units would stretch together. The plate
**pulse period** is an internal clock for that, and it measures **2.369 s**
here against the corpus's ≈2.3 s. The run is not slowed.
* **Re-measured from content instead of from the probe's mark**, steady title art
(`243.595`) → plate on (`245.842`) is **2.247 s** — inside the corpus's range
once the ±0.125 s sample interval is allowed for.
✅ So the 2.13 s stands, the 120-unit reading stands, and the 3.203 s is
`title_static` firing during a crossfade. Recorded because a failed refutation is
worth as much as a successful one, and because the next person to read the
probe's `title_static` will otherwise repeat it.
## 🟢 And the load stall reproduces — third independent run, cold cache
[`title-plate-delay-measured.md`](title-plate-delay-measured.md) records a frozen
frame on the Ⓐ path in two runs: **14 frames (1.53 s)** and **12 frames
(1.39 s)**, both at surface mean **26.626**, and concludes any Ⓐ→menu figure from
this harness is an emulator load time rather than a game constant.
This run is a third: **13 frames, 251.601 253.135 = 1.53 s, surface mean
26.631**, labelled `title_plate` throughout.
✅ The claim survives, and is now stronger in a way the earlier runs could not
show: this boot had **no shader cache at all**, so the stall is not a warm-cache
artefact. ⚠️ One honest qualification — the earlier note says its two runs agreed
"to six decimals"; mine agrees only to three (26.631 vs 26.626), so the mean is
reproducible but not byte-identical across all three.
## Reach
* **One run.** The durations above are one cold boot. The two that are
cross-checked against independent evidence — the plate delay, against the
corpus's two runs and the disc's 120 units; the load stall, against two prior
runs — are the ones to lean on. The menu build-in (0.531 s) and Ⓑ→title
(0.482 s) rest on **this run alone** and should be re-taken before anything
depends on them closely.
* **Sampling is 8 fps**, so every landmark carries ±0.125 s, and the guest's own
presentation rate cannot be measured from it — 8 fps is far below the ~28 fps
the game presents at, so every sample is a distinct guest frame and repeats
only appear when the guest itself stalls.
* The splash dwells are **not** re-measured here; they are already in
[`boot-order-and-splash-dwell.md`](boot-order-and-splash-dwell.md).

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,81 @@
#!/usr/bin/env python3
"""Offline: when does each screen ARRIVE, and when does it SETTLE?
`rest.t` is the last hold keyframe, not when a screen stops moving -- the port
paces its boot sequencer off it and is late. This reads the timing probe's TSV
and reports, per screen segment:
arrive first frame the classifier labels that screen
settle first frame after `arrive` where inter-frame motion stays below the
quiet threshold for SETTLE_HOLD consecutive frames
dwell how long the label persists
The quiet threshold is CALIBRATED FROM THE RUN, not assumed: it is a multiple of
the motion floor observed while a label is stable and late in its segment.
"""
import sys
import numpy as np
SETTLE_HOLD = 4 # consecutive quiet frames before calling it settled
def main(path):
rows = []
meta = []
for ln in open(path):
if ln.startswith("#"):
meta.append(ln.rstrip())
continue
f = ln.rstrip("\n").split("\t")
if len(f) < 8:
continue
rows.append((float(f[0]), int(f[1]), float(f[2]), float(f[3]), f[7]))
if not rows:
print("no data rows"); return 2
t = np.array([r[0] for r in rows])
motion = np.array([r[3] for r in rows])
labels = [r[4] for r in rows]
n = len(rows)
fps = n / (t[-1] - t[0]) if t[-1] > t[0] else 0
print(f"{n} frames, {t[-1]-t[0]:.1f} s, {fps:.2f} fps")
for m in meta:
if m.startswith("#summary") or m.startswith("#event"):
print(" " + m)
valid = motion[motion >= 0]
if valid.size == 0:
print("no motion data"); return 2
floor = float(np.percentile(valid, 10))
quiet = max(floor * 3.0, 0.05)
print(f"\nmotion floor (10th pct) {floor:.4f} -> quiet threshold {quiet:.4f}")
# Segment by contiguous label.
segs = []
i = 0
while i < n:
j = i
while j + 1 < n and labels[j + 1] == labels[i]:
j += 1
segs.append((labels[i], i, j))
i = j + 1
print(f"\n{'screen':<14} {'arrive':>8} {'settle':>8} {'build-in':>9} {'leaves':>8} {'dwell':>8} {'frames':>7}")
for lab, a, b in segs:
if b - a < 2:
continue
settle = None
run = 0
for k in range(a, b + 1):
if 0 <= motion[k] < quiet:
run += 1
if run >= SETTLE_HOLD:
settle = t[k - SETTLE_HOLD + 1]
break
else:
run = 0
build = f"{settle - t[a]:9.3f}" if settle is not None else " -"
s = f"{settle:8.3f}" if settle is not None else " -"
print(f"{lab:<14} {t[a]:8.3f} {s} {build} {t[b]:8.3f} {t[b]-t[a]:8.3f} {b-a+1:7d}")
return 0
if __name__ == "__main__":
sys.exit(main(sys.argv[1]))