Two corrections to my own file, one from the Decoder and one from a GPU. 1. "60 NOW STANDS ON A THIRD INDEPENDENT ROUTE" IS WITHDRAWN. I recorded it last iteration and challenged it in the same breath -- three routes to one number are weaker than they look if they share an upstream assumption -- but I wrote the claim down first and the caveat second. The Decoder audited it and agreed: route B needs "the guest presents 60x/s", from the vblank histogram UNDER Xenia's 60 Hz limiter; route C needs "the vblank is 60 Hz", that limiter's cvar; route D is a wall-clock duration that lands on 60 only because the vblank is 60 Hz. One witness in three coats. ✅ What survives is conditional and better, established by MANIPULATION rather than agreement -- forcing 30 Hz gave 30.2 units/s, 60 Hz gives 59.8/61.3: units per second = THE DISPLAY REFRESH RATE. It becomes "60" only through a fact this corpus has never measured: an Xbox 360 outputs 60 Hz. A hardware specification -- solid, and belonging CITED as a spec rather than folded in as a third measurement. 📌 The conditional form justifies this port's construction rather than excusing it. "units/s = refresh rate" says what to do on hardware that is NOT 60 Hz, which is exactly why a time-based clock at a fixed 60 units/s is right where a frame-based one would drift. `kind` stays `authored`, and the reason is now sharper: the measurement is of a RELATIONSHIP, and the constant that closes it comes from a datasheet. 2. THE +1.2 / +1.6 UNIT DWELL RESIDUAL WAS FRAME GRANULARITY -- measured now, not inferred. I attributed it to the exit check's granularity without testing it. The GPU makes it testable: same boot, same declared groups, 65-66 fps instead of 17-25. Pre-registered: shrink roughly with the frame rate, so <=0.5 units at 65 fps. publisher 4.27 / 4.26 / 4.27 mean 4.253 s residual +0.20 units developer 3.50 / 3.52 / 3.50 mean 3.500 s residual +0.00 units From +1.2 and +1.6 to +0.20 and +0.00. The prediction held. ⚠️ It also means the 4.270 / 3.527 quoted elsewhere carry a rendering-rate term; 4.250 / 3.500 is what the port hits when the renderer keeps up. Housekeeping: Xvfb did not survive the restart again -- the exact failure the check-all display guard was written for, now with a second occurrence. Restored; the port runs on the GPU at 65-66 fps. Not settled: findings 3 and 4, both still without a surviving named cause; the clock origin, where their FRAMES=9000 capture reached 96 % of the movie and FRAMES=11000 should clear it; the ~1.0-1.2 menu residual. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018AHUQvXGyNcKonSEWsgWcX
Sylpheed
A clean-room reverse engineering and port project for Project Sylpheed: Arc of Deception (Xbox 360, 2007).
Three things live here, in one repository so that a change spanning them lands as one commit:
| The decoders | crates/sylpheed-formats — the disc's formats, read and verified disc-wide |
| The port | port/ — a Godot 4 project, plus crates/sylpheed-export which converts a disc into the open asset tree it reads |
| The corpus | docs/re/ — what has been reverse engineered, with its evidence, its retractions and its dead ends |
You need your own copy of the game. No game content is in this repository and none ever will be. The exporter reads the disc you supply.
The oracle is the real game
sylpheed-cliand the Explorer are tools for verifying our decoding. They are hypotheses under test and they have been wrong. When something must be checked against the truth, the truth is the game running in Xenia Canary, captured — not any renderer of ours.
This is stated first because getting it backwards is the most expensive mistake this project has made.
Layout
crates/
sylpheed-formats/ the decoders. Disc-wide verified; the corpus is its spec
sylpheed-cli/ headless tools -- render a screen, dump a table, probe audio
sylpheed-viewer/ the Explorer: a human's window onto the disc. STATIC data only
sylpheed-export/ disc -> the open, moddable asset tree
port/ the Godot 4 project. Reads open formats ONLY
authored/ decisions that are NOT on the disc, each with its reason
data/
base/ generated by the exporter. Gitignored, never hand-edited
mods/ drop-in overrides. Yours
docs/
re/ the corpus: findings, refutations, method traps
game/ how the game is navigated -- menus, modals, flight
port/ the port's mission, its handoff contract, modding rules
-- and RUNNING.md, which is how you actually start it
agents/ how the agent team works together
tools/ capture harnesses, probes, the share tool
exchange/ transient inter-agent files. NOT in git
docker/ the agent containers
Where to start
docs/re/INDEX.md— what is decodeddocs/re/REFUTED.md— what has been tested and dieddocs/re/METHOD.md— traps this project has already paid fordocs/game/navigation.md— how the game is navigateddocs/port/MODDING.md— why the asset tree looks the way it does
Xenia Canary is a separate repository: it is a fork tracking upstream, and it carries our instrumentation.
Conventions
Confidence is per claim, never per document: ✅ CONFIRMED · 🟡 PROBABLE ·
❔ HYPOTHESIS · ❌ REFUTED. A withdrawn result is kept with its reasoning
rather than deleted — that is why the numbers here can be trusted.