If you look at where models actually do useful work today, the strongest case is coding. Coding agents have outpaced almost every other category, not because the underlying models are dramatically better at writing code than at writing prose, but because the substrate around coding is unusually rich. The agent has a repo, a filesystem, a test runner, a compiler, a linter, a version control system, and an executable environment — all of which produce ground truth that the model can probe directly. The model doesn’t have to imagine whether its code works. It can run it.
This observation is enough to suggest a thesis: a coding agent’s quality is determined less by model cleverness and more by how well it inhabits the workspace.
A coding agent’s quality is determined less by model cleverness and more by how well it inhabits the workspace.
The harness is the product. The model is a component. The workspace primitives — git, the shell, the test runner, the sandbox — are what determines whether the agent can do anything real.
The harness, not the model, is the product
This sounds obvious in retrospect, but it took a while to stop being controversial. Through 2023 most coding agents were chat interfaces that emitted code blocks. The user copied the code, pasted it into their editor, ran it, found a problem, came back, pasted the error, got a corrected snippet, and repeated. The model was doing the thinking; the human was the runtime. This worked, sort of, for small tasks. It broke for anything serious — large refactors, debugging across files, working with unfamiliar dependencies — because the user couldn’t keep up with the loop of running, observing, and re-prompting.
The next generation of coding agents — Cursor, Claude Code, Aider, Continue, OpenHands, and several others — moved the workspace into the harness. The model no longer emitted code for a human to run. It ran the code itself, inside the harness, in an environment it could see and probe. The user moved from being the runtime to being the reviewer. This is the move that made coding agents genuinely useful.
Once you make this move, the design decisions stop being about prompts and start being about workspace primitives.
What can the agent see in the filesystem? Can it open arbitrary files, or only files within the project? Can it write outside the project? Can it execute shell commands? With what permissions? Can it use git? Can it commit? Can it push? Can it install packages? In what sandbox?
Each of these is an OS-level design decision. Each shapes what the agent can do and what it can break.
Workspace primitives are OS-level decisions
The agents that work best treat the workspace as a first-class environment to be designed, not a passive substrate to be reached into. Let me walk through the primitives that matter.
Filesystem affordances. Reading files is the most common agent action. The shape of the read tool matters enormously. Can the agent read a whole file, or just a range of lines? Are the lines numbered (so the model can refer to specific positions)? Are reads cached, or always fresh? Can the agent list directories? Can it see file sizes before deciding to read? These tradeoffs determine whether the agent burns through context reading too much, or fumbles around looking for files it can’t navigate to. The harnesses that ship excellent file affordances make agents look smart; the harnesses that ship rough ones make them look lost.
Editing primitives. Just as important as reading is editing. The cheap option is to have the agent regenerate whole files. The smart option is to have it produce focused edits — diffs, search-and-replace operations, line-level patches. The cost of producing a full file is high (more tokens, more chances to introduce regression). The cost of producing a clean edit is low. Harnesses that invested in good editing primitives — apply_diff, str_replace, line-range edits — see massively better behavior than harnesses that just have the model rewrite files in place.
Shell access. Letting the agent run shell commands is the single biggest capability multiplier in coding agent design. With a shell, the agent can run tests, install dependencies, search the codebase, query databases, hit local servers, do anything a developer can do. Without a shell, you’re hobbling the agent to whatever capabilities you’ve pre-defined. The shell is the universal escape hatch. The right design isn’t “no shell”; it’s “shell with appropriate sandboxing.”
Sandbox isolation. A coding agent can do real damage. It can rm -rf. It can leak credentials. It can install ransomware if its training data has any malicious patterns and it gets confused. The right place to defend against this isn’t a model instruction — it’s a sandbox. Run the agent’s code in a container, a VM, or a userspace sandbox like bubblewrap. Constrain the network. Strip credentials. The harness should be the thing that enforces these limits, not the agent itself, because the agent cannot be trusted to enforce limits on itself.
Test runners as verification loops. The most powerful feature of coding agents is the verification loop the test suite provides. The agent makes a change; it runs the tests; the tests pass or fail; the agent learns. This loop is the agent’s source of ground truth, and it’s the reason coding agents work better than most other agent types. If you’re building a coding agent and your harness doesn’t make test execution cheap and structured, you’re leaving most of the value on the table. Tests should run automatically after relevant edits, with output captured and re-fed to the model, with failure modes parsed and categorized.
Version control as memory. Git, used well, is a coding agent’s memory. The agent can branch before risky changes, commit incrementally, examine its own history, revert when things go wrong. Harnesses that treat git as a native primitive — making commits cheap, branches navigable, diffs inspectable — give agents a kind of stable temporal memory that pure context windows can’t provide. The agent’s recent work doesn’t have to fit in context; it can be reconstructed from the git log.
A modest model with a great workspace beats the reverse
The point of laying these out individually is to make a single argument: the bulk of coding agent quality lives in these primitives, not in the model. A modest model with an excellent workspace will outperform a great model with a poor workspace. This is empirically the case — you can take the same Claude or GPT model, drop it into Cursor versus drop it into a bare API, and watch its effective ability to ship working code change dramatically.
The post-model era is visible in coding first
There’s a broader implication. The model is becoming a commodity component in a system whose differentiation is the substrate around it. Coding agents make this exceptionally clear because the substrate is so rich and so directly tied to outcomes. Whoever owns the best workspace primitives owns the best coding agent. Whoever owns the best model is hosting a useful component, but no longer the differentiating one. This is the inversion at the heart of the post-model era, and it’s most visible in coding before it’s visible anywhere else.
The next post is about three specific systems that exemplify different ways of thinking about this — Claude Code, Pi, and OpenHands — and what their differences reveal about the design space.