EssaysThe Engine Shop
Part 2

Part 2: The Obvious Answer Is `--yolo` // The Obvious answer is insane

What happens when agentic development escapes the approval queue

Part 1 ended by telling us to fire ten thousand engines and spend human attention only on the ones that hold pressure.

There's a small practical problem: the engines have shell access to your laptop.

The best frontier models no longer want to attack a difficult software problem alone. Give one a sufficiently large task and it starts behaving like a middle manager unconstrained by morals or labor laws. It dispatches one subagent to search the repository, another to investigate the failing test, a third to read the documentation, and several more to try implementations in parallel. OpenAI's coding systems can spawn specialized subagents concurrently and collect their results back into a parent thread; Claude Code similarly gives subagents their own context, tools, and permissions. (OpenAI Developers)

This is awesome. It's also where the current development model begins to fall apart.

Put an approval prompt in front of every file write, shell command, package install, network request, or excursion outside the current directory and you haven't created a swarm. You've created a line at the DMV, and you are the clerk. The model may be capable of managing twenty parallel threads of work, but they all eventually queue behind one human clicking Allow.

OpenAI's auto-review system is a useful attempt to remove that particular human bottleneck. When the main agent asks to cross a sandbox boundary, a separate reviewer agent can approve or deny the request instead of stopping for a person. But the main agent remains inside the same sandbox, with the same approval policy and the same filesystem and network boundaries. Auto-review changes who answers the permission prompt; it doesn't answer the larger question of what world the model should be permitted to inhabit. (ChatGPT Learn)

To use frontier AI properly, you are therefore pulled toward the obvious answer:

--yolo

Stop asking permission. Let the model edit the files, run the tools, launch its subagents, reverse direction, rewrite the module, and generally get on with it.

The obvious answer is also fucking insane.

Part 1 dealt with the most sophisticated version of the danger: the model can write code that looks reasonable, passes obvious tests, and is nevertheless naive, insecure, internally incoherent, or simply wrong. But there's a more primitive danger that arrives before any of that code is reviewed. The agent has a shell. It can overwrite unrelated work, delete the wrong directory, poison configuration, destroy $HOME, expose credentials, publish something that should never have left the machine, or spend money through an external API with the serene confidence of a toddler ordering room service.

No sane professional developer wants to submit their real machine and real codebase to that. And yet, to use a frontier model at anything close to its potential, you kind of have to.

That's the central problem of Part 2. How do we make --yolo both safe and productive? How do we give a model enough freedom to explore without giving it enough authority to destroy anything we care about? How do we preserve the useful state it accidentally passes through, turn a swarm of subagents into a structured search rather than a pile of contaminated diffs, and eventually scale the whole thing from one model to hundreds or thousands of simultaneous attempts?

Part 1 designed a codebase that expects the implementer to be wrong. Now we need to design the room where the implementer is allowed to be wrong at full speed.

Build a world the model is allowed to destroy

The first mistake is putting the agent inside your world and asking it to behave. You don't need a better-behaved model. You need a smaller world.

The agent should run inside an isolated container or virtual machine whose destruction is acceptable. It shouldn't see the developer's actual filesystem. It shouldn't inherit every secret sitting in the shell environment. It shouldn't possess the same cloud credentials as the person who launched it. And it should never learn that your SSH directory exists because a recursive search wandered one level too high.

Instead, it should receive a synthetic view of the project: a sparse filesystem mounted through something like FUSE, containing only the repository paths, tools, build artifacts, and supporting files relevant to the work. The agent working on payments may be allowed to read the shared type definitions, modify the payments service, run its tests, and inspect the database schema. It doesn't need write access to the authentication service, the deployment system, your dotfiles, six unrelated repositories, and every credential you've accumulated since 2014.

That sparse view should carry real permissions. A path may be readable but not writable. Another may be visible only through a generated interface. A sensitive directory may not exist at all from the model's perspective. Network access should be scoped the same way: explicit destinations, narrow credentials, bounded side effects. Compute and token budgets should limit how large an explosion the agent can create before somebody notices.

The model can be emperor of a postage stamp.

This is capability security applied to the development environment. The agent doesn't receive the ambient authority of the human operator; it receives the minimum set of powers required to attempt the task. Its subagents inherit those powers (or a narrower subset), not some magical ability to widen the world by delegation. The parent may send a research agent to inspect an RPC definition and another to run the integration suite, but neither can obtain authority the parent itself never possessed.

