The harness: how the run kept track of its own work
In Claude Code, you are the orchestrator: you remember what each session was for and carry what it found into the next. The run’s agents were the same kind of coding agent, 2,481 jobs of them, with one operator behind them all. Cairn, the harness the run used, did the remembering. This page shows how, on objects from the run itself.
- threads
- 6
- issues
- 900
- agent jobs
- 2,481
- messages
- 35,598
- verb calls
- 83,193
- operator
- 1

main thread.Open the screen full size to read the panes.Sources
rs/140 builder, its 31-minute wait, begun Wed 21 Oct, 12:32:58 PM: the screen shows it 27 min 58 s in, at 1:00:56 PM
rs/119 builder, its 15-minute wait, begun Wed 21 Oct, 8:11:28 AM: the screen shows it 4 h 49 min in
main, the last call its pane shows, Wed 21 Oct, 1:00:30 PM
rs/158 coordinator, the last call its pane shows, Wed 21 Oct, 1:00:51 PM
rs/153 planner, the last call its pane shows, Wed 21 Oct, 1:00:54 PM
main, its next call, not yet on the screen, Wed 21 Oct, 1:01:14 PM
rs/158 coordinator, its next call, not yet on the screen, Wed 21 Oct, 1:00:58 PM
the operator's message to main, half-typed on the screen, sent Wed 21 Oct, 1:03:25 PM
the jobs of the 17 issues on the screen: each pane's agent at work at 1:00:56 PM, or its pull request open
the operator's screenshot of their Cairn screen, given to this site's documenting thread, Mon 26 Oct, 10:58 PM
Everything has an address
Cairn keeps the work in objects that outlive any session: threads, issues, executions, nodes, artifacts, messages and tenets. Each one has an address, and an address works like a path in a file system. It names an object by naming everything above it, so the address alone tells you where the object sits and what it belongs to.
This page follows one issue, rs/843, from filing to merge. It was filed at 1:25 AM on Sunday 25 October, to write down the measured run order of the final attempt once that attempt was over. This is the address of the pull request that did it.
- cairn://p/rs/main
- a thread: a name where an issue has a number, and no end. This is the one the operator talked to most.
- cairn:~/wakes
- the same grammar seen from inside an agent: the ~ is the agent writing the address, so this is its own list of wake subscriptions.
Every prefix of the address is an address too. cairn://p/rs/843 is the issue, the unit of work, with its description and comments. cairn://p/rs/843/1 is an execution, one attempt at that work, which runs a fixed set of agents against the issue. cairn://p/rs/843/1/builder is a node, one agent in that execution, here the builder, and create-pr is an artifact, the thing that agent produced: the pull request. Reading any of these addresses returns the object, along with the actions it accepts.
Because the objects live outside the agents, the work does not end when an agent does. The builder’s session ended at 5:11 AM. At 10:01 AM a different agent, the integration thread, merged the pull request it had left behind.
Sources
issue rs/843, filed Sun 25 Oct, 1:25 AM and merged Mon 26 Oct, 10:01 AM
issue rs/843, execution 1 (the build recipe)
issue rs/843, its builder, Mon 26 Oct, 4:16 AM to 5:11 AM
issue rs/843, pull request #708, merged Mon 26 Oct, 10:01 AM
the rs project's main thread, created Tue 20 Oct, 2:37 PM
the rs project's export: its 900 issues, 2,481 agent jobs and 35,598 messages
Threads talk, issues work
A thread is a long-lived agent that a person talks to. It has a name where an issue has a number, and it has no end. The run had six. main held the speedrun itself, and host, integration, markets, document and autoresearch each held one part of the project. Most of what the operator typed before the run took the record, at 4:15 AM on Monday, went to them: 526 of 737 messages.
A thread hands out work by filing issues. Each issue also has a parent, the thread or issue it reports back to, which is usually the one that filed it. An issue whose parent is a thread lands its pull request on the project’s base branch.
Not drawn: 22 issues filed by builders and two by the harness itself.
Most issues, though, were filed by other issues. A coordinator is an issue whose agent’s job is to file issues: it splits a mission into child issues, reviews what each child sends back, and puts the results together. Of the 862 issues filed before the record, coordinators filed 719 and the threads 119, so the work forms a tree: the operator at the top, the threads below, coordinators below the threads, and the agents doing the work at the leaves. The red mark on main’s line is rs/3, a coordinator for quest routes that main filed at 3:41 PM on Tuesday. The section on asking and answering comes back to it.
Who files an issue and where it reports can differ. The other red mark, on the coordinators’ row, is rs/843: the rs/158 coordinator filed it, but gave it main as its parent, so the harness’s notices about it went to main. This page counts an issue as filed by the agent that filed it; its parent is where its news is routed.
A child issue is different from the sub-agent you know from Claude Code. A sub-agent runs inside your session, and its report comes back into your context and goes when the session does. A child issue is a full issue: it can file children of its own, and what it finds can be committed to the repository. The run made this a rule a minute before rs/3 was filed. At 3:40 PM on Tuesday, the operator approved rs tenet 3 (a tenet is a project rule; they have their own section below), which put research in child issues and gave the reason: “We do not run research as blocking sub-agent tasks (they cannot fan out and their reports vanish from the repo).”
Sources
the main thread, created Tue 20 Oct, 2:37 PM
the host thread, created Wed 21 Oct, 2:11 PM
the integration thread, created Wed 21 Oct, 2:11 PM
the markets thread, created Thu 22 Oct, 2:55 PM
the document thread, created Fri 23 Oct, 2:03 PM
the autoresearch thread, created Sat 24 Oct, 11:45 AM
the 862 issues filed up to the #1, Mon 26 Oct, 4:15 AM, each counted by its author, the agent that filed it
issue rs/3, the quest-route coordinator, filed by main Tue 20 Oct, 3:41 PM
issue rs/843, filed by rs/158 coordinator under the main thread Sun 25 Oct, 1:25 AM
rs tenet 3, its statement
One issue, from filing to merge
An issue can exist long before anyone works on it. rs/843 was filed held: it was not to start until the final attempt was over, because the run order it would record did not exist yet. While it waited, for 26 h 50 min, agents left 53 comments of evidence on it, where the agent that eventually took it could read them.
Work on an issue starts with an execution, and an execution runs a recipe: a small, fixed graph of nodes, each one an agent or an artifact. rs/843’s execution started at 4:16 AM on Monday and ran the build recipe, which has three nodes: a trigger, a builder agent and a pull request.
The builder worked in turns. A turn is one stretch of an agent working, and it ends when the agent has nothing to do until something happens; the harness starts the next turn when that something does. The builder’s first turn ended when it started the full test suite. The tests kept running while the agent sat idle, and three of its later turns began when a test run finished. Two began with a message from rs/158, the coordinator reviewing its work, and one with a finished command and two messages from rs/158 at once.
woken when a command it left running finishedwoken by a message from rs/158
The pull request is an artifact: something an agent writes that the harness then acts on. The builder’s first version, at 4:46 AM, opened pull request #708. rs/158 reviewed it by message, and the builder answered each round by writing a new version of the artifact, seven in all. At 5:20 AM a comment on the issue recorded “Final independent review approved”, and at 10:01 AM the integration thread merged the pull request, which closed the issue.
Cairn’s documentation describes a different path. Its standard recipe is planbuild: a planner writes a plan, a person confirms it, and then a builder, a pull request and a review agent follow. planbuild waits on a person at every plan. The run used it for 20 executions and used build for almost all the rest, and it reviewed the way rs/158 did, with a coordinator reading the work and answering by message. The whole run had 20 review jobs. I read those counts as a consequence of there being one person: a recipe that stops for that person at every plan does not scale to hundreds of issues, so the run skipped the plan and let coordinators review.
- buildtriggerbuilderpull request×910
- coordinatortriggercoordinatorboardpull request×23
- planbuildtriggerplannerplan you confirmbuilderpull requestreview×20
Circles are agents; squares are artifacts and pull requests. The run also used thread ×6 and memory-triage ×3, for 962 executions in all.
An issue can have more than one execution. Starting a new one supersedes the one before, and nothing is deleted: rs/302 has three executions on record, and the first two are marked superseded. A retry and the attempts it replaced stay side by side on the issue.
Sources
issue rs/843, comments 1 to 59, Sun 25 Oct, 1:41 AM to Mon 26 Oct, 12:30 PM
issue rs/843, its builder's 7 turns and 62 verb calls, Mon 26 Oct, 4:16 AM to 5:11 AM
issue rs/843, the builder's pull request, versions 1 to 7, 4:46 AM to 5:10 AM
issue rs/843, comment 57, the final review approval, Mon 26 Oct, 5:20 AM
pull request #708, merged by the integration thread Mon 26 Oct, 10:01 AM
issue rs/843, execution 1's stored recipe
issue rs/302, its three executions
the build recipe as stored with its first execution, and its 910 executions
the coordinator recipe as stored with its first execution, and its 23 executions
the planbuild recipe as stored with its first execution, and its 20 executions
the thread recipe as stored with its first execution, and its 6 executions
the memory-triage recipe as stored with its first execution, and its 3 executions
Three verbs
Agents act on all of these objects with three verbs. read fetches and searches anything with an address. write changes things: it edits files, and it also files issues, sends messages, writes artifacts and subscribes to wakes. run executes commands. Each call carries a batch of items, and each item names its target by address, so one call can reach several kinds of object at once.
Here is a call main made at 3:33:27 PM on the first afternoon. The game client running in its terminal had hung, in the fletching-menu bug the story tells.
main thread’s call, its items as sent (the new issue’s description shortened)write({changes:[ {mode:"delete", target:"cairn:~/terminal/lite-lab"}, {mode:"create", target:"cairn:~/terminal/lite-lab",
payload:{command:"bash -lc 'cd ~/rs-play/server/webclient && bun src/lite/runner.ts Lab'", description:"headless game client for test bot Lab"}}, {mode:"append", target:"cairn:~/wakes",
payload:{subscribe:{kind:"terminal", on:"output", phrase:"registering as", ref:"cairn:~/terminal/lite-lab"}}},cairn:~/ is whoever makes the call, here cairn://p/rs/main {mode:"append", target:"cairn://p/rs/issues",
payload:{title:"Game client hangs in a busy loop when a loc interaction is sent while the fletching product menu is open", execution:{recipe:"build"}, description:"## Symptom ..."}},]})
The first two items replace the client. A terminal has an address like everything else, so main could delete it and create it again the way it would a file. The third item asks the harness to wake main when the new client prints “registering as”, so main could end its turn instead of watching the output. The ~ in these targets means the agent making the call, so cairn:~/wakes is main’s own list of wake subscriptions. The fourth item files rs/1, the project’s first issue, by appending it to the issues collection, and names the recipe to start on it. Filing an issue is a write like any other, and so is merging a pull request. (The builder that took rs/1 found the hang began with a malformed call in main’s own script, which neither client rejected.)
The verb an agent used most shows what its job was. Builders ran commands above all: 24,909 of their 52,186 calls were run. Coordinators and threads used write more than anything else, because filing issues, sending messages and merging are all writes.
writereadrun
Not shown: 5,094 calls by planners, reviewers, the integrator and 1,287 explore tasks.
Sources
the main thread's write, Tue 20 Oct, 3:33:27 PM
issue rs/1, filed by that write Tue 20 Oct, 3:34:18 PM
every read, write and run call in the export's agent transcripts, by the job that made it
Asking, answering, reporting up
Agents need decisions from the person, and the person needs to hear what the agents did. Cairn routes both through objects. A question is an object the harness puts in front of the operator. A decision travels down as a message, and a report travels up as a message to the issue’s parent. A message wakes the agent it is addressed to.
These are three minutes on the first evening around rs/3, the quest-route coordinator, with main above it, the operator above main, and its 18 child issues below.
main, its child issues, and the two fixes it started- 6:37:04 PMrs/10’s builder reports up to rs/3: “From rs/10 (gnome chain), answers to your two messages.”
- 6:37:11 PMrs/3 asks the operator “Should I start them?” and offers three answers: “Start rs/23 only”, “Start both” or “Leave them”.
- 6:37:50 PMThe operator answers “Start both”, 39 seconds later.
- 6:38:03 PMrs/3 starts work on rs/22 and rs/23, two client fixes, neither of them rs/3’s child.
- 6:38:19 PM
mainto rs/3: “Two decisions from main.”mainhas started both fixes too; its starts become execution 2 of each and supersede rs/3’s. - 6:39:35 PMrs/3 passes the decisions to eight of its children: “Coordinator (rs/3): two decisions from the main thread.”
- 6:39:36 PMrs/3 reports up to
main: “rs/3 coordinator: both decisions applied.” - 6:39:50 PM
mainreplies: “Confirmed on all points.”
The question has its own address, cairn://p/rs/3/1/coordinator/questions/q-1, and the operator’s part in these minutes was one answer to it, 39 seconds after it was asked. Everything else was agents messaging agents. Two of them acted on the same fixes at once. rs/3 started rs/22 and rs/23 on the operator’s answer, and seconds later main started both as well. Supersession settled which start counted: main’s became execution 2 of each, and rs/3’s are marked superseded.
Every turn an agent takes opens with a briefing from the harness that says what woke it. Counted over the whole run, most of those wakes were messages from other agents. The next largest group was messages from the harness itself, among them the branch notices and the check-ins this page comes to below.
Messages are counted by the sender each briefing names: 31,671 messages in 31,189 notices. Not shown: 8,270 pointers to unread chat and 10 notices about the harness itself. Terminals woke agents too: 207 exits and 188 watched phrases.
Waking on messages left one gap. Coordinators needed to check their running children for stuck turns, and a coordinator’s execution could not schedule a recurring wake to do it. The workaround was an instruction from the operator, which the harness delivered 456 times. It read:
Coordinator check-in backstop (operator, 18:44 PDT 2026-10-21): on each wake, poke the live coordinators (rs/41, rs/147, rs/158, rs/185, rs/186) to sweep their running children for stuck turns, since coordinator executions cannot schedule recurring wakes …
Sources
issue rs/3 and its 18 child issues
rs/10 builder to rs/3 coordinator, Tue 20 Oct, 6:37:04 PM
rs/3 coordinator to the operator, Tue 20 Oct, 6:37:11 PM
the operator to rs/3 coordinator, Tue 20 Oct, 6:37:50 PM
rs/3 coordinator to rs/22, rs/23, Tue 20 Oct, 6:38:03 PM
main to rs/3 coordinator, Tue 20 Oct, 6:38:19 PM
rs/3 coordinator to 8 child builders, Tue 20 Oct, 6:39:35 PM
rs/3 coordinator to main, Tue 20 Oct, 6:39:36 PM
main to rs/3 coordinator, Tue 20 Oct, 6:39:50 PM
the 26,739 attention briefings the harness opened turns with, the items in each, and the sender each names
the harness's terminal-exit and terminal-output notices
the harness, Wed 21 Oct, 7:01 PM
Tenets: the rules only the operator makes
Some decisions have to reach every agent, including agents that do not exist yet. In Claude Code you would write them into a CLAUDE.md file. In Cairn they are tenets. A thread proposes a tenet, a statement of how the project does something. Only the operator can answer it, and once approved it binds every agent that comes after. The operator answered quickly, half the time within a minute, and one tenet, #38, is still waiting.
Here is the last tenet the operator approved. A thread proposed it on the Sunday night the story tells, after the scored account died.
We keep pursuing the overall #1 until achieved, rather than stop after attempt5. Finish current SCORED and publish its honest result even if it misses, then prepare further fresh scored attempts as needed. Completion alone is not the finish line because the operator explicitly wants #1. Individual live launches still require main's operational GO; demonstrated death paths must be corrected. This replaces tenet35's final-attempt limit, not its safety requirements. …
cairn://p/rs/tenets/39, approved at 9:09 PM on Sunday, four seconds after a thread proposed itThe documentation describes tenets as gates: a filing waits until the operator rules on it. In the run, only three worked that way (#13, #15 and #36). The rest were standing rules, and standing rules change: a later tenet supersedes an earlier one, and the ledger draws each supersession as a curve. The rule on merging moved twice. Tenet 5 said the main thread merges child pull requests; tenet 14 superseded it, and tenet 19 superseded that. By the end main had merged 212 pull requests by write call, coordinators 203 and the integration thread 19, among them rs/843’s.
The operator declined two, and said why.
hmmm idk I think I would rather see the stats than “pixelated guy runs around”. Mpb is only loaded bc we’re busy building this and other things. When time of run comes we can shut everything else down and run wherever fastest, but I think the video should be first person
if its on its own vps why limit to 6? I meant like 6 within current bbs/twin/etc limits, requisition some of the E0N thieves or something
Sources
rs tenet 39, its statement and verdict
rs tenet 3, its statement
rs tenet 8, declined, and the operator's comment
rs tenet 27, declined, and the operator's comment
the rs project's 39 tenets: proposed, answered and superseded
Where it got in the way
All that merging had a cost. Each issue’s work sat on its own branch, and every merge into the base branch moved the base under every other open branch. The harness rebased those branches itself when it could, and sent the agent a notice when it could not. When the operator asked for this page, at 2:03 PM on Monday, they wrote that Cairn had played a major role, and was also a “bit of a hindrance with all the git state stuff”.
Over the run, 1,921 notices needed an agent to act on its branch. Some cost more than a turn. At 7:40 AM on Wednesday, rs/95’s builder could not publish its branch, and writing its pull request artifact again had not helped:
rs/95: re-writing create-pr (version 3, 07:38) didn't help.
Two minutes later main answered, “rs/95's one-off push is APPROVED”, and the branch was published.
Sources
the harness's own messages about branches: base-branch and branch updates, and divergent history
rs/95 builder, Wed 21 Oct, 7:40 AM
main, Wed 21 Oct, 7:42 AM
the operator to this site's documenting thread, Mon 26 Oct, 2:03 PM
Why one person could run it
Put together, these objects decide what reaches the person. Agents file the work, start it, review it and merge it by writing to objects, and they wake each other with messages. What rises to the operator is narrow: questions, tenets to rule on, and what the threads choose to report.
So the operator’s side of the run was 870 inputs over six days, counting typed messages, answers to questions and tenet verdicts. The agents’ side was 29,273 messages to each other.
Many of the operator’s inputs were tiny: 135 messages were a single “^”, which tells an agent to go on.
Sources
the operator's 765 typed messages in the agents' transcripts, less 28 the app wrote itself
the 71 turns that began with the operator's answer to a question
the operator's tenet verdicts
the export's 35,598 messages, 6,325 of them from the harness