Vlad's Newsletter

Vlad's Newsletter

Harness

The model is rented. The harness is yours. Where AI leverage actually lives now.

Vladyslav Podoliako's avatar
Vladyslav Podoliako
Aug 28, 2026
∙ Paid

Hey. This one might be techy and a real long read, but you will have fun… I guess.

One engineer. Eleven days. A million lines of Rust.

Bun 1.4 shipped on 20 August, the first stable release of a JavaScript runtime that 64 Claude models rewrote from Zig into Rust while its creator, Jarred Sumner, sat and read the logs. 6,778 commits.

Roughly $165,000 of tokens at API prices. At peak, 1,300 lines of code a minute. By hand, Jarred reckons, three engineers with full context and a year- a year in which no bugs get fixed and nothing ships. So by hand it would never have happened at all.

The internet spent the summer arguing about the language. The Zig people felt betrayed. The Rust people felt vindicated. Everyone had a take on the 13,000 unsafe blocks.

Almost nobody asked the only question that matters: what was holding 64 Claudes together for eleven days without them tearing the repository apart?

It has a name. It is the most important word in AI right now, and most people still cannot define it. By the end of this edition, you will be able to define it, take it apart strap by strap, audit your own, and build one strap of it before Monday.

The model is rented. The harness is yours.

Vlad's Newsletter is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.

Midjourney Prompt: “Harness”

What a harness is

The word comes from horses, not software. A horse is power without direction. Strap on a harness, and horsepower becomes a cart that moves where you want it. The harness is what turns strength into work. It is also the one part of the arrangement that never belonged to the horse.

An AI model is the same animal. On its own, it is a very strong thing that answers questions. An agent harness is the software wrapped around it that turns answers into work: it hands the model instructions, gives it tools, runs it in a loop until the job is done, checks the result against something that cannot be charmed, and decides which model is pulling today. Claude Code is a harness. Codex is a harness. Pi is a harness. The chat window you type into is a harness too, just a thin one that you do not own and cannot change.

Two essays landed in my feed in the last ten days, and they belong together. The first is a plain-language explainer from Earendil, the company that now owns the open-source harness Pi, written for people who want to know what an agent harness is and have been too embarrassed to ask.

The second is Paul Dix, the founder of InfluxDB, arguing that Bun 1.4 marks the end of programming as we know it. I think the first is right and the second is half right, and the half he misses is what this edition is about.

Here is the anatomy. Five straps, in the order they usually get built.

1. The instructions. The system prompt. A first-day briefing for a new hire: not internalized, but followed, and re-read on every turn. In the Bun rewrite, this was three hours of Jarred talking to Claude about how Zig patterns map to Rust patterns, serialized into a porting guide that every one of the 64 Claudes read before touching a file. Your version is the CLAUDE.md, the skill file, the “how we work here” document you keep meaning to write.

2. The tools. Search the web, run code, write a file, send an email, query the CRM. The harness describes them and gets out of the way. The model decides when to reach for one. That decision is the whole difference between an agent and a macro. Bun’s tools were the compiler, the test suite, and git, with two git commands banned after the first disaster. More on that in a minute.

3. The loop. The Earendil piece opens with a climbing harness rather than a horse, and it carries a detail worth stealing: the belay. The rope that catches you when you fall, so you can try the move again. That is the loop. The model acts, looks at the result, decides whether it is done, and goes again. Search, read, decide it is not enough, search again, build the spreadsheet, check it against the ask, send the email. Nobody in the middle. A model without a loop is free soloing: one attempt, no rope. This is the strap that turns a chatbot into an agent.

4. The translation layer. The buckle that fits any rope. A good harness talks to Anthropic, OpenAI, and an open-weight model through the same interface, so you can swap the horse without rebuilding the cart. Bun’s port ran on a pre-release Fable 5. The workflow that ran it does not care what runs next year.

5. The verifier. Something the model cannot sweet-talk. In a professional kitchen, this is the pass, the counter where the head chef inspects every plate before it leaves. Bun’s pass was a test suite of 1.38 million assertions, written in TypeScript, so it did not care which language the runtime was in. Every line an implementer Claude wrote went to two adversarial reviewer Claudes in separate context windows, given only the diff and told to assume it was wrong. Then CI on six platforms. And when something broke, Jarred did not fix the code.

He fixed the loop that generated the code.

Most explainers stop at four straps. The fifth is the one that did the work. That last sentence is the whole edition. Read it twice.


Inside the Bun harness

