Overview
A control plane that takes a brief through Requirements → Design → Coding → Testing → Deployment. One specialised agent per stage, each in a fresh context receiving only the previous stage's approved artifact, with a human approve/decline gate between every one. A decline routes back to the same agent with the reviewer's feedback rather than cancelling the run.
The problem
Autonomous coding agents fail in a particular way: they produce plausible output, and plausibility is indistinguishable from correctness until something ships. The interesting problem is not getting an agent to write code — it is building a system where a human can trust what came out, and prove afterwards what happened.
Approach
- 01Five agents in a linear chain with fresh context each, passing forward only the finished artifact — so a mistake cannot propagate silently through shared conversation state.
- 02Per-agent least privilege. Three of the five stages are read-only and no agent is granted a shell at all; installs, builds, tests and deploys run through platform-owned ports driven by the orchestrator behind the gates.
- 03A deterministic pre-execution hook that blocks destructive commands, secret exposure and out-of-scope file access before the tool call runs — code, not prompt text.
- 04A hash-chained, append-only audit log covering every agent action, tool call, hook block and human decision.
- 05Every external dependency behind a port with local and hosted adapters, wired in exactly one file, so the pipeline logic contains no vendor SDK.
Decisions & trade-offs
Fail closed on engine selection, at the cost of availability
The platform refuses to boot in production without a model credential rather than degrading to its scripted engine. That looks over-strict until you notice the scripted engine is built to emit plausible artifacts — so five human approvals are not a defence, because plausibility is precisely what is being approved. A credential resolving to an empty string would otherwise open a pull request full of fabricated work on a client repository.
The QA gate trusts an exit code, never the agent's claim
The testing agent writes an assessment, but pass/fail comes from the real test runner. It cuts both ways: an exit code produced by a malformed invocation is a bug in the gate, not a flaky test. One generated app shipped a test command that Node resolves as a module path — exit 1, zero tests run, three auto-fix cycles chasing a defect that did not exist. The fix normalises the command before it runs.
Branch on capabilities, never on engine names
Nothing above the composition root knows which engine is running; it branches on declared capabilities instead. A repo check fails the build if a tier-string comparison appears above that seam, because an optimistic capability flag becomes a silent correctness bug in the run machine rather than a visible failure.
Start CI at the coding gate, not after it
The tree is final the moment the coding agent stops writing, so CI starts as the gate opens and runs while a human reads the diff. Measured on one run: 109s of CI absorbed into a 248s gate wait. Reuse is gated on a source fingerprint built from git's own file list, so any change to the tree simply misses and CI runs again.
What it does not do
- There is no separation of duties — one operator can start a run and approve its own gates. The audit trail makes every decision attributable, but it does not make it independent.
- In-stage approvals await in-process rather than durably, so a restart mid-approval loses that wait. Stage-level gates are durable; in-stage ones are not.
- A connected repository's code index informs no agent's context yet — the port exists and is wired into analysis only.
- It generates greenfield applications well and brownfield changes cautiously; large existing codebases are the harder, less-proven case.