The port is deliberately separate from the reverse-engineering project: its own repository, its own clone, its own container. Two writers in one working tree means files change under whoever is mid-edit and a `git add -A` by one sweeps up the other's work -- which happened today in the Reborn tree, so this is set up not to repeat it. The wall: Godot never reads a disc format. An offline Rust exporter converts the user's disc into JSON + PNG + Ogg, and the Godot project reads only that. No GDExtension, no Rust in port/. Beyond the practical reason -- Godot cannot read IPFB, RATC, T8aD, XMA or WMV -- there is the design one: modding is a goal, and if the runtime reads the original formats then modding means reverse engineering, whereas if it reads JSON it means opening a file. The decoders come from sylpheed-formats PINNED BY REVISION (8b6dbcf), not vendored and not reimplemented. `sylpheed_formats::media` in particular already owns every case where one playable thing is not one archive entry: entries that span segment files, banks with several sub-waves, and the cutscene voices, which are one continuous XMA stream chunked into VOICE_*.slb entries whose boundaries do NOT match the cues. That last one is the easiest thing in this project to get subtly wrong, so the mission says outright not to re-derive it. docs/MISSION.md is the objective (P0-P7, each gated by an artifact rather than by compiling). docs/BLOCKED.md lists what cannot proceed until the RE agent answers Q1-Q10, and says plainly that none of it may be guessed -- this agent has no emulator and no oracle, so a value it invents is indistinguishable from a decoded one a month later. The container is deliberately small: 3 cpus / 4 GB against the RE container's 6 / 7, and an image with no C++ toolchain, no Vulkan stack and no emulator. Two full-size containers do not fit on this box beside a desktop. Its launcher sets the git identity through GIT_AUTHOR_*/GIT_COMMITTER_* rather than writing [user] into .git/config -- the config route captures every commit made in that tree, including a human's, which is how six of today's commits ended up attributed to the RE agent. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
68 lines
2.4 KiB
Bash
Executable File
68 lines
2.4 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Push the current topic branch to origin — the ONLY sanctioned way out of the
|
|
# container.
|
|
#
|
|
# Why a wrapper instead of plain `git push`:
|
|
#
|
|
# * **`main` and shared branches are refused.** The agent commits to
|
|
# `auto/<topic>`; a human merges. A token that can push anywhere is one
|
|
# confused iteration away from rewriting the consolidated line.
|
|
# * **Force-push is refused**, always. Nothing here needs it, and history
|
|
# rewriting is the one mistake that cannot be undone by merging.
|
|
# * It pushes the CURRENT branch only, by name, so a stray `--all` cannot
|
|
# publish another agent's worktree branch mid-experiment.
|
|
#
|
|
# Credentials come from a file mounted read-only at ~/.git-credentials (see
|
|
# `sylph-agent`). They are never printed, never logged, and never passed on a
|
|
# command line.
|
|
#
|
|
# push-work push the current branch
|
|
# push-work --dry-run say what it would do
|
|
set -euo pipefail
|
|
|
|
DRY=0
|
|
[ "${1:-}" = "--dry-run" ] && DRY=1
|
|
|
|
repo_root=$(git rev-parse --show-toplevel 2>/dev/null) || {
|
|
echo "push-work: not inside a git repository" >&2; exit 1; }
|
|
cd "$repo_root"
|
|
|
|
branch=$(git rev-parse --abbrev-ref HEAD)
|
|
if [ "$branch" = "HEAD" ]; then
|
|
echo "push-work: detached HEAD — check out a branch first" >&2; exit 1
|
|
fi
|
|
|
|
case "$branch" in
|
|
auto/*) ;;
|
|
*)
|
|
echo "push-work: refusing to push '$branch'." >&2
|
|
echo " Only auto/* topic branches may leave the container; a human merges" >&2
|
|
echo " them into main. Move your work: git switch -c auto/<topic>" >&2
|
|
exit 1 ;;
|
|
esac
|
|
|
|
if [ ! -s "$HOME/.git-credentials" ]; then
|
|
echo "push-work: no credentials mounted at ~/.git-credentials." >&2
|
|
echo " The host must start the container with SYLPH_GIT_CREDENTIALS pointing" >&2
|
|
echo " at a file containing one line:" >&2
|
|
echo " https://<user>:<token>@git.mc02.dev" >&2
|
|
exit 1
|
|
fi
|
|
|
|
# `store` reads the file we mounted; nothing is written back (it is read-only).
|
|
git config --local credential.helper "store --file=$HOME/.git-credentials"
|
|
|
|
ahead=$(git rev-list --count "origin/$branch..$branch" 2>/dev/null || git rev-list --count HEAD)
|
|
echo "push-work: $branch — $ahead commit(s) to publish"
|
|
|
|
if [ "$DRY" = 1 ]; then
|
|
echo "push-work: --dry-run, stopping here"
|
|
exit 0
|
|
fi
|
|
|
|
# --force-with-lease is deliberately NOT offered. If this is rejected as
|
|
# non-fast-forward, someone else moved the branch: fetch and merge, do not
|
|
# overwrite.
|
|
git push --set-upstream origin "$branch"
|
|
echo "push-work: pushed $branch"
|