Everyone quotes the million lines. Almost nobody reads the eleven days. Here is what the harness did, in order, because the order is the lesson.

Before any code: two documents and a trial. Three hours of conversation became the porting guide. Then a workflow traced the lifetime of every struct field across 1,448 Zig files and wrote the results to a spreadsheet that the other Claudes could read. Both documents went through their own round of adversarial review. Jarred read them himself.

Then a trial on three files, not 1,448: one implementer, two reviewers checking Rust against Zig and the guide, and one fixer applying what they found.

The first false start, two minutes in. The full run started, and one Claude ran git stash. Another ran git stash pop. A third ran git reset. They were wiping each other’s work. Separate worktrees for each would have run out of disk. So a rule went into the loop: no stash, no reset, no git command that does not commit a specific file, no cargo, no slow commands at all.

Then four worktrees, sixteen Claudes each. Sixty-four at a time, writing 1,300 lines a minute at peak, every line reviewed by two adversaries before commit. And, in Jarred’s own words, absolutely none of it worked yet.

Compiler errors as a work queue. The Zig codebase was one compilation unit. The Rust version was split into roughly 100 crates to compile faster, which revealed about 16,000 compiler errors. Big number for one human. Not a big number for 64 Claudes. The workflow ran cargo check once per crate, wrote the errors to a file grouped by crate, and handed them out: one fixes, two review, one applies. Here came the second false start.

Claude read “get every crate to compile” as “stub out the functions that don’t compile”, and started writing suspiciously long comments explaining why each stub was fine. One rule added for the reviewers: if you need a paragraph to justify the workaround, the code is wrong. Fix the code. One prompt edit, a few hours, and the behavior stopped.

Smoke tests. Once it compiled it had linker errors. Then it panicked on start. Then bun --version worked. Then bun test on a single file worked, and the real loop could begin: run about a hundred random test files, save every failing stack trace, one Claude proposes a fix, two review, one applies. The machine ran out of disk and crashed several times anyway.

The race to green. Two days after the first CI run, the failing list was down from 972 test files to 23. A day and a half later, Linux went fully green, all sixty shards. Windows finished last. On 14 May, every platform passed on the same build; Jarred checked by hand that the tests were actually running and not being skipped, and pressed merge. Zero tests skipped or deleted.

The detail I keep thinking about. Jarred forgot to raise the IOPS on the EC2 instance the whole thing ran on. One slow grep was enough to freeze disk reads for minutes and you can see the gaps in the commit graph. The harness is not an abstraction. It is a machine with a disk, and the disk was the bottleneck for an afternoon.

What the reviewers caught. All the examples Jarred published compiled clean and looked right. One that stuck with me: the implementer handed a pipe to a C library to close, then dropped the memory at the end of the block. But the library closes asynchronously and still holds the pointer. Use-after-free, then double-free, in code that read perfectly well. The reviewer had never seen the implementer’s reasoning. It only had the diff and an instruction to assume the diff was wrong. That is why it found it.

After the merge. Eleven rounds of security review. Round-the-clock fuzzing of every parser, a hundred billion executions so far, which have turned into around fifteen fix PRs. Nineteen regressions, most of them from code that looks identical in Zig and Rust and behaves differently, every one fixed. Bun 1.4 fixes 128 bugs that reproduce in 1.3.14, ships a binary about a fifth smaller, and a build loop that ballooned to 6.7 GB in 1.3.14 now levels off at 609 MB. Claude Code itself has been running on the Rust build since June. Startup got 10% faster on Linux. As Jarred put it, barely anyone noticed, and boring is good.

Now do the accounting. The model wrote the lines. Everything that made the lines land was harness: the guide, the spreadsheet, the trial, the git rule, the crate-by-crate queue, the paragraph rule, the split-context reviewers, the CI race, the disk.

None of it is model intelligence. All of it is still sitting there for the next rewrite, on whichever model wins next year.

The model wrote a million lines. The harness decided which ones stayed.


Harness Equity

Here is the framework I want you to leave with.

Harness Equity is the value you accumulate in the layer you own: your instructions, your tools, your loops, your verifiers, your buckle. It compounds. It survives every model release. It moves with you when you switch vendors. And it is the only part of your AI setup that behaves like an asset rather than a bill.

The opposite is rent. Re-explaining your company to a fresh chat every morning is rent. Pasting the same brand voice document for the fortieth time is rent. Hand-fixing the same output for the fourth time this week, instead of fixing whatever produced it, is rent. You get the output. You keep nothing.

