A leather and brass driving harness hanging from a single iron hook against a dark wall under hard studio light.

Start With the Model. Harness What You Cannot Afford to Guess.

By Derek Neighbors on September 8, 2026

Claude offered to put itself in my build last week. I had asked it to fix a formatting bug on this site, a field that sometimes had quotes around it and sometimes did not. The first plan it wrote was to add a model call to the build step. Every build, forever, to strip quotes.

I said no and asked for the function. It wrote the function and the tests in one pass, faster than I could have typed the first line, and the model has not been in that build since. The model was never the problem. The build is a harness, and stripping quotes is not a rule I need reconsidered every morning.

That is the whole argument, and it is the opposite of the one most engineering teams are having right now. They are arguing model versus code one ticket at a time, slowly, with a lot of nervous energy about the bill. The faster teams stopped arguing. They start with the model, go as fast as the tool allows, and keep a short written list of the things the model does not get to decide on its own. That list is the harness. The rest of this piece is about how long the list should be and what goes on it.

What Stays in the Harness Is the Only Question Left

Michael Frendo, the CTO at New Relic, runs his engineering organization on one sentence I heard in an interview: if it can be solved deterministically, it should be, because the cost is lower and the answer can be promised. I have been turning that sentence over for a month, and I think it is half right, and the two halves are not equal.

The cost half is weak and getting weaker, and the promise half is the entire harness.

Deterministic means the same input produces the same output every time, and a test can prove it. A tax-rounding function is deterministic. A model call is not. It gives you a distribution of answers with a most likely one on top, and the shape of that distribution moves when the vendor ships a new version on a Tuesday. You cannot test a distribution. You can sample it on a schedule and notice when it moved, which is what an eval is, and that is a different thing from a promise.

So the routing question is not “can the model do it.” The answer to that is yes for almost anything that crosses a desk, and a question whose answer is always yes cannot help you decide. The routing question is “what do I have to promise about this answer, and to whom.” A promise is understanding in a form another person can rely on, which is why it outranks speed on the few paths where the two conflict. Every path where the answer is “nothing, and nobody” belongs to the model by default, and every path where the answer is “this exact number, to an auditor, next April” belongs in the harness.

Smart model, dumb harness. The model handles interpretation, unstructured input, and the rules that keep changing. The harness is the deterministic wrapper that owns what the model does not get to decide alone: what it can spend, who it is acting as, whether an action can run twice, what gets logged, and when a human has to look. The harness stays simple on purpose so it can be tested and promised, which is what lets the model stay as powerful and as fast as the tool allows.

Three Things That Set the Length of the List

Risk sets the gates. Governance, in the plain sense I mean here, is the set of places a change can be stopped before it is real, and risk decides how many of those places a path gets. The software development lifecycle has gates for a reason. A change to a function goes through a pull request, a review, a test run, and a deploy, and every one of those is a place a bad change can get caught. A prompt an end user edits has none of that. The change is live the moment they hit save. That is the trade, stated plainly, and it is a good trade on a lot of paths. The pricing estimate that finance redefines every quarter is a better fit for a prompt the owner edits than for a ticket that waits for a sprint, and the rounding on the invoice is not. The higher the risk, the more stages a change passes through before it is real, and on the highest-risk paths one of those stages is a person.

Volatility favors the model. Adding two numbers is never going to change, so it is a function and you will never think about it again. “Estimate” is an algorithm today, and next quarter someone wants shipping weighted differently, and the quarter after that they want a regional adjustment. Every one of those changes is a deploy if the logic is code and a sentence if the logic is a prompt. Whoever owns the prompt owns the eval that stands in for its test, and the person who gets to make the Tuesday edit owns the Wednesday result. The more often a rule changes, and the further the people who change it sit from the repo, the more the model earns the path. There is a counterweight, and I take it seriously: with agents, changing code got cheap too. The estimate function that used to be a sprint is twenty minutes and a pull request now. So the remaining advantage of model-driven logic is narrower than “it is easier to change.” It is that non-engineers can change it, and that some rules are too fuzzy to write down at all. Both are real, and neither is a reason to keep the model out.

Latency is the cost that still counts. The bill is a weak reason to avoid the model, and I want to say that clearly because it is the reason most teams reach for first. Models get smarter, which means fewer calls to get the same outcome. Then they get cheaper and faster without losing the smartness. Local inference is going to move both the price and the round trip in ways nobody is pricing yet. Token usage never goes down, and that is fine. Calls per outcome fall while what counts as an outcome grows, so the total rises and the per-outcome argument still holds. Hunting for the cheapest model is a waste of an engineer’s afternoon. What does not get cheaper on its own is a second-long call in a checkout flow that used to take a millisecond. That is a product decision, and it belongs in the harness conversation, not the budget one.

Put the three together and you get two axes that matter: how much you must promise, and how often the rule changes. Risk and stakes are how you size the first axis, not a third one. Stable and must be promised, like auth or tax rounding, is code, and it is code you write once with the model’s help. Stable and low stakes, like stripping quotes, is code because it is free and nobody wants to think about it again. Changes often and low stakes, like the estimator, is the model, and the owner drives the prompt. Changes often and must be promised is the interesting quadrant, and it is where most of the real product logic in a company lives. The model stays in the path there. The prompt gets treated like code: a fixed eval set that stands in for the test, and a review before a change goes live. That is a harness too, one built around a prompt.

The Leverage Point Is a Written List

The decision that sets everything downstream is the list: what the model does not get to decide on its own in this system, and who signed off on that. Which model, which prompt, and which vendor all matter less than that one page.

Most teams do not have one. They have a feeling, and the feeling shows up as an argument in every design review about whether this particular call should be a function. Write the list once and the arguments stop. Mine, for the software I build, is short: money, identity, idempotency, the audit log, rate limits, and anything a customer can quote back to me from a contract. Everything else, the model can have, and the model usually does.

