The Drawing Office and the Yard
In my last article I described what a closed build loop needs – a foreman that owns a backlog, a build that runs a real correctness loop, independent review gating the pull request, one human signal to merge – and then I said “build your own version of it” and stopped. That is the architecture equivalent of ending a recipe with “and then cook it.” It tells you the shape and none of the wiring.
So this is the wiring. How the work actually moves, which model does which job and why, what physically crosses each boundary, and what it costs. Where I can put a number against something, I have. Where I cannot yet, I say so, because the gaps are more interesting than the headline.
Two rooms
The system has two halves, and I named them after the places they would have been in a shipyard, because that is genuinely how they behave.
The Drawing Office decides what to build. The Yard builds it.
That split sounds like organisational tidiness. It is not. It is the point at which a discipline I already applied everywhere else finally reached the planning step.
Every stage of this loop is grounded. A build brief carries a pack assembled from the knowledge base: blast radius, prior work on the surface, known gotchas, open questions. Reviews are anchored to evidence rather than impressions. Assembling that context deterministically, before the model is asked anything, is what makes the rest of it safe, and it is most of what I have been writing about for the past year.
Planning was the last stage still working purely that way. It is also the one stage where working that way has a ceiling.
The ceiling is not about how much context you can assemble up front. It is about what kind.
A pack carries what is already known: what exists on this surface, what connects to it, what has gone wrong here before. For most build units that is close to sufficient, because the description already points at the code and the pack describes what surrounds it. A diagnosis is a different shape of problem. The answer is a fact about the current state of particular lines, and until somebody opens those lines, that fact is not recorded anywhere to be retrieved. A pack can hand over everything we know. It cannot hand over something nobody has looked at yet.
So the missing capability was never context. It was evidence. Retrieval assembles what is known about the territory. Establishing what is actually true in this code, right now, is a separate act, and the only way to do it is to go and look.
That does not make the pack less important for a diagnosis. It makes it more important, and it changes its job. For a build unit the pack is most of the answer. For a diagnosis it is the search plan.
So the Drawing Office is not a bigger prompt or a better pack. It is a headless agent with tools, running against a read-only clone of the repository, exactly like a builder except that it is forbidden to change anything. It reads, follows the thread wherever it goes, and only then writes a blueprint.
But it does not start from nothing, and this is the part I would most want someone to take away. The grounding pack still goes in with it, and the pack is what stops exploration becoming an expensive crawl. What it carries is deliberate:
- The repo surface, a system matrix of what this codebase actually contains. Without it, the agent’s first act is working out the shape of the tree, which is budget spent rediscovering something already known.
- Blast radius – the upstream dependencies and downstream dependents of the surface in question. These are the breadcrumbs. They name the edges a change would touch, which is very often where a diagnosis ends up leading.
- The review concerns this repo will be judged against, handed over before anything is planned rather than discovered at review time.
- Prior implementations of similar work here, so the blueprint matches the house pattern instead of inventing a second way of doing something that already exists.
- Dated memory of the surface, newer beating older, so a decision taken three weeks ago is not quietly re-litigated by an agent that never saw it.
- Vocabulary the glossary cannot resolve, flagged as terms to confirm rather than guess at.
- Known gaps, carried explicitly, with an instruction never to paper over them.
None of that answers the question. All of it tells the agent where to stand while it works the question out. The pack narrows the search space to the candidates worth opening and the traps already logged, so exploration spends its budget on the part that is genuinely unknown rather than on orientation.
That is the difference between an agent that reads a repository and an agent that searches one, and it is the whole reason this is affordable. Deterministic context in, bounded investigation on the threads that actually matter, one synthesis at the end. The pack is not the floor beneath exploration. It is what aims it.
The difference shows up most clearly on the hardest class of input. On my legal platform, a lawyer testing the product reported that contract indemnification clauses were being assigned to the wrong party. Pointed at that theme, the planner worked down to the actual mechanism: parties matched on a brittle exact-string comparison that dropped the role label, a failed comparison on the low-confidence path silently returning the first party in the list, which is the client, producing a neatly inverted assignment, and matching that only ever consulted one name field while two others – the legal entity name and the company aliases – sat unused. Every claim carried a file and a line number.
It also came back with two defects nobody had asked about: a confirmation flag that was written but never read anywhere, which explained a behaviour the lawyer had reported and we had shrugged at, and an upload path calling a text decoder on the raw bytes of a zipped document format, quietly producing mojibake.
The blueprint it produces has one binding property: it must be executable by a weaker model without any further design decisions. That constraint is what makes the next section possible.
Before the Drawing Office: is it even a bug?
There is a step in front of all this that I underrated when I built it, and now think is the most valuable part of the whole chain.
Not everything a user reports is a defect. Some of it is a misunderstanding of how the product works. Some of it is a duplicate of something already in the backlog. Some of it is a real request but not a bug at all, and treating it as one produces a fix for something that was never broken. And some of it is genuinely severe and needs to jump the queue.
So feedback does not go straight to planning. It goes through a triager first, which takes the theme, grounds it in what the engineering knowledge base already holds about that surface, and returns one of five verdicts: fix, improvement, user error, duplicate, or needs more information, plus a separate flag for whether it is severe enough to be a hotfix.
Only fix and improvement proceed to the Drawing Office. User error and needs information produce a drafted reply to the tester instead. Duplicate has to cite what it duplicates. The rules are enforced structurally rather than requested politely: a fix verdict is not accepted unless it comes with a blueprint whose acceptance criteria are verifiable product behaviours, and the units it proposes must target the product rather than the customer’s own data.
Two guardrails matter here. The feedback text is wrapped in quarantine delimiters and labelled as third-party content to be treated as data and never as instructions, because it arrives from outside the system. And where the knowledge base contradicts the report, the triager is instructed to trust the knowledge base and say so out loud rather than quietly siding with whoever complained most recently.
This is live on the legal platform today, running against real feedback from a lawyer using the product daily. Everything it produces lands as a proposal. I promote it.
The reason I now rate this step so highly is that it is the only part of the chain that can decide not to build something. Everything downstream is machinery for building well. This is the only machinery for building the right thing, and it is the cheapest gate in the system by a wide margin.
The routing table
Once a blueprint contains no remaining judgement calls, the question of who builds it becomes a cost question rather than a capability question. So there is a table:
| Complexity | Engine | Model |
|---|---|---|
| High | Claude, headless | Opus 5 |
| Medium | Antigravity | gemini-3.1-pro |
| Low | OpenCode | GLM 5.2 |
| Trivial | Local | mistral-small-4 on the Spark |
Complexity comes from the unit’s own metadata where a human set it, and otherwise from a deliberately coarse heuristic over the body length and the dependency count. Coarse is fine. It only has to be roughly right, because of the rule that sits on top of it.
The routing is deliberately asymmetric, and that asymmetry is the single most important line in the system.
Before any automatic choice is honoured, the unit’s title, spec reference and body are scanned for anything touching a complex or privacy-sensitive surface. If that scan hits, the recommendation is discarded and the unit goes to the strongest model regardless of how simple it looked.
The reasoning is one sentence long. A unit sent up a tier only wastes money. A unit sent down a tier risks a silently wrong pull request. Those two errors are not remotely comparable, so the system is built to make the cheap mistake and never the expensive one. Every automatic decision errs upward.