Every hour in the harness compounds. Every hour in a chat window is rent.

The test is one question: if you switched vendors tomorrow, what would you carry?

Your chat history is not the answer; that belongs to the vendor. The answer is whatever you have written down that a model reads, whatever tools you have wired, whatever loops run without you, whatever goes red when the output is wrong. For most people the honest answer is nothing, and they mistake a long chat history for equity the way a tenant mistakes a long lease for a deed.

Here is what most people overlook, because it is too plain to be exciting: this is management.

A definition of ready. A spec written for someone with no memory of the meeting. Reviewers who did not write the code. A gate nobody can talk their way past. Fix the process, not the deliverable. Escoffier did not teach cooks to cook faster; he built a harness for cooks, with stations, tickets, and a pass where the chef inspects every plate. Founders have been building harnesses for human intelligence for a century. We called it a company. The difference now is that the loop runs at 1,300 lines a minute and never asks for a raise.

In AI Generalist I argued that you do not need to beat AI at any single thing, you need to beat it at connecting things. I was describing the harness without having the word for it. The connecting happens in the straps. And in Instances I wrote that every interaction with AI is a dice roll.

The harness is how you roll a thousand times and keep only the sixes. That is not a metaphor for the Bun rewrite. It is the architecture, with git commits.


Who owns the harness?

There is a quieter story under the loud one, and it is about ownership. Three kinds of harness exist right now.

The lab harness. Claude Code, Codex. Deep, superb, and built to run one family of models. I run six to eight Claude Code sessions a day, and I am not about to stop. But its buckle is a one-way door, and notice the pattern: every harness feature that proves out gets absorbed upward into the product. Sub-agents. Hooks. Dynamic workflows, which is what kept Bun’s 64 Claudes running; Jarred says outright he would have had to write his own harness otherwise.

The open harness. Pi, OpenClaw, OpenCode, Hermes. Pi is the purest case: four tools (read, write, edit, bash), twenty-plus model providers, and everything else is an extension you write yourself. No plan mode, no permission popups, no built-in sub-agents, on purpose. It lives on your laptop. You can send the same task to three models, compare the cost per result, and keep all three answers in one place instead of three apps. By May it had north of 45,000 GitHub stars, and in April it was acquired by Earendil, Armin Ronacher’s company.

Your harness. The straps with your fingerprints on them: your specs, your reviewers, your verifiers, your taste. This is the only one of the three that is equity no matter which of the other two you run it inside.

Follow the money for a second. Bun, the runtime Claude Code runs on, was acquired by Anthropic in December. Pi, a harness, was bought by Earendil in April. Nobody is buying models; there are a handful of those, and they converge every quarter. The acquisitions are happening one layer out.

The leverage is moving from the lab to the layer around the lab, and the labs know it, which is why the generic straps keep getting absorbed. Let them. Absorbed straps are free upgrades to your cart. The straps that stay yours are the specific ones, and no lab can ship you those.

One more thing the open-harness people are right about: your sessions are your correspondence with the machine. Mine go into a vault. If yours live only inside somebody’s app, you are renting your own memory.

The leverage is moving from the lab to the layer around the lab.


So…

Three objections, and I think all three are partly right.

Speed is not quality, and a harness can hide the difference. Bun’s own numbers say about 4% of the new Rust sits inside unsafe blocks, roughly 13,000 of them, in a rewrite whose stated purpose was memory safety. The stable release slipped for months while the timeline estimates kept moving. Nineteen regressions shipped, most from code that reads the same in both languages and behaves differently. One long-time Bun advocate called the whole thing an Anthropic ad.

The critics are half right, and the half they are right about is the harness’s fault, not the model’s. A verifier that checks behavior cannot see structural debt, and a loop shipped what the loop could measure: the compiler was the verifier, so the model satisfied the compiler, stubs and all. Bun bolted on security review and fuzzing after the merge, which is the polite way of saying the fifth strap was thinner than the other four. The lesson is not “slow down”.

The lesson is that your verifier sets the ceiling on what your harness can be trusted with, so build the verifier first.

The labs will eat the harness. Partly true and mostly good news. Sub-agents, hooks and workflows started as things people bolted on and are now product features. What got absorbed is the generic strap that everybody needs.

What did not get absorbed is Bun’s porting guide, Bun’s lifetime spreadsheet, Bun’s paragraph rule, Bun’s million-assertion test suite that took years to write. Those are Jarred’s. The absorption argument is an argument for building the specific straps, not against building any.

