**The pin.** Pin a TAG, never a bare sha. A sha reachable only from an auto/* branch is orphaned when that branch is deleted or -- worse -- squash-merged, because squash creates new commits: main looks like it contains the work while the pin becomes unreachable and this project stops building for a fresh checkout, silently, at their build. formats-pin-2026-08-29 exists for the current state. Also says plainly why NOT to float to a branch, which was the tempting fix: Cargo resolves a git dependency once and writes the sha into Cargo.lock, so floating gives staleness you cannot see instead of staleness you can read. push-work now pushes --follow-tags so annotated tags travel with the branch. **Audio.** docs/AUDIO-VERIFICATION.md separates three questions that were being asked as one: is the transcode faithful (no engine, no device -- a file-vs-file difference measurement), does Godot route it (AudioEffectRecord on the Master bus writes a WAV from a headless run), and what does the GAME play (a PulseAudio null sink, which needs a rebuild). It leads with the three ways the fidelity measurement lies, because all three were hit on the first attempt and each produces a confident wrong number rather than an error: unaligned subtraction, mismatched channel layouts, and probing a file another process is still writing. The 5.1 disc fact deliberately is NOT copied here -- it lives in the RE corpus at docs/re/structures/movie-audio-channels.md and is linked, so there is one copy to keep true rather than two that drift. Same reason HANDOFF is a summary with links. The downmix itself stays flagged as an unmade decision, not quietly resolved. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sylpheed Godot
A clean-room Godot 4 port of Project Sylpheed: Arc of Deception, starting with the menu shell: developer splash → intro video → title → main menu → submenus.
You need your own copy of the game. Nothing in this repository is game content. An offline exporter reads the disc you supply and writes an open, moddable asset tree; the Godot project reads only that tree and never touches a disc format.
your disc ──▶ crates/sylpheed-export ──▶ export/ ──▶ port/ (Godot 4)
(Rust; decoders come from JSON + PNG reads ONLY
sylpheed-formats) + OGG + OGV open formats
Why the wall
Two reasons, and the second is the interesting one:
- Godot cannot read IPFB archives, RATC bundles, T8aD textures, XMA banks or WMV video, and it should not learn to.
- Modding is a goal of this port. If the runtime reads the original formats, modding means reverse engineering. If it reads JSON and PNG, modding means opening a file.
Where the knowledge comes from
The decoders live in sylpheed-formats, pinned by revision — a
separate project, where the reverse engineering happens. Its
docs/port/HANDOFF.md is the contract: what has been decoded, what was measured
off the running game, and what is known to be undecodable. Read it before
assuming a value is on the disc.
Layout
crates/sylpheed-export/ |
disc → open formats. Regenerates export/ wholesale |
port/ |
the Godot 4 project |
authored/ |
decisions that are not on the disc, each with its reason |
export/ |
generated, gitignored, never hand-edited |
tools/ |
verification harnesses that hold the port to the reference renderer |
docs/ |
the mission, the format spec, the agent's loop prompt |
Verifying
The oracle is the Xenia Canary capture and the game, not either renderer.
sylpheed-cli screen render is an explorer and extraction CLI for verifying
decodes, and it can be wrong -- three times both it and the port agreed and both
were wrong, each caught only by a capture.
So tools/verify-screen is a consistency check and a regression detector,
not a grade. It draws every exported screen both ways -- built from the same
sylpheed-formats revision the exporter is pinned to -- and reports the largest
per-channel difference in the frame:
tools/verify-screen # every screen in the manifest
tools/verify-screen main_menu # one of them
A difference means the two moved apart; docs/DECISIONS.md says which one moved
and why, rather than tuning the port until the number goes down. Correctness is
checked against the captures indexed at docs/re/captures/ORACLE-CAPTURES.md --
mind that they are not gamma-neutral, so RMSE against them has a floor.
Status
P1. The exporter writes GP_TITLE's twelve screen builds and their sprites,
and the Godot project draws any of them statically at 1280x720 from that tree
alone. main_menu matches the reference renderer to within 3/255 on every
channel of every pixel. Next: P2, keyframe animation.