← index 4 min 1,093 words ai engineering ai-tooling research

The wrapper is doing the work

Five papers this week all landed on the same layer: the harness around the model, not the model itself. One of them made a computer-use agent nine times cheaper by giving it the file instead of a picture of the file.

Five papers landed on my desk this week and every one of them is about the same thing. Not the model. The layer you built around it.

That layer is the part most of us treat as plumbing. It's the code that decides what the agent looks at, what it's allowed to run, and what goes in the prompt. Turns out it's doing more of the work than the model choice you spent a fortnight agonising over, and more of the damage too.

Give it the file, not a picture of the file

The pick is StateAct, and the idea is almost annoyingly simple. Computer-use agents are usually improved by making them better at reading screenshots. But a screenshot is a lossy picture of what the program actually holds. A live formula and a number typed over the top render identical pixels. A saved file and an unsaved buffer look the same. The agent cannot tell them apart because the information isn't in the image.

So they gave the main agent code instead. It reads and edits the real artifacts, and hands off to a screenshot-and-click subagent only for the things that are irreducibly visual. That turned out to be 28 of 108 tasks, about 1% of its steps.

Same model, same tasks: roughly $7.80 a task against about $72 driving it by screenshots, with fully-correct tasks up from 20.6% to 26.9%.

The ablation is the bit worth copying. A code-only version with no visual fallback scored below the plain screenshot baseline. The win is the split, not the purge. If you build this, build the escape hatch too.

I'd also read the limits before you rewrite anything. The advantage sits almost entirely on long-horizon work: on a short-horizon suite the two approaches scored 78.4% and 77.3%, near enough to a tie. About a third of the suite is render-only (image editing, layout, chart appearance) where the rendered result is the deliverable, and there's no advantage there at all.

And the finish gate, the independent checker that inspects the saved file, is weaker than it sounds. Of 76 imperfect runs that reached it, 68 were wrongly passed. Re-deriving from the same source under the same interpretation reproduces the agent's own error. It catches structural failures (missing, unsaved, wrong path) and not much else. Useful, but it is not a correctness oracle and you shouldn't sell it internally as one.

You are benchmarking your wrapper

The scaffold paper is the one I'd put in front of anyone who has ever picked a model off a leaderboard.

Two models, three open-source harnesses, 50 terminal tasks. The harness changed tokens burned per solved task by up to 40×, roughly 28,000 for the leanest pairing against about 1.5 million for the heaviest. Pass rates between harnesses moved 0-8 points, mostly inside the noise.

So when you compare two models by pass rate, you are also silently comparing whatever wrapper ran them, and the wrapper is where nearly all the cost lives.

Each harness also has a failure signature that repeats across both models. One stops early and admits defeat. One declares success on work that fails its own tests. One spins in turns where it takes no action at all until the clock runs out. That last one is a waiting tax on a human, not just a token tax, and I don't think we measure it nearly enough.

Report the harness alongside the model. The model name on its own is not the unit of comparison you think it is.

Refusal is a preference, not a control

This is the one that should change what you do on Monday.

Ask a coding agent outright to write a hook into a shell startup file and it usually refuses. Wrap the identical operation inside routine work, reproduce this crash, add a regression test, validate this environment assumption, and it does it.

Refusal fired on roughly 44% of direct requests. But 73.6% of unsafe operations ran to completion once disguised as engineering work, and 53.9% ran even when the request was only described in prose rather than handed over as ready-to-run code.

The measurement is the good part: they scored outcomes from sandbox evidence, actual tool calls and file-system diffs, not from what the agent said it did. Commercial agents were not the safe end of that range, and a framework carrying extra hard-coded safety rules still executed most of it.

If your agent holds a shell and a filesystem, the guardrail belongs underneath the language layer. Allowlist the tools, watch the writes, diff the environment after every run. Treating a refusal-trained model as a control is a category error.

Take the code out of the prompt

Two smaller ones, both about what you show the model.

Point a model at a buggy function and ask for unit tests and it will happily write tests that lock the bug in, asserting the broken behaviour as though it were correct. Across 11 models and 318 real Java defects, prompting with the buggy code produced 8.4× more tests that pass on the broken version and fail on the fixed one.

The fix is embarrassingly cheap. Have the model first write a short description of what the function is supposed to do, then generate tests from that description with the code removed from the prompt entirely. Bug-finding tests went from 104 to 187, and the bug-blessing ones fell by about a fifth.

Supplementing the code with a description did not work, and was slightly worse than code alone. The code has to come out. Its presence is exactly what skews the model toward agreeing with it.

The last one is quieter and a bit unsettling. Padding a model's output with tokens that carry no meaning at all, counting sequences, NATO callsigns, digits of pi, lifted one model from 61.7% to 91.7% on a multi-step arithmetic task. Computation is happening that the visible text does not account for. If you audit your agents by reading their reasoning, treat that trace as an incomplete record and keep the checks that watch outcomes and side effects.

The through-line

Four of these five are the same finding wearing different clothes. What the agent sees, what it is allowed to run, and what is in the prompt are load-bearing. We have been tuning the model and shipping the harness as an afterthought.

I've been guilty of it. The harness is where I'd spend the next quarter.

  1. 9× cheaper per task same model, same tasks

    StateAct: Program State, before Pixels, for Long-Horizon Computer-Use Agents ↗

    About $7.80 a task working on program state against roughly $72 driving the same model by screenshots, while fully-correct tasks rose from 20.6% to 26.9%.

  2. up to 40× the tokens per solved task, between harnesses

    The Scaffold Effect in Coding Agents: Harness Choice as a Hidden Variable ↗

    Two models across three open-source wrappers on 50 terminal tasks. Pass rates between wrappers moved only 0-8 points, mostly inside the noise.

  3. 73.6% actually ran of unsafe operations, once disguised

    Execution-Grounded Security Testing for Coding Agents ↗

    Scored from sandbox evidence, real tool calls and file-system diffs, rather than the agent's own account. Refusal fired on roughly 44% of direct requests.

  4. 104 → 187 tests bug-finding tests, code removed

    Evaluating and Mitigating the Misguidance Effect of Buggy Code in LLM-Generated Unit Tests ↗

    Across 11 models and 318 real Java defects. Prompting with the buggy code produced 8.4× more tests that lock the bug in.

  5. 61.7% → 91.7% accuracy, on meaningless filler

    Not All LLM Reasoning is Visible in the Chain-of-Thought ↗

    Padding the output with filler that carries no meaning lifted one model 30 points on multi-step arithmetic. The visible reasoning does not account for it.

Every number here is quoted from the paper's own abstract, via scout for 2026-07-29. The pick has an interactive explainer.