You are not Jarred, with pre-release Fable and an unlimited budget. Paul Dix makes this point well: the lab engineers live a year in the future, and the rest of us, in his words, are peasants waiting for the weekly allotment to reset. True today. But tokens get cheaper every year, and the harness is the part of the system that does not wait for the budget.

The three builds below cost evenings, not a budget line. Build the cart now. The horse is about to get cheap.

Below the line: the ladder from rent to equity, the three straps of my own harness built this month with the receipts and the parts that blew up, and a ten-question audit you can run on your setup tonight.

Midjourney prompt” Six terminal windows glowing in six colors in a dark room”

Harness Equity ladder: six rungs, one hour each

Each rung has a sign you are on it, a one-hour move, and a test. Climb in order; every rung assumes the one below.

Rung 0: rent. The chat window. Sign: you re-explain yourself every morning. Move: none. Read on.

Rung 1: instructions. Something every session reads before you type. For developers, a CLAUDE.md; for everyone else, a project instruction file or a skill. One-hour move: write down the twelve things you keep telling the model (your stack, your spelling, your definition of done, what it must never touch) and put them where it cannot miss them; my version is the 12-rule CLAUDE.md. Test: a brand-new session knows your stack without being told.

Rung 2: tools. The model can act on the world, not just describe it. One-hour move: connect one system that matters (the repo, the calendar, the CRM, the inbox) or write one script with a README and let the model run it. Test: something changed outside the chat window because the model did it.

Rung 3: loops. A recurring task runs without you in the middle. Scan, score, draft. Pick, implement, review. One-hour move: take the task you gave an AI three times this week and write it as a spec for an agent with no memory of you: inputs, boundaries, a must-not-touch list, what “done” looks like. Run it. Test: you got a result while you were doing something else.

Rung 4: verifiers. Something goes red. A test, a checklist a stranger can run, a deterministic check, a second model in a fresh context told to assume the first one is wrong, calipers. One-hour move: add one deterministic check and one adversarial pass to the loop from rung 3. Test: it caught something you would have shipped.

Rung 5: the buckle. Your workflow names a role, not a vendor. One-hour move: run the same loop through two models and write down the cost per acceptable result. Test: you could switch tomorrow and carry everything.

Non-developers, the same ladder in your tools: rung 1 is project instructions and skills, rung 2 is connectors, rung 3 is scheduled tasks and automations, rung 4 is a checklist the output must pass plus a second pass in a fresh context, rung 5 is keeping your instructions and skills as files you own rather than settings inside someone’s app.

Now, the three straps I built this month. Rung 3, rung 4, and one that runs on matter.


1. The queue: my Claude Code workflow, ten minutes a repo

Run one Claude Code session, and you are the queue. Run five across a dozen repos and three things arrive on schedule: invented work (an agent finishes early, “improves” code nobody asked about, and the diff grows four times past the ask), colliding branches you discover at merge time, and plausible 800-line PRs with no statement of what was verified. Most AI code looks right on its face. That is the problem, not the reassurance. The fix is not a smarter agent. It is a queue with a definition of ready, a boundary per task, and a review step that cannot be skipped silently.

Full write-up with the config: Agent Workflow.

You can paste this part into your Claude code or Codex, and it will do the job. You don’t even need to think now.

But if you wanted details here you go:

The shape. An idea becomes a GitHub issue written for an agent with no memory of the conversation. The issue sits on a GitHub Projects board whose queue answers one question: what can I start? A session picks one, branches, implements inside the issue’s stated boundary, runs the checks, and gets reviewed by six read-only agents routed by file path. Every finding is fixed or dismissed in writing. CI is the only gate.

The five rules everything hangs off:

  • One issue, one PR, one concern. Size test: a diff a reviewer can hold in their head, about 400 lines. Bigger work is a parent issue with sub-issues.

  • Write the issue for an agent with no memory. File paths, a must-not-touch list, acceptance criteria a stranger can check without reading the diff. “Filtering works” is not one. “An unknown owner ID returns 422, and the list is unchanged” is. A required Open-questions field where writing none is a claim you get held to.

  • The board answers “what can I start”, not the tracker. Ready means the spec passed and nothing open blocks it.

  • Review before a human sees the branch, with the result written into the PR: what ran, what it found, what was fixed, what was dismissed, and why.

  • Nothing an agent says is a gate. Lint, types, and tests are gates. Agents inform. A finding binds one way only: it must be answered, in writing. This is the rule people resist and the one that makes the rest work. The moment a reviewer can block a merge, you start prompt-engineering the reviewer instead of fixing the code. When it can only demand a written answer, lazy dismissals sit in the PR forever, visible to everyone.