The concept-tagging pipeline on this site is the version of this I actually run. Every post gets scanned for Greek terms, and the scan is a list: an italicized word that matches a known transliteration. When the scan finds a term that is not on the list, a model drafts the definition, the pronunciation, and the etymology for me to read. The list is the harness, and the reason is not cost. A list cannot be wrong about a word that is on the list, and the definitions are the fuzzy part where I want the smartest thing available doing the first draft. If the site were a billing system, the list would be longer. It is a blog. The list is one item.

Whether the model can even see your data is the prior constraint, and whether your process was ever real is what the agent shows you in week one. This piece assumes you have both. The question left is how long the list is.

The Harness Rule in Practice

Start with the model. On any new path, build it with the model in the loop first, in development, and get it working at the speed the tool allows. You will learn what the real rule is faster by watching a model handle fifty real inputs than by whiteboarding it.

Write the harness list before the path takes its first production action. On a money or identity path that means the list exists before the first real call, and the model-first build runs against test data until it does. Money, identity, idempotency, audit, rate limits, contract terms. Add what your risk demands and nothing your nerves demand. The engineer building the path writes the list and brings it to whoever owns the risk, whether or not anyone upstream asked for it, and the review belongs to that owner rather than to whoever is nervous about the bill.

For every path that stays with the model, name the promise. If the honest answer is “none,” ship it and let the owner drive the prompt. If the answer is a number someone will hold you to, the prompt gets an eval set and a review, the same as a code change would, and the model stays where it is.

Let the model write the harness. The parser, the validator, the idempotency check, and their tests are exactly what a frontier model produces well in one pass. The harness is deterministic even though the author was not. That is the trade you want, and it is the same one I made on the build step.

Check latency last, and check it in the request path only. A batch job does not care about an extra second, and a checkout flow does. If a path is latency-sensitive, that is a harness decision, and local inference is on the table before “replace it with a function” is.

Do not spend an afternoon on the bill. If the model curve genuinely eats the margin at next year’s volume, you will see it in the finance review, and the fix is deleting the calls on the harness list that never should have been model calls, not switching vendors. That is usually a short list too.

Big pull requests from agents already broke one old rule of thumb. This is the rule that replaces it: the size of the diff matters less than how much of it sits inside the harness.

What Changes When the List Exists

The arguments stop. Design reviews stop relitigating model versus code, because the answer is on the list or it is not, and if it is not, the model has the path. They stop because someone wrote the list, and until someone does, every one of those arguments is on the person who could have written it and did not.

Speed goes up, because the default is the fast tool and the exceptions are written down. Teams that argue every ticket move at the speed of the argument.

The promises get specific. The things you can put in a contract are the things on the list, and the things on the list have tests. The things off the list have evals and an owner, and everyone knows which is which.

On every path I have watched get a harness, the model’s hit rate went up, and that part surprises people. When the harness has already cleaned the input and narrowed the case, the model is handed a sharper problem.

And the list starts to change shape as the tools do. The next step after agents is groups of agents, then graphs, then loops that watch the data, see the trend move, and update their own prompts and their own code. When the rule changes, the system changes itself. Where I think this goes is that the harness becomes the list of what the loop cannot rewrite without a gate, and governance becomes an eval and a rollback instead of a pull request. That is a different article, and I am already writing it in my head. The list is how you get ready for it.

Final Thoughts

Start with the model. Go as fast as the tool allows. Then write down, in one place, the short list of things it does not get to decide on its own, and set the length of that list by what you have to promise, not by what the vendor charges.

Frendo is right that a promised answer needs a deterministic path and wrong that cost is the reason, and the difference matters, because teams that harness for cost build long lists and slow down while teams that harness for risk build short lists and ship. The list is the proof that someone understands the system well enough to say what it must never do alone, and everything not on it belongs to the model.

If you want a community of engineers and leaders who build fast with models and argue in public about what belongs in the harness, MasteryLab is where that argument happens every week.

FAQ

Should you use an AI model or regular code for a given task?

Start with the model. It is faster to build with, and a rule that changes often is easier to change in a prompt than in a deploy. Then ask how much you have to promise about the answer. Money, identity, audit trails, idempotency, and anything you signed a contract on go in the harness, meaning code with tests and gates. Everything else can stay with the model. The size of the harness is set by risk, not by the vendor’s price.

What is “smart model, dumb harness”?

The model handles interpretation, unstructured input, and the rules that keep changing. The harness is the deterministic wrapper around it that owns the things the model does not get to decide on its own: what it can spend, who it is acting as, whether an action can run twice, what gets logged, and when a human has to look. The harness stays simple on purpose so it can be tested and promised, which is what lets the model stay as powerful and as fast as the tool allows.

When does a rule belong in a prompt instead of code?

When it changes often and the stakes of a wrong answer are low enough that you can tolerate a bad week before anyone notices. A pricing estimate that finance redefines every quarter is a good prompt candidate. Tax rounding is not. If the rule changes often and the stakes are high, keep the model in the path but treat the prompt like code: an eval set that stands in for the test, and a review before a change goes live.

Is the cost of calling an AI model a good reason to use code instead?

Rarely. Models get smarter, which means fewer calls, and then they get cheaper and faster without losing the smartness. Local inference is going to change both cost and latency further. Hunting for the cheapest model is a waste of engineering time. The one cost that still counts is latency in a request path, where a second-long model call in a checkout flow is a product decision, not a budget one.

Practice Excellence Together

Ready to put these principles into practice? Join our Discord community for daily arete audits, peer accountability, and weekly challenges based on the concepts in this article.

Join the Excellence Community