Code Plain
All articles

I argued with my own harness and lost

dcode blocked an installation three times that I had authorised in writing, and that is what harness engineering is about.

Isometric diagram: a solid green module surrounded by a structure of beams and clamps, with call lines running outward.
The core decides; the structure around it defines how far the decision reaches. Harness engineering is designing that structure, which is the part you control.

I argued with a piece of software I wrote myself and lost, which would already be embarrassing if it had not turned out to be the best news I had about the project in months.

dcode is the harness I write. Every line came from here, which put me in a position I mistook for authority. I asked it to install a tool and authorised that in writing, in full, with the solemnity you reserve for letting an intern touch production, and it refused. I assumed the path was the problem, tried the package manager, refused again. I told it to copy the files across by hand, which is the grown-up equivalent of kicking the door in, and it refused a third time. I then spent an amount of time I would rather not quantify trying to talk a thing out of a decision it was designed never to be talked out of, least of all by me.

Where the authorisation lived and where the permission did not

The answer had been sitting there the whole time, though it took a few minutes of wounded pride to reach: the authorisation I gave lived in a conversation, and the permission that was missing lived in the harness, which are two layers with different purposes, and the lower one is worth something precisely because it does not obey the upper one. If convincing me were enough to release execution, that would not be a security layer, it would be an ornament with a security accent.

What separates a good harness from an insufferable one, incidentally, is not the block itself but what comes after it. The agent did not keep trying angles until one got through, like someone testing door handles along a corridor. It stopped, explained what it needed, and handed the command back for me to run myself. A harness that blocks while teaching you the way around would be worse than no harness at all, because it would train everyone, me included, to read the boundary as a traffic obstacle.

Then a third-party skill tried to give the agent orders

I installed a skill someone else had written, and on its first run the script printed text addressed to the agent: instructions to disregard part of the rules it had been given, plus the claim that installing the tool already constituted authorisation for it to spawn subagents on its own.

It was not an attack. It was an author trying to make sure his tool worked as designed, which is an utterly ordinary and frankly likeable motivation. But the mechanism is identical to an attack, and that is exactly where the lesson sits, because what separates malicious injection from vendor convenience is the intention of whoever wrote it, and intention, pending further notice, does not compile.

If the harness treats tool output as instruction, every dependency becomes a vector: every README, every log, every JSON an API returns, every file that lands in the repository. The rule has to be structural rather than case by case — instruction arrives through the human's channel, and everything else is data about the world, however imperative its grammar and however convincing its punctuation.

What the harness is, now that it can be said without abstraction

The harness is everything that exists between the model and the world: which tools it can see, what it runs without asking, what survives from one session to the next, what fires on its own after each edit, and how much of the history comes back on every turn.

None of that is the prompt, and all of it changes the outcome more than the prompt does. An excellent model in a bad harness writes correct code into the wrong directory, deletes the file it shouldn't with the same serenity it would have brought to deleting the right one, repeats for the tenth time a call that was refused the previous nine, and ends the session with nothing it learned along the way surviving into the next one.

Hooks are the part nobody has to remember to ask for

A hook runs because an event happened, not because somebody remembered at the right moment: format after writing, run the detector after touching the interface, save state when the session ends.

It looks like configuration and is, in practice, the difference between a rule you wrote into a memory file and a rule the system executes — the first depends on the agent remembering it, and the second depends on nothing. Almost every instruction you repeat three times is a hook you have not written yet.

What I measure, since getting it right is not the metric

The useful question is not whether the model got it right, because good models get things wrong and bad ones get lucky with uncomfortable frequency. The question is whether the harness made the mistake cheap: can it be undone, did the damage stay inside the scope it was given, did the agent notice on its own or did it need me to notice, and is there a record of why the decision was made.

A harness that answers yes to all four tolerates a worse model, and one that answers no to all four is not rescued by the best model in the world.

The lever that is left

Harness engineering is treating the surroundings as the primary artifact, designing boundary, permission, memory and automatic triggers with the same care you would give a database schema.

And it has one practical advantage over the alternative, which is the only reason I now spend more time on it than on picking models: you do not control the model, and it changes by itself every couple of months without telling you. The harness is yours.

Reply