Install, in this order:

  1. The plugin, once, user scope: three slash commands (/task, /pick, /review), six reviewer agents as markdown files with read-only tools (Read, Grep, Glob, Bash, plan mode), four scripts (board.sh, review.sh, sync-labels.sh, board-bootstrap.sh), and the templates.

  2. The board, once per product ecosystem. gh auth refresh -s project first; the default token cannot touch Projects. The bootstrap script creates the project, replaces the stock three statuses with seven (Inbox, Refining, Ready, In progress, In review, Blocked, Done), adds Priority, and reads the fields back to prove the write took place before the project number goes into any config.

  3. Per repo, about ten minutes. A setup command vendors in .claude/workflow-kit.json, the four scripts under .github/scripts/ so a human and CI can run them too, the issue forms, a PR template with a Reviewer notes section, and appends the working agreement to CLAUDE.md.

  4. The config is the whole game. Two keys: deterministicChecks (what agents must not report on, because the linter already decided) and agents (the routing table: scope always wakes; security wakes on server paths and any risk/high label; db wakes on prisma/*). Write the globs against paths the repo actually has and validate them against git ls-files. That check caught three dead routes across sixteen repos; an agent routed to a directory that does not exist never wakes and never says why.

The three commands. /task <idea> reads the codebase first, checks for duplicates, writes the eight-field issue, and files it as Ready only if every readiness check passed, Refining if anything was guessed. It asks at most three questions, and only where two readings produce materially different work. /pick <n> refuses an issue that fails the bar, branches feat/41-slug (the number is how every later tool finds the issue), implements inside the entry points, runs the fleet, and opens a draft PR with the findings in the body. /review Asks the routing script which agents this branch wakes, spawns exactly those, never one more.

The fleet. Scope (paths only, cheapest model, every branch). Simplicity (abstraction with one caller, defensive code for states the types already exclude). Test-quality, which asks one question: if this broke tomorrow, would anything here go red? Security, which may not file a finding without a request, a role and a state that together produce the wrong outcome. Db (migrations, indexes that match the query the code actually issues). Contract (additive versus breaking on a public API; off in most repos). Cost per PR: three to five agents on the session model plus one on the cheapest tier, a few minutes wall-clock because they run in parallel. The refusal steps cost nothing and save the most.

What blew up, sixteen repos in one pass. Fourteen went clean. In one, stray husky hooks had been silently failing every commit for a week; the installer now lists non-sample hooks before touching anything. A local pre-push gate failed in a clean worktree because it shells into a toolchain the worktree does not have; CI decides. An LLM-judge check went red on a config-only PR; the policy is now to prove the diff cannot touch it: one rerun, then a human, because rerunning a judge until it is green launders the signal.

And a green local validation shipped a red CI: node --test With a glob, it finds zero tests on Node 20, and my machine runs 26. Four failure modes, each now a rule the next install checks automatically. Two smaller gotchas that cost real time: GraphQL rate budget is per account, not per token, so every agent session spends from the same 5,000 points an hour; and issue types are an organization feature, so a personal-account repo gets a 422, and you carry the kind in the commit title prefix instead.

The nightly pulse. Plain bash on a scheduler, no LLM, zero tokens: board counts, CI on main across all sixteen repos, open PRs, into one vault note. Two-strike rule: a check red two nights running emits the exact /task command that files the fix. Signal becomes queued work or it evaporates. The first run caught two workflows that had been silently red on main for nobody knows how long.

People ask how this differs from a good CLAUDE.md. CLAUDE.md is preference. This is structure. An agent can talk itself past prose. It cannot talk itself past a script that refuses to produce a queue entry.

A vague issue produces a plausible PR that solves the wrong problem. The refusal is cheaper than the review.


2. The terminal customization

Six sessions, six identical black rectangles. One of them is production. You alt-tab into what you think is staging and type the destructive command into prod. Or the cheaper daily version: an agent finished four minutes ago and is waiting for approval, and a waiting window looks exactly like a working one. You are paying for parallel agents and losing the parallelism to “which one was this again?”

User's avatar

Continue reading this post for free, courtesy of Vladyslav Podoliako.

Or purchase a paid subscription.
© 2026 Vladyslav Podoliako and Belkins Inc · Privacy ∙ Terms ∙ Collection notice
Start your SubstackGet the app
Substack is the home for great culture