Harness

Harnesses I already have

Before designing a harness, it helps to look at the ones I've already written without calling them that.

Seven projects in my repos put a model to work. Six call the API with their own code. The seventh has no code and runs inside Claude Code. This page checks each one against the parts listed on the front page. Everything here comes from reading the code, except the Claude Code row, which is covered in more depth in Claude Code, taken apart.

The projects

wordle (valet)
Claude plays Wordle with a single guess tool. This is the textbook loop: call the model, run its tool, send back the feedback, repeat. If Claude answers without calling the tool, the code nudges it to guess, and a 12-turn cap keeps the loop from running forever.
codenames (valet)
Two agents cooperate. The spymaster sees the key and the operative sees only the board, so each agent's context is part of the game's rules. Invalid clues are rejected and retried a limited number of times, and each round has a call budget.
date (valet)
Two agents talk, with no tools. Each reply has a private MIND part and a spoken SAY part, and the code passes only SAY to the other agent. The conversation runs for a fixed number of turns, then a third model call judges it.
tarot (valet)
One agent and a person typing at the terminal. The code draws the cards and paces the reading in three stages. The model interprets the cards but doesn't choose them.
symposium
A dialogue among characters. Each speech is a single call that includes the whole transcript so far, with cache breakpoints so the growing transcript is reused between calls. In unscripted scenes, a small model (Haiku) picks who speaks next. If that call fails, the code falls back to the script's order.
jackpot
An investing simulation. On each decision date, a single call gets only the prices from before that date and returns target weights as JSON that must match a schema. The code checks the weights before using them. There is no history between decisions. A separate "probe" asks the model whether it recognizes the data, to test whether it knows the future from training.
carver
A repo for editing prose and code, with no code of its own. The harness is Claude Code. The program is AGENTS.md, which describes the editing process, plus STYLE.md, which shows the target style.

Against the parts

Who drivesToolsContextChecksMemoryDelegation
wordlemodel1, closedfull historygame rejects bad wordsnonenone
codenamesmodel, within rounds1 per rolesplit by roleclue validator, budgetsnonetwo roles
datecodenonetwo histories, private part strippedfixed turnsnonetwo agents + judge
tarotcode + personnonefull historyfixed stagesnonenone
symposiumcode, or a small modelnonetranscript rebuilt per callstop reasonnonedirector model
jackpotcodenonefresh per call, time cutoffschema + weight checksnonenone
Claude Codemodelopen: shell, files, web, MCP; most loaded on demandinstruction files, compactionpermission modes, rules, hooksCLAUDE.md, auto memorysubagents
Codexmodelopen: one exec tool running codeAGENTS.md, compactionOS sandbox, escalation, saved rulessessions; memories feature offsub-agents

None of these keeps memory between runs. The logs and transcripts they write are for me to read, not for the model.

What this shows

Who decides what happens next

Only wordle and codenames let the model steer: the model calls a tool, and the loop keeps going until the model stops. In the other four, the code decides who speaks, how many turns there are, and when to stop, and the model only supplies content at each step. The front page lists "loop" as a part of a harness, but whether the model or the code controls the loop matters more. Claude Code sits at the model-driven end.

Context is the part that gets real design

Every project controls what the model sees, usually as the point of the experiment. Examples: the MIND/SAY split in date, the key the spymaster sees but the operative doesn't, jackpot's date cutoff, symposium's cached transcript. None of them handles running out of room, because every task is short. Claude Code has to handle it because its sessions are long.

Checks do the job of permissions

With closed tools, nothing needs approval, because a Wordle guess can't do damage. What the code checks instead is whether the model's output is valid: is the clue legal, do the weights add up, does the JSON match the schema. Permissions are the same kind of check for tools that can do damage. Claude Code needs approval prompts because it gives the model a shell.

Jackpot turns a harness back into a model

Jackpot can call Claude through the Claude Code CLI instead of the API. To do that, it passes --tools "", --setting-sources "", --strict-mcp-config, --disable-slash-commands, --no-session-persistence and --max-turns 3. Those flags list what Claude Code adds on top of the model: tools, config files, MCP servers, commands, saved sessions and an open-ended loop. The whole list has to be switched off to get back to one question and one answer.

Carver is a program written for a harness

Carver uses Claude Code as it comes, and its instructions do the programming. It's the opposite of the valet experiments, which build a harness around a fixed task. Carver keeps the harness fixed and writes the task.

Changes for the front page