You spend a quarter wiring an agent into the way your team already works. It clones the repository into a sandbox of its own, reads the conventions checked in next to the code, pulls in the history of the issue, and opens the pull request even on the runs where the model forgets to. Then your model vendor ships an SDK that does most of that out of the box, and it looks like you burned three months. You did not. The two things are the same system assembled from opposite ends, and the part you cannot redo later was never the code.

Every railway begins by choosing a gauge

A railway company starts with one decision that outlives everybody who makes it: how far apart to lay the rails. Lay your own gauge and the route goes exactly where your ore is, around the hill you care about, with sidings where your yards happen to be. Join the national gauge and rolling stock shows up that already fits, together with signalling and a timetable you did not have to invent, but the route runs where the network runs.

Building the internal platform is laying your own track. Each task thread gets an isolated sandbox that persists. The system prompt is assembled from the repository’s own instructions file plus whatever the issue or the chat thread already said. The toolset is curated by hand, which is a polite way of saying the action space is kept deliberately narrow. Sub-agents work in their own context. Middleware sitting outside the model handles errors, injects the comment that arrived mid-run, and opens the pull request if the agent finished without doing it.

Adopting the model-native harness is joining the gauge. The same primitives arrive standardized, the instructions file and skills and shell and patching, plus a manifest that declares where inputs are mounted and where output belongs, so the model meets the same layout in a prototype and in production. Snapshots live outside the container, so an expired sandbox is rehydrated instead of mourned.

What you own is what you maintain

Both routes arrive at an agent that works, and they charge for different things. Lay your own and every invariant you refuse to leave to a sentence of English is yours to build: the retry, the routing of a message that lands while a run is in flight, the pull request that has to exist at the end. That is real engineering, and it stays real every time a new model changes how the whole thing behaves. Join the gauge and those primitives are there on day one, but you live inside a layout somebody else maintains, and when it shifts under you, you shift.

Some bills are identical either way. Concurrent tasks sharing one filesystem will spoil each other’s work on either gauge. A toolset that grew because nobody ever removed a tool confuses the model on either gauge. And credentials belong in a vault or behind a proxy, never inside the sandbox executing what the model just wrote, because generated code is untrusted code and owning the track changes nothing about that.

One seam decides how permanent this is

There is a way to make the decision cost less, and it is not choosing correctly. Managed agent designs cut the thing in three: the brain, meaning the model and the harness around it; the hands, meaning sandboxes and tools behind one uniform call; and the session, an append-only log of events belonging to neither. The harness keeps no state of its own. It reads that log and appends to it, so when a harness process dies another wakes on the same session and carries on, and when a sandbox dies the model just receives a tool error and asks for a replacement.

Keep that seam and the harness is rolling stock, swappable, and expected to be swapped as models move. Collapse it, with session and harness and sandbox in one container, and a single crash takes the run and the memory of the run together. It is the same lesson as the loop that survives a reboot: what makes an agent dependable was never inside the model.

Choose the gauge once, on purpose. Everything running on it is rolling stock.