From 46ee0d7f7871c5d4f72c65967a4063dc6744f452 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 20 Sep 2026 13:12:26 +0200 Subject: [PATCH] chore(agents): restore evidence sharing after the asset purge MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Issue #49 removed game assets from git. It also, silently, removed the only transport agents had for showing each other evidence: each agent works in its OWN clone, so "commit the screenshot, the other one pulls it" was the mechanism, and PROTOCOL.md's file table said so in as many words -- "evidence cited by a finding -> git". That row sat directly above "🔴 Never commit game content", which is how 76 MB accumulated: the two contradicted each other and the table won, because it was the one that told you what to do. WHAT REPLACES IT * one host directory, `Sylpheed/docs/re/captures/`, bind-mounted read-write into BOTH agents at /work/docs/re/captures. All three -- host, decoder, port -- see the same files live, every citation resolves, and nothing can reach git history. Read-write on purpose: showing each other a screenshot is the point. * PROTOCOL.md's table rewritten. Cited evidence -> present but never committed; derived measurements (csv/tsv/txt/log/json) -> still git, they are our numbers not game content; evidence that must cross MACHINES -> attached to the issue or PR, because a bare clone has no captures. Verified, not assumed: container A wrote a .png there, a SEPARATE container B read it back, the host saw it, `git status` reported 0 changes, and `git check-ignore` named the rule. THE CHECKER WAS RED ON EVERY CLEAN CHECKOUT A fresh clone/worktree/CI has no captures, so it called all 134 citations dangling and exited 1. A gate that is red before anyone changes anything is one people learn to ignore -- the exact failure this file already carries a comment about. It now distinguishes "no captures here" (expected, explains itself, exit 0) from "these are missing" (real, exit 1, unchanged when assets ARE present). Both paths tested. ALSO * `sylph-decoder` no longer mounts `xenia-rs` -- retired repo, gone from disk, the mount pointed at nothing. * CONSOLIDATION.md closed: it still described captures as committed and the history fork as undecided. Both are settled. Co-Authored-By: Claude Opus 5 (1M context) --- docker/decoder/sylph-decoder | 10 +++++++- docker/port/sylph-port | 8 +++++++ docs/agents/CONSOLIDATION.md | 24 +++++++++++++++++++ docs/agents/CONTAINERS-AND-AGENTS.md | 36 ++++++++++++++++++++++++++++ docs/agents/PROTOCOL.md | 10 +++++++- tools/re/check-capture-citations | 15 ++++++++++++ 6 files changed, 101 insertions(+), 2 deletions(-) diff --git a/docker/decoder/sylph-decoder b/docker/decoder/sylph-decoder index 7c49e9f2..df75430e 100755 --- a/docker/decoder/sylph-decoder +++ b/docker/decoder/sylph-decoder @@ -122,11 +122,19 @@ docker_args() { # (file offset = VA - 0x82000000), which removes the need to boot the # emulator and scrape /dev/shm to get at it. An earlier belief that this # file was STALE was tested and refuted -- it is current. - -v "${SYLPH_XENIA_RS:-$PROJECT/xenia-rs}:/xenia-rs:ro" -v "${SYLPH_PE:-$PROJECT/Project Sylpheed - Arc of Deception (USA, Europe) (En,Ja).pe}:/image/sylpheed.pe:ro" -e "SYLPHEED_DB=/xenia-rs/sylpheed.db" -e "SYLPHEED_PE=/image/sylpheed.pe" -e "SYLPHEED_IMAGE_BASE=0x82000000" + # 🔴 EVIDENCE IS SHARED, NOT COMMITTED (issue #49). Each agent works in its + # OWN clone, so a gitignored capture written in one container is invisible to + # the other and to the human -- git used to be the transport and no longer is. + # One host directory, bind-mounted into both agents, is: all three see the + # same files live, every `docs/re/captures/...` citation resolves everywhere, + # and nothing can reach git history. Read-write on purpose -- showing each + # other a screenshot is the point. + -v "${SYLPH_CAPTURES:-$PROJECT/Sylpheed/docs/re/captures}:/work/docs/re/captures" + # The shared exchange: transient files with provenance, outside git history. -v "sylpheed-exchange:/exchange" -e "PROJECT_DIR=/work" diff --git a/docker/port/sylph-port b/docker/port/sylph-port index f1f49065..7130b6d7 100755 --- a/docker/port/sylph-port +++ b/docker/port/sylph-port @@ -67,6 +67,14 @@ docker_args() { -v "sylpheed-port-claude:/sylph-home/port/.claude" -v "${SYLPH_CLAUDE_HOME:-$HOME/.claude}:/sylph-home/port/.claude.seed:ro" -v "${SYLPH_CLAUDE_JSON:-$HOME/.claude.json}:/sylph-home/port/.claude.host.json:ro" + # 🔴 EVIDENCE IS SHARED, NOT COMMITTED (issue #49). Each agent works in its + # OWN clone, so a gitignored capture written in one container is invisible to + # the other and to the human -- git used to be the transport and no longer is. + # One host directory, bind-mounted into both agents, is: all three see the + # same files live, every `docs/re/captures/...` citation resolves everywhere, + # and nothing can reach git history. Read-write on purpose -- showing each + # other a screenshot is the point. + -v "${SYLPH_CAPTURES:-$WORKSPACE/Sylpheed/docs/re/captures}:/work/docs/re/captures" -v "sylpheed-exchange:/exchange" -e "PROJECT_DIR=/work" # Same guardrail as the decoder, added the same day and for its reason: the diff --git a/docs/agents/CONSOLIDATION.md b/docs/agents/CONSOLIDATION.md index 03b57bd0..51eac75d 100644 --- a/docs/agents/CONSOLIDATION.md +++ b/docs/agents/CONSOLIDATION.md @@ -1,3 +1,27 @@ +# ✅ CLOSED 2026-09-20 — every phase done, and the two human decisions taken + +Nothing on this page is outstanding. It is kept as the record of how the two-repo +layout was reached; **where it describes the repository's present state it is +now out of date on purpose**, and the notes below say how. + +| the page says | what is true now | +|---|---| +| "**Still open, for the human**: the history fork" | **Taken: full purge.** `git filter-repo` stripped 182 assets from every commit; force-pushed 2026-09-19. `main` `2a93be99` → `e16556dc`, `.git` **217 MB → 114 MB**, **0** assets anywhere in history, verified from an independent fresh clone. Backups + runbook: `~/sylph-repo-backup-2026-09-19/` | +| "`docs/re/captures/` is 118 MB of game screenshots inside a public repository" | **Decided (#49): no game assets in the repos.** Captures live on disk, gitignored, shared between the host and both agents by bind mount; derived measurements (csv/tsv/txt/log/json/npy) stay tracked. PR #59 | +| "all six repos are `private=False`" | Still true, and now deliberate — there is nothing game-derived in them | +| "`ai-agent-*.md`, `scratch/`, `_voice_span.rs` — keep or drop" | `scratch/` and `_voice_span.rs` dropped in the 2026-09-18 cleanup; the `ai-agent-*.md` files are the human's and stay | +| the four archived repos | unchanged: `Sylpheed-Godot`, `xenia-rs`, `xex2tractor` archived read-only, `Syplheed-Reborn` deleted. ⚠️ Their local clones are **gone from this machine** too, and `sylph-decoder` no longer mounts `xenia-rs` | + +🔴 **The one thing this page got right and nobody acted on.** It named +`crates/sylpheed-export`'s dependency on **this repository by tag** as the hard +blocker for a rewrite. It was not re-checked before the purge, the locked rev +vanished, and the build broke for every clean checkout while still working on the +machine that did the rewrite — its `~/.cargo/git` still held the old object. +Fixed in PR #60 (re-lock) and PR #61 (path dependency, which removes the class). +**Before any future history rewrite, grep for a dependency on the repo's own URL.** + +--- + # Consolidating six repositories into two **Set by the human, 2026-09-13.** The end state is **two** repositories: diff --git a/docs/agents/CONTAINERS-AND-AGENTS.md b/docs/agents/CONTAINERS-AND-AGENTS.md index 2c4ccfc4..f696db3b 100644 --- a/docs/agents/CONTAINERS-AND-AGENTS.md +++ b/docs/agents/CONTAINERS-AND-AGENTS.md @@ -88,6 +88,42 @@ sylph-agent-canary-build the warm 235 MB Canary build tr sylpheed-exchange agent -> agent files, read-only in ``` +**Plus one bind mount, which is not a volume on purpose** — the host's +`Sylpheed/docs/re/captures/`, mounted read-write into both agents at +`/work/docs/re/captures`: + +``` +-v "${SYLPH_CAPTURES:-/Sylpheed/docs/re/captures}:/work/docs/re/captures" +``` + +🔴 **Why it has to exist.** Each agent works in its OWN clone, so before issue +#49 the transport for evidence was *git*: commit the screenshot, the other agent +pulls it. #49 removed that — captures are gitignored now — and without a +replacement a capture written in one container is invisible to the other agent, +to the human, and to `check-capture-citations`, which would call every citation +dangling. One host directory shared by all three restores it: the same file is +live everywhere, every `docs/re/captures/...` citation resolves, and nothing can +reach git history. Read-write on both, because showing each other a screenshot +is the point. + +Verified rather than assumed: container A wrote a `.png` there, a **separate** +container B read it back, the host saw it, and `git status` reported **0** +changes. + +⚠️ **Evidence that must cross MACHINES still cannot go this way** — a bare clone +on the other desktop has no captures at all. Attach it to the issue or PR; that +is the only channel that travels. + +⚠️ **The agent volumes were all deleted in the 2026-09-18 cleanup** and Docker +recreates them empty on next launch. Nothing was lost — both agent clones were +verified clean with nothing unpushed, and the exchange held only spent artefacts. +One side effect is welcome: the empty `*-claude` volumes mean the next launch +starts a **fresh** session, which is the documented workaround for the +"resumes the old brief" defect below. + +⚠️ **`sylph-decoder` used to mount `xenia-rs` read-only. That repo is retired and +the directory is gone**, so the mount pointed at nothing; removed. + **Credentials** — three files on the host, `chmod 600`, mounted read-only: ``` diff --git a/docs/agents/PROTOCOL.md b/docs/agents/PROTOCOL.md index fb4cd289..4b05e234 100644 --- a/docs/agents/PROTOCOL.md +++ b/docs/agents/PROTOCOL.md @@ -129,10 +129,18 @@ exchange volume carries the working artefacts. | kind | where | why | |---|---|---| | code, decoded knowledge | **git** | history, review, permanence | -| evidence cited by a finding | **git** | it is the proof | +| evidence cited by a finding — a screenshot, a frame, a savegame | **`docs/re/captures/`, present but NEVER committed** | it is the proof, but it is game content. The directory is gitignored and shared between the host and both agents, so all three see the same file; `tools/re/check-capture-citations` fails if a citation has no file, and fails again if an asset is tracked | +| a measurement you derived — csv, tsv, txt, log, json | **git** | our own numbers, not game content, and most findings rest on them | +| evidence that must cross machines | **attached to the issue or PR** | captures are local-only now, so a bare clone has none of them. Attaching is the only channel that reaches the other desktop or a reviewer | | **evidence a human must look at** — the screenshot or film behind a `state/needs-human` item | **attached to that issue** | it travels *with* the item, a person sees it in a browser, and it cannot be orphaned from the claim it supports | | exploratory captures, work in progress, "look at this" | **`share`** → `/exchange` | no history; would bloat the repo forever | +⚠️ **This table's first row used to say "git", and that is how 76 MB of +screenshots accumulated** — directly above the rule forbidding exactly that. The +two contradicted each other for months and the table won, because it was the one +that told you what to *do*. Issue #49 settled it and the history was rewritten; +if you find yourself reaching for `git add -f` on a capture, the answer is no. + 🔴 **Never commit game content.** Not sprites, not audio, not transcoded video, not a capture of the running game — under *any* directory name. On 2026-09-04 this rule was live, and freshly tightened, while **545 MB of extracted disc diff --git a/tools/re/check-capture-citations b/tools/re/check-capture-citations index 9e755bec..ffeb757b 100755 --- a/tools/re/check-capture-citations +++ b/tools/re/check-capture-citations @@ -235,6 +235,21 @@ def main() -> int: print(" cited by a page or a tool : %d" % (len(files) - len(orphans))) print(" cited by nothing : %d (reported, not failed —" % len(orphans)) print(" an orphan may be evidence a page owes)") + # 🔴 A BARE CLONE HAS NO CAPTURES AT ALL, and that is not a defect. + # Since #49 the assets are never committed, so a fresh clone, a worktree or + # a CI checkout legitimately has none — and the naive check calls all 134 + # citations dangling and exits 1. A gate that is red on every clean checkout + # is one people learn to ignore, which is how the last wrong-by-default + # check in this file cost a session. Distinguish "none here" from "this one + # is missing": with some assets present, a gap is real and still fails. + assets_here = sum(1 for f in files if f.lower().endswith(ASSET_SUFFIXES)) + if assets_here == 0 and dangling: + print(" ⓘ no captures on this checkout: %d citations unresolved" % len(dangling)) + print(" Expected — captures are local-only (#49) and a fresh clone has none.") + print(" Copy them in, or read the evidence on the issue it is attached to.") + print(" 🔴 game assets TRACKED : %d" % len(stowaways)) + return 1 if stowaways else 0 + rc = 0 if dangling: print(" 🔴 cited but NOT present : %d" % len(dangling)) -- 2.49.1