diff --git a/authored/flow.json b/authored/flow.json index 4a06f5e2..98c8b50a 100644 --- a/authored/flow.json +++ b/authored/flow.json @@ -51,7 +51,7 @@ "", "It first said 'a screen's dwell is its OWN keyframe group'. Then GP_TITLE", "build 4 was measured dwelling ~1100 presented frames against a declared ~120,", - "and I generalised that into 'the boot is KNOWN TOO FAST on both splashes'.", + "and I generalised that into 'the boot is KNOWN TOO FAST [refuted] on both splashes'.", "๐Ÿ”ด THAT WAS AN OVER-CORRECTION and it is withdrawn. Build 4 is the title: its", "exit is caused by something outside its timeline, so it holds. A splash's exit", "is caused by nothing, so it plays its declared timeline and leaves. The title", diff --git a/authored/timing.json b/authored/timing.json index 49c35f6a..aec783cc 100644 --- a/authored/timing.json +++ b/authored/timing.json @@ -46,7 +46,7 @@ "", "It first said 'a screen's dwell is its OWN keyframe group'. Then GP_TITLE", "build 4 was measured dwelling ~1100 presented frames against a declared ~120,", - "and I generalised that into 'the boot is KNOWN TOO FAST on both splashes'.", + "and I generalised that into 'the boot is KNOWN TOO FAST [refuted] on both splashes'.", "๐Ÿ”ด THAT WAS AN OVER-CORRECTION and it is withdrawn. Build 4 is the title: its", "exit is caused by something outside its timeline, so it holds. A splash's exit", "is caused by nothing, so it plays its declared timeline and leaves. The title", diff --git a/docs/port/BLOCKED.md b/docs/port/BLOCKED.md index c4794127..a3e76941 100644 --- a/docs/port/BLOCKED.md +++ b/docs/port/BLOCKED.md @@ -122,7 +122,7 @@ HANDOFF. |---|---|---|---| | ~~P6 audio~~ | ~~which cue fires on move / confirm / back~~ | Q8 | โœ… **answered 2026-08-28** โ€” the RE agent retracted "cannot be extracted". The waves are located in `Static.slb` by playing them: **move `0x1ec0`** (8 192 B, 0.533 s), **confirm `0x5d6c0`** (12 288 B, 1.016 s), **back `0x0ec0`** (4 096 B, 0.344 s), and โฌ…โžก play nothing. Move and back reproduce across two boots. ๐ŸŸก that the cursor's wave is the cue *named* `SE_UI_CURSOR` is still a name match, and โ’ถ's wave is not separated between `SE_UI_DECIDE` and `SE_UI_SUB_WIN_OPN`. P6 can now export real audio; the exporter has to grow an SE path. **โœ… TAKEN at P6, 2026-08-29.** The three offsets now live in `authored/audio.json` `se.*` โ€” *not* in the exporter โ€” because MISSION ยง3 puts a measured value in `authored/` and a measured offset compiled into a Rust `const` is a measurement wearing the costume of a decoded field. `sylpheed_formats::media::se_wave_riff` does the assembly. | | ~~P6 audio~~ | ~~which BGM the menu plays~~ | Q10 | ๐Ÿ”ด **THIS ROW WAS WRONG WHEN IT WAS WRITTEN, and the port acted on it.** It read *"not on the disc โ€ฆ the port is choosing a track, and that choice is authored"*, and P6 duly picked `BGM_001` and labelled it arbitrary. **The menu's music is `BGM_103`, and it is in HANDOFF at `9ca1eb5` โ€” the exact commit this page says it was reconciled against.** Not stale: misread. HANDOFF's negative is bounded and the bound is the whole content of it โ€” the *tables* (`SOUNDS`, `FILES`, bank headers) name no screen; `GamePart_Title`'s `sub_821C5580` carries `li r5, 1103`, cue 1103 is `BGM_103`, and `BGM_103.slb`'s two declared waves (3 876 864 / 3 930 112 B) are byte-for-byte the two streams the XMA probe saw decoding at the main menu. HANDOFF's own sentence: *"The port does not have to choose a track."* **The lesson is not "re-read HANDOFF" โ€” this page's own staleness check passed.** It is that a row here must quote the reach of a negative, because a negative summarised without its bound reads as a bigger negative than it is. | -| P6 looping | where a menu loop restarts | Q10 | โ” **still open, and the port shipped the ugly answer on purpose.** No loop-point field has been identified in any bank โ€” `BGM_001` is the one characterised end to end (fades out at 167.663 s into 6.15 s of silence) and nothing suggests `BGM_103` differs in kind. `authored/audio.json` sets `loop: "restart"` โ€” replay from sample 0 โ€” so the listener hears the fade-out and the trailing silence at the seam. **Trimming to the fade would sound better and be worse**: it would invent a loop point, and an invented one is indistinguishable from a decoded one a month later. What settles it: a loop-point field, or a capture of the real menu looping. โš ๏ธ **The cost is now measured, 2026-08-30.** The bed loops at 87.8 s against the track's own 87.7 โ€” `loop: "restart"` behaves exactly as authored โ€” and the seam is **36 consecutive near-silent 50 ms windows, 84.40โ€“87.80 s**: about **3.4 seconds of silence** after a fade from RMS 2057 to 431. Long enough to read as the music having stopped rather than looped. That does **not** license trimming to the fade, which would still invent a loop point; it is recorded so the missing field's price is a number rather than an adjective. | +| ~~P6 looping~~ | ~~where a menu loop restarts~~ | Q10 | โœ… **ANSWERED AND SHIPPED, and this row stood stale for days while the fix was live.** The loop is a **runtime** field โ€” `loop_start`/`loop_end` in the XMA decoder context, set by `XMASetLoopData` โ€” and for `BGM_103` it is **[9.44 s, 71.31 s], cycling every 61.87 s**. `authored/audio.json` has shipped `loop_start_s: 9.44` / `loop_end_s: 61.87` since, and its `loop_why` marks the dead sentence `[refuted]`. ๐Ÿ”ด **The correction reached the manifest and not this file**, which is the exact failure `audio.json`'s own `why` warns about โ€” *a correction that does not reach the artifact a consumer reads has not been made*. Found by the Decoder reading my file, not by my checker: `check-claims` held the phrase but matched **case-sensitively**, and the copy here begins a sentence, so a capital **N** hid a registered dead claim in the one document whose job is to say what is still open. Matching is case-insensitive now, which immediately surfaced **five more** unmarked sites. | ~~P5 focus marker~~ | ~~the focus ring's spin PERIOD, and whether it loops~~ | Q1 + *"groups hold"* | โœ… **answered 2026-08-29, and NOT ON `main` YET.** The Decoder pointed at it over the message channel and the pointer resolves: branch `auto/no-disc-and-menu-captures`, commit **`4fa3099`** (branch head `66e74d4`), file `docs/re/focus-ring-spin-measured.md`, frames under `docs/re/captures/focus-ring/`. **The ring spins continuously โ€” period 2.177 s wall-clock, eight evenly spaced autocorrelation peaks over nine revolutions**, with no angle estimated anywhere (both angle estimators failed their own controls and were not used). It also reconciles with the declared `t=120` without a new constant: 120 units = 60 rendered frames, which is 2.00 s at a true 30 Hz and 2.08โ€“2.17 s at the 27.6โ€“28.8 fps this emulator runs, so the measurement sits at the top of the predicted band. ๐ŸŸก The Decoder is explicit that this is *consistency, not closure* โ€” the guest frame rate was not measured in the same run. โš ๏ธ **Do not read `captures/focus-ring/ring-20s-mean-uniform.png` as a frame**: the spin averages to a uniform circle, which is the finding, not a headless ring. **The port has not implemented this yet** โ€” it still draws 0ยฐ, which the same corpus says is a pose the game never shows. That is next iteration's work and it is no longer blocked. | | ~~P3/P5 โ€” the title screen~~ | ~~does the idle post-boot title show the `PRESS โ’ถ` plate?~~ | Q2 | โœ… **STALE โ€” struck 2026-08-30, and it had been wrong for weeks.** Every factual claim in it is now false: the boot does **not** end on a plateless build 4, `press_start` is **not** unused, and the port **has** drawn two builds at once since the plate-delay work. Verified this iteration โ€” `boot ends on title + press_start`, `overlay press_start โ€ฆ drew 1: ptbtn00`, plate region mean **95.70** against 33.6 for the bare title. ๐Ÿ”ด The row directly below it was already marked *answered and TAKEN* for the same question: two rows on one question, one struck and one live claiming the opposite, and the live one was the stale one. That is this page's own documented failure mode, caught by auditing it rather than by reading it. โš ๏ธ What remains open is a **different** question and has its own row: whether the plate *stays up* after its 8-unit window. | | P5 โ€” โ’ท on the main menu | ~~is โ’ท what returns to the title, or the idle timer?~~ **how long does โ’ท take?** | Q5 | ๐ŸŸก **the ORDERING is answered, the latency is not โ€” and this row's own argument is refuted, 2026-08-30.** It reasoned that *"the title self-returns after ~8โ€“10 s idle, so one unrecorded observation cannot separate them"*. HANDOFF `27938aa` measures the main menu as **not self-returning for โ‰ฅ 60 s untouched**, and places the ~8โ€“10 s idle on the **title**, not the menu โ€” so the confound the row was built on does not exist. โ’ท is delivered (Canary logs `vk=5801`) and is the only input in โ‰ฅ 100 s before the return: **the ordering is measured**. What stays open is only the latency, from a backlogged run. `authored/flow.json` already implements the ordering and is now under-claiming rather than over-claiming. Surfaced by `blocked-provenance` at score 10.6 against `9a10258`, unread for a day. | @@ -151,8 +151,8 @@ HANDOFF. | Milestone | Needs | HANDOFF | State | |---|---|---|---| -| P4/P7 โ€” transcode fidelity | **nothing from anybody; my instrument cannot answer yet** | `0159527` | ๐Ÿ”ด **THE GATE HAS NEVER CARRIED A FIDELITY CLAIM, and now it says so.** `AUDIO-VERIFICATION.md` ยง1 calls this the question P4 actually raised; nothing implemented it, and `verify-video-audio` explicitly declines it. `tools/port/verify-transcode-fidelity` exists and is **report-only**: best alignment is corr 0.763 on `S00A` and 0.075 on `ADV`, and both still report the difference *louder* than the source, which is impossible for two aligned signals at equal level โ€” so the fault is on my side of the instrument, not necessarily in the transcodes. Four traps reproduced on the way, three of which ยง1 names and one (**`-ss` before `-i` returning 4.6 s for a 4.0 s request**) it does not. โš ๏ธ A tool printing "not faithful" in this state would put a **false defect on the exporter**. | -| P4/P7 โ€” a `ยง1` addition for the HUMAN | **add the imprecise-seek trap to `AUDIO-VERIFICATION.md` ยง1?** | `0159527` | ๐ŸŸก **proposed, not done.** ยง1 lists three ways the measurement lies; a fourth is now reproduced โ€” a container-level seek returns a different span than requested, so the two windows cover different audio and no shift can align them (best corr 0.172). It is **indistinguishable from the alignment trap ยง1 already names**. ยง1 is the human's document, so this is a proposal rather than an edit. | +| P4/P7 โ€” transcode fidelity | ~~nothing from anybody~~ **the WAVEFORM half is still open** | `0159527` | ๐ŸŸก **PARTLY ANSWERED, by changing the kind of quantity.** Band energies need no alignment, and both transcodes match their sources to **0.66 dB worst-case across four bands** while an unrelated movie lands at **19โ€“20 dB** โ€” two populations an order of magnitude apart, so the 1.5 dB tolerance sits between measured values. Asserting in `check-all`, with the known negative on every run. โš ๏ธ **This is weaker than P4 wanted**: band agreement cannot distinguish a faithful transcode from one that kept the spectrum and mangled the waveform. The difference-signal half stays report-only and asserts nothing โ€” and the band result now **proves** its failure is my alignment, since matching spectra mean same content at same level. Earlier text: ๐Ÿ”ด **THE GATE HAS NEVER CARRIED A FIDELITY CLAIM, and now it says so.** `AUDIO-VERIFICATION.md` ยง1 calls this the question P4 actually raised; nothing implemented it, and `verify-video-audio` explicitly declines it. `tools/port/verify-transcode-fidelity` exists and is **report-only**: best alignment is corr 0.763 on `S00A` and 0.075 on `ADV`, and both still report the difference *louder* than the source, which is impossible for two aligned signals at equal level โ€” so the fault is on my side of the instrument, not necessarily in the transcodes. Four traps reproduced on the way, three of which ยง1 names and one (**`-ss` before `-i` returning 4.6 s for a 4.0 s request**) it does not. โš ๏ธ A tool printing "not faithful" in this state would put a **false defect on the exporter**. | +| P4/P7 โ€” a `ยง1` addition for the HUMAN | **add the imprecise-seek trap to `AUDIO-VERIFICATION.md` ยง1?** | `0159527` | ๐ŸŸก **proposed, not done โ€” and NARROWED 2026-08-30 before it was written up.** The Decoder reproduced it independently (4.597 s on `ADV`, 4.256 s on `S00A` for a 4.0 s request, correlations โˆ’0.03 and โˆ’0.34 at zero shift: different content, not a shift) and established that the **VIDEO** container-seek on this disc is **exact** โ€” byte-identical frames at 20 s. So the trap belongs to the **audio stream**, not to `-ss` placement, and the phrasing matters in the direction that bites: a check looking only at video would clear a path still unsafe for audio. Original: ๐ŸŸก **proposed, not done.** ยง1 lists three ways the measurement lies; a fourth is now reproduced โ€” a container-level seek returns a different span than requested, so the two windows cover different audio and no shift can align them (best corr 0.172). It is **indistinguishable from the alignment trap ยง1 already names**. ยง1 is the human's document, so this is a proposal rather than an edit. | ## Not blocking, recorded so nobody re-investigates โ€” 2026-08-30, HANDOFF `91ada14` diff --git a/docs/port/DECISIONS.md b/docs/port/DECISIONS.md index b7630048..9b40f2fa 100644 --- a/docs/port/DECISIONS.md +++ b/docs/port/DECISIONS.md @@ -9,7 +9,7 @@ dies, which is what this file is for. -257 sections. Search this before re-deriving anything. +260 sections. Search this before re-deriving anything. * [P0 โ€” the exporter, 2026-08-28](#p0--the-exporter-2026-08-28) * [P1 โ€” Godot draws the screen, 2026-08-28](#p1--godot-draws-the-screen-2026-08-28) @@ -268,6 +268,9 @@ dies, which is what this file is for. * [๐Ÿ”ด I measured my own claim and it is wrong: the player skips, heavily](#i-measured-my-own-claim-and-it-is-wrong-the-player-skips-heavily) * [๐Ÿ”ด Correcting the correction: the frame probe is an UPPER BOUND, and my contrast was contention](#correcting-the-correction-the-frame-probe-is-an-upper-bound-and-my-contrast-was-contention) * [The P4 fidelity question, attempted: four traps reproduced, no verdict yet](#the-p4-fidelity-question-attempted-four-traps-reproduced-no-verdict-yet) +* [Changing the KIND of quantity answered it on the first attempt](#changing-the-kind-of-quantity-answered-it-on-the-first-attempt) +* [๐Ÿ”ด My seek trap was over-general โ€” the Decoder narrowed it](#my-seek-trap-was-over-general--the-decoder-narrowed-it) +* [A capital letter hid a refuted claim in the file whose job is to say what is open](#a-capital-letter-hid-a-refuted-claim-in-the-file-whose-job-is-to-say-what-is-open) ## P0 โ€” the exporter, 2026-08-28 @@ -1594,7 +1597,15 @@ halving is a mix decision nobody made โ€” and because a sum can clip, the peak i ### The loop seam is ugly on purpose -No loop-point field has been identified. `loop: "restart"` replays from sample 0, +๐Ÿ”ด **SUPERSEDED โ€” see *"the menu BGM loop window"* below and `authored/audio.json`'s +`loop_start_why`.** The loop point exists: it is a **runtime** field set by +`XMASetLoopData`, and for `BGM_103` it is **[9.44 s, 71.31 s], cycling every +61.87 s**, which the exporter has trimmed to since. This section is kept because +it is what the port believed when it shipped the seam, and the reasoning below โ€” +that inventing a loop point is worse than an ugly one โ€” is why the wait was +cheap. Every claim in the paragraph that follows is dead. + +No loop-point field has been identified [refuted]. `loop: "restart"` replays from sample 0, so a listener hears the track's own fade-out and its trailing silence before the music comes back. @@ -13250,3 +13261,139 @@ right move is to propose the addition rather than edit it silently. are faithful to their sources. After this iteration that is *less* settled than it looked yesterday, because the question now has an instrument that says it cannot answer yet, instead of no instrument at all. + +## Changing the KIND of quantity answered it on the first attempt + +The Decoder's rule, from two failed attempts of their own: **two failed attempts +at the same measurement are evidence the quantity is wrong, not the parsing.** I +was four attempts into sample-exact difference-signal alignment with no verdict โ€” +well past the point where that rule applies. + +So the quantity changed. **Band energies need no alignment at all**: a statistic +over the window cannot be corrupted by a lag of any size. + +| band | `ADV` | `S00A` | +|---|---|---| +| 0โ€“500 Hz | โˆ’0.15 dB | โˆ’0.02 dB | +| 500โ€“2 000 Hz | โˆ’0.28 dB | โˆ’0.15 dB | +| 2 000โ€“6 000 Hz | โˆ’0.66 dB | โˆ’0.22 dB | +| 6 000โ€“16 000 Hz | โˆ’0.63 dB | โˆ’0.29 dB | + +**Worst deviation 0.66 dB**, transcode consistently a fraction of a dB quieter, +which is what lossy encoding should look like. The **known negative runs on every +invocation, not behind a flag**: comparing each source against the *other* movie's +transcode gives **20.02 dB** and **19.10 dB** โ€” two populations an order of +magnitude apart, so the 1.5 dB tolerance sits between measured values rather than +being picked. Now an asserting step in `check-all`. + +### It also diagnoses the failure it replaced, by elimination + +Matching spectra within 0.66 dB mean the two decodes **are the same content at +the same level**. So the difference-signal result โ€” difference louder than source +โ€” cannot be a level mismatch or a content mismatch. **It is my alignment, and now +that is evidence rather than my assumption.** The difference path stays in the +tool, report-only, asserting nothing. + +โš ๏ธ **The honest limit, stated in the tool's own output:** band agreement cannot +distinguish a faithful transcode from one that preserved the spectrum and mangled +the waveform. That is exactly what the difference signal was for, and it is still +open. **This is a weaker claim than P4 wanted, and it is the one I can support.** + +## ๐Ÿ”ด My seek trap was over-general โ€” the Decoder narrowed it + +I wrote *"`-ss` before `-i` is a container-level jump"* as though inexactness +followed from the placement. They checked it on the same movies: the **video** +container-seek here is **exact** โ€” a frame taken at 20 s via container seek is +**byte-identical** to one from a full decode, on both films. + +๐Ÿ“Œ So on this disc it is a property of the **audio stream**, not of `-ss` +placement as such. The correction matters in the direction that bites: **a check +that only looked at video would clear a path that is still unsafe for audio.** +Narrowed in the tool's own trap list rather than in prose only. + +โœ… Their reproduction is independent and closer than I expected โ€” 4.597 s on +`ADV` and 4.256 s on `S00A` for a 4.0 s request, against my 4.6 on a different +file in a different container, with correlations โˆ’0.03 and โˆ’0.34 at zero shift. +**Different content, not a shift**, which is the distinction that makes this trap +imitate the one ยง1 names. + +๐Ÿ“Œ And their cheap defence for the boundary family is now in the tool: **print +the search range beside the answer, so an edge reads as an edge.** The refusal +path was already there; the range was not, and a refusal that does not say what +it was searching is one an impatient reader widens by guessing. **Four instances +between us now, and the control caught all four.** + +### ๐Ÿ”ด And the control caught its own harness + +`check_extras_resets` reported **`PASSES A WRONG CONTRACT โ€” it checks nothing`**. +Not a broken check: the Decoder's delivery heading now appears **twice** in +HANDOFF, and `--control` perturbed only the **first** occurrence +(`h.replace(old, new, 1)`), so the check found the untouched duplicate and passed. + +๐Ÿ“Œ **A perturbation that does not reach every copy of the anchor makes the check +untestable, and does it silently โ€” because the check keeps passing.** The only +reason this surfaced is that the control asserts *the check must fail*, so a +check that could no longer be broken became a loud failure instead of a quiet +pass. Fixed to replace every occurrence, in both the HANDOFF and walk paths. + +โš ๏ธ Worth naming: **this is the first time a control has failed because of a +change in someone else's document rather than in my code.** The anchors couple me +to their prose, which we both knew; what is new is that *duplicating* a sentence +is enough to disarm a check without either of us touching a checked value. + +## A capital letter hid a refuted claim in the file whose job is to say what is open + +The Decoder read my `BLOCKED.md` and found the `P6 looping` row still asserting +**"No loop-point field has been identified in any bank"** โ€” days after +`authored/audio.json` shipped `loop_start_s: 9.44` / `loop_end_s: 61.87` and +marked that very sentence `[refuted]` in its own `why`. + +๐Ÿ“Œ **The correction reached the manifest and not the blocked list**, which is the +exact failure `audio.json`'s `why` warns about in its own text: *a correction that +does not reach the artifact a consumer reads has not been made.* I wrote that +sentence and then did it. + +### ๐Ÿ”ด And my checker held the phrase and could not see it + +`check-claims` has carried `no loop-point field has been identified` in its +register the whole time. It matched **case-sensitively**, and the copy in +`BLOCKED.md` begins a sentence โ€” so **a capital `N` hid a registered dead claim**, +and the check reported clean on every run. + +This is the Decoder's finding of the same day in its cheapest possible form. +Theirs was a register missing a revival that kept the claim and changed the second +clause; mine was one letter. **A register matching exact wording does not protect +the documents that rewrite most, and capitalising a sentence is the smallest +rewrite there is.** + +โœ… Matching is case-insensitive now, and it **immediately surfaced five more +unmarked sites** the old check had never been able to see: + +| | | +|---|---| +| `authored/flow.json`, `authored/timing.json` | *"the boot is KNOWN TOO FAST [refuted] on both splashes"* โ€” inside its own withdrawal, untokened | +| `tools/port/verify-screen` | *"composited rather than standalone"* [refuted] โ€” likewise | +| `tools/port/check-claims` | my new comment quoting the phrase while explaining it โ€” the recursion, again | +| `docs/port/DECISIONS.md` | **a whole section, *"The loop seam is ugly on purpose"*, still describing the refuted state** | + +All six fixed: five tokened, and the two that were **stale rather than +un-tokened** โ€” the `BLOCKED` row and the `DECISIONS` section โ€” rewritten with the +shipped values and the supersession stated. Controlled: a planted **capitalised** +revival fails the check, and removing it passes. + +### What I am not accepting from the same message + +โš ๏ธ They also flagged **"P4/P7 video โ€” whether โ’ถ skips a movie"** as stale in my +file. **It is not.** That row reads *"๐ŸŸก (a) ANSWERED, (b) still open"*, cites +HANDOFF Q9, and points at `authored/flow.json`'s `skippable: true` with its `why` +carrying the 57 s against 193 s baseline. The open half **(b)** is a different +question. Reported back rather than quietly "fixed", because accepting a +correction to a row that is already right would put a false stale-marker on a +live one โ€” and their own message is about an index amplifying exactly that kind +of error. + +๐Ÿ“Œ Their root-cause note is worth keeping and applies to my pages too: **a +negative about the METHOD written as a negative about the SUBJECT.** *"`Static.slb` +resists static scanning"* became *"SE audio is not extractable"* โ€” and the wrong +one was the heading. Every โ” row I write asserting something *cannot be known* +should be checked for whether it means *my instrument cannot see it*. diff --git a/tools/port/check-all b/tools/port/check-all index 9905a553..821920ca 100755 --- a/tools/port/check-all +++ b/tools/port/check-all @@ -49,6 +49,10 @@ step modding-rules must-pass tools/port/check-modding # 2026-08-30 nothing checked what any of them rested on -- seven were resting on # a sibling `why` that argued a different claim. step authored-kinds must-pass tools/port/audit-kinds +# Band levels are alignment-free and carry their own known negative on every run; +# the difference-signal half of the same tool stays report-only and asserts +# nothing. See docs/port/DECISIONS.md -- the waveform question is still open. +step transcode-bands must-pass tools/port/verify-transcode-fidelity step capture-controls must-pass tools/port/check-capture-controls step menu-audio must-pass env OUT="$OUT/audio" tools/port/verify-menu-audio # A stale index is worse than none: it answers "is this already decided?" with a diff --git a/tools/port/check-claims b/tools/port/check-claims index 16d639c2..962a7440 100755 --- a/tools/port/check-claims +++ b/tools/port/check-claims @@ -127,11 +127,12 @@ import sys f, claim, marker, w = sys.argv[1], sys.argv[2], sys.argv[3], int(sys.argv[4]) s = open(f, encoding="utf-8", errors="ignore").read() i = n = 0 +low, claim_low = s.lower(), claim.lower() while True: - i = s.find(claim, i) + i = low.find(claim_low, i) if i < 0: break - if marker.lower() not in s[max(0, i-w):i+w+len(claim)].lower(): + if marker.lower() not in low[max(0, i-w):i+w+len(claim)]: print(" unmarked in %s at char %d" % (f, i)) sys.exit(1) n += 1 @@ -145,7 +146,15 @@ print(n) sys.exit(0) PY ) && marked=$((marked + out)) || { printf '%s\n' "$out"; bad=$((bad+1)); } - done < <(grep -rl -- "$claim" docs/ crates/ port/ tools/ authored/ 2>/dev/null || true) + # ๐Ÿ”ด CASE-INSENSITIVE since 2026-08-30, and the reason is a live miss. The + # register held "no loop-point field has been identified" [refuted]; `BLOCKED.md` + # it capitalised at the start of a sentence, and the check reported clean while + # a refuted claim stood unmarked in the file whose whole job is to say what is + # still open. The Decoder found the same class the same day from the other end + # -- their register missed a revival that kept the claim and changed the second + # clause. A register matching EXACT wording does not protect the documents that + # rewrite most, and a capital letter is the cheapest rewrite there is. + done < <(grep -ril -- "$claim" docs/ crates/ port/ tools/ authored/ 2>/dev/null || true) if [ "$bad" -eq 0 ]; then printf ' %-42s %d file(s), %d occurrence(s) suppressed\n' "$claim" "$hits" "$marked" total_marked=$((total_marked + marked)) diff --git a/tools/port/contract-check b/tools/port/contract-check index d3f56212..82d925e3 100755 --- a/tools/port/contract-check +++ b/tools/port/contract-check @@ -212,7 +212,7 @@ def fn_nav_perturbed(fn, old, new): """ global nav real = nav - nav = lambda: (real()[0].replace(old, new, 1), real()[1]) + nav = lambda: (real()[0].replace(old, new), real()[1]) try: fn(None) finally: @@ -233,7 +233,13 @@ def control(h): before, FAIL = FAIL, 0 with contextlib.redirect_stdout(io.StringIO()): if src is h: - fn(h.replace(old, new, 1)) + # ๐Ÿ”ด EVERY occurrence, not the first. A one-shot replace left the + # check reading an untouched duplicate and passing a perturbed + # contract -- reported 2026-08-30 the day a delivery's heading + # came to appear twice. The control caught its own harness: a + # perturbation that does not reach every copy of the anchor makes + # the check untestable, silently, because it keeps passing. + fn(h.replace(old, new)) else: fn_nav_perturbed(fn, old, new) noticed, FAIL = FAIL > 0, before diff --git a/tools/port/verify-screen b/tools/port/verify-screen index fe224913..dde94508 100755 --- a/tools/port/verify-screen +++ b/tools/port/verify-screen @@ -54,7 +54,7 @@ # 2026-08-30: a screen "carries its own background" when it declares a # full-screen untextured primitive at `t=0` with `fade_argb 0xff000000` -- # opaque black. Twelve do (`pteff00`, `palogo_eff0`, `pgloading_eff00`). -# Four do NOT. I first called those four "composited rather than standalone"; +# Four do NOT. I first called those four "composited rather than standalone" [refuted]; # that reading is REFUTED disc-wide (see below) and what they share is only # that they do not begin from black: # diff --git a/tools/port/verify-transcode-fidelity b/tools/port/verify-transcode-fidelity index d1ed3e03..1d79415c 100755 --- a/tools/port/verify-transcode-fidelity +++ b/tools/port/verify-transcode-fidelity @@ -11,8 +11,10 @@ The doc names three ways the measurement lies, and all three are handled here rather than hoped about: ALIGNMENT a one-sample offset makes the difference nearly as loud as the - source. Cross-correlated at 8 kHz, then refined sample-exact at - the full rate, BEFORE subtracting. + source. Cross-correlated coarse-to-fine BEFORE subtracting, and + the search REFUSES when its best lag sits on the boundary -- + printing the range beside the answer, so an edge reads as an + edge. CHANNEL LAYOUT the source is 5.1 and the transcode is stereo. The source is folded with `video.rs`'s own `DOWNMIX_51` -- read out of the manifest's recorded command, not restated here -- so both sides @@ -20,6 +22,14 @@ rather than hoped about: A PARTIAL FILE `ffprobe` once reported 33 s for a 137 s transcode because the encode was still running. Duration and mtime are checked, and a file written in the last 60 s is refused. + THE SEEK `-ss` before `-i` returned 4.6 s of AUDIO for a 4.0 s request on + this WMA Pro source, so the two windows covered different audio. + Not in ยง1. โš ๏ธ NARROWED after the Decoder checked it: on this + disc the VIDEO container-seek is EXACT -- a frame taken at 20 s + via container seek is byte-identical to one from a full decode. + So it is a property of the AUDIO STREAM, not of `-ss` placement + as such, and a check that only looked at video would clear a + path still unsafe for audio. ๐Ÿ”ด AND IT RUNS ITS OWN KNOWN NEGATIVES. A fidelity check that has only ever returned "faithful" is the unfalsifiable clean run this project keeps finding: @@ -43,6 +53,10 @@ RATE = 48000 COARSE = 8000 WINDOW_S = 25.0 PASS_DB = 40.0 +# Per-band tolerance. Both shipped transcodes sit at 0.29 and 0.66 dB worst-case +# across four bands, and the unrelated-movie control lands an order of magnitude +# out, so this is set between two measured populations rather than picked. +PASS_BAND_DB = 1.5 def sh(*a): @@ -124,7 +138,12 @@ def align(src, dst, af): if rate == 2000: lag, c = best_lag(a, b, span, stride) if abs(lag) >= span: - return None, c # pinned: refuse rather than report it + # Refuse AND say what the range was: the Decoder's cheap defence + # is printing the search range beside the answer so a boundary + # reads as a boundary rather than as a result. + print(f" coarse lag {lag:+d} of a +/-{span} search at {rate} Hz" + f" -- ON THE BOUNDARY, so this is the window's edge, not a peak") + return None, c coarse = lag / rate else: centre = int(round(coarse * rate)) @@ -134,6 +153,59 @@ def align(src, dst, af): return int(round(coarse * RATE)), c +BANDS = [(0, 500), (500, 2000), (2000, 6000), (6000, 16000)] + + +def band_db(path, af, lo, hi, seconds=25.0, skip=2.0): + """RMS in one band, straight out of `astats`. + + ๐Ÿ”ด A DIFFERENT KIND OF QUANTITY, and that is the whole reason it exists. The + difference-signal method needs the two decodes aligned to the sample, and + four attempts at that produced four different failures and no verdict. The + Decoder's rule from their own two failed attempts: **two failed attempts at + the same measurement are evidence the QUANTITY is wrong, not the parsing.** + Band energy needs no alignment at all -- it is a statistic over the window, + so a lag of any size cannot corrupt it. + + โš ๏ธ It is a WEAKER claim than a difference signal. Matching band energies + cannot distinguish a faithful transcode from one that preserved the spectrum + while mangling the waveform. It is what this instrument can honestly support, + and it is stated as that rather than dressed up as fidelity. + """ + chain = [(af + "," if af else ""), "aformat=channel_layouts=mono"] + if lo > 0: + chain.append(",highpass=f=%d" % lo) + if hi < 20000: + chain.append(",lowpass=f=%d" % hi) + chain.append(",astats=measure_perchannel=none") + out = subprocess.run( + ["ffmpeg", "-hide_banner", "-i", path, "-ss", str(skip), "-t", str(seconds), + "-af", "".join(chain), "-f", "null", "-"], + capture_output=True, text=True).stderr + m = re.search(r"RMS level dB: (-?[\d.]+|-inf)", out) + if not m or m.group(1) == "-inf": + return None + return float(m.group(1)) + + +def bands(src, dst, af, label): + """Per-band level, source against transcode. No alignment involved.""" + print(f" {label}") + worst = 0.0 + for lo, hi in BANDS: + a = band_db(src, af, lo, hi) + b = band_db(dst, None, lo, hi) + if a is None or b is None: + print(f" {lo:>5}-{hi:<5} Hz one side silent -- no comparison") + continue + d = b - a + worst = max(worst, abs(d)) + flag = "" if abs(d) <= 1.0 else (" <- " + ("transcode louder" if d > 0 else "transcode quieter")) + print(f" {lo:>5}-{hi:<5} Hz source {a:7.2f} transcode {b:7.2f}" + f" {d:+6.2f} dB{flag}") + return worst + + def downmix_of(manifest, name): """The fold the EXPORTER used, read back out of the recorded command.""" for v in manifest.get("videos", []): @@ -211,6 +283,24 @@ def main(): fail += 1 continue af = downmix_of(man, name) + worst = bands(src, dst, af, f"{name} -- band energies (needs no alignment)") + verdict = "ok" if worst <= PASS_BAND_DB else "๐Ÿ”ด OUT OF TOLERANCE" + print(f" worst band deviation {worst:.2f} dB {verdict}") + if worst > PASS_BAND_DB: + fail += 1 + # ๐Ÿ”ด THE KNOWN NEGATIVE RUNS EVERY TIME, not behind a flag. A band check + # that has only ever seen a faithful pair cannot be told from one that + # compares a file with itself by accident -- and this tool has already + # produced four confident wrong numbers on the other quantity. + other = [v for v in man["videos"] if v["name"] != name] + if other: + osrc = os.path.join("export", other[0]["file"]) + bad = bands(src, osrc, af, f" control: vs {other[0]['name']}, must be FAR out") + ctl = "ok" if bad > 3 * PASS_BAND_DB else "๐Ÿ”ด an unrelated movie passes as faithful" + print(f" worst band deviation {bad:.2f} dB {ctl}") + if bad <= 3 * PASS_BAND_DB: + fail += 1 + print() if af is None: print(f" {name:<28} โš ๏ธ no `-af` in the recorded command: the source" " is stereo, comparing without a fold") @@ -232,7 +322,12 @@ def main(): print(" ๐Ÿ”ด an unrelated movie scores as faithful") fail += 1 print() - print(" ๐Ÿ”ด REPORT ONLY -- NO FIDELITY VERDICT IS CLAIMED, and the numbers") + print(" โš ๏ธ WHAT IS ASSERTED: per-band level agreement, which needs no") + print(" alignment. It CANNOT tell a faithful transcode from one that kept") + print(" the spectrum and mangled the waveform. That is the honest limit of") + print(" this quantity, and it is what the difference signal below was for.") + print() + print(" ๐Ÿ”ด THE DIFFERENCE SIGNAL IS REPORT ONLY -- NO VERDICT, and the numbers") print(" above must not be read as one. Best alignment so far is corr") print(" 0.763 on `S00A` and 0.075 on `ADV`, and both still report the") print(" difference LOUDER than the source, which is impossible for two")