eb45f9320d842bb52f6c76ec6eee71544fa8cb53
4 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
c346c65568 |
port: a capture must pass a provenance check before anyone analyses it
The 6-channel capture I spent an iteration refuting was corrupt, and the Decoder found the cause: PulseAudio remapping between two mismatched channel maps, where a 6-channel remap SILENTLY DROPS AND DUPLICATES. Its control -- six channels, six tones, same sink, same parec -- came back 400/3200/200/800/800/200 for an input of 400/800/200/1600/3200/6400. Two source channels gone entirely. So the negative was right, and the byte-identical pair I reported was the thread that unravelled it. Worth recording precisely, because it nearly went unreported: it began as an idle look at two channels whose peak AND RMS matched to six decimals, and it only became evidence because a coincidence at six decimals is cheaper to hash than to explain. `tools/port/check-capture` makes that check one command -- split the file, hash every channel, fail on any duplicate pair -- and AUDIO-VERIFICATION.md gains a section 5 saying to run it FIRST, every time, plus the two conditions the same incident produced: start the recorder before the process, and log what was on screen against the recording's own clock so a miss is diagnosable. Controlled both directions, because a checker nobody controlled is what this incident is about: six distinct tones PASS; the remap's own output pattern FAILS naming all four pairs; the corrupt capture FAILS on ch2 == ch5. THE KNOWN-BAD CONTROL IS THE POINT. All six of its channels report a peak of -18.063656 dB, identical to six decimals, while containing three duplicate pairs. A level check cannot see this failure. That is why the tool hashes rather than measures, and why the corrupt capture's "plausible per-channel levels" were never evidence. The tool says of itself that it is necessary, not sufficient. Withdrawn with the file, both the Decoder's: "all six channels carry signal", and the non-zero-surround observation offered as weak support for 5.1. Unaffected: the three-XMA-context concurrency result, read from the emulator's log rather than the audio path, on two independent boots. The corrupt file is dropped from the exchange so the next agent cannot pick it up and repeat the work. Nothing in the export changed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01N7FiFFFwbvG2uxdcEh8HyF |
||
|
|
bb9626defe |
port: the game decodes all three voice streams at once, and two baseline rows were comparing blank frames
TWO FINDINGS, one mine and one handed to me, and the second retires a premise I built on twice. THE P1 BASELINE HAD ROWS THAT PROVED NOTHING. `build_12` and `build_15` render pure black in BOTH renderers -- mean 0, max 0 -- so the difference is zero and `verify-screen` scored them `max 0 over3 0 OK`, the strongest verdict it has. Two of sixteen rows were comparing nothing against nothing. Worse than a missing test, because a missing test is visible in the count. Cause isolated by a control, not by reading: `build_00`/`build_01` are the same loading screen minus three elements and render fine (mean 1.913, max 214.5). The dressed variants add `pgloading_eff00`, a 1280x720 primitive resting OPAQUE BLACK at t=38 inside its own opening black hold, with no layer key so paint order puts it last. The rule I was about to write -- "rest.t before the last timed keyframe is the pathology" -- was killed by running the census first: 152 of 212 elements in this export have rest.t earlier than their last timed keyframe. It is the norm. What is actually unusual is the CONTENT, and its reach is one: `pgloading_eff00` is the only element in the export whose resting pose is a fully opaque full-frame quad. One instance is not a rule, so the renderer is unchanged and the HARNESS is fixed: a blank pair now reports BLANK -- both renderers drew nothing; this row proves nothing. `status` is untouched, so an unrelated DIFFERS still fails. THE VOICE EXPORT IS KNOWN INCOMPLETE. The Decoder booted Canary with --xma_param_probe and the game decodes ALL THREE streams CONCURRENTLY, in three XMA contexts whose byte sizes match the disc payloads exactly. So "three presentations of one take, pick one" is refuted by the running game and the question I had been arguing -- WHICH presentation -- has no answer. This one no census could have caught. Every measurement was right: the streams are equal-duration, one is silence, one is 0.60x another with the residual 26.8 dB down. The frame around them was wrong, and the file says ChannelMask 0x0002 on all three. It took the running game -- which is the mission's own sentence arriving in practice. BEHAVIOUR HELD DELIBERATELY. An equal-gain 1/n sum of channel pairs is not a downmix either -- MISSION section 6 pins an explicit matrix for exactly that reason -- and summing cost S00A 6.02 dB when one stream was silence. Swapping one guess for another on a message is what produced this entry twice. What changed is that the wrongness is now LOUD, because this failure sounds like success: one stream is clean audible dialogue. A top-level manifest warning per movie, the console line, and the authored entry all say `1 of 3 streams`. "They are 5.1" is recorded as the Decoder's HYPOTHESIS with its own counter-evidence attached, and nothing builds on it. What settles it is asked: a recording of the game's own output over ADV through the null sink, which turns channel roles into a fit against an oracle. Refutation attempt, survived: the Decoder's loading-screen variant map. Entries 0/1 carry 7 elements and 12/15 carry those seven plus baseeff, eff00 and loop5 -- exact in count and identity, and it is what made build_00 a control. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01N7FiFFFwbvG2uxdcEh8HyF |
||
|
|
cdea236713 |
port: the P1 regression harness could not have run since the monorepo merge
verify-screen resolves its reference binary to a path build-reference-cli
stopped being able to produce: that script greps Cargo.toml for a
`Syplheed-Reborn.git", rev = "..."` pin, and
|
||
|
|
65cefa74c3 |
monorepo: one repository for the decoders, the port and the corpus
Some checks failed
Merges the Godot port into the reverse-engineering repository, preserving both
histories -- 1019 commits of corpus plus the port's 31, brought in by subtree
merge and then moved into place so git can follow each file across the rename.
The reason is not tidiness. The two-repo split forced the exporter to depend on
the decoders by pinned revision, and that created a whole class of failure that
now disappears: a sha reachable only from a topic branch, orphaned by a
squash-merge, breaking a fresh checkout silently at build time. It also forced a
live read-only mount of one agent's working tree into another's container, which
is why a contract file could move mid-iteration. With a path dependency, a
decoder change and the exporter change it requires land in the same commit or
not at all.
Canary stays separate: it is a fork tracking upstream.
New structure for the long term:
docs/game/ how the game is NAVIGATED -- menus, modals, prompts, alerts,
and in-game flight. Written so nobody rediscovers it. Mostly
open questions on purpose; the in-game tutorials are the
resource for the flight half.
docs/port/MODDING.md
modding as a constraint on the exporter TODAY, not a later
feature: one logical asset in one file (the disc splits nearly
everything, and resolving that is the exporter's job), names a
person recognises, PNG/OGG/OGV/JSON only, base-and-overrides so
re-exporting is always safe, provenance in every file.
data/base + data/mods
generated tree and drop-in overrides, both gitignored
exchange/ transient inter-agent files, deliberately outside history
docs/agents/ the team protocol
Both the README and the navigation doc lead with the correction that cost the
most: the oracle is the real game under Xenia Canary. Reborn's renderer is a
hypothesis under test, it has been wrong, and treating it as ground truth
propagated into three documents and both agents before a human caught it.
Scripted modding stays possible without being built: no screen name is hardcoded
in GDScript and there is no native code in port/, which is what Godot Mod Loader
needs to be able to substitute behaviour later.
|