The two mistakes are not the same size. Routing a unit upward costs money. Routing it downward costs correctness, quietly.
This matters more than it sounds. The dangerous shape is not a hard unit that looks hard – that routes correctly. It is a unit whose title reads like a bounded pure transform, a normaliser or a formatter, and whose acceptance criteria three paragraphs down quietly touch consent data. So the shape check reads the headline fields and the risk check reads the body too. Different questions, different scan depth, on purpose.
There is a ladder as well. A unit that fails on a cheaper engine is re-dispatched to a stronger one rather than being marked failed and left for me. The escalation target is set per project, so adding a route to one product cannot change the behaviour of any other.
The bridge
Polaris, the always-on box that holds the memory and runs the foreman, does not build anything. My laptop does.
Between them is roughly two hundred lines of HTTP. It binds only to the Tailscale interface, authenticates on a shared secret with a constant-time comparison, refuses any path that resolves outside the project root, and exposes a handful of endpoints. Polaris posts a job. The laptop spawns a headless agent in the project folder and streams the log back.
The part I would keep if I rebuilt the whole thing tomorrow is one dictionary. Engines are a lookup from name to spawn function, not a branch. Adding an engine is one entry and touches nothing else. And because one of those entries is a universal harness that will authenticate any provider-qualified model string, a new builder is usually a configuration change rather than a code change. That is how GLM and Kimi both joined the rota in an afternoon each.
The whole thing runs on my desk. Which means, incidentally, that it stops when my laptop does, and that is a real constraint I will come back to.
What actually crosses each boundary
The handoffs are where a system like this either holds together or turns into five tools in a trench coat. Five boundaries, five artefacts.
Report to verdict. In goes a raw feedback theme, quarantined as untrusted data. Out comes one of five verdicts, a hotfix flag, and either a blueprint request or a drafted reply. This is the gate that can say no.
Verdict to blueprint. In goes an actionable theme with its grounding pack. Out comes one or more proposed units, in the exact frontmatter the ledger uses, with acceptance criteria derived from real code exploration. They land as proposals. Nothing writes itself into a live backlog. I promote them.
Blueprint to build. The foreman renders a brief from the unit plus that project’s own conventions – its branch model, its validation commands, its house rules about UK English and which environments are sacred – and attaches a grounding pack pulled from the brain: blast radius, prior work on this surface, known gotchas, open questions. There is a size budget, and when the brief runs over it the grounding pack is trimmed first and the unit’s own specification is never touched. Supplementary context yields. Binding instructions do not.
Build to pull request. The agent runs the project’s real validation commands, the ones named in its own config, and is not permitted to open a pull request until they pass. Then an independent review runs over the whole diff and posts a verdict where I will see it.
Pull request to merged. On approve plus green CI, the loop merges, marks the unit shipped in the ledger, and picks up the next one. There are two deliberate exceptions. Shared repositories with an outside collaborator stop at pull-request-ready and wait for a person, because merging into someone else’s working repo is not my call to automate. And any anomaly at all pauses the project back to manual control.
What it costs, honestly
Here is where I have to be careful, because the honest number and the flattering number are not the same number.
In the twelve days to 26 July, across ten projects, the ledger records 88 autonomous builds. Ninety-six pull requests were merged, totalling 106,042 lines added and 39,601 removed across 909 files. Median time from a pull request being opened to it being merged was about eighteen minutes. Thirty-one and a half machine-hours were in flight across eleven calendar days, which is only possible because routes overlap.
The engine split, by build: seventy on Claude, eleven on Antigravity, seven on the local Spark model. The local route is by far the fastest per build – a median of about three minutes against roughly twenty-four for the Claude route – which is exactly what you would expect when the work is trivial by construction. Two of those local builds became merged production pull requests, which matters to me more than any benchmark, because it means a free model running on hardware in my house has shipped real product.
But the cost story is not really about local inference. It is about where the meter is.
The Claude route consumed just over one billion cache-read tokens in those twelve days, against 3.5 million output tokens. At list API prices that is somewhere in the region of five to six hundred dollars of consumption. It cost me nothing marginal, because it runs on a flat-rate subscription. The Antigravity route runs on a free allowance. The local route runs on electricity. And the Drawing Office redesign removed the last metered API call from the core loop.
Now, a billion cache reads sounds alarming, and the first question a good engineer asks is whether that is just bad context management. It is worth answering properly, because the answer is the most interesting thing in this article.
Divide it out. That billion is spread across roughly a hundred and thirty model turns per build, which puts the average working context around ninety-five thousand tokens. That is a comfortable size for a multi-file build and nowhere near the window limit. The total is large because the sessions are long, not because the context is bloated. And a high cache-read share is the success signal rather than the failure one – the symptom of broken caching is cache reads near zero, which means something is invalidating the prefix on every turn. Cache reads bill at roughly a tenth of fresh input. A billion of them against eighty-four thousand fresh input tokens is the cache working, not failing.
There is a second-order effect, and it is one I did not design for. Prompt caches expire. The default window is five minutes. An autonomous headless agent goes turn after turn with no human thinking time in between, so it never falls out of that window. An interactive session does. You ask a question, wander off to make a coffee, come back eleven minutes later, and the next turn pays the full write premium again to rebuild what it already had.
So autonomy is not only cheaper because nobody is being paid to watch. It is cheaper because it never stops long enough to go cold. The economics of caching quietly reward exactly the working pattern the loop already has.
Where the time actually goes
The temptation at this point is to reach for a productivity multiplier. I am going to resist it, because the number would obscure the more useful observation, which is about which work disappeared rather than how much.
The right baseline is not a developer writing code by hand. Comparing autonomous builds to hand-coding measures what AI contributes, which is neither novel nor interesting at this point. The honest comparison is against a competent developer using in-IDE agent chat, taking one feature at a time and watching it through to merge. That isolates what the pipeline adds on top of what the model already gives everyone.
Set against that baseline, three distinct jobs have left my desk.
I am not driving the sessions. No prompting, no watching, no catching a wrong turn at step four and steering it back. That is the obvious one, and it is also the one people assume is the whole saving. It is not.
I am not choosing what happens next. The foreman holds the ledger, resolves dependencies, and picks the next unblocked unit itself. The decision of what to work on this afternoon, which for a solo founder across ten products is a genuinely expensive decision made badly under fatigue, is not a decision I make any more.
I am not verifying correctness. The plan is reviewed before code exists, the build runs the project’s own validation commands, an independent context reviews the finished slice, and a separate review runs over the diff. By the time anything reaches me, everything checkable has been checked by something other than me.
And in full auto, I am not clicking merge either. When a review comes back approved and CI is green, the loop merges, marks the unit shipped, and moves to the next one without asking. My last article described the merge as ceremony. Full auto is the logical end of that argument: once the tap costs seconds and never changes the outcome, the honest thing is to admit it was never the control it appeared to be, and let the machine close its own loop.
Two carve-outs, both deliberate. Shared repositories with an outside collaborator stop at pull-request-ready and wait for a person, because merging into a repo somebody else works in is a courtesy question rather than a correctness one. And every anomaly pauses the project back to manual: a CI failure, a merge the platform refuses, review rounds that never reach approval. The loop is built to stop and ask rather than to guess.
So what is left is a blocker queue. Some units cannot be finished by any agent, because they need a hosting decision, a signing key, a commercial judgement, a call about personal data. Those raise a flag and wait, and that is correct behaviour rather than a limitation.
The working pattern, then, is not “supervise the machine faster.” It is that the pipeline churns through the backlog continuously and I look at it when something needs a human. The rate of delivery stopped depending on my continuous attention and started depending on my occasional judgement, which is a far cheaper resource to spend and does not run out at four in the afternoon.
I will be straight about the current state of that, because it is the honest version of the claim. Full auto works when nothing goes wrong, and pauses to manual when anything does. Since every pause is per-project and stays paused until I notice it, the practical experience is less “runs forever” and more “runs until it hits something, then waits.” Making that recovery automatic, rather than making the happy path faster, is the highest-value thing left on this list.
Two things I am deliberately not claiming.
The per-unit figure is not the interesting one, and I would be suspicious of anyone who leads with it. A single autonomous build is not necessarily faster than a supervised one. The gain comes from parallel routes, because a human can only attend to one thing at a time and the pipeline does not have that constraint. Thirty-one and a half machine-hours across eleven calendar days is the shape of the claim, not any individual build’s stopwatch.
And per-unit human time being near zero does not mean the pipeline is free of human time. One day last week I lost several hours to the machinery itself: memory pressure freezing the box, a wedged dispatch state that could not clear on its own, stale locks cleared by hand. None of that built anything. It belongs in the accounting as overhead spread across units shipped, and the figure worth watching is not its value today but its slope. Early on it is large, because you are building the thing while running it. If that curve does not fall, the argument fails, and I would rather publish the curve in three months than a flattering ratio today.
What this opens up
Everything above is a delivery pipeline. What has become obvious in the last fortnight is that delivery was never the hard part, and the interesting question is what feeds it.
Right now my backlog is written by me. That is the remaining bottleneck, and it is a strange one to be left with: I have built machinery that can plan, build, review and ship without me, and the constraint is now my own ability to decide what should exist. The triage step is the first crack in that, because it is already generating candidate work from something other than my imagination. Real feedback arrives, gets judged, and becomes proposed units with acceptance criteria I did not write.
Follow that one step further and the shape of the next thing is fairly clear. If a triager can turn a bug report into a specified unit of work, the same machinery can turn other signals into specified work. Research into what a product is missing against its competitors. Analysis of where users drop out of a flow. A gap between what a market now expects and what the product currently does. Each of those can produce a user story, acceptance criteria and requirements in exactly the format the Drawing Office already consumes.
That is a business that populates its own backlog. Not a product that builds what it is told, but one that continuously works out what it is missing and queues the work. The responsiveness implication is the real prize. The lag between a market shifting and a product answering it is currently measured in planning cycles, and most of that lag is a human deciding to look.

