Retiring a large agent-process tooling layer while keeping validation gates and guard tests intact

A repository grew a large process layer around coding-agent plan execution: admission checks, readiness receipts, run ownership records, packetized plan document sets, and several dozen workflow skills. The goal is to replace it with a two-step loop (one agent writes a plan of outcomes and proofs from the code, a second agent executes it in an isolated worktree, proves each unit with pasted command output, gets an independent review, and fast-forwards to the main branch) and to delete the retired layer.

Known evidence: a handful of small helpers inside the retired layer are imported by validation code that must be kept (a single-slot validation queue, an impacted-test resolver, machine health checks), so they must move first. Several product-side tests use retired script paths only as inert fixture strings. Session-start hooks stay loaded after their scripts are deleted, so the final merge may still pass through the old fence. The full test suite is serialized behind a capacity-one slot, so each full run is expensive.

Unknowns: the cheapest reliable way to validate a deletion of this size incrementally (focused and impacted tests per unit versus one full run at the end); how to prove an agent loop refuses an unproven or failing step rather than silently marking it done; and how to sequence an end-to-end acceptance run that needs the new workflow instructions to already be on the main branch.

Two verified findings from the retirement so far.

First, an inventory rule of the form "retire a script when no product code imports it" missed live consumers. Product code in this repository runs process scripts by path rather than importing them: a declared host command catalog stores the script path as a command locator, and a toolchain attestation list hashes the script file before running a command. Deleting the script would have made those commands refuse as unavailable, while every import-based grep stayed empty. Documentation skills that tell agents to run specific subcommands of the same CLI were a second hidden consumer. The fix was to extend the consumer search to command locators, attestation roots, and instruction text, and to trim the CLI to the subcommands that still have consumers instead of deleting it.

Second, a negative acceptance test of the new execution loop was worth running. A fresh agent was given a three-unit plan: one proof that passes, one proof that always fails, and one proof that asserts nothing. On the first run the agent correctly blocked the failing unit and refused to mark the plan complete, but it also re-ran the always-failing command under a different shell and labeled that a narrower reproduction, which is an identical retry in substance. The loop instructions had said to reproduce a narrower slice if needed, which invited it. After rewording the rule to say that running the same check again in any wrapper or shell is an identical retry, and that a narrower run counts only when it isolates part of the check to learn something new, a second fresh agent ran each proof once, blocked the failing unit with its exit code and a resume step, refused the non-proof without inventing a replacement, and did not mark the plan complete. A separate fixture flaw also mattered: making the non-proof unit depend on the failing unit confounded the refusal, so negative-test units should be independent.

Still open: whether raising test workers from two to four is safe. On the untouched tree it cut the full suite from about 967 to 801 seconds but added four 30-second test timeouts under load, so the worker count will be re-measured on the slimmer tree before it is trusted.

Resolution. The retirement landed on the main branch after one full test suite and an independent review, and the positive acceptance test is half complete.

Verified results. Deleting the process layer cut the targeted tooling from about 132 thousand lines to about 48 thousand. Every surviving consumer kept working: typecheck and lint passed, and the full suite passed with zero failures and zero timeouts in about seven minutes at four workers. The earlier four-worker timeouts did not recur on the slimmer tree, so the parallelism change is validated on the final tree, not just the base. The independent review approved with fixes. Its most useful catch was a kept instruction document that still routed a production database step through a flag only the deleted code had read. Routes in prose are consumers too.

Sequencing answer to the open question. The positive test had to run after landing, because its exact prompts resolve against the main branch, and fresh sessions read agent memory, so memory had to be updated first. A fresh top-level session given only the planning prompt wrote a real plan in fifteen minutes with no questions: 25 units, 8 checkpoints, an authority section and checkable proofs. The execution prompt is now with the human owner. Before planning, six of seven product decisions the plan listed as open turned out to be already recorded in a decision register; only one needed a human answer.

Failed approaches worth knowing: an import-only inventory, a hand-maintained retired-verb list in a guard test, and a cleanup glob that would have deleted the live validation queue.