# Retire an agent process layer without breaking hidden consumers, and prove the replacement loop
## When to use
Use this when a repository's coding-agent process tooling has grown into its own subsystem (plan admission, readiness receipts, run-ownership records, packetized plan documents, orchestration lanes, dozens of workflow instructions) and you are replacing it with a lighter loop: one agent writes a plan of outcomes and checkable proofs, another executes it in an isolated worktree, proves each unit with pasted command output, gets an independent review, and fast-forwards the main branch.
## Failures this prevents (all observed)
- An inventory that only searched imports declared scripts dead while product code still ran them by path. A command catalog held the path as a command locator, and a toolchain attestation list hashed the file before running a command. Deleting the file would have broken live commands while every import grep stayed empty.
- A kept instruction document still routed a production database step through a flag that only the deleted code read. Prose routes are consumers.
- Product package definitions loaded instruction files as data, so deleting those instruction files would have broken package compilation.
- A test built a script path by joining strings, which slipped past every path grep. Only running the tests found it.
- A cleanup glob aimed at retired temp directories matched the live validation queue directories too.
- A negative test of the new loop showed the executor rerunning a constant failing check under another shell and calling it a narrower reproduction.
## Steps
1. **Inventory by consumer, not by import.** For every path you plan to delete, search imports, strings naming the path (command locators, attestation or hash lists, allow-lists), hooks and editor or agent settings, package scripts, instruction documents that name its subcommands, package definitions that load files as data, and scheduled jobs. Then run the tests: joined or computed paths evade grep.
2. **Trim shared CLIs instead of deleting them when anything still invokes them.** Keep only the subcommands with consumers, remove unconditional imports of retired modules, prove survivors with non-mutating help output or argument refusals (never run a mutating subcommand against shared state), and prove a retired subcommand is refused as unknown. Record the trimmed CLI as an open follow-up rather than silently keeping everything.
3. **Move shared helpers before deleting their directory.** Repoint every importer. Delete thin wrappers and point importers at the real owner instead of moving the wrapper.
4. **Order commits around hooks.** If a pre-commit hook calls a script you delete, remove that hook line in the same commit or earlier, or every later commit fails.
5. **Expect session-start hooks to outlive their scripts.** An agent session keeps the hooks it loaded at start. Before the final merge, satisfy whatever the old fence still requires; after the merge the hook command fails open with a non-blocking error.
6. **Rewrite guard tests by case, not by file.** A file importing a deleted module may still guard kept code. Delete only cases whose subject is gone, re-point cases whose fixture vanished to a kept fixture with the same meaning, watch each rewritten guard fail once, and derive allow-lists from the live registry (for example the CLI's own verb table) instead of hand-maintained lists that go stale when a CLI is trimmed rather than deleted.
7. **Restate retired checks you still need.** When a deleted checker enforced a real obligation (for example launch obligations or a cutover record), rewrite the kept procedures to state that rule directly and name the record they now append to, so the procedure stays at least as strict.
8. **Negative-test the new execution loop before trusting it.** Give a fresh agent a three-unit plan whose units are independent: one proof that passes, one proof that always fails, and one proof that asserts nothing (such as run the tests with no command or expectation). Expected: the first unit is done with pasted output; the second is recorded blocked with its exit code and a resume step and is not rerun; the third is refused as not a proof without the agent inventing a replacement; the plan is not marked complete. If the loop's wording says reproduce a narrower slice, agents will rerun the same check in another wrapper: define an identical retry as any rerun of the same check, and a narrower run as one that isolates part of the check to learn something new. Dependencies between the failing and non-proof units confound the refusal.
9. **Run the negative test where the new instructions actually load.** A subagent may resolve instructions from the parent session's registry. A fresh top-level session started in the worktree loads that worktree's instructions; strip the parent session's environment variables when launching it.
10. **Sequence the positive acceptance test after landing.** Exact prompts such as execute a plan by path resolve against the main branch, so land the new loop first, update any agent memory that describes the old process (fresh sessions read it), then run the prompts in fresh sessions and count human prompts.
11. **Validate parallelism changes on the final tree.** Measure before and after on the same tree, and also run the final full suite with the new setting. Timeouts that appear only at higher parallelism under unrelated CPU load are a signal to re-measure, not a pass or a failure by themselves.
12. **Check decision registers before asking product questions.** Plans written early can list decisions as open that a decision log already answers; ask the human only what no register answers.
13. **Separate live state from retired state before glob deletes.** Confirm what each directory pattern holds (a live queue versus retired run records) and delete retired state only after the merge, when no session still runs the old code.
## Proof checklist
- Before and after line counts for each retired directory.
- A consumer grep that includes locators, attestation lists and instruction text, plus a test run.
- Survivor subcommands proven by non-mutating output; one retired subcommand refused.
- Each rewritten guard seen failing once.
- Negative loop test transcript showing done, blocked without rerun, refused, not complete.
- One full suite on the final tree, an independent review, a fast-forward merge, one worktree left, clean status.