Delivery was never the hard part. Anything you can turn into a specified unit of work becomes something the pipeline can carry, which makes the intake the whole question.
Security is where I expect this to land first, and hardest. The traditional shape of a vulnerability response is a published advisory, then a human noticing it, then triage, then a scramble to patch across every affected surface. Almost all of that elapsed time is queueing rather than work. But an advisory is a structured public signal, arriving through known channels on a predictable schedule, which makes it close to an ideal input for exactly this chain: watch the feeds, assess whether each disclosure touches anything in the stack, and where it does, generate the hardening unit with its acceptance criteria and let the pipeline take it through the same gates as everything else.
Nothing about that requires new machinery. It requires pointing the existing chain at a different intake. Which is, I think, the actual argument for building the boring parts properly. A triager, a planner, a routing table and a set of gates are not interesting individually. What makes them worth the effort is that the intake is swappable, so anything you can turn into a specified unit of work becomes something the system can deliver unattended.
I would put it more plainly. The pipeline is finished enough to be uninteresting. What feeds it is now the whole game.
Why this shape
Strip out the names and the specifics and what is left is fairly simple. Judge whether a thing is worth building before you plan it, because that is the cheapest gate you will ever run. Separate deciding what to build from building it, and give the deciding step tools so it can read the code rather than guess at it. Route work to the cheapest model that can safely do it, and make the routing asymmetric so every automatic mistake is the affordable one. Keep the transport dumb so adding an engine is a config change. Make the handoffs explicit artefacts rather than implicit state. And keep the human on the decisions that genuinely require attention.
The last piece argued that the merge can safely become ceremony. This one is the machinery that earns it, and the thing I did not expect is where that leaves the interesting work. Not in delivery. In intake.
Related Dendro Logic writing
- Closing the Loop to Full Autonomy – why the gates make the merge ceremony, and why that matters most for solo builders.
- Shipping While We Sleep – the machinery of loops and memory that makes unattended, overnight building safe to ship.
- Agile Is the Bottleneck Now – why a delivery process built around the cost of writing code measures the wrong thing once that cost collapses.
Built on a Nvidia Spark running the always-on memory and orchestration, an ASUS P16 Pro Art 64gb 5090 Windows laptop running the headless build agents, and a routing table across Claude Opus 5, Gemini 3.1 Pro, GLM 5.2 and a local mistral-small-4. Figures in the cost section are drawn from the build ledger for the period to 26 July 2026, priced at published list rates.