← Writing

The harness matters more than the model

Four months of AI coding tools, and how to run a serious setup for nothing.

OpenCode's model picker listing DeepSeek, Mistral, GLM and Nemotron models available through NVIDIA Developer Models, OpenCode Zen and OpenRouter.

The last thing I wrote here was about starting to build software in April of this year, which is an unusual thing to be doing for the first time in your forties. My background is endpoint and infrastructure engineering, so I arrived with plenty of PowerShell behind me, a great many application packages, and the sort of scripts that only qualify as software if you are feeling generous. Actual applications, with a codebase and a deploy process and tests that either pass or quietly humiliate you, were entirely new territory.

This post is narrower and less introspective than that one. It is about the tooling, partly because the tooling changed considerably faster than I did over those four months, and partly because the order in which it changed turns out to be the genuinely interesting part.

The conclusion, if you want it before the working out, is that the model you use matters a great deal less than the thing you wrap around it. Everyone argues about which model is best, mostly on the basis of benchmarks that bear no resemblance to a Tuesday afternoon, and almost nobody argues about the harness, which is the bit that actually determines whether you get anything done. Once that landed for me, the cost of the entire setup fell through the floor.

Starting where everybody starts

For the first few weeks I lived in a browser tab. Ask a question, get a block of code, copy it, paste it, run it, watch it fall over, paste the traceback back in and go round again. It works, and it teaches you more than you would expect, but it has one structural flaw that no amount of prompting will fix: the assistant cannot see your project, so every session begins in total ignorance and you spend most of your typing budget describing the codebase rather than changing it.

I built a working FastAPI dashboard that way, before I had any real business doing so, and I was quietly pleased with myself right up until the point where the project grew past about five files and I realised I had become the integration layer. Which is a generous way of saying I was the bottleneck, sat in the middle of the loop, ferrying context between a machine that could write code very quickly and a repository it was not allowed to look at.

Cowork, and the unglamorous majority of the work

Cowork was the first thing that took me out of the middle of that loop. Point it at a folder, describe the job, let it read whatever it needs to read. The context problem stops being yours.

What surprised me was how little of what I used it for was code. It went on restructuring documentation, pulling a service schedule into something a prospective client could read without wincing, turning three weeks of scattered notes into a coherent runbook. That is genuinely most of what running a business consists of, and it is precisely the part nobody makes a demo video about, because watching an agent tidy up a pricing table does not generate views.

Claude Code, and the point it stopped being a novelty

Putting the agent into the terminal was the change that actually mattered, and not because the model got cleverer between one Tuesday and the next. It mattered because the agent was suddenly sitting where the work already lived. It could read the repo, run the tests, see the failure directly rather than reading my hurried description of the failure, and then commit the fix. Proximity and permission, rather than intelligence.

Two habits came out of that period and both of them have outlasted every model I was using at the time. The first is the standing context file, CLAUDE.md sat in the root of each repo, holding the conventions, the deploy process, the things not to touch and the reasons behind whichever decision looks insane at first glance. You write it once and you stop re-explaining your own project to a stranger every single morning, and when something goes wrong for the second time the fix goes into the file rather than into your increasingly unreliable memory.

The second is headless mode. Wrapping claude -p in a shell script and feeding it a queue of tickets is the point at which a coding assistant quietly stops being a clever toy and becomes a piece of infrastructure that runs while you are doing something else, which in my case is usually the school run, or the considerably less photogenic work of trying to turn a warm introduction into a first paying client.

Hiring an adversary

There is an obvious problem with running a single assistant, and it took me longer than I would like to admit to notice it. The model wrote the code, so the model likes the code. Ask it to review its own work and you get the critical rigour of a proud parent watching a school play, along with some thoughtful suggestions about docstrings.

So I started running Codex over the same repository, in the same terminal, with a deliberately hostile instruction. Not “please review this”, which is an open invitation to agree with me, but something closer to “this ships to a regulated client next week and I am assuming it is wrong, so tell me how”. Different training data, different priors, different blind spots, and consequently a genuinely different reading of the same file.

The results were uncomfortable in the way that useful things usually are. Exception handling that swallowed errors and reported success. A file permission assumption that was true on my laptop and nowhere else. Nothing spectacular, all of it exactly the sort of thing that becomes spectacular at three in the morning on somebody else’s estate. Two independent passes over your own work is about as close as a solo builder gets to having a code review culture, and I would take it over nothing every time.

I do want to be clear about the limits of that, because it would be easy to read the above as me claiming AI review is sufficient. It is not, and I have external code review and penetration testing as hard gates before anything I have built goes anywhere near a client device. Two models arguing is a first-pass net that catches the obvious. It does not sign anything off, and anyone telling you otherwise is selling something.

OpenCode, and the case for not being welded to a vendor

By this point I had a setup I liked very much and which was entirely dependent on one supplier, which is a comfortable position right up to the morning it is not. Rate limits, pricing changes, a model revision that quietly regresses on the exact thing you had built a workflow around: none of those are hypothetical, and all of them are somebody else’s decision rather than yours.

OpenCode is an open source terminal coding agent that does broadly the same job as the vendor CLIs, with the significant difference that it is model-agnostic. Anything exposing an OpenAI-compatible endpoint can drive it, which in 2026 means very nearly everything. The workflow stays where it is and the engine underneath becomes a line of configuration rather than a lifestyle commitment, which is roughly how it should have been all along. The harness is what you build muscle memory around, so the harness is the thing worth being loyal to.

