This repository has been archived on 2026-09-16. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
Syplheed-Reborn/docker/agent/loop-task.md
Sylpheed RE agent b5a193839c port: make the Godot menu shell the agent's primary objective
Sets a new mission: boot the real disc through developer splash -> intro video
-> title -> main menu -> submenus in Godot 4, interactively, with no gameplay,
no 3D and no emulator.

docs/port/MISSION.md defines it -- eight gated milestones, each finished by an
ARTIFACT rather than by compiling, plus the Ready Room as an explicitly gated
stretch goal with a one-iteration probe that decides go/no-go. GP_READY_ROOM is
1106 entries with 6 recoverable names and is ISL-scripted, so it is either a
week or a quarter, and the agent must not start it on its own authority.

Architecture, per the user's decision: the Godot project is INDEPENDENT of the
Rust viewer and never reads a disc format. An offline Rust exporter converts the
disc into open formats; Godot reads only those. No GDExtension, no Rust in the
Godot project, and sylpheed-viewer is off limits -- it stays the human's
verification tool with its static-data rule intact.

docs/port/FORMAT.md specifies the open format, versioned, because modding is the
port's second goal and that makes the layout a deliverable rather than a temp
directory: JSON over XML (Godot parses JSON natively; its XMLParser is SAX),
names never hashes, provenance in every generated file, and unknowns listed
rather than guessed.

The discipline the whole thing rests on is the derived/authored split. `export/`
is regenerated wholesale and never hand-edited; `authored/` is hand-written and
survives a re-export. Three things this milestone needs are NOT on the disc in
any decoded form -- which button does what, paint order, and menu sound cues --
so they live in `authored/` with a stated `why`. Deleting an authored entry
because the exporter can now emit it IS the measure of progress.

`export/` is gitignored: it is generated from the user's own disc and this stays
a clean-room repo.

Container: adds a pinned Godot 4 (windowed under Xvfb for screenshots, plus a
headless wrapper). ffmpeg already carries libtheora, which is the video target --
Godot 4 plays only Ogg Theora natively and the disc's ADV.wmv is WMV3/WMA Pro.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-28 17:11:35 +02:00

5.5 KiB

Build the Godot menu port of Project Sylpheed, one milestone at a time.

Your objective

Syplheed-Reborn/docs/port/MISSION.md — read it every iteration. It defines the milestones (P0…P7 plus a gated S1), the gate each one must pass, and the two decisions already made. Work the lowest unfinished milestone; do not skip ahead because a later one looks more interesting.

Reverse engineering has not stopped, but it is no longer the goal. An RE item earns attention when the port is blocked on it, and the write-up still goes in docs/re/ under the usual convention.

Read these first, every iteration

Short on purpose, and the reason this prompt is short:

  1. docs/port/MISSION.md — the objective, the milestones, what is out of scope.
  2. docs/port/FORMAT.md — the export schema. It is versioned; changing it is a deliberate act with a version bump, not a silent edit.
  3. docs/re/REFUTED.md — claims already tested and dead. Grep it for your nouns before designing anything.
  4. docs/re/METHOD.md — the traps this corpus has already paid for.
  5. docs/re/INDEX.md — what is already decoded. Re-deriving a row is not a finding.
  6. docker/agent/AGENT.md — the container's tooling.

docs/re/disc-atlas.html is the map of how the assets reference each other — useful when you need to find what feeds what.

These files are the memory. A finding that lives only in your context is lost when the container dies.

Each iteration

  1. Pick the lowest unfinished milestone from MISSION.md. If you are mid-item, continue it rather than starting another.
  2. Build the smallest thing that reaches its gate. The gate is an artifact — a validating JSON file, a screenshot, a human-clickable build — never "it compiles".
  3. Keep derived and authored apart. export/ is regenerated wholesale and is never hand-edited; authored/ is hand-written and survives a re-export. If you are tempted to hand-fix a file under export/, the fix belongs in the exporter or in authored/. Every authored/ entry carries a why.
  4. Write down what you learned — in docs/port/ for port decisions, in docs/re/ for anything about the disc.
    • Refuted something → a line in REFUTED.md.
    • Bitten by a general trap → a line in METHOD.md.
    • Closed a format → update its INDEX.md row.
  5. Commit to auto/<topic>, one logical change per commit.
  6. Publish: push-work. Every iteration that produced a commit.
  7. Say plainly what you did not settle, and stop.

Hard rules

  • Never commit game assets. export/ is generated from the user's own disc and is gitignored. Code, schemas, authored mappings and docs only. If you are about to commit a sprite PNG or a transcoded video, stop.
  • No Rust in the Godot project, no GDExtension. If Godot cannot read something, the exporter emits it differently. The wall between the two halves is the design, not an inconvenience.
  • Do not touch crates/sylpheed-viewer. The Explorer is the human's verification tool, it is independent of the port, and it keeps its static-data-only rule. Do not refactor it to share code with the exporter.
  • Never commit to main, never rebase a shared branch, never delete a branch, never rewrite history.
  • Do not touch another agent's worktree. git worktree list first; branches marked + are checked out elsewhere.
  • One emulator at a timerun-canary enforces it with a lockfile.
  • Measure the oracle; never infer it. If you need to know what the real game does, run it. This applies with full force to the keyframe time unit and to any transition timing.
  • Do not improvise around a blocker. If a milestone needs a decision only the user can make — a new dependency, a scope change, the Ready Room go/no-go — write what you found, note it in MISSION.md, and move to the next thing you can actually finish.

Verifying

  • build-reborn test wires up SYLPHEED_DISC; without it the disc tests self-skip and a green run means almost nothing.
  • sylpheed-cli screen render is the reference renderer. When Godot draws a screen, diff it against the CLI's composite of the same build — they should agree, and where they do not, one of them is wrong and you must say which.
  • Godot runs headless in this container (godot --headless), and screenshot captures the windowed one under Xvfb.
  • A regenerated artifact that comes out byte-identical is strong evidence a change was additive. When it does change, check that every diff line pairs.

Publishing

push-work pushes the current branch to origin. It refuses anything that is not auto/* and never force-pushes, so the consolidated line stays a human's decision. Run it every iteration that produced a commit — not at the end of some longer arc, which is exactly when a container dies.

If it reports no credentials, say so in your reply and continue working. Do not improvise another route out: no remote rewrite, no credential helper of your own, no alternate transport. A push that is blocked is a blocked push.

Pacing

One milestone step plus its write-up is a good iteration; a marathon is not. Stop with a clean commit, a push, and an honest list of what is still open.

An emulator session must fit inside ONE turn — a Stop hook kills xenia when the turn ends — but sequential tool calls within a turn are fine.

The loop runs on a fixed interval set by the harness, so you do not need to arm the next wakeup yourself. Spend that attention on the write-up instead.