diff --git a/decomp-architect/memory-seed/MEMORY.md b/decomp-architect/memory-seed/MEMORY.md new file mode 100644 index 000000000..27dc7bf7c --- /dev/null +++ b/decomp-architect/memory-seed/MEMORY.md @@ -0,0 +1,33 @@ +# Memory Index + + + +## Already provided by ProjectArchitect 2.0's seed (cited, not duplicated) +`who-is-dev` · `project-governance-system` · `autonomous-within-phases` · `build-tasklist-after-plan-approval` · +`capture-knowledge-before-fresh-session` · `clarify-misconception-before-costly-action` · `justify-new-tools-before-adopting` · +`dont-block-loop-with-askuserquestion` · `no-commit-co-author` · `commit-per-task-user-pushes` · `plain-english-recap` · +`session-start-rules-in-full` · `worklogs-reference-only` · `keep-ops-current` · `effort-discipline` · +`effort-prompt-ultracode-on-breadth` — and the repository-resident state itself (`.claude-state/`, registry rule H8). + +## The decomp seed +- [The byte gate is the only claim](the-byte-gate-is-the-only-claim.md) — "matched" means byte-identical output AND a green whole-binary hash; nothing functionally equivalent counts; "banked" is written from a tool's printed line +- [The matching flywheel](the-matching-flywheel.md) — consult the knowledge base before every match, feed the generalizable lesson back into BOTH the cookbook and the tooling after it +- [MCP reconnect after restart](mcp-reconnect-after-restart.md) — after restarting the disassembler's MCP server or switching the served program, pause and ask the developer to reconnect the client; the agent cannot +- [Offline tooling first](offline-tooling-first.md) — every COMPUTABLE step becomes a deterministic zero-token tool; keep deterministic recovery and search separate; ask "is this residual computable?" before reaching for a model +- [A slow gate is a bug](a-slow-gate-is-a-bug.md) — banking, not drafting, is the bottleneck; nothing in the gate is serial; pass `-j` to every build; measure the gate before fearing it +- [Breadth is isolated agents](breadth-is-isolated-agents.md) — the main loop's context accumulates roughly quadratically; N isolated agents cost about linearly and run in parallel; hand-by-main-loop wins only for a handful +- [Route by measured difficulty](route-by-measured-difficulty.md) — tier drafters by a cliff you measured on your own corpus; escalate sooner; the strongest model is for new wall classes, never for reviewing a corpus +- [One runbook is the procedure](one-runbook-is-the-procedure.md) — one document is the operating procedure for the campaign loop, read before every run, kept current in the same change; a superseded runbook gets a banner +- [Keep an accelerator ledger](keep-an-accelerator-ledger.md) — every late discovery that would have sped earlier work is recorded with when it was found, when it could have been, and what it would have saved +- [Checkpoint means everything is already in a file](checkpoint-means-everything-is-already-in-a-file.md) — a checkpoint is the LAST thing written; a good commit message is not in the load order; the sweep before the block +- [A PhaseEnd carries the narrative axis](phaseend-carries-the-narrative-axis.md) — what was believed, what failed and why it looked right, what it cost, what to do sooner — because transcripts die and the retrospective is rebuilt from the files +- [Tool change ships with its consumers and docs](tool-change-ships-with-its-consumers-and-docs.md) — the commit that adds a tool also wires its callers and adds its ops row; integrating an agent's tool change IS a tool change; no end-of-session audits +- [No sleep-polling background tasks](no-sleep-polling-background-tasks.md) — the harness re-invokes on completion; one sanity check after launch, then wait +- [Long checks run in the foreground](long-checks-run-in-the-foreground.md) — a background long verification can be killed by the harness's memory guard; run it in the foreground with a timeout; check for orphaned workers +- [Resume means resume the run](resume-means-resume-the-run.md) — replay interrupted work so it finishes itself, same run, same agent, transcript intact; never re-plan or re-route on your own inference +- [Answer before grinding in live co-op](answer-before-grinding-in-live-coop.md) — only the final message of a turn is guaranteed to be seen; end the turn with the answer the person is waiting on before starting long work diff --git a/decomp-architect/memory-seed/a-slow-gate-is-a-bug.md b/decomp-architect/memory-seed/a-slow-gate-is-a-bug.md new file mode 100644 index 000000000..d1ad8bdaa --- /dev/null +++ b/decomp-architect/memory-seed/a-slow-gate-is-a-bug.md @@ -0,0 +1,20 @@ +--- +name: a-slow-gate-is-a-bug +description: Banking, not drafting, is the bottleneck of a matching campaign; nothing in the gate is serial; pass -j to every build; measure the gate before fearing it; gate in isolated worktrees under a per-binary lock +metadata: + type: feedback +--- + +A gate that takes tens of minutes per binary is a defect to fix, not a cost to absorb. Drafting is cheap and parallel; the +byte gate — a build and a hash per draft — is where a campaign's wall-clock goes. + +**Why:** on the source project one binary's gate ran for an hour while thirty-seven finished drafts queued behind it; sixteen +binaries were once gated serially to protect one carving job, an hour for what the parallel form did in minutes; and a single +binary's build without `-j` was measured six times slower than with it, byte-identical either way. The gate had been believed +to cost forty to sixty minutes; clean, it cost fifteen seconds — the stalls were bisects. + +**How to apply:** parallel is the default — each binary gates in its own worktree (isolation: a carving worker writes only inside +its tree) under a per-binary lock (mutual exclusion: two lanes never gate the same binary). Every tool that shells a build passes +the parallel flag; a bad parallel build fails the hash, it cannot bank wrong bytes. Batch the expensive population behind a strong +pre-filter and bisect on failure. Merge carve state — per-binary files adopted whole, a shared registry spliced by block — so two +workers never clobber each other. If you find yourself writing a serial loop over binaries, stop: that is the hour-long mistake. diff --git a/decomp-architect/memory-seed/answer-before-grinding-in-live-coop.md b/decomp-architect/memory-seed/answer-before-grinding-in-live-coop.md new file mode 100644 index 000000000..1abc2dd4f --- /dev/null +++ b/decomp-architect/memory-seed/answer-before-grinding-in-live-coop.md @@ -0,0 +1,20 @@ +--- +name: answer-before-grinding-in-live-coop +description: In a live co-op session (the person at the emulator or the controls, pacing on the agent's replies) END THE TURN with the answer they are waiting on before starting long autonomous work — only the final message of a turn is guaranteed to be seen +metadata: + type: feedback + upstream: PA +--- + +During a live interactive loop — the developer at the emulator, waiting on the agent's read of each step — text placed between +tool calls is not reliably displayed. From the developer's side the agent "never spoke again" after the step they had been asked +for, and they sat idle at a game-over screen while the agent ground builds for an hour. + +**Why:** the harness guarantees only the FINAL message of a turn is seen. In co-op mode the person's time is the scarce +resource, and they pace themselves on the replies. + +**How to apply:** when the person reports a step done, the very next thing they get is a turn-ending reply — the result of +their step and what to do next, or an explicit "your part is done, you can close X". Only after that turn ends does long +autonomous work start. When the interactive phase ends, say so unambiguously as a final message, not buried mid-stream. Announce +long grinds with their expected duration before starting them, and never leave a question from the person unanswered across +one. diff --git a/decomp-architect/memory-seed/breadth-is-isolated-agents.md b/decomp-architect/memory-seed/breadth-is-isolated-agents.md new file mode 100644 index 000000000..87755a46e --- /dev/null +++ b/decomp-architect/memory-seed/breadth-is-isolated-agents.md @@ -0,0 +1,20 @@ +--- +name: breadth-is-isolated-agents +description: For breadth-shaped work (many independent functions), isolated agents are token-CHEAPER than the main loop doing them serially — the main context re-sends everything each turn (≈ quadratic), an agent's context is fresh and tiny (≈ linear) and runs in parallel +metadata: + type: reference +--- + +For breadth-shaped work — drafting byte-exact C for N functions — spawning one isolated agent per item is cheaper than the +main conversation doing them one after another, even though it looks like N copies of the same prompt. + +**Why:** the main conversation re-sends its entire growing context on every turn, so function N is processed with functions 1 +through N−1's disassembly, diffs and drafts still in context — the cost grows roughly quadratically. Each spawned agent gets a +fresh, small context (its one function) — roughly linear — and the agents run in parallel, so hours become minutes. Measured on +the source project: forty functions serially cost several times what forty isolated agents cost. The redundant per-agent reading +of shared documents is real but secondary. + +**How to apply:** batch a few functions per agent, pre-filter the trivial ones, and trim what each agent reads (an inline idiom +cheat-sheet beats "read the whole cookbook" — more context was measured to be worse, not better). The compile-and-hash gate is +local and free; only the drafting costs tokens. Fully model-free drafting hits a low ceiling; the model is what lifts it. Working +a function by hand in the main loop wins only for a handful of high-value items; past that, accumulation makes it lose. diff --git a/decomp-architect/memory-seed/checkpoint-means-everything-is-already-in-a-file.md b/decomp-architect/memory-seed/checkpoint-means-everything-is-already-in-a-file.md new file mode 100644 index 000000000..c3c407931 --- /dev/null +++ b/decomp-architect/memory-seed/checkpoint-means-everything-is-already-in-a-file.md @@ -0,0 +1,25 @@ +--- +name: checkpoint-means-everything-is-already-in-a-file +description: When the developer says "checkpoint", the checkpoint block is the LAST thing written — every perishable piece of session context is already in a file in the load order; a good commit message feels like documentation and is not +metadata: + type: feedback +--- + +By the time the checkpoint block is written, everything the session learned that would otherwise be lost is already in a file +the next session loads: idioms in the cookbook, tools in the ops reference, pivots in the decision log, late discoveries in the +accelerator ledger, procedures in the runbook, and every stale assertion the session invalidated corrected. Not a plan to bank +it; not a commit message describing it. + +**Why:** on the source project a full checkpoint was declared done, and a sweep the developer had to ask for found four things +missing — an entire byte-proven procedure that existed only in commit messages, two tools without ops rows, no decision-log entry +for a session that pivoted the phase, no accelerator entry — plus a stale caveat in a tool still asserting something the session +had disproved hours earlier. The trap is specific: a really good commit message, with measurements and controls, produces a +strong false sense that the knowledge is banked. The commit log is not in the load order. If it is only in a commit message, it is +lost. + +**How to apply:** before writing the block, run the sweep every time: idioms (from your own debugging, from agents' reports — +notifications truncate the long notes — and from near-miss diagnoses; grep before claiming novelty; name any wall verdict +overturned) → the cookbook; every new or changed tool → its ops row and its consumers; pivots and dead ends → the decision log; +"this would have saved earlier work" → the accelerator ledger; procedures → the runbook, not a docstring; hunt the stale +assertions; regenerate derived artifacts and run the health check; then verify each item is present in HEAD, not just on disk. +Verification-layer lessons — what a check can and cannot prove — count as idioms. diff --git a/decomp-architect/memory-seed/keep-an-accelerator-ledger.md b/decomp-architect/memory-seed/keep-an-accelerator-ledger.md new file mode 100644 index 000000000..675544646 --- /dev/null +++ b/decomp-architect/memory-seed/keep-an-accelerator-ledger.md @@ -0,0 +1,19 @@ +--- +name: keep-an-accelerator-ledger +description: Every late discovery that would have sped up EARLIER work goes into a dedicated ledger the same session — what it is, when it was found, when it COULD have been found, what it would have saved — so the next project gets it on day one +metadata: + type: project +--- + +Keep one document (`docs/accelerators.md` on the source project) whose only question is "what should phase one of the NEXT +project do differently?" The per-phase records say what happened; they do not answer that question. + +**Why:** the source project found its biggest levers late — the whole-binary byte-gate harvest at phase twelve, cross-binary +propagation at phases eleven to fifteen, the compiler's codegen map at phase twenty-three, the instrument-integrity audit at +twenty-six — each available years, in project time, before it was built. Reading the ledger is how a new project inherits that +order instead of rediscovering it. + +**How to apply:** when a discovery lands, ask "would this have changed earlier work?" If yes, add an entry the same session with +the four fields. Distinguish honestly between a lever that was available earlier and one that structurally could not exist yet +(it needed the fleet onboarded, the compiler pinned); the second kind goes in too, marked, because its prerequisite is the real +advice. The ledger feeds the retrospective and the next project's roadmap. diff --git a/decomp-architect/memory-seed/long-checks-run-in-the-foreground.md b/decomp-architect/memory-seed/long-checks-run-in-the-foreground.md new file mode 100644 index 000000000..b236bc4d2 --- /dev/null +++ b/decomp-architect/memory-seed/long-checks-run-in-the-foreground.md @@ -0,0 +1,20 @@ +--- +name: long-checks-run-in-the-foreground +description: A long verification target run as a BACKGROUND task can be killed by the harness's low-memory guard during a transient spike; run it in the foreground with an explicit long timeout, log to a file, and check for orphaned workers afterwards +metadata: + type: feedback + upstream: PA +--- + +Long verification runs (the project's health target, a fleet rebuild) belong in the foreground with an explicit timeout, their +output redirected to a file with the exit code appended. + +**Why:** the source project's health target, run as a background task, was killed twice in one session with "the system is +running low on memory" — both times inside a step whose worker fan-out is a transient memory spike, with tens of gigabytes free +seconds later. The same command in the foreground, with a fifteen-minute timeout, passed both times. The killed run also left a +tool's scratch file behind that must never be committed. + +**How to apply:** `make > /_health.log 2>&1; echo "EXIT=$?" >> …` in the foreground, never as a +background task; read the exit code, not the last line of output. While there, check the process table for orphaned workers +from earlier sessions and stop them by PID — never with a process-name pattern that appears in your own shell's command line, +which kills the calling shell. diff --git a/decomp-architect/memory-seed/mcp-reconnect-after-restart.md b/decomp-architect/memory-seed/mcp-reconnect-after-restart.md new file mode 100644 index 000000000..76c9fab52 --- /dev/null +++ b/decomp-architect/memory-seed/mcp-reconnect-after-restart.md @@ -0,0 +1,19 @@ +--- +name: mcp-reconnect-after-restart +description: After restarting the disassembler's MCP server or switching the program it serves, PAUSE and ask the developer to reconnect the client (/mcp) — the agent's calls time out until then and it cannot reconnect itself +metadata: + type: feedback +--- + +Whenever the reverse-engineering MCP server is stopped and restarted — for a headless import, or to serve a different program — +the coding agent's client connection goes stale and every call to that server times out until the client reconnects. The agent +cannot run the reconnect command itself. + +**Why:** the first time it happened the agent noted "client may need reconnect" and kept going, burning turns on timeouts and +working around them. The correct move is to stop and ask. + +**How to apply:** a server restart always ends with one message — "I restarted the MCP server (now serving X); please run +`/mcp` to reconnect, then I will verify and continue" — followed by one cheap verification call before any real work. Treat +the reverse-engineering database's persistence the same way: the server holds an open transaction while serving, so work is +saved only on a clean stop; renames made through the server may not persist at all — mirror symbols through a headless script +and verify with a read-only reopen. diff --git a/decomp-architect/memory-seed/no-sleep-polling-background-tasks.md b/decomp-architect/memory-seed/no-sleep-polling-background-tasks.md new file mode 100644 index 000000000..1306b20ec --- /dev/null +++ b/decomp-architect/memory-seed/no-sleep-polling-background-tasks.md @@ -0,0 +1,19 @@ +--- +name: no-sleep-polling-background-tasks +description: Never sleep-poll a running background task — the harness re-invokes the agent when it completes; one sanity check right after launch, then wait +metadata: + type: feedback + upstream: PA +--- + +When a background task is running (a backgrounded shell command, a long command the harness moved to the background, a +subagent), do not issue repeated "sleep, then read the log" calls to watch it. The harness re-invokes the agent with a +completion notification the moment the task finishes; polling buys nothing and burns tokens. + +**Why:** the developer flagged it hard mid-session — the agent had sleep-polled a long sweep every couple of minutes ("stop +polling, we talked about this, you are wasting tokens"). The harness's own guidance says the same. + +**How to apply:** launch, then stop and wait for the notification. At most one quick sanity check right after launch, to confirm +the task started without a systematic error (an empty log and no process is "never started", not "running"). If the developer +sends a message while it runs, answer that; do not invent poll turns. Reach for paced checking, with a delay matched to how fast +the state actually changes, only for external work the harness genuinely cannot track (a CI run, a remote queue). diff --git a/decomp-architect/memory-seed/offline-tooling-first.md b/decomp-architect/memory-seed/offline-tooling-first.md new file mode 100644 index 000000000..512b09461 --- /dev/null +++ b/decomp-architect/memory-seed/offline-tooling-first.md @@ -0,0 +1,22 @@ +--- +name: offline-tooling-first +description: Standing goal — push every COMPUTABLE step of the loop into deterministic, model-free tooling that runs at zero token cost on every future item; reserve the model and the search for what is genuinely not computable +metadata: + type: feedback +--- + +When a recovery, diagnosis or integration step is computable, it belongs in a deterministic tool that runs with zero tokens on +every future draft — not in an agent prompt and not in a search. + +**Why:** the measured economics kept pointing the same way on the source project. A fifty-agent wave once added a third of a +percent while deterministic recovery added nearly three points for about no tokens; the permuter's problem turned out to be +targeting, not a missing transform — most of its CPU was aimed at residuals a search provably cannot close, fixed for free by a +deterministic classifier. Every hour of agent drafting is spent once; every deterministic stage is spent once and paid forever. + +**How to apply:** keep the two engines separate — deterministic recovery (declaration, arity and cast reconciliation, type +lifts, carve repairs: computable fixes, applied always, arbitrated by the byte gate) and search (the permuter, for register and +schedule permutations where the answer must be explored). Putting a computable fix into the search is a category error. When a +draft fails to bank, ask "is this residual computable?" before reaching for agents or the permuter; if yes, add a stage — and +check whether the logic already exists in another tool (one implementation, many callers). A stage that mutates shared state +undoes by snapshot-restore, never by an inverse transform, and is verified fleet-wide. Track the model-free fraction of the +work and make raising it the objective. diff --git a/decomp-architect/memory-seed/one-runbook-is-the-procedure.md b/decomp-architect/memory-seed/one-runbook-is-the-procedure.md new file mode 100644 index 000000000..3ebe1f009 --- /dev/null +++ b/decomp-architect/memory-seed/one-runbook-is-the-procedure.md @@ -0,0 +1,20 @@ +--- +name: one-runbook-is-the-procedure +description: ONE document is the operating procedure for the campaign loop — read it before every run; each guard in it is paired with the measurement that produced it; keep it current in the same change as any step or tool it names; a superseded runbook gets a banner at once +metadata: + type: project +--- + +The campaign loop (draw work → build cards → draft → gate → recover → harvest → verify the fleet → checkpoint) has one +procedure document, and it is read before every run. + +**Why:** the most expensive mistakes of one session on the source project were procedural, not technical — a hand-typed target +that invented a function (tens of thousands of tokens), a hand-rolled serial gate while the parallel tool existed (an hour for +minutes of work), a function re-derived at cost because a card said "no banked twin" when the twin scan had not been run on the +world. Each became a guard in the runbook, paired with the measurement that earned it; that pairing is what a generic guide +cannot have. An earlier runbook titled "as it actually runs" kept describing a retired pipeline for weeks and was followed. + +**How to apply:** treat the runbook as the deliverable — the shape (guard + measurement) matters as much as the steps. Update it +in the same change as any step or tool it names, the way the ops reference is kept current. When a pipeline is retired, put a +banner at the top of its runbook the same day and point at the successor; a stale procedure document is worse than none. +Every target payload comes from a file the draw tool wrote, never from a hand-typed name. diff --git a/decomp-architect/memory-seed/phaseend-carries-the-narrative-axis.md b/decomp-architect/memory-seed/phaseend-carries-the-narrative-axis.md new file mode 100644 index 000000000..34f4a9c61 --- /dev/null +++ b/decomp-architect/memory-seed/phaseend-carries-the-narrative-axis.md @@ -0,0 +1,22 @@ +--- +name: phaseend-carries-the-narrative-axis +description: Write the phase records on a SECOND, narrative axis alongside the operational one — what was believed, what was tried and failed and why it looked right, what it cost, what to do sooner — because transcripts die and the retrospective is rebuilt from these files +metadata: + type: project +--- + +The phase records (the in-flight phase log, the PhaseEnd, the decision log) are not only crash recovery for the next session. +They are the primary source from which the project's story and retrospective will be reconstructed, because session +transcripts are lost — on the source project the first month's transcripts were gone, and only git plus these files survived +for the whole span. + +**Why:** a retrospective without costs cannot rank what mattered; a story without the beliefs that turned out false cannot say +what to do sooner. Anything true but unwritten is gone. + +**How to apply:** keep the operational sections tight (the state, the next task, the do-not-re-learn list) and add the narrative +material where it belongs — the PhaseEnd synthesis, the log's progress entries, the decision log: dead ends with their reasoning +intact; costs quantified (tokens, wall-clock, a red binary); beliefs named as false when they turned out so; claims that had to +be withdrawn, kept rather than quietly corrected; dates on everything. The test before closing a phase: could someone with only +git and these files reconstruct what we believed, what we tried, what it cost and what we would do differently? If not, the +missing piece goes in now. Sequence the endgame deliverables timeline → retrospective → guide, and capture the judgement live — +the numbers are safe in git forever; the "why" evaporates. diff --git a/decomp-architect/memory-seed/resume-means-resume-the-run.md b/decomp-architect/memory-seed/resume-means-resume-the-run.md new file mode 100644 index 000000000..c05b9fe72 --- /dev/null +++ b/decomp-architect/memory-seed/resume-means-resume-the-run.md @@ -0,0 +1,20 @@ +--- +name: resume-means-resume-the-run +description: "Resume" after a rate limit or interruption means replaying the interrupted work so it finishes itself — the same run, the same agent, transcript and cache intact; never re-plan, re-target or re-route models on your own inference +metadata: + type: feedback + upstream: PA +--- + +When the developer says "resume" after an interruption, they mean: pick up exactly where the work stopped, with the paid context +intact — not re-plan it, not re-target it, not route it to a different model. + +**Why:** rebuilding targets or re-routing on the agent's own inference wastes the context already paid for and changes the +experiment; a replay finishes itself. Fifteen interrupted agents were resumed this way in one session after a provider rate +limit, each continuing from its own transcript. + +**How to apply:** an orchestrated workflow resumes by its run id; a subagent resumes by a message to the same agent — "continue +exactly where you left off; your files are intact" — same agent, same model, transcript retained. When subagents will outlive +the session, the checkpoint must say how a fresh session aggregates their output (the tool that reads their transcripts and the +paths). Agents write their deliverables early — the draft file first, the verdict last — so an agent lost to a limit still +leaves something to bank. diff --git a/decomp-architect/memory-seed/route-by-measured-difficulty.md b/decomp-architect/memory-seed/route-by-measured-difficulty.md new file mode 100644 index 000000000..48ac79b99 --- /dev/null +++ b/decomp-architect/memory-seed/route-by-measured-difficulty.md @@ -0,0 +1,23 @@ +--- +name: route-by-measured-difficulty +description: Tier drafting models by a difficulty cliff you MEASURED on your own corpus (a small manual wave, bank rate by size), escalate sooner rather than later, and reserve the strongest model for NEW wall classes — never for reviewing a corpus +metadata: + type: feedback +--- + +Route drafters by measured difficulty, not by price per agent. On the source project the first routing boundary was guessed and +was wrong by a factor of two: the cheap tier matched the small functions as well as the strong one at a fraction of the cost, but +its bank rate collapsed past a cliff that measurement placed far lower than the guess. Later measurement over more than a hundred +agents, priced per MATCHED instruction (a failed agent is billed in full), showed the cheaper tier costing more per bank in the +band it could not handle; the ladder was then cut to two tiers with an earlier escalation. + +**Why:** the expensive mistake is running a cheap tier into a wall, paying for the failures, then paying again to escalate. +Higher tiers crack harder functions in fewer tokens. + +**How to apply:** run a small manual wave first and measure your own cliff — bank rate by instruction count — then route on it, +and re-measure as the tooling changes. Cheap tiers are honest filters (every claimed match was real) but never the gate. The +strongest model is for genuinely new wall classes: an unsolved tooling problem, an adversarial review of a design, a residual no +documented lever reaches — briefed with every number already measured, the files and sections to read first, the house rules as +hard constraints, and an explicit deliverable path; then verify every claim against the bytes yourself. It is NOT for reading a +pile of artifacts against an existing knowledge base (idiom distillation, cookbook review) — that is judgement over a corpus, +mid-tier work, and routing it to the frontier tier was a correction the owner had to make. diff --git a/decomp-architect/memory-seed/the-byte-gate-is-the-only-claim.md b/decomp-architect/memory-seed/the-byte-gate-is-the-only-claim.md new file mode 100644 index 000000000..80ef55997 --- /dev/null +++ b/decomp-architect/memory-seed/the-byte-gate-is-the-only-claim.md @@ -0,0 +1,21 @@ +--- +name: the-byte-gate-is-the-only-claim +description: "Matched" means the compiled output is byte-identical AND the whole binary's hash still equals the original; nothing "functionally equivalent" counts; "banked" is written only from a tool's printed success line +metadata: + type: project +--- + +A function is matched when its compiled output is instruction-identical to the original, register allocation included, and the +whole binary still hashes to its recorded value with that function compiled from source. A diff that "looks right", a closeness +score, a compiler that "ran without errors", an agent's verdict — none of these is a result. The gate is the arbiter; every other +signal is a filter that feeds it, and each filter is blind to something (a masked standalone compile cannot see symbol identity; +a real-translation-unit probe cannot see link-time identity; only the whole-binary hash sees everything). + +**Why:** the documented failure mode of AI-driven reverse engineering is fake success — stubs, shortcuts, redefined terms. An +incorruptible oracle is what makes an autonomous agent's work trustworthy at all. On the source project the whole-binary hash ran +inside every build of every binary, a clean rebuild followed every batch, and twice a ledger claimed a "bank" that had not +happened — a helper had no-op'd on an empty list; a wrong draft directory — because the message was written from intent. + +**How to apply:** verify from a clean rebuild, never an incremental one, after any batch that touches shared code. Write "banked" +or "matched" only by quoting the gate's own printed success line. Never ship a default build that links unmatched C (a guard keeps +logically-correct-but-unmatched code out of it). When a claim rests on a tool's output, name the tool that produced it. diff --git a/decomp-architect/memory-seed/the-matching-flywheel.md b/decomp-architect/memory-seed/the-matching-flywheel.md new file mode 100644 index 000000000..05b34e36b --- /dev/null +++ b/decomp-architect/memory-seed/the-matching-flywheel.md @@ -0,0 +1,20 @@ +--- +name: the-matching-flywheel +description: Consult the knowledge base (the idiom cookbook, the pinned toolchain, the permuter harness, the decompiler's context) BEFORE every match, and feed the generalizable lesson back into BOTH the cookbook AND the tooling after it +metadata: + type: project +--- + +Matching runs on a deliberately compounding knowledge base: a cookbook of compiler idioms (each with the residual it explains, +the mechanism, the lever and the byte proof), the pinned compiler/assembler triple, a permuter harness for near-misses, and the +decompiler's context file of known globals and types. Each part is consulted before a match and updated after it. + +**Why:** compiler nuances repeat across nearly every function; an autonomous loop scales only if each match makes the next one +cheaper. The goal is to drive the average function toward one-shot and shrink the hard tail — not literal zero-intervention. + +**How to apply:** before matching, grep the cookbook by symptom (never read it whole once it is large — keep a symptom index) +and scaffold with the decompiler. After a hard-won match, extract the GENERALIZABLE lesson — a recurring class, not a one-off — +and feed it into both the cookbook and the tooling (a permuter recipe or weight, a context entry, a helper). Two laws learned at +cost: harvest lessons only from byte-proven results, and strip a credited lever from the accepted body and recompile before it +enters the base — about one in three credited levers was byte-inert. A name on a work card must resolve in the knowledge base +by the words on the card; a label a worker cannot look up costs a search and buys nothing. diff --git a/decomp-architect/memory-seed/tool-change-ships-with-its-consumers-and-docs.md b/decomp-architect/memory-seed/tool-change-ships-with-its-consumers-and-docs.md new file mode 100644 index 000000000..f8c8f55c2 --- /dev/null +++ b/decomp-architect/memory-seed/tool-change-ships-with-its-consumers-and-docs.md @@ -0,0 +1,23 @@ +--- +name: tool-change-ships-with-its-consumers-and-docs +description: The commit that creates or changes a tool also wires the sibling tools that should use it AND updates the docs (the ops row, the cookbook or runbook entry); integrating an agent's tool change IS a tool change; no end-of-session documentation audits +metadata: + type: feedback + upstream: PA +--- + +Whenever a tool is created or updated, the same change (1) updates the related tools so they know how and when to use it — +wire it in, call it, refuse without it; a tool nobody calls is a tool nobody uses — and (2) updates the docs that consume that +knowledge: the ops reference row, the cookbook or runbook entry. If those are not in the diff, the change is not finished. + +**Why:** asked a plain yes/no question — "are the tools and docs up to date with this session's changes?" — the agent once +answered by launching a nine-agent audit that burned about a million tokens before the developer stopped it; the answer was yes, +and the agent already knew it, because the wiring and docs had gone in with each change. Later the same day the honest answer +was NO, and the gap had one shape: every tool change that came from a SUBAGENT had shipped with a rich commit message and no +docs. A report is not an ops row and not a cookbook section. + +**How to apply:** budget documentation per MERGE, not per session — when an agent's report contains a law (a measurement, a +refuted premise, a new lever), it goes into the cookbook before the merge is called done. When asked whether things are up to +date, answer from what you did, briefly, with concrete examples; cheap deterministic checks (an index check, a grep for a +hard-coded path, the health target) are fine, an agent fan-out is not. Scale the response to the question: a yes/no question gets +a yes or a no. Do not run end-of-session audits — an audit at the end is a symptom of not having done it during. diff --git a/phase-ends/CURRENT_PHASE.md b/phase-ends/CURRENT_PHASE.md index 9b5dbbfbc..df57fb5bb 100644 --- a/phase-ends/CURRENT_PHASE.md +++ b/phase-ends/CURRENT_PHASE.md @@ -47,7 +47,7 @@ in-tree links to `docs/wiki/.md`. 8. `.run/`: only what git tracks; no sca - [x] **6** Sunset moves (59 files — `family-hseq.md` stays, see the log) with the referrer census by command; `docs/sunset/README.md`; `Archive-index.md` rows (backticked paths + `v1.32.1`); DIGEST §4 + `docs/history/README.md` refreshed; coverage: 0 `docs/` files outside wiki/how-to/sunset uncovered — xHigh — see Log 2026-09-07 Task 6 - [x] **7** Checkers: `doc_links.py` (sunset refusal, index-derived allowlist, wiki-first warnings, TRACKED/UNTRACKED citation classifier + `--disk`, coverage ⊆); reachability in `wiki_render --selftest`; `timeline.py` regen in `report BINARY=main` + `--check` in `audit-digest`; the 13 dangling cookbook cites; the gitignore-template diff; tools-health wiring; SETUP rows — xHigh — see Log 2026-09-07 Task 7 - [x] **8** Tracked `.run/` prune (218 paths untracked: the 172 inertia files + 44 finished logs + the 2 firewall listings; `untracked_after_rewrite.txt`; `audit_public` check 4 with both controls; runbook §11; the four tool notes) — xHigh — see Log 2026-09-07 Task 8 — **P6 rules check done after it** -- [ ] **9** Memory reconciliation (move the off-project file; the 7 stale updated; `bfm-decomp-context-system` refreshed; the seed set under `decomp-architect/memory-seed/` with `upstream: PA` tags) — xHigh +- [x] **9** Memory reconciliation (the off-project file parked; the 7 stale updated in place; `bfm-decomp-context-system` refreshed; the seed set — 16 files — under `decomp-architect/memory-seed/` with `upstream: PA` tags) — xHigh — see Log 2026-09-07 Task 9 - [ ] **10** Kit part 1: `README.md`, `intake.decomp.md`, `decomp-architect.md`, `templates/registry-E.decomp.md`, `corpus/decomp-kernels.md`, `templates/PLACEHOLDERS.md` — Max - [ ] **11** Kit part 2: the firewall pack, docs/run READMEs, ops-setup, bootstrap, CLAUDE overlay, `pa-overlays.md`, LICENSE/NOTICE/README/CONTRIBUTING skeletons, `.clang-format` + format snippet, `tools/MANIFEST.md`; `tools/kit_lint.py` in tools-health — xHigh - [ ] **12** Kit part 3: `SETUP.md` (§0–§10, `--answers`, the PA-2.0 version pin, the honesty section, Path A only) — Max — **then P6 rules check** @@ -418,53 +418,86 @@ overwrite blind (the `.gitignore` edits are additive re-excludes under dated com splat yaml or overlays.mk was touched); never commit ROM-derived content (the pair is out of the index; check 4 now guards the class); never `git clean -x`; `purge_set.txt` never edited in this phase. Continuing with task 9. -## 🛑 SESSION CHECKPOINT — Tasks 0–8 ✓ (P6 check done); NEXT = task 9 (memory reconciliation + the kit's memory seed; xHigh) +### 2026-09-07 — Task 9 — Memory reconciliation + the kit's memory seed (xHigh) +**The project store** (`~/.claude/projects/-home-musashi-bfm-decomp/memory/`, outside git by Drew's decision): the off-project +`vantage-edge-never-leaks.md` was MOVED to `~/.claude/memory-parked/` (no Vantage project store exists under `~/.claude/projects/` — +only this project's and `-mnt-c-Users-user`, which has no memory directory; never deleted) and its index row removed. The seven +stale memories got a dated **"Updated 2026-09-07 (Phase 33.5)"** block APPENDED (the originals stay as records): the cheap-tier A/B +(→ the record; routing superseded twice), the effort doctrine (CLAUDE.md now agrees), the private-repo backup policy (HISTORICAL; +R78 is the backup), the endgame deliverables (all three shipped), roadmap-to-100 (archived; plan from phase34-seed + gen3-handoff), +the ROM-content policy (INVERTED — H1 in force, R74, the relaxation's bill), the context-system status block (P33.5 open / P34 next / +Gen3 at 35, the R64 load order). Their `MEMORY.md` hooks rewritten; two more index defects fixed while there — `continuous-gater- +lane-plan.md` had NO index row (added) and the model-ladder hook still described the dead Haiku→Sonnet→Opus ladder (now the +2026-09-01 two-tier rule). Index rows == files: 80 == 80. **The kit seed** `decomp-architect/memory-seed/`: 16 files + `MEMORY.md` +(PA 2.0's own sixteen seeds cited by name, not copied) — the three decomp seeds (`the-byte-gate-is-the-only-claim`, +`the-matching-flywheel`, `mcp-reconnect-after-restart`), the nine portable working agreements (`offline-tooling-first`, +`one-runbook-is-the-procedure`, `keep-an-accelerator-ledger`, `checkpoint-means-everything-is-already-in-a-file`, +`phaseend-carries-the-narrative-axis`, `tool-change-ships-with-its-consumers-and-docs`, `no-sleep-polling-background-tasks`, +`long-checks-run-in-the-foreground`, `resume-means-resume-the-run`, `answer-before-grinding-in-live-coop`) and the riders folded +into three more (`a-slow-gate-is-a-bug`, `breadth-is-isolated-agents`, `route-by-measured-difficulty` — the measured cliff, escalate +sooner, the frontier-agent briefing recipe, what the frontier tier is NOT for). Five carry `upstream: PA` (the harness-generic ones: +the four planned + the live co-op one). Every body de-BFM'd: no project name, owner name, paths, sessions, addresses, rule numbers +or section numbers (the kit_lint pattern + `Drew` → 0 hits); numbers appear only as "measured on the source project". **Verify:** +16 files == 16 index rows; frontmatter parses (name == stem, type ∈ the four, optional `upstream: PA`); every seed has **Why** and +**How to apply**; every index link resolves. + +## 🛑 SESSION CHECKPOINT — Tasks 0–9 ✓; NEXT = task 10 (kit part 1: README, intake, methodology, registry-E, corpus, PLACEHOLDERS; **Max** — prompt Drew, R27) ### 0. How to use this block You are a FRESH SESSION that has read `PROJECT_CONTEXT.md`, `phase-ends/DIGEST.md`, `PhaseEnd_Phase31/32/33.md` and this file, and nothing else (R64). Replay this block verbatim, state phase / done / NEXT / effort, list the rules from the digest (R1–R83), then -WAIT for Drew. Rebuild the harness task list (16 rows, R28) marking tasks 0–8 completed and task 9 in progress. +WAIT for Drew. Rebuild the harness task list (16 rows, R28) marking tasks 0–9 completed and task 10 in progress. ### 1. Where we are **Phase 33.5** (sub-phase; v1.32.0 → v1.32.1), gate 1 approved 2026-09-07 by Drew in plan mode at Max; effort follows the plan's -column (Max for tasks 10, 12, 15 — prompt at each transition, R27; xHigh now). Baseline HEAD `80d45b29b`; task 0 = `39d524991`; -task 1 = `a0cf302e5`; task 2 = `d06923a06`; task 3 = `5d10a0d12`; task 4 = `9970f1e62`; task 5 = `a0d4ae836`; task 6 = `6ec4786bd`; -task 7 = `21c98ed5a`; task 8 = the commit after it (the prune). No build input changed; the fleet is 218/218 at the Phase-33 close. -Tracked `.run/` = 868 files; `audit_public` OK with its four checks; `gate_scan --all --worktree` PASS; `doc_links --strict` green; -the pending list empty. The doc-side half of the phase (tasks 1–8) is DONE; what remains is the memory reconciliation (9), the kit -(10–13) and the closing pages (14–15). +column (Max for tasks 10, 12, 15 — prompt at each transition, R27). Baseline HEAD `80d45b29b`; task 0 = `39d524991`; task 1 = +`a0cf302e5`; task 2 = `d06923a06`; task 3 = `5d10a0d12`; task 4 = `9970f1e62`; task 5 = `a0d4ae836`; task 6 = `6ec4786bd`; task 7 = +`21c98ed5a`; task 8 = `ae71efe56`; task 9 = the commit after it (the seed). No build input changed; the fleet is 218/218 at the +Phase-33 close. Tracked `.run/` = 868; `audit_public` OK; `gate_scan` PASS; `doc_links --strict` green; pending list empty. The kit +directory so far holds ONLY `decomp-architect/memory-seed/` (16 seeds + MEMORY.md). Tasks 10–13 build the rest of the kit; 14–15 close. -### 2. What NEXT does (task 9, xHigh) — exact steps -The memory store is `~/.claude/projects/-home-musashi-bfm-decomp/memory/` (81 files + `MEMORY.md`; NOT in the repo, by Drew's decision -2026-09-07 — kit seed only). Ledger L3 in this file classifies every file. -1. **Move the off-project memory:** `ls ~/.claude/projects/` → find the Vantage project's directory (a `-mnt-…` or `-home-…` slug whose - MEMORY.md mentions Vantage); `mv` `vantage-edge-never-leaks.md` there (append its index line to that MEMORY.md); delete its line from - this project's `MEMORY.md`. If no Vantage store exists, move it to `~/.claude/memory-parked/` and say so in the log — never delete. -2. **Update the 7 stale memories IN PLACE** (Edit; keep frontmatter; add a dated "Updated 2026-09-07 (P33.5)" line): `cheap-tier-ab-validated` - (→ the ladder in `subagent-model-ladder`; the ≤50 band was later measured as ≤~30; keep as the A/B record); `effort-doctrine-xhigh-default` - (CLAUDE.md now agrees — the contradiction is resolved); `private-repo-backup-policy` (→ R78: text export + checksums + the archive repo; - never `git clean -x`); `project-endgame-deliverables` (all three shipped in P33 — story/timeline, retrospective, wiki+how-to; keep the - sequencing lesson + "capture live, transcripts die"); `roadmap-to-100` (→ archived at P33.5; the live seeds are `docs/phase34-seed.md` + - `docs/gen3-handoff.md`); `rom-content-git-policy` (INVERTED: H1 in force since P33 C3, no private exemption ever again — R74; the - relaxation cost the rewrite); `bfm-decomp-context-system` (status block → P33.5 open, Phase 34 next, Gen3 at 35; the load order per R64). - Also refresh `MEMORY.md`'s hook lines for those seven. -3. **Write the kit seed set** under `decomp-architect/memory-seed/` (the directory does not exist yet — create it; task 10 adds the rest of - the package around it). Frontmatter per PA 2.0 (`name`, `description`, `metadata.type`), bodies de-BFM'd (no paths, sessions, function - addresses; "the project" not "BFM"), each with **Why** and **How to apply** lines: the NINE new — `no-sleep-polling-background-tasks`, - `live-coop-answer-before-grinding`, `tools-health-foreground-not-background` (generalise: "long verification tools run in the foreground - with a timeout"), `resume-means-resume-the-run`, `tool-change-ships-with-its-consumers-and-docs` (+ "no end-of-session audits"), - `checkpoint-means-everything-is-already-in-a-file` (the commit-message trap), `phaseend-carries-the-narrative-axis`, - `offline-tooling-first` (computable vs search), `one-runbook-is-the-procedure` (+ banner superseded runbooks); the FIVE riders folded - into whichever seed fits (the quadratic main-loop-context arithmetic → a `breadth-is-isolated-agents` seed; the accelerator ledger - as a habit → `keep-an-accelerator-ledger`; the per-stuck-lane briefing recipe + "what the frontier model is NOT for" → `route-by- - measured-difficulty`; "a slow gate is a bug" → `a-slow-gate-is-a-bug`); the THREE decomp seeds — `the-byte-gate-is-the-only-claim`, - `the-matching-flywheel` (R16), `mcp-reconnect-after-restart` (R29). Tag the four harness-generic ones with `upstream: PA` in - metadata (no-sleep-polling, tools-health-foreground, resume-means, tool-change-ships-with-consumers). `memory-seed/MEMORY.md` in PA's - row format (`- [title](file.md) — hook`), listing these AND citing PA 2.0's seven already-seeded ones by name (not copied). -4. Verify: `ls memory-seed/*.md | grep -vc MEMORY.md` == the number of `- [` rows in `memory-seed/MEMORY.md`; every file's frontmatter - parses (`name`/`description`/`metadata.type`); `grep -rlE 'SLUS|Musashi|BFM|Druthulu|func_80|ov_SC|/home/musashi|/mnt/z' memory-seed/` - is empty; this project's `MEMORY.md` rows == its files. Log + checkpoint; commit by explicit path (the kit dir + this file). Task 10 is - **Max** — prompt Drew (R27). +### 2. What NEXT does (task 10, **Max**) — exact steps (plan D5) +Read first: `/mnt/z/Storage/git/ProjectArchitect/README.md` (the install ritual, "What gets installed"), `…/project-architect-2.0/SETUP.md` +(§0–§9 — the shape to mirror; §8 fills `PROJECT_CONTEXT.md` from the Mode-1 intake and §9 hard-stops, so the kit NEVER writes the +constitution), `…/project-architect-2.0/project-architect-2.0.md` (Mode 1's 12 intake items — the kit's `intake.decomp.md` pre-answers +them), `…/templates/RULES_REGISTRY.seed.md` (§E's provenance-tag convention), `…/corpus/README.md` (the corpus's "growing it" rule), +`docs/how-to-ai-decomp/03-bootstrap-order.md` (the order + the 12-item checklist), `docs/accelerators.md`, `docs/retrospective.md` §4, +`docs/gen3-standards.md` §2–§3, `docs/generic-decomp-package.md`, `docs/wiki/The-ROM-firewall.md`, `docs/wiki/Docs-and-scratch-conventions.md`. +Write (all under `decomp-architect/`; de-BFM'd — BFM numbers only inside ```` ```calibration ```` fences; the kit_lint pattern is +`SLUS|Musashi|BFM|Druthulu|func_80|ov_SC|/home/musashi|/mnt/z|172\.17\.|\bR[0-9]{1,2}\b|§[0-9]+` outside those fences and `provenance:` lines): +1. `README.md` — for humans: what the kit is; **step 1 install ProjectArchitect 2.0** (copy its folder, "Read SETUP.md and do it") **handing + its interview `intake.decomp.md`**; step 2 copy `decomp-architect/`; step 3 "Read decomp-architect/SETUP.md and do it" (Phase 0.5); what it + installs and what it does NOT (no tools — the MANIFEST is Phase-1 work until the split); platform scope (generic in structure, PS1-complete + in content, `TODO(platform)` elsewhere); the version pin (PA 2.0). +2. `intake.decomp.md` — PA Mode-1's intake items pre-answered for a decomp (the developer fills the game-specific ones: title, platform, + region/serial, the dump, community work, goals) + **the canonical phase ladder**: per phase — the machine-checkable milestone, the tools + built, the rules ratified, and the accelerator/retrospective item that earned its position. The order: extraction with a committed manifest + → the all-assembly byte-identical baseline → the compiler pinned by evidence (the candidate ladder) → the honest corpus census with + self-asserting tools + the differential-oracle harness at 0% → propagation/twin band/families/the reconcile ladder + carve chain + the + draw filter → the codegen map + the permuter → crack leverage-first with the widening review at every close → publish (the firewall was + day one) → the readability generation (pins recorded at draft time, shared bodies as C, types canonical at bank time, names with evidence, + formatting from install). +3. `decomp-architect.md` — the methodology: the ladder narrative; the byte gate; lanes/waves/cards; the flywheel laws (harvest only from + proven results; the inert-rider law; vocabulary decides findability; the one-wave lag); models/effort as METHOD (measure the cliff; + escalate sooner); the AI-use conduct (the five rules); Gen3-at-day-one (the six inversions); what stays hard; the economics' SHAPE. +4. `templates/registry-E.decomp.md` — the §E seed: G-rules (the disassembler + emulator as the oracles, the byte gate, no unmatched C in a + default build, address provenance, never rename blind, duplicates first, compiler honesty) + the distilled R-rules as G-numbered entries + with `provenance: ` lines (coverage assertion; derive don't re-derive; a second disagreeing oracle; fix the + instrument first; probe before costing; read the recorded verdicts; negative-control every refusal; exonerate the instrument; quote the + denominator; commit banked work immediately; refuse unsupported input; draw-time bankability; a budget is part of the harness; consume + every verdict layer; never key by bare name; a soft error is an error; periodic fleet verification; derived config goes stale; verify a + build by its exit code; a guard downstream is not a guard; unattended lanes leave evidence; a wall verdict names the pass; "banked" from + the printed line; agents write deliverables early; a producer census before a spelling sweep; port the sibling's spelling first; a + similarity score is not a shape oracle; reproducers before probes; no ROM bytes in any artifact; numbers generated never typed; rehearse + irreversible ops; a probe never writes into what it guards; a rewritten history is not private until the host purged it; outward text + by a person) + the AI-conduct rules. +5. `corpus/decomp-kernels.md` — the accelerators (A1–A9, #12–#20, the harness wounds, the late rows) + the failure museum's rows + the + retrospective's ten "sooner" items, each de-BFM'd into a kernel: takeaway · when it applies · the cost it saved/cost; the corpus README's + "growing it" rule at the top. +6. `templates/PLACEHOLDERS.md` — every `{{…}}` the kit uses, tagged copy-time (filled at §2–§5) or generation-time (filled at §7–§9). +Verify: `git grep -nE '' decomp-architect/ | grep -v calibration | grep -v 'provenance:'` empty (the lint tool lands in +task 11 — run the grep by hand now); every ladder phase names its citation; `doc_links` still OK (the kit is not in its set — add +`decomp-architect/README.md` to DEFAULT in task 11). Log + checkpoint; commit by explicit path. Task 11 is xHigh — prompt Drew to drop back. ### 3. Standing facts for every task of this phase - One commit per task, after this file's log line (R8/R42 form); commit by explicit path; no trailers (R5); Drew pushes (R6).