This is the longer version of how the pipeline works: the nine principles I build it on, and the five artifacts every run leaves behind in the repository.
##methodology
This is what I have learned about how much engineering it actually takes to let agent teams ship production software, and about where a human still has to decide.
"I spent far less time on the loop itself than on the graph, the gates, and the memory around it. That surrounding machinery is where the real engineering lives, and it is what lets agents ship software you would actually merge."
agentic loops & graphs — self-improving systems
Every principle below is in service of the same goal. I want human judgment concentrated into a few named gates, the span between those gates automated, and every run leaving the system smarter than it found it.
[01] spec
##spec-first
I author requirements before a line of code is written, and I give each one a permanent, immutable ID. When a requirement is superseded I tombstone the row with a pointer to its replacement rather than delete it. The point of all this is that every ambiguity has an address, so an agent can go read the requirement instead of inventing the behavior itself.
[02] graph
##graph-engineering
I write tickets as thin vertical slices and wire them together with blocked-by edges. Once the graph exists, readiness is something you can compute, so the loop derives the ready set from the graph and nobody has to hand-order the work. Laid out by build depth the columns become build waves, and the tall columns are where running lanes in parallel actually pays off. The critical path sets the floor.
[03] gates
##concentrate-the-gates
Most agentic workflows I have used either interrupt you constantly or never stop at all, and I wanted a third path. So I concentrate every human decision into a few named, high-leverage gates: scope, epic approval, drain start, and PR merge. Each ruling lands in a durable artifact, which means no stage downstream ever has to ask you the same question twice.
[04] dial
##autonomy-dial
I treat autonomy as a dial running from L0 (assisted) to L3 (auto-merge), and it has hard ceilings the agent is not able to raise for itself. Heavy-risk changes, which for me means models, migrations, auth, money, and sensitive data, cap at human-merge no matter what. And any run that authored a new requirement never auto-merges at all.
[05] loop
##compound-learning
Every run leaves five artifacts behind: code, specs, learnings, e2e tests, and a test-case ledger. The learnings are captured before ship and then applied automatically by future planning runs, so an afternoon I spent debugging becomes a head start for the next session. Over time the things the system got wrong turn into the rules it works by.
[06] verify
##verification-honesty
I have learned not to trust a green I did not personally observe. The lanes report their results, and then the lead re-runs every gate, reads the diff, drives the live app, and queries the database directly for ground truth. Each check gets exactly one verdict, and I do not let "not run" stand in as one.
[07] schema
##schema-first-prompts
I never let a subagent return prose that something downstream has to re-parse. Every fan-out defines a JSON schema and the harness retries until the output validates, so orchestration is always consuming typed data. A pleasant side effect is that disagreement between agents becomes something you can type.
[08] budget
##budget-the-loop
I put spawn budgets, 3-strike root-cause rules, round caps, token reserves, and broken-baseline hard stops on everything. Budgets are the contract that makes a multi-agent system debuggable at all. Without them you have no way to tell the difference between an agent making progress and an agent that simply kept trying.
[09] qa-left
##test-cases-before-code
I derive a ticket's test cases before any implementer starts, using the same rules file QA uses after merge, with its version pinned into the ledger so the two derivations cannot drift. The rules generate the scenarios and only spec rows may supply the expected outcomes, so anything a rule needs that no row governs becomes a spec-gap line a human has to rule on. A 75-ticket epic had drained clean and then reopened 37% of its tickets in QA, and this is the change that brought the rate down to about 15%.
##artifacts
Every run leaves the repo richer than it found it. Code is only one of the five outputs, and the other four are the ones that make the next run smarter. That is what the word "compound" is doing in compound engineering, and it is how the context concentrates in the repository for the next person or agent.
[01] code
##code
The change itself, built to a plan that was debated first, then QA-looped, reviewed through multiple lenses, and verified against the running app with live browser drives and direct DB reads before any PR opens.
[02] specs
##functional-and-nonfunctional-specs
Versioned requirement catalogs with permanent, immutable IDs, where a superseded row is tombstoned with a pointer to its replacement rather than deleted. They are consulted at write time, checked at the review gates, and snapshotted at ship. Alongside them sit the non-functional catalogs: a security baseline, a HIPAA overlay, and PHI handling.
[03] learnings
##learnings
A grep-able catalog of solved incidents, captured before ship and applied automatically by future planning runs. The debugging I did in one session becomes the head start for the next one, and over time the things the system got wrong become the rules it works by.
[04] e2e
##e2e-coverage
Playwright tests annotated to the requirement IDs they cover, audited continuously and snapshotted at every ship, so that the requirement catalog stays something you can actually test against.
[05] ledger · new since 2026-09
##test-case-ledger
One execution ledger per ticket, derived before the build from a 17-area requirement analysis under a shared rules file that QA also uses after merge, with the rules version pinned into the ledger so the two derivations cannot drift apart. It carries the underspecified lines and the human dispositions on them, content-hashed case IDs that survive a refresh, a substrate tag on every case saying whether a unit run, an API call, a real browser, or a human can prove it, and a status precedence where a browser case is never marked passed from a unit run. The same list is executed three times: by the implementer's QA teammate, by verify in a real browser, and by QA after merge, posted once as a single comment on the ticket. It became the fifth artifact in September 2026, after a 75-ticket epic reopened 37% of its tickets in QA and I found that most of what QA caught was something a derivation would have named before a line of code was written.
// compliance-by-construction
The same spec machinery extends to security and compliance. I ran a STRIDE threat model on a healthcare AI product and promoted its findings into three living non-functional spec catalogs: a security baseline covering secrets, auth realms, tenant isolation, transport, and log hygiene; a HIPAA overlay that expresses the technical safeguards as engineering controls; and a PHI-handling catalog covering the 18 identifiers along with logging, URLs, proxying, retention, and de-identification. The gaps in our live posture then became a prioritized, requirement-cited backlog that the loop can drain, with every ticket mapped to the specific rule it violates and the file it lives in. The pipeline checks these catalogs at its review gates, which means the compliance posture is maintained as we build instead of being rediscovered during the next audit.