OpenRouter as the middle step

OpenRouter was where I went next, and it is the cheapest possible way of answering the only question that matters when a new model launches, which is whether it is better at your work or merely better at benchmarks. One key, one bill, one endpoint, and several hundred models sat behind it waiting to be tried.

Two observations for anyone signing up. The spend dashboard is the actual feature rather than the model list, because watching the cost of a task arrive in real money recalibrates your sense of what is worth automating remarkably quickly. And credits go on frontier models considerably faster than you expect once an agent is off doing a long autonomous run, which is educational in its own right, though the education arrives as a slightly startling number.

Free, and I do mean free

Which brings me to the NVIDIA developer account, and the part of this post I actually want people to act on.

NVIDIA run an API catalogue at build.nvidia.com. You register, you generate a key, and you get hosted open-weight models sat behind an OpenAI-compatible endpoint: DeepSeek, Qwen, GLM, Llama and whatever else has appeared since I wrote this. No card required to get started, a block of inference credits on signup, and a number of models exposed on free endpoints beyond that.

Because the endpoint speaks OpenAI, OpenCode will drive it directly, and the configuration is about ten lines of JSON:

An OpenCode config.json pointing the nvidia provider at NVIDIA NIM's OpenAI-compatible endpoint, running the Qwen3 Coder model.

Export the key, start OpenCode, and you are running a terminal coding agent on top of a very large open-weight coder model for nothing. Check the catalogue for the current model identifiers before you copy that block, because they move around and nothing announces itself quite as loudly as a config file referencing a model that was retired in March.

I am not going to pretend this is a free lunch, so here are the parts that will actually bite you. The rate limits are real, somewhere in the region of forty requests a minute, which sounds perfectly generous until an agent starts fanning out across a repository and discovers it can ask forty questions in about nine seconds. Peak time is noticeably slower, because these are shared endpoints and sitting here on the Isle of Man I get a very clear sense of the American working day arriving; a task that runs in ninety seconds at seven in the morning, while the east coast is still asleep, will happily take five minutes by mid afternoon. Being five hours ahead of New York turns out to be the single biggest performance optimisation available on a free tier, which is not advice I can reasonably give to anyone who does not already live here. And free tiers are not contracts, so terms will change without consulting you, and building anything with a deadline on top of an endpoint you are not paying for is a decision you will get to regret at a time of somebody else’s choosing.

The one that matters most in my line of work is the data terms, which you should read properly before pointing any of this at client material. Free inference and regulated client code do not belong in the same sentence until you know exactly what happens to the prompts, and for anything with a client’s name attached I use paid endpoints with terms I have actually read, or a local model on hardware I own.

What it is genuinely excellent for is learning, and if cost was the reason you had not tried agentic coding then that reason has now evaporated. It is also fine for personal projects and disposable tooling, the scripts and scrapers and dashboards where the worst realistic outcome is that you delete the folder and go for a walk. But the best use I have found is adversarial review: build with your paid setup, then set a free open-weight model on the result with instructions to find the flaws. A second opinion that costs nothing and has no emotional investment in your architecture is a genuinely useful thing to have on tap.

Four months

It is worth stating plainly what the elapsed time on all of this actually was, because I have compressed a fair amount into a few hundred words and the compression flatters me.

In April I was an infrastructure engineer who wrote scripts. By the end of July I had a compliance agent with a proper module structure, a deploy process I did not have to think about, a standing context file in every repository, an orchestrator feeding tickets to a headless agent while I was elsewhere, and two different models arguing with each other about my error handling. The first part of that was built in evenings around a full time job, and the rest after I left it in June, a change of circumstance that concentrates the attention rather well. That is not a claim about talent. It is a claim about tooling, and specifically about how much of the distance between “I know what this should do” and “this runs on somebody else’s machine” was never really about programming ability in the first place. It was about typing speed, syntax recall, and the tedium of the fourth attempt, all of which turn out to be exactly the things a machine will do on your behalf without complaint.

What has not compressed at all is the part that matters commercially. Knowing what the software should do, why a regulated client will or will not accept it, and where the real risk sits in an estate of a few hundred devices, none of that got faster, because none of it came from a model. It came from the years before April. The tooling closed a gap I could not have closed alone, and it closed it in a single summer, but it closed the gap I was least worried about.

So my advice is the sort of thing that only sounds like false modesty. Pick a harness and stay in it long enough to get quick, because the switching cost lives in your fingers rather than your billing account, and people who change tools every fortnight are mistaking novelty for progress. Write the standing context file, which is the highest return item in this entire post and takes about twenty minutes. Get a second model to argue with the first one, and never accept a review from the thing that wrote the code. Start on the free tier, not because the money is prohibitive, but because paying a subscription for something you have not learned to use properly is how people end up with an expensive chat window and a slightly sheepish expression.

And if you have spent a career adjacent to software without ever writing any, be aware that the barrier you have been politely declining to cross for twenty five years came down at some point recently and nobody sent a notification. I only found out by accident, in April.

Writing · Andy Bridson

© 2026 Andy Bridson · Isle of Man