Once the world is drawn correctly, most permission prompts disappear. The agent can operate freely inside the boundary because the boundary has already encoded the decision. It can read what it's allowed to read, write what it's allowed to write, run what it's allowed to run, and ask for intervention only when the task genuinely requires moving the wall.

This is the difference between permission theater and containment. Clicking Allow on two hundred individual commands feels safe because a human was technically involved, but the human is rarely evaluating each action with enough context to understand its consequences. A capability-bounded environment moves the meaningful decision earlier: what should this agent be able to touch at all?

The agent is allowed to be reckless because the environment is not.

Of course, containment only solves the stupidest class of failure. A container can stop the model from deleting your home directory. It can't stop it from deleting the conceptual integrity of the subsystem it was asked to improve. That's why the hard contracts from Part 1 still matter. The filesystem boundary limits the operational blast radius; types, schemas, permissions, tests, and state machines limit the semantic one.

A sandbox is the blast wall around the engine stand. It isn't the instrument panel, the black box, or the test itself. We still need to know what happened inside.

Record every explosion

An isolated room is useful because you can destroy it. It becomes vastly more useful when you can rewind it to the moment just before the explosion.

Traditional Git assumes a human author is curating the history. The developer recognizes that a meaningful unit of work has been completed, stages the relevant files, writes a commit message, and preserves the state. Until then, the working tree is private scratch space whose meaning lives mostly in the developer's head.

That assumption is badly suited to autonomous agents.

A model may spend forty minutes exploring three approaches. It may get the difficult part right halfway through, overwrite it while trying to clean up, then confidently present the worst of the three attempts as the final answer. It may discover the real failure, add a useful test, and then abandon both because its context was summarized and the next step began from an incomplete memory.

The best state produced by an agent is often not the state in which it stops. So the system has to preserve state before the agent knows that state matters.

Enter jj. Jujutsu models the working copy itself as a commit, snapshots changed contents as commands run, records repository mutations in an operation log, and supports multiple workspaces backed by the same repository. Earlier states can be inspected and recovered even if the agent never paused to package them into a clean, human-authored commit. (JJ VCS)

For an agent, that operation log is a flight recorder.

The model can rewrite a directory, run the tests, reverse the rewrite, generate a migration, split a module, and later decide that none of it worked. We still have the sequence of repository states. We can recover the version that passed one critical test before the cleanup broke it. We can branch a new attempt from the exact point where the original run made an interesting discovery. We can compare the model's claimed solution with the state it had twenty operations earlier, rather than relying on its retrospective explanation of what it thinks happened.

This is more than undo. Undo assumes you know you want to go backward; a flight recorder lets you discover, after the fact, that an earlier state was valuable.

It also changes what --yolo means. In the naive version, --yolo means trusting the model not to make destructive edits. In the sane version, it means assuming the model will make destructive edits and ensuring that none of them can erase the project's history.

There are limits. Version control can't unsend an email, unpublish a package, recover a secret already exfiltrated over the network, or refund the cloud bill generated by an accidental thousand-node cluster. That's why the capability boundary, credential system, network policy, and resource budget remain separate layers. The sandbox contains external consequences; jj preserves the changing repository state.

Together, they answer the first two questions any autonomous development environment should be able to answer: what did the agent change, and how do we get back? But there's a third question, and it's where things get more interesting. Which parts of what it changed were actually useful?

Let the search branch

A sufficiently capable model doesn't approach hard work as one clean line from issue to implementation. It forms hypotheses.

The bug may be in the parser. It may be in the schema. It may be a race. It may be an incorrect caller. It may be that the abstraction itself is wrong and the bug is merely the first symptom anybody noticed.

A frontier model with subagents will naturally divide that search. One worker tries the minimal patch. Another traces the data flow. Another writes a reproducer. Another studies the history. Another proposes the larger rewrite. This is exactly what we want: more shots at the problem, in parallel, while the attempts are cheap.

What we don't want is all of those hypotheses being poured into one working tree like six cooks improvising in the same saucepan.

Each line of exploration needs an identity. We treat those as implementation bookmarks: named speculative states that can fork from one another, evolve independently, be compared, and later recombine. A bookmark isn't yet a polished answer. It's a claim about where in the search tree an interesting possibility currently lives.

The continuously captured jj draft preserves the work while it's still wet. As useful decisions emerge, Meta's Sapling gives them structure. The surviving changes can be arranged into a stack of commits: a schema change at the bottom, a new service contract above it, generated clients above that, and one or more implementation candidates on top. Sapling treats stacks as first-class work, and its smartlog exposes the relationships among the commits instead of making the operator reconstruct them from an archaeology of branch names. Its absorb command can also take pending edits and, when their origin is unambiguous, move them into the earlier commit that introduced the relevant lines. (Sapling SCM)

That sounds like version-control nerdery until you watch an agent produce a correct insight in the wrong layer.

Suppose a subagent working on the implementation discovers that the RPC contract itself is missing a field. In an ordinary branch, it adds the field along with four hundred lines of unrelated code. Now the contract decision is trapped inside the implementation candidate. With a stack and something like absorb, that change can be moved down into the contract commit where it belongs, and every implementation above it can be restacked against the revised premise.

The history isn't being polished for aesthetic reasons. The search is being made editable.

This matters because failure is rarely monolithic. An agent can be wrong overall and still produce the best test, the cleanest schema, the right security observation, or a useful simplification. The branch-and-pull-request model asks a binary question: should we merge this thing or close it? That's the wrong question.

Imagine three agents working on scoped API credentials. The first produces a correct schema and a catastrophically naive authorization check. The second writes the right authorization logic but invents a migration that would strand every existing credential. The third never gets the feature working at all, but writes the regression test that proves the first two are broken.

There is no winning branch. The correct system is distributed across the failures.

A stack gives the work anatomy. The schema can survive without the authorization code above it. The regression test can be extracted from the failed attempt and placed beneath a new implementation. The dangerous migration can be isolated for explicit review instead of smuggled inside a giant diff. The mechanical generated code can live in its own layer, where nobody has to pretend it deserves the same attention as the permission model.

The agent should be free to generate slop. The system should be good at performing surgery on the slop afterward.

Preserve the saga, not the transcript

Human-authored pull requests usually present a polite fiction. The author appears to have understood the problem, selected a design, implemented it, and arrived at the final diff by something resembling a straight line.

Anyone who's written software knows this is bullshit, but it's socially useful bullshit. The dead ends are omitted. The wrong theory from Tuesday isn't preserved. The commit history is cleaned until the result looks intentional.

With AI, aggressively erasing the failed paths becomes a mistake, because the failures are part of the evidence used to judge the survivor.

Why was candidate A abandoned? Which test killed candidate B? Did candidate C fail because its implementation was wrong or because it exposed a mistaken contract? Did the final implementation actually resolve the original issue, or did the issue quietly mutate until the implementation could pass?

We don't need to pickle every shell command in amber. Nobody benefits from immortalizing the six times an agent reran the same failing test because it had already lost the output from the first attempt. But we do need durable lineage.

The issue should preserve the original intent. Searchable conversation history should preserve the reasoning and disagreement around it. Each workspace should produce a .handoff/ artifact that explains what it attempted, what it learned, what failed, which state is currently valuable, and what the next agent shouldn't waste its time repeating. The implementation bookmarks should preserve the candidate genealogy. The tests and automated reviews should preserve the evidence that killed or promoted each line of work.

That's what I mean by preserving the saga. Not a surveillance log of everything the model did, but the engineering history required to understand why this particular collection of parts was allowed to survive. The final review object should be beautiful, not necessarily because the code is beautiful, but because the evidence is presented with enough color and fidelity that somebody can reconstruct the experiment.

That solves one frontier model and the subagents working beneath it. It gives us a safe test cell: a capability-bounded environment, a sparse view of the repository, continuous recovery, branching hypotheses, and structured review.

Part 1 did not ask us to fire one engine. It asked us to fire ten thousand.

One test cell is not an engine shop

There are two distinct kinds of parallelism hiding inside the phrase "multi-agent development."

The first is intra-task parallelism: one frontier model decomposes one objective among several subagents. They share a parent context, a common goal, and an orchestrator responsible for synthesizing the results. This is the test cell we just built. The second is inter-task parallelism: many top-level agents working across an entire project. Different issues, different assumptions, different baselines, different timelines, overlapping files, and occasionally incompatible ideas about what the product even is.

The first needs autonomy; the second needs an operating system.

At ten, a hundred, or a thousand simultaneous agents, the issue tracker stops being a human backlog and becomes the shop's work-order system. An issue records the durable intent, priority, dependencies, known constraints, affected contracts, and expected evidence of completion. It may be opened by a human, a failed test, an automated review, a production trace, or another agent that discovered a problem outside its assigned scope.

The issue shouldn't contain the implementation. It should coordinate the search for one.

One issue may launch a single workspace for a straightforward repair. Another may launch ten workspaces deliberately exploring different designs. A third may produce a research-only attempt whose job is to map the affected system before anybody writes code. The point isn't that every issue deserves a swarm. The point is that the work-order system can express and coordinate the distinction.

At this scale, each workspace needs to be both isolated and synchronized.

Isolation means the agents don't share one mutable filesystem, one process tree, or one set of half-written changes. They can't step on one another merely because they happen to touch the same directory.

Synchronization means they don't disappear into private universes. Every workspace must know which repository state it began from, which contracts have changed since, which neighboring attempts now overlap with it, and whether its assumptions have gone stale. When a lower-level schema lands, the workspaces built on the old schema should be rebased, retested, restarted, or explicitly declared obsolete.

Cloud workspaces stop being a convenience here and become load-bearing. A CitC-style layer (the name comes from Google's "clients in the cloud") can give each workspace a sparse, current projection of the same underlying repository without requiring every agent to clone and maintain the entire world. The agent sees the files it needs through a mounted view, while the system retains knowledge of the global repository, the workspace baseline, and every other attempt operating against it.

The workspace stays separate enough to be destroyed. The code stays connected enough to remain real.

Conversation history and .handoff/ artifacts become more important here because agents, like contractors and certain vice presidents, leave. Their context windows fill. The parent model is replaced. The work gets paused and resumed by something else. A durable handoff should let the next agent understand the state of the attempt without reading every token produced by its predecessor.

At fleet scale, "progress" also needs to become explicit. Researching, implementing, testing, blocked on a contract, awaiting another stack, superseded, ready for integration: these aren't cosmetic labels. They let the scheduler decide where to send capacity and let the human understand the shop without opening a hundred chat transcripts.

A thousand isolated rooms are still capable of producing a thousand incompatible truths. Coordination alone is not enough.

We need selection.

Do not choose a winner; assemble one

Most multi-agent demonstrations treat parallelism as a tournament. Generate several answers, ask a judge to score them, and keep the winner.

That's better than taking the first answer, but it leaves most of the value on the floor.

Software candidates are not indivisible contestants. Go back to the three agents from the scoped-credentials issue. A tournament scores all three as losers: broken authorization, catastrophic migration, unfinished feature. But the correct schema is sitting in the first attempt, the right authorization invariant in the second, the only honest regression test in the third, and the best final system doesn't exist anywhere in the original candidate set.

It has to be assembled. Take the schema from the first agent, the authorization logic from the second, the test corpus from the third, and generate a fresh implementation against all three. The result is Captain Planet software engineering. By your powers combined, we may finally have a rocket that clears the tower.

Recombination at that granularity is what the earlier machinery is actually for: continuously recoverable drafts, implementation bookmarks, stacks, smartlog, absorb, and semantic analysis, all pointed at the ability to select at several resolutions. An entire workspace. One candidate bookmark. A commit from the middle of a stack. A logical hunk inside that commit. A semantic change extracted from an otherwise failed implementation.

Today, doing this across several branches is a small archaeological expedition. Find the right commit hash. Cherry-pick it. Discover it also contains an unrelated change. Split the commit. Resolve a conflict against a schema that moved yesterday. Copy the useful test out of a closed pull request. Ask the agent that wrote it what the test means, only to discover that session no longer exists.

In the engine shop, recombination has to be ordinary. The smartlog should expose the candidate tree and let the operator fork, move, rebase, hide, revive, compare, and combine parts directly. The version-control system should preserve where each piece came from. The review system should retain the evidence attached to it. The workspace layer should be able to materialize the proposed combination and run it as a new candidate.

This also changes what a diff is for.

The ordinary diff answers a textual question: which lines changed? At fleet scale, the important questions are often semantic. Which contracts changed? Did the permission surface widen? Did two candidates interpret the same enum differently? Did one add a state transition that another assumes is impossible? Did a dependency move across a boundary? Did an implementation quietly weaken a database constraint while adding more validation code above it?

Two candidates can modify entirely different files and still be in fundamental conflict. They can also modify the same lines for mechanically different but semantically equivalent reasons.

Textual conflicts are the easy ones.

The dangerous collisions are the ones that merge cleanly.

A serious agent-native system therefore needs richer diff and merge analysis: types, schemas, RPC definitions, permission graphs, state machines, dependency structure, tests, and runtime behavior. The goal isn't a model producing a prettier summary of the patch. The goal is understanding how the behavior of one candidate overlaps with, contradicts, or complements another.

Only then can we do what Part 1 requires: evaluate candidates against the actual boundaries of the system, rather than choosing the diff that looks most convincing.

The N1 problem returns

The rocket metaphor comes back to collect its debt.

Every candidate can look excellent in isolation. Every workspace can have green tests. Every component can satisfy the local contract it was shown. We can still assemble thirty brilliant engines into one vehicle that explodes because nobody tested the interactions.

The engine shop therefore needs more than a winner-selection loop. It needs an integration matrix.

Each candidate should be tested against the baseline from which it began, because that tells us whether it solved the problem it was actually assigned. It should also be tested against current main, because the world may have changed while it was working. Individual layers of a stack should be validated where that makes sense. Candidate combinations should be materialized into temporary composite workspaces and tested together before any human mistakes local success for system confidence.

We can't brute-force every possible combination. Ten independently variable candidates already create more combinations than anybody wants to pay for, and a thousand-agent shop would turn exhaustive integration into its own space program.

So the system has to use structure to decide what deserves pressure.

Go back to the credentials issue one more time. The schema and the authorization logic came from different agents and touch the same contract, so they get a composite workspace and run together before anyone considers promoting either. The migration rewrites the table the schema defines, so it gets exercised against the schema plus every implementation selected above it, against production-shaped data, which is exactly where it strands the existing credentials and dies cheaply (in a workspace) instead of expensively (in an incident). The regression test from the failed third attempt gets attached to the composite so the naive authorization check can never sneak back in. Nobody fired every combination. The contract structure told us which combinations were load-bearing.

That generalizes. Candidates that touch the same contract should be tested together. Changes that widen a permission boundary should be combined with the callers that depend on them. A schema migration should be exercised against every implementation selected above it. Semantic diff analysis should identify the dangerous edges: shared state, shared types, retries, transactions, security boundaries, lifecycle transitions, and the places where one candidate's premise became another candidate's hidden dependency.

This is the software equivalent of deciding which engine clusters need a full static fire rather than assuming thirty successful component tests add up to one successful first stage.

Thirty green CI badges can still make one red launch.

The integrated candidate should be treated as another attempt, not as the ceremonial merger of already-approved parts. Give it a workspace. Give it the same hard judges from Part 1. Run the tests, load, fault injection, security checks, and whatever partial oracles the system possesses. Preserve the resulting evidence. If the composite fails, return the failure to the candidate tree and let the next round of agents work from the crater.

This is why AI review belongs inside the loop, but should never be confused with the loop itself.

A review agent can inspect every change, identify suspicious surfaces, notice that a test was weakened, flag a widened permission, compare competing implementations, and tell the next worker where to look. It can turn a raw diff into a useful account of risk. It can create a new issue when it finds a problem outside the current task.

What it can't do is establish correctness merely by nodding at another model's work.

AI reviewing AI is another sensor on the stand. It is not physics.

The hard judgments from Part 1 come first: compiler, types, schemas, constraints, permissions, tests, resource limits. Model review interprets the evidence, finds gaps, and routes the next investigation. Human judgment remains where the meaning of the system changes or where the available evidence can't settle the question.

The point is not to eliminate human review.

The point is to stop wasting it on everything else.

Take your bitter-lesson pills, bro

At this point the meanest reply guy on the internet has an obvious response:

This is an absurd amount of machinery wrapped around temporarily bad models. Workspaces, candidate trees, bookmarks, stacks, semantic diffs, integration matrices: cope all the way down. Take your bitter-lesson pills, bro. In three years the model will write the right implementation on the first try and your engine shop will be landfill.

There's a real objection buried under the posting style.

Better models should produce fewer useless candidates, recognize bad approaches earlier, and internalize more of the search. We may need forty explicit attempts today and four in three years. Some of today's machinery will move behind the wall; some will disappear entirely. Any toolchain built around the precise failure rate of today's models deserves to become landfill. But that isn't what the Bitter Lesson says.

Rich Sutton's argument is that the methods which ultimately win are the general methods capable of turning increasing computation into better results, and he identifies two broad ways of doing that: learning and search. (Incomplete Ideas) The engine shop is the search half. Generate candidates. Apply pressure. Preserve useful discoveries. Reject failure. Recombine what survives. Repeat at greater scale.

So yes, I took the pills. Read the bottle. It says learning and search.

A future model may perform much more of that search internally and hand the operator one answer instead of forty visible candidates. Fine. The shop moved behind the wall. It didn't cease to exist. Somewhere, hypotheses were still generated, evaluated, rejected, and combined. One-shot perfection is not the Bitter Lesson. Scalable computation is.

And most of this machinery isn't compensation for the model being stupid. It's compensation for parallel work being structural.

Google didn't build an enormous shared repository, a common source of truth, and custom systems and workflows because tens of thousands of Google engineers were insufficiently intelligent. It built them because large numbers of capable people changing one shared system create coordination costs that intelligence alone does not dissolve. Meta didn't add mutation history, stacks, automatic restacking, sparse profiles, and absorb to Sapling because its engineers lacked taste. Those features exist because work moves across people and machines, changes underneath other work, and has to retain its ancestry while it does.

Nobody thinks Google's source infrastructure is cope for Googlers being too dumb to use Git.

Agents inherit all of those problems and add several more. Their memory is transient. Their output arrives at a much higher rate. They explore speculatively. They create partial successes inside otherwise failed attempts. They can execute commands without a human watching. Better models reduce the error rate inside each stream of work; they don't make concurrent streams stop overlapping, going stale, depending on one another, or disagreeing about the shape of the system.

The same is true of containment.

No amount of RL makes --yolo safe on your real machine.

That's not because the model must remain permanently stupid. Safety was never a personality trait of the worker. Prompt injection, poisoned dependencies, hostile inputs, inherited credentials, compromised tools, and accidental external side effects are properties of the world the worker operates inside. A smarter worker in a booby-trapped room is still in a booby-trapped room.

We don't give our best principal engineers root access to every system, every credential, every customer database, and every production environment merely because we trust their judgment. Least privilege is not an accommodation for incompetence. It's what allows competent people to make mistakes, encounter hostile systems, or have a bad day without converting one local action into a company-wide incident.

Competence is not containment.

There's also a deeper gap that model capability can't simply scale away. A conventional compiler receives a formal program. The consequential semantic decisions have already been encoded by the programmer in a language with defined rules. An AI coding system receives an incomplete expression of intent.

A better model can infer unstated intent more accurately, recognize ambiguity sooner, and ask better questions. What it can't do is verify its implementation against a decision that nobody has made, a business rule that exists only in somebody's head, or an unresolved disagreement among several humans who all think the prompt is perfectly clear.

If nobody has decided what "sharing a project with a team" means after a user leaves the company, no amount of reinforcement learning can prove that the generated behavior is correct. The model can choose an answer. It can't manufacture the missing authority to declare that answer the product.

Reliability increases as the consequential parts of intent move out of human heads and into durable forms: contracts, schemas, examples, policies, tests, state machines, and explicit decisions. That is not scaffolding around a weak model. It is the permanent work of deciding what the system means.

So the concession is real but narrow. Better models will reduce exploration width, hide more of the search, and may turn some of today's explicit bookmarks, candidate trees, and review surfaces into internal implementation details. The exact jj command, smartlog interface, or workspace shape is not a law of nature. But an autonomous development system will still need scope, recoverable state, provenance, coordination, stale-work detection, integration, and an external representation of intent. It will still need to contain the actions of capable workers and test the interactions among locally successful changes.

Better models change how many engines we need to fire. They do not abolish the stand, the black box, the shared work order, or the integrated static test.

The shop is permanent. The fixtures are not.

What the human should finally see

By the time a candidate reaches a person, the system should have done considerably more than run tests and generate a summary.

The review object should not be a thousand-line surprise. It should be a stack whose shape explains the work: contract, migration, tests, implementation, generated consequences, operational changes. The human should see the original issue and the current interpretation of it, the contract changes separated from their implementations, the candidate lineage, the important failed alternatives, the automated review findings, the isolated and integrated test results, and the reasons this particular stack was assembled from these particular pieces.

A reviewer should be able to inspect the permission change without reading generated client code. They should be able to approve the schema and reject the implementation above it. They should be able to replace one candidate with another while preserving the regression suite. They should know whether an implementation was selected because it was actually better or merely because it was the last agent still running when somebody got tired.

That is what the interactive smartlog is really for.

Sapling's smartlog already presents relevant commit history as a graph rather than a flat log, and its interactive version exposes commit relationships, bookmarks, pull-request state, stack operations, and direct manipulation such as drag-and-drop rebasing. (Sapling SCM) In an agent-native environment, that graph has to expand beyond commits. It should include issues, workspaces, conversations, agents, drafts, implementation bookmarks, stacks, checks, reviews, conflicts, and promotion state.

A pull-request queue is an inbox.

The engine shop needs a map.

The map should show that two workspaces are competing implementations of the same issue, that one shares a contract with a third, that a fourth was superseded but contains a unique test, and that the integration candidate currently failing in CI was assembled from all of them. The operator should be able to move through this graph, inspect the evidence, request another attempt, extract a useful part, or kill an entire line of exploration without reconstructing its history from seven browser tabs and three forgotten terminals.

The conversation is not the product surface; it's one stream of evidence attached to the work. The commit graph isn't the complete surface either; it describes the code lineage but not the agents, workspaces, intent, or test history around it. The real object is the evolving engineering search, and that is what the interface has to make visible.

Why we built it

Full disclosure: this is the system we've been building at Noumena.

We didn't begin with a grand theory that the world needed an "agent-native software-development control plane," because nobody should be allowed to say that many nouns in a row without being struck by lightning. We began by trying to use frontier agents to build a real system with a team of one. Anyone can spin up a fleet of agents. We just had no way to fall back when running them got ugly: no bigger team to soak up the babysitting and the duplicated work, and no comfortable story that the next model release would fix it (we build and evaluate models; we knew it wouldn't), and no appetite for renting a closed loop whose reasoning we weren't allowed to see.

The models could write code. That was not the thing that broke.

Everything around them broke.

Each additional agent brought another terminal, another checkout, another branch, another context, another permission queue, another set of test results, and another large plausible diff that somebody had to understand. Work was duplicated because one agent didn't know what another had discovered. Useful intermediate states vanished. Good tests were trapped inside bad implementations. A contract moved in one workspace while three others kept building against the old one. The human operator spent less time thinking about the system and more time moving messages among tools that had no idea they were participating in the same piece of work.

We had automated implementation and accidentally created a dispatcher job.

The architecture described here grew out of trying to escape that job: capability-bounded execution, sparse views of the repository, jj drafts that preserve every mutation, sl stacks that make the useful work legible, issues that coordinate intent, isolated cloud workspaces, searchable conversations and .handoff/ artifacts, semantic comparisons, and a smartlog that shows the shape of the shop.

That model is now explicit in Noumena Code: issues create scoped workspaces, agents produce drafts, and related changes are reviewed as stacks, with jj and Sapling-style workflows treated as native surfaces rather than awkward compatibility layers. (Noumena Code)

But Noumena is not the conclusion of the argument. It's evidence that the argument came from use rather than a whiteboard.

The broader conclusion is that the traditional development environment is built around the wrong scarce resource. It assumes code is difficult to produce and therefore organizes everything around helping one human author one coherent change. Once implementation becomes abundant, that entire center of gravity moves.

The first problem becomes safe autonomy: let the model operate at full speed inside a world whose boundaries you trust. Then memory: preserve every meaningful state without expecting the model to recognize it in advance. Then structure: turn parallel hypotheses into editable, reviewable stacks rather than a landfill of branches. Then coordination, so many such experiments don't drift, collide, or repeat one another forever. And finally synthesis: combine the best parts of several imperfect attempts, test the result under integrated pressure, and present the surviving work to a human with its evidence intact.

That is the engine shop.

Part 1 gave us the pressure vessel: a codebase with enough hard contracts and local oracles to make bad implementations fail mechanically. Part 2 gives us the blast walls, the black box, the test cells, and the machinery required to fire thousands of candidates without losing the useful wreckage or confusing component success with a working rocket.

Once those things exist, something subtle begins to happen to the status of the implementation itself. The durable intellectual work moves into the intent, the contracts, the candidate lineage, the tests, and the evidence explaining why the selected system survived. The code starts to look less like the precious original artifact and more like something emitted by a larger process.

Before code can become compiler output, the compiler needs somewhere safe to be wrong.

Part 3 is about what that does to the people who loved writing the code themselves.