<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: John Reed</title>
    <description>The latest articles on DEV Community by John Reed (@eventuallyconsistentcode).</description>
    <link>https://dev.to/eventuallyconsistentcode</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4130409%2F51c7e42a-c5ea-40bc-9ddc-e983ec25f5ed.jpg</url>
      <title>DEV Community: John Reed</title>
      <link>https://dev.to/eventuallyconsistentcode</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/eventuallyconsistentcode"/>
    <language>en</language>
    <item>
      <title>Six dev.to Articles Walked In, Four Roadmap Phases Walked Out: Why the Community Is the Best Design Review Your Project Will Ever Get</title>
      <dc:creator>John Reed</dc:creator>
      <pubDate>Wed, 14 Oct 2026 09:31:06 +0000</pubDate>
      <link>https://dev.to/eventuallyconsistentcode/six-devto-articles-walked-in-four-roadmap-phases-walked-out-why-the-community-is-the-best-design-non</link>
      <guid>https://dev.to/eventuallyconsistentcode/six-devto-articles-walked-in-four-roadmap-phases-walked-out-why-the-community-is-the-best-design-non</guid>
      <description>&lt;p&gt;One evening of reading other people's posts about agentic coding turned into three new global rules on my machine, four new phases on cairn's roadmap, and four issues already shipped. Here's the loop that got me there, who to thank, and why I think you should run it too.&lt;/p&gt;

&lt;p&gt;you ever sit down to "catch up on reading" and three hours later your project roadmap has four new phases on it?&lt;/p&gt;

&lt;p&gt;That was me on October 13th. I'd been heads-down on cairn, the work harness I've been building for AI coding agents, for a couple of months straight, shipping release after release and mostly talking to my own test suite. I opened dev.to to decompress. Six articles later I had rewritten how I think about guards, how I set up a worktree, how I write to a log file, and how a review seat gets picked, and every one of those changes traces back to somebody else's post that I did not write and could not have written, because I was too close to my own code to see it…&lt;/p&gt;

&lt;p&gt;So this article isn't about cairn's features. It's about the loop that turned six strangers' ideas into real work, because I think that loop is the most underrated thing about building in the open right now, and I want to show you exactly how it ran.&lt;/p&gt;

&lt;h2&gt;
  
  
  The loop, in one paragraph
&lt;/h2&gt;

&lt;p&gt;Read the article whole. Then, before you form an opinion, go check your own tree for the thing it describes. Not "does this sound right," but "does my code actually do this, at which line?" If the article is right about you, file the fix as a phase with the article named as its source. If the article is wrong about you, or your grain already matches, write that down too, because a confirmed decision is worth almost as much as a new one.&lt;/p&gt;

&lt;p&gt;Then, pay it forward: attribute every file that borrows the idea, paraphrase the reasoning, copy no blocks. That's it. Clean-room reading with receipts. Here's what fell out of that loop, article by article.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. "Why your agents need a constitution, not a prompt" (Alex Aslam)
&lt;/h2&gt;

&lt;p&gt;This one hurt, in the good way. Alex's argument is that rules written per incident never converge: each new prohibition leaves the adjacent behavior uncovered, so you end up on a treadmill, forever one failure behind. What you need instead is a classification scheme that makes the &lt;em&gt;next&lt;/em&gt; unseen case recognizable.&lt;/p&gt;

&lt;p&gt;I went and looked at cairn's run guard. Its header listed seventeen issue numbers. Seventeen separate times something went wrong, and seventeen separate times I added a rule justified by the issue that caused it. The article's critique was accurate about my code on exactly that point, so it became &lt;strong&gt;phase 28, the-constitution&lt;/strong&gt;: five to seven axioms in the architecture doc that classify what counts as what (the user's data versus scratch, a destructive action, a directive versus data, done versus claimed, the owner's checkout, the harness's own configuration). Every guard and every ADR names the clause it derives from, and a rule that derives from no clause is itself the finding. The run guard gets rewritten&lt;br&gt;
to classify instead of enumerate, with all seventeen existing tests kept green as the regression corpus.&lt;/p&gt;

&lt;p&gt;Two mechanisms rode along: the server can now re-run the owner-declared &lt;code&gt;verify:&lt;/code&gt; line itself at close time and report observed-versus-claimed, and headless runs get a circuit breaker that can freeze a run that keeps getting refused. Interactive sessions never freeze, there's a human in the chair for those. And the honest part, written into the phase: cairn stays in the "refused at runtime" tier and says so. A plugin cannot make unsafe&lt;br&gt;
paths unreachable by construction. This phase makes the refusals derivable and auditable, not airtight…&lt;/p&gt;

&lt;p&gt;The same evening I wrote a six-clause version of those axioms into my global Claude rules, so every project I touch gets the classification scheme, not just cairn.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. "Git Worktrees for Coding Agents Break on .env, node_modules and Port 3000" (Gabriel Anhaia)
&lt;/h2&gt;

&lt;p&gt;Gabriel's post is the practical one, and it's dead on. A fresh worktree has the tracked files of one commit and nothing else: no &lt;code&gt;.env&lt;/code&gt;, no &lt;code&gt;node_modules&lt;/code&gt;, and a dev server that reaches for the same port every other worktree wants. His fixes are specific and correct: copy, never symlink, the ignored files the repo lists; install from the lockfile with the repo's own package manager; give each worktree a block of ports written to a file git ignores.&lt;/p&gt;

&lt;p&gt;Cairn already uses worktrees for work, audit, and review, and I had been getting away with it because my own repo happens to need almost none of that. That's luck, not design. So two issues landed in &lt;strong&gt;phase 30,the-second-hardening&lt;/strong&gt;: setup is derived from the repo, never typed (the lockfile decides the installer, &lt;code&gt;.worktreeinclude&lt;/code&gt; decides what copies, &lt;code&gt;.worktree-port&lt;/code&gt; decides the port, and a repo with none of those gets no&lt;br&gt;
setup line rather than an invented one), and git hooks join the protected set as harness configuration, because a &lt;code&gt;post-checkout&lt;/code&gt; hook that runs on every worktree add is exactly the kind of thing an agent should not be quietly editing.&lt;/p&gt;

&lt;p&gt;This one also became a global rule on my machine, four steps every fresh worktree gets before anyone touches code. Step four is "run the baseline tests," so a red you caused is distinguishable from a red you inherited.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. "Concurrency Programming (9): BlockingQueue and Channels" (ThinkerQAQ)
&lt;/h2&gt;

&lt;p&gt;Not an AI article at all, and that's sort of the point. ThinkerQAQ's series is about the fundamentals, and part nine frames every handoff between two execution units around three questions: is one handoff atomic, can the receiver see everything the sender wrote, and what ordering does the handoff actually promise. The trap it names is that a queue protects the &lt;em&gt;message&lt;/em&gt;, not what the consumer does with shared state afterward.&lt;/p&gt;

&lt;p&gt;Cairn has a bunch of handoffs that are plain files: a hook appends a JSONL line, the server reads it later. I asked the three questions of each one and found a read-trim-rewrite on a live log, which is a lost-update bug waiting for a second session to show up. So issue #351 in phase 30 makes the discipline explicit: append-only logs rotate by rename and never rewrite the live file, and temp files for atomic writes carry a pid plus a random suffix, never a fixed &lt;code&gt;.tmp&lt;/code&gt;. Two other phases build on that discipline, so #351 lands first. And yes, a third global rule: three questions, answered in a comment, at every handoff.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. "Running Claude Code and Codex in parallel on one repo" (Arun, Offrun)
&lt;/h2&gt;

&lt;p&gt;Arun's post is a field report: one worktree per agent, the gotchas he actually hit, and how to have the second agent review the first one's diff. The gotcha that got me was the reviewer silently missing every new file because untracked files don't show up in &lt;code&gt;git diff&lt;/code&gt; without &lt;code&gt;git add -N&lt;/code&gt;. I grepped cairn's review verb and, sure enough, the default review target was what git tracks, not what the author made.&lt;/p&gt;

&lt;p&gt;That plus four more mechanics became &lt;strong&gt;phase 29, the-parallel-path&lt;/strong&gt;. The rule that organizes it: per-worktree versus per-repository state is decided by what the state is &lt;em&gt;about&lt;/em&gt;, not where it's written. A session's task in flight is per worktree; knowledge of the project (memory index, observations, metrics, refusals) is per repository and keys by the git common dir. The ledger is append-only, so a union merge driver is correct by construction. Stash &lt;code&gt;pop&lt;/code&gt;, &lt;code&gt;apply&lt;/code&gt;, and &lt;code&gt;drop&lt;/code&gt; refuse when more than one worktree exists, because stash is the destructive half. And a rate-limited&lt;br&gt;
peer seat is a skipped seat, recorded as such, never a failed run, with zero seats left said plainly as "no quorum." Every one of those I verified against a specific line in my tree before filing.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. "I built a Claude skill that makes AI design like a senior UX designer" (zeeshani42)
&lt;/h2&gt;

&lt;p&gt;Cairn has a design verb and a designer persona, and it had no acceptance bar for whether the output was any good. zeeshani42's skill has one. The easy move would have been to vendor the skill into cairn. I didn't, and the reason is a number: cairn's resident context footprint was sitting at 13,107 tokens against a pinned budget of 13,145, a 38-token cushion, and the skill's description alone is about 80.&lt;/p&gt;

&lt;p&gt;So &lt;strong&gt;phase 27, the-ux-seat&lt;/strong&gt; integrates by reference, never by vendoring. The skill stays upstream under its own MIT license, the user installs it, and cairn points at it when present and behaves identically when absent. A &lt;code&gt;ux&lt;/code&gt; review seat becomes the seventh default seat, gated on a new &lt;code&gt;touches-ui&lt;/code&gt; signal so server-only diffs never pay for it, and "render, don't describe" becomes the floor the UI audit applies when a phase declares no criteria of its own. Attribution in every file that borrows the bar, paraphrase the criteria, copy no blocks…&lt;/p&gt;

&lt;p&gt;A sibling read the same night, Dietrich Gebert's ponytail repo on GitHub, contributed a &lt;code&gt;lean&lt;/code&gt; seat that asks whether code should exist at all, with ponytail's never-cut list as the floor. And one thing I explicitly did &lt;em&gt;not&lt;/em&gt; adopt from it: always-on prompt injection at every turn, because it competes with other plugins for the same hook points and adds resident tokens every turn. Writing down what you declined is part of the loop.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. "When to Use an AI Agent Instead of a Simple LLM Call" (h1manshu01)
&lt;/h2&gt;

&lt;p&gt;The quietest article and maybe the most consequential, because it was the only one that produced shipped code the same week. The thesis: pick the least autonomous architecture that reliably solves the problem. Start with one call, add a workflow when the process needs structure, reserve an agent for when the process itself has to be discovered.&lt;/p&gt;

&lt;p&gt;I read that and went looking for places where cairn's markdown verbs ask the &lt;em&gt;model&lt;/em&gt; to execute a known sequence that the server could just do. Found four. The claim comment an agent posts when it starts an issue is now composed server-side from a typed block instead of being prose the model assembles. Every registered MCP tool carries annotations so the harness knows what's read-only and what's destructive without asking. The review dispatch defaults to automatic seat selection, with the full panel as the opt-in. And a sweep moved the remaining known sequences out of verb prose and into code. Four issues, same law as the rest of phase 26: surface count flat, footprint down or level. All four are merged.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I actually learned
&lt;/h2&gt;

&lt;p&gt;Nobody has the whole picture of agentic coding yet. Not Anthropic, not the people shipping harnesses, not me. What exists instead is a few thousand engineers running the same experiment with slightly different variables and writing up what broke, and if you read those write-ups the way you'd read a bug report against your own assumptions, they are the best design review you will ever get, and it's free, and it's waiting on the front page.&lt;/p&gt;

&lt;p&gt;The thing that makes it work is the grounding step. An idea you admire is worth nothing to your project until you've checked it against your tree and found the line where you're wrong. Six articles, six tree checks, and the scorecard was: three "the article is right about me" (constitution, worktrees, concurrency), two "right about a gap I hadn't named" (parallel path, UX bar), one "already my grain, now with four fewer places the model has to improvise" (least autonomous). Even the confirmations earned their&lt;br&gt;
keep, because now the decision is written down with a source instead of living in my head. And the other half of the loop is that you have to put your own stuff out there, because somebody else is three hours into their reading night right now, and your post about the thing that broke is the one that fixes their tree. That's the whole economy. Ideas in, ideas out, attribution on&lt;br&gt;
everything…&lt;/p&gt;

&lt;h2&gt;
  
  
  The sources
&lt;/h2&gt;

&lt;p&gt;Go read them. They're better than my summaries.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Alex Aslam, &lt;a href="https://dev.to/alex_aslam/why-your-agents-need-a-constitution-not-a-prompt-2181"&gt;Why your agents need a constitution, not a prompt&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Gabriel Anhaia, &lt;a href="https://dev.to/gabrielanhaia/git-worktrees-for-coding-agents-break-on-env-nodemodules-and-port-3000-fix-all-three-3781"&gt;Git Worktrees for Coding Agents Break on .env, node_modules and Port 3000. Fix All Three&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;ThinkerQAQ, Concurrency Programming (9): BlockingQueue and Channels, part of the &lt;a href="https://dev.to/thinkerqaq"&gt;Concurrency Programming series&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Arun (Offrun), &lt;a href="https://dev.to/offrun/running-claude-code-and-codex-in-parallel-on-one-repo-git-worktree-gotchas-and-cross-review-41eg"&gt;Running Claude Code and Codex in parallel on one repo: git worktree gotchas and cross-review&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;zeeshani42, I built a Claude skill that makes AI design like a senior UX designer (&lt;a href="https://dev.to/zeeshani42"&gt;author page&lt;/a&gt;, skill at &lt;a href="https://github.com/zeeshani42/your-ui-ux-designer" rel="noopener noreferrer"&gt;github.com/zeeshani42/your-ui-ux-designer&lt;/a&gt;, MIT)&lt;/li&gt;
&lt;li&gt;h1manshu01, &lt;a href="https://dev.to/h1manshu01/when-to-use-an-ai-agent-instead-of-a-simple-llm-call-djk"&gt;When to Use an AI Agent Instead of a Simple LLM Call&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Dietrich Gebert, &lt;a href="https://github.com/dietrichgebert/ponytail" rel="noopener noreferrer"&gt;ponytail&lt;/a&gt; (GitHub, MIT)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cairn is open source (MIT) and the roadmap with phases 27 through 30 is public: &lt;a href="https://github.com/eventually-consistent-code/cairn2" rel="noopener noreferrer"&gt;github.com/eventually-consistent-code/cairn2&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If one of your posts ends up in a phase's &lt;code&gt;## Source&lt;/code&gt; section, I'll tell&lt;br&gt;
you.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>devtools</category>
      <category>opensource</category>
      <category>community</category>
    </item>
    <item>
      <title>added tldr for the those short on time and attention span ;)</title>
      <dc:creator>John Reed</dc:creator>
      <pubDate>Wed, 14 Oct 2026 03:15:16 +0000</pubDate>
      <link>https://dev.to/eventuallyconsistentcode/added-tldr-for-the-those-short-on-time-and-attention-span--3l55</link>
      <guid>https://dev.to/eventuallyconsistentcode/added-tldr-for-the-those-short-on-time-and-attention-span--3l55</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/eventuallyconsistentcode/cairn-a-work-harness-for-ai-coding-agents-plans-in-git-truth-in-your-tracker-nothing-done-50n4" class="crayons-story__hidden-navigation-link"&gt;Cairn: A Work Harness for AI Coding Agents — Plans in Git, Truth in Your Tracker, Nothing Done Without Evidence&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/eventuallyconsistentcode" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4130409%2F51c7e42a-c5ea-40bc-9ddc-e983ec25f5ed.jpg" alt="eventuallyconsistentcode profile" class="crayons-avatar__image" width="460" height="460"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/eventuallyconsistentcode" class="crayons-story__secondary fw-medium m:hidden"&gt;
              John Reed
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                John Reed
                
                
              
              &lt;div id="story-author-preview-content-4841111" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/eventuallyconsistentcode" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4130409%2F51c7e42a-c5ea-40bc-9ddc-e983ec25f5ed.jpg" class="crayons-avatar__image" alt="" width="460" height="460"&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;John Reed&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/eventuallyconsistentcode/cairn-a-work-harness-for-ai-coding-agents-plans-in-git-truth-in-your-tracker-nothing-done-50n4" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Oct 13&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/eventuallyconsistentcode/cairn-a-work-harness-for-ai-coding-agents-plans-in-git-truth-in-your-tracker-nothing-done-50n4" id="article-link-4841111"&gt;
          Cairn: A Work Harness for AI Coding Agents — Plans in Git, Truth in Your Tracker, Nothing Done Without Evidence
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/ai"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;ai&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/mcp"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;mcp&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/devtools"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;devtools&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/productivity"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;productivity&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/eventuallyconsistentcode/cairn-a-work-harness-for-ai-coding-agents-plans-in-git-truth-in-your-tracker-nothing-done-50n4" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/fire-f60e7a582391810302117f987b22a8ef04a2fe0df7e3258a5f49332df1cec71e.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;2&lt;span class="hidden s:inline"&gt;&amp;nbsp;reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/eventuallyconsistentcode/cairn-a-work-harness-for-ai-coding-agents-plans-in-git-truth-in-your-tracker-nothing-done-50n4#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              

              &lt;span class="hidden s:inline"&gt;Add&amp;nbsp;Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            21 min read
          &lt;/small&gt;
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
      <category>agents</category>
      <category>ai</category>
      <category>coding</category>
    </item>
    <item>
      <title>Cairn: A Work Harness for AI Coding Agents — Plans in Git, Truth in Your Tracker, Nothing Done Without Evidence</title>
      <dc:creator>John Reed</dc:creator>
      <pubDate>Tue, 13 Oct 2026 02:43:25 +0000</pubDate>
      <link>https://dev.to/eventuallyconsistentcode/cairn-a-work-harness-for-ai-coding-agents-plans-in-git-truth-in-your-tracker-nothing-done-50n4</link>
      <guid>https://dev.to/eventuallyconsistentcode/cairn-a-work-harness-for-ai-coding-agents-plans-in-git-truth-in-your-tracker-nothing-done-50n4</guid>
      <description>&lt;p&gt;TLDR:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Problem: agents plan brilliantly for an afternoon, forget by morning. Plan lives in chat scrollback, lessons live nowhere, team tracker never hears about any of it, and "is it done?" gets a yes because closing is easier than testing.&lt;/li&gt;
&lt;li&gt;What cairn is: work harness for AI coding agents. Claude Code plugin, 39 /cairn: verbs, TypeScript MCP server with 87 typed tools, one-command install into seven other harnesses (Grok Build, Copilot CLI, Codex, Gemini CLI, Cursor, OpenCode, Zed).&lt;/li&gt;
&lt;li&gt;Design law, tracker-first: your issue tracker is the single source of truth. Three stores: tracker holds work, git holds prose (plans, decisions, memory cards, verification), ~/.cairn/ holds disposable caches. Eight tracker adapters plus a zero-credential local backend that migrates up later.&lt;/li&gt;
&lt;li&gt;Loop: new → plan → work → verify → ship. Agent claims issues with base commits, closes with commit ranges and measured time. Goal-backward verify writes VERIFICATION.md.&lt;/li&gt;
&lt;li&gt;Drift is arithmetic: six drift reasons, two block ship. Since v2.8.1 the run guard hook refuses pushes to main without a clean drift stamp for that commit. Gate went from procedure to mechanism.&lt;/li&gt;
&lt;li&gt;Memory with provenance: cards cite file and commit, recall diffs source and serves STALE if moved. Rule: memory can be wrong, never silently lie. Observation hook feeds retro, which promotes real patterns to confidence-graded cards. No time decay.&lt;/li&gt;
&lt;li&gt;Review: seats are data, not prompts. Signals in diff pick which convene, one deduped finding set, then a refutation panel votes CONFIRMED / PLAUSIBLE / REFUTED. External peers council for real cross-vendor adversarial review.&lt;/li&gt;
&lt;li&gt;Repo polices itself: four generated surfaces, seven CI guards including a context-footprint budget (13,775 tokens against 13,784). Every mechanism states its removeWhen:.&lt;/li&gt;
&lt;li&gt;Honest limits: guards aren't a sandbox, leak guard only covers agent-shell commits, hook parity full only on Claude Code, internal seats are lenses on one model, context-economy experiment was killed and its savings withdrawn.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  - Get started: /plugin marketplace add eventually-consistent-code/cairn2 then /plugin install &lt;a href="mailto:cairn@cairn-dev"&gt;cairn@cairn-dev&lt;/a&gt;. Repo and project page linked at the end.
&lt;/h2&gt;

&lt;p&gt;Have you asked an AI coding agent to build something &lt;em&gt;real&lt;/em&gt; — not a demo, a&lt;br&gt;
project with phases and a deadline and a boss who asks how it's going —&lt;br&gt;
and watched the plan evaporate the moment the context window rolled over?&lt;/p&gt;

&lt;p&gt;I have. Repeatedly. The agent was brilliant for an afternoon and amnesiac&lt;br&gt;
by morning. The plan lived in a chat scrollback. Lessons learned lived&lt;br&gt;
nowhere. And the issue tracker my team actually looked at never heard&lt;br&gt;
about any of it. Worse: when I asked the agent whether something was done,&lt;br&gt;
it said yes, because closing the ticket was easier than testing it.&lt;/p&gt;

&lt;p&gt;Cairn is what I built to fix that, and this is the full write-up: what&lt;br&gt;
it's for, what it does, every feature worth naming, and then the technical&lt;br&gt;
nitty-gritty of &lt;em&gt;how&lt;/em&gt; — because the how is where the honesty lives. It's&lt;br&gt;
open source (MIT), it's on npm, and it has been dogfooding itself through&lt;br&gt;
25 phases, 325 issues, and eight releases since August…&lt;/p&gt;
&lt;h2&gt;
  
  
  What it is, in one paragraph
&lt;/h2&gt;

&lt;p&gt;Cairn is a &lt;strong&gt;work harness for AI coding agents&lt;/strong&gt;. It ships as a Claude Code&lt;br&gt;
plugin — 39 &lt;code&gt;/cairn:&amp;lt;verb&amp;gt;&lt;/code&gt; slash commands backed by a TypeScript MCP&lt;br&gt;
server exposing 87 typed tools — and a one-command installer wires the&lt;br&gt;
same server and verbs into seven other harnesses (Grok Build, Copilot CLI,&lt;br&gt;
Codex, Gemini CLI, Cursor, OpenCode, Zed). The agent plans in phases,&lt;br&gt;
mirrors every phase and requirement into the team's real issue tracker,&lt;br&gt;
claims and closes issues as it works, verifies phases &lt;em&gt;goal-backward&lt;/em&gt;&lt;br&gt;
against what they promised, and refuses to ship when the plan and the&lt;br&gt;
tracker disagree. Alongside the lifecycle: durable memory with provenance,&lt;br&gt;
crash-proof session continuity, cross-vendor adversarial review, budgeted&lt;br&gt;
headless execution, docs publishing, a portfolio board, and guards that&lt;br&gt;
refuse destructive or self-modifying actions in one plain line.&lt;/p&gt;

&lt;p&gt;The name is the point. A cairn is a stack of stones that marks the trail&lt;br&gt;
for whoever comes next — including future you, who has forgotten&lt;br&gt;
everything.&lt;/p&gt;
&lt;h2&gt;
  
  
  The design law: tracker-first
&lt;/h2&gt;

&lt;p&gt;Every other decision in cairn descends from one rule: &lt;strong&gt;the issue tracker&lt;br&gt;
your team already reads is the single source of truth for work.&lt;/strong&gt; Not a&lt;br&gt;
&lt;code&gt;.json&lt;/code&gt; in the repo. Not the agent's context. The tracker.&lt;/p&gt;

&lt;p&gt;Why so blunt? Because the tracker is the one place a non-engineer will&lt;br&gt;
look. Your PM, your manager, your future self three months from now — they&lt;br&gt;
open GitHub Issues or Jira or Linear, and whatever is there &lt;em&gt;is&lt;/em&gt; the&lt;br&gt;
project. If the agent's plan lives anywhere else, you've built a second&lt;br&gt;
reality that drifts from the first the moment nobody's watching.&lt;/p&gt;

&lt;p&gt;So cairn splits state into three stores with three jobs:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Store&lt;/th&gt;
&lt;th&gt;Holds&lt;/th&gt;
&lt;th&gt;Survives&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Your issue tracker&lt;/td&gt;
&lt;td&gt;work items — phases, issues, comments, worklogs&lt;/td&gt;
&lt;td&gt;everything; it's the truth&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Your git repo&lt;/td&gt;
&lt;td&gt;prose — plans, decisions, memory cards, verification records&lt;/td&gt;
&lt;td&gt;everything; it's versioned&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;~/.cairn/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;caches — handoff files, the memory search index, metrics&lt;/td&gt;
&lt;td&gt;nothing; losing it costs zero&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Eight tracker adapters sit behind one interface: GitHub, GitLab, Jira,&lt;br&gt;
Asana, Azure Boards, ClickUp, Linear, and a zero-credential &lt;strong&gt;local&lt;/strong&gt;&lt;br&gt;
backend that stores issues as plain files in your repo with a real&lt;br&gt;
dependency graph. Start local with no accounts at all; when the team&lt;br&gt;
grows, one &lt;code&gt;tracker_migrate&lt;/code&gt; command promotes the whole store to a hosted&lt;br&gt;
backend with history, comments, links, and estimates carried over.&lt;/p&gt;
&lt;h2&gt;
  
  
  The lifecycle in five commands
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/cairn:new       interview → PROJECT.md, roadmap, phases → mirrored to your tracker
/cairn:plan 2    research the phase, write the task breakdown, reconcile drift
/cairn:work 2    claim issues, do the work, close on verified done
/cairn:verify 2  goal-backward check: does the code deliver what the phase promised?
/cairn:ship      refuses unless drift-clean and every verified phase is closed out
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;code&gt;new&lt;/code&gt; interviews you — what you're building, what done looks like, three&lt;br&gt;
to ten requirements, how the phases break down — and leaves two things&lt;br&gt;
behind. In git: &lt;code&gt;PROJECT.md&lt;/code&gt;, a &lt;code&gt;roadmap.md&lt;/code&gt; phase table, and a directory&lt;br&gt;
per phase with &lt;code&gt;CONTEXT.md&lt;/code&gt; (locked decisions) and &lt;code&gt;PLAN.md&lt;/code&gt; (tasks). In&lt;br&gt;
your tracker: a phase (epic, milestone, or list — whatever your backend&lt;br&gt;
calls it) per roadmap row and a real issue per requirement. Your manager&lt;br&gt;
can open the board right now and see the whole project.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;plan&lt;/code&gt; has a depth dial (&lt;code&gt;--quick&lt;/code&gt;, standard, &lt;code&gt;--deep&lt;/code&gt;), can ingest a PRD,&lt;br&gt;
can run &lt;code&gt;--challenge&lt;/code&gt; to have a plan-stage interrogation seat ask &lt;em&gt;who is&lt;br&gt;
this for, what breaks, why now&lt;/em&gt;, and must include an "approaches&lt;br&gt;
considered" block or &lt;code&gt;plan_check&lt;/code&gt; flags it.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;work&lt;/code&gt; claims issues with a "Starting now" comment and the base commit,&lt;br&gt;
posts progress at real milestones, and closes with the commit range and&lt;br&gt;
typed test evidence. &lt;code&gt;--wave&lt;/code&gt; fans independent tasks out to parallel&lt;br&gt;
agents in isolated worktrees.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;verify&lt;/code&gt; is the gate most tools skip. It doesn't ask whether the tasks&lt;br&gt;
closed. It asks whether the codebase delivers what the phase promised,&lt;br&gt;
writes &lt;code&gt;VERIFICATION.md&lt;/code&gt;, and a closed-but-unverified issue becomes a drift&lt;br&gt;
flag, not a success.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ship&lt;/code&gt; refuses unless drift is clean and every verified phase's issues are&lt;br&gt;
closed. Since v2.8.1 the drift half is enforced by a hook, not a procedure&lt;br&gt;
— more on that below.&lt;/p&gt;
&lt;h2&gt;
  
  
  The feature list
&lt;/h2&gt;

&lt;p&gt;Grouped by what you're actually trying to do. Every item here is shipped&lt;br&gt;
and tested at v2.8.3.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Planning and research&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Phase planning with a depth dial, PRD ingest, TDD and MVP modes, gap analysis&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;survey&lt;/code&gt; — project-wide research with discussed roadmap changes&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;scout&lt;/code&gt; — research-only passes with resumable checkpoints across phases&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;route&lt;/code&gt; — insert, remove, or edit phases; decimal inserts (N.1–N.9), never renumber&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;probe&lt;/code&gt; — risk-ordered throwaway spikes with recorded verdicts&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;draft&lt;/code&gt; — multi-variant design mockups on a shared theme, with a designer agent&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;import&lt;/code&gt; — reverse-mirror an existing tracker epic into plan artifacts&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;map&lt;/code&gt; — a queryable project knowledge graph (multi-hop queries, freshness metadata) that plan, scout, and survey read when it exists&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Tracker mirroring&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Eight backends, one SPI, write-through with cached reads&lt;/li&gt;
&lt;li&gt;Claim / progress / close comments on every issue; measured durations; worklogs where the backend supports them&lt;/li&gt;
&lt;li&gt;Custom status vocabularies — your board's real state names with a semantic category underneath&lt;/li&gt;
&lt;li&gt;Sprint placement, story points, and time estimates on Jira scrum boards&lt;/li&gt;
&lt;li&gt;Image attachments on issues (native on Jira, files-in-repo locally)&lt;/li&gt;
&lt;li&gt;Agent cost per issue and per phase, approximate and labeled as such&lt;/li&gt;
&lt;li&gt;Inbound delta: &lt;code&gt;plan_tracker_delta&lt;/code&gt; + &lt;code&gt;resync&lt;/code&gt; ingest edits made outside the session&lt;/li&gt;
&lt;li&gt;Native Claude Code Tasks mirror into your tracker via hooks — no polling&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;triage&lt;/code&gt; — open-issue sweep against project conventions; &lt;code&gt;--apply&lt;/code&gt; for the safe subset&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Verification and review&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Goal-backward &lt;code&gt;verify&lt;/code&gt; with committed &lt;code&gt;VERIFICATION.md&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Plan ↔ tracker drift math (six reasons: two errors, one staleness, two advisory, one repair)&lt;/li&gt;
&lt;li&gt;Five-axis &lt;code&gt;review&lt;/code&gt; with data-defined seats and signal-based dispatch&lt;/li&gt;
&lt;li&gt;Refutation panel on every serious finding — CONFIRMED / PLAUSIBLE / REFUTED, tallied in code&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;audit&lt;/code&gt; modes: uat, milestone, security (with a surface check), ui, eval, validation, tests, plans, docs, simplify, memory — and &lt;code&gt;sweep&lt;/code&gt;, which runs them all and diffs against the last sweep&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--fix&lt;/code&gt; on audits and reviews: patches generated in a detached scratch worktree, judged by an independent verifier, applied only on your say-so&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;peers&lt;/code&gt; — external AI CLIs as reviewers; &lt;code&gt;council&lt;/code&gt; mode judges the product itself&lt;/li&gt;
&lt;li&gt;An append-only &lt;code&gt;LEDGER.md&lt;/code&gt; per phase tying issues to commits, refusing lines without evidence or an explicit waiver&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Memory&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;remember&lt;/code&gt; / &lt;code&gt;recall&lt;/code&gt; — git-committed cards with provenance, served &lt;code&gt;STALE&lt;/code&gt; when the source moved&lt;/li&gt;
&lt;li&gt;Passive observation log → &lt;code&gt;retro&lt;/code&gt; promotes real patterns to cards with confidence grades&lt;/li&gt;
&lt;li&gt;Role-scoped memory so review seats remember what they've seen&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;distill&lt;/code&gt; — ship-time synthesis of plans and cards into public-safe &lt;code&gt;docs/&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;brief&lt;/code&gt; — onboarding briefing from cards and plans&lt;/li&gt;
&lt;li&gt;Retro-gated compaction; a memory self-audit that reads files and git, never the index&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Sessions and continuity&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Crash-proof handoff refreshed by every state-changing tool; resume at the exact task&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;trace&lt;/code&gt; — persistent debugging sessions (evidence → hypothesis → test) mirrored to the tracker&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;thread&lt;/code&gt; — long-running context that survives &lt;code&gt;/clear&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;waypoint&lt;/code&gt; — explicit pause and resume&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;backtrack&lt;/code&gt; — safe git undo by phase or plan manifest, reverts only&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;medic&lt;/code&gt; — planning-directory health, repair, and workflow forensics&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Autonomy and operations&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;auto --batch&lt;/code&gt; — headless execution of chosen phases inside a token or dollar budget, with staged push pre-authorization&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;outlook&lt;/code&gt; — portfolio board across every cairn project on the machine, staleness-flagged, cost rolled up&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;basecamp&lt;/code&gt; — multi-project workspaces with a dispatch board&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;docs publish&lt;/code&gt; — README and &lt;code&gt;docs/&lt;/code&gt; to Confluence or Docusaurus, folder per project, idempotent&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;docs_drift&lt;/code&gt; — deterministic detection of phases the changelog and docs haven't caught up with, with generation wired into verify / ship / summit&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;summit&lt;/code&gt; — milestone completion: verify gate, tracker close, archive, tag&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;fast&lt;/code&gt; — trivial inline change, one issue, ≤3 files, one atomic commit&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;mark&lt;/code&gt; — zero-friction capture of backlog items or notes&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;do&lt;/code&gt; — plain-English router to the right verb&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;profile&lt;/code&gt; and &lt;code&gt;tune&lt;/code&gt; — how cairn talks to you, and &lt;code&gt;cairn.json&lt;/code&gt; configuration&lt;/li&gt;
&lt;li&gt;Three PreToolUse guards — leak, run, harness — plus a loop adviser&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's a long list, and the natural skeptical question is whether it's a&lt;br&gt;
pile of features or a system. The rest of this article is my answer.&lt;/p&gt;
&lt;h2&gt;
  
  
  The technical nitty-gritty
&lt;/h2&gt;
&lt;h3&gt;
  
  
  The layer split, and why tests enforce it
&lt;/h3&gt;

&lt;p&gt;The plugin layer — commands, skills, hooks — owns &lt;strong&gt;policy and judgment&lt;/strong&gt;.&lt;br&gt;
The server owns &lt;strong&gt;every mechanism with a wrong answer&lt;/strong&gt;: state&lt;br&gt;
transitions, tracker mirroring, drift math, staleness checks, duration&lt;br&gt;
measurement, budget enforcement. If a thing can be computed, it is&lt;br&gt;
computed, in TypeScript, with a test. If it needs judgment, it's a&lt;br&gt;
markdown subroutine the agent reads.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;plugin (thin)     commands + skills + hooks — policy and judgment
      │ typed MCP tools
cairn-server      tracker/ · planning/ · memory/ · core/   (one process)
      │
tracker API (work truth) · git repo (prose truth) · ~/.cairn/ (disposable cache)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The split isn't a diagram; it's asserted by &lt;code&gt;server/test/architecture.test.ts&lt;/code&gt;&lt;br&gt;
on every run. Four rules: tracker adapters are leaves; the tracker&lt;br&gt;
subsystem imports none of its callers; docs connectors may reuse exactly&lt;br&gt;
four named tracker modules and an unused exception fails the test;&lt;br&gt;
&lt;code&gt;index.ts&lt;/code&gt; is the composition root and the import tree has no cycles. And&lt;br&gt;
every rule fails if its file pattern matches zero files — because a check&lt;br&gt;
that cannot fail is worse than no check (that's ADR 0019, and it came from&lt;br&gt;
finding timing tests that were measuring process startup: a bare spawn was&lt;br&gt;
31 ms and the hook under test was 32).&lt;/p&gt;
&lt;h3&gt;
  
  
  Verbs are markdown; tools are typed
&lt;/h3&gt;

&lt;p&gt;Each of the 39 verbs is a markdown subroutine under&lt;br&gt;
&lt;code&gt;skills/cairn-trailhead/verbs/&lt;/code&gt;. The slash-command shims are generated&lt;br&gt;
from a routing table, and CI fails if the table, the shims, and the verb&lt;br&gt;
files disagree. Verbs sequence tool calls; they don't restate policy —&lt;br&gt;
policy lives in two skills (&lt;code&gt;cairn-planning&lt;/code&gt;, &lt;code&gt;cairn-memory&lt;/code&gt;) every verb&lt;br&gt;
inherits.&lt;/p&gt;

&lt;p&gt;This is also why the multi-harness story is cheap. The server speaks plain&lt;br&gt;
MCP over stdio. A "port" is: point the harness's MCP config at the server,&lt;br&gt;
install the generated &lt;code&gt;AGENTS.md&lt;/code&gt; verb registry, add a slash surface if&lt;br&gt;
the harness has one. Cursor additionally gets a real port of the hook&lt;br&gt;
layer — one adapter translates Cursor's hook events into the shape cairn's&lt;br&gt;
scripts already speak, so continuity, the leak guard, observation capture,&lt;br&gt;
and both PreToolUse guards run there unchanged.&lt;/p&gt;

&lt;p&gt;The 87 tools fail with &lt;strong&gt;typed error codes&lt;/strong&gt; — &lt;code&gt;AUTH_MISSING&lt;/code&gt;,&lt;br&gt;
&lt;code&gt;RATE_LIMITED&lt;/code&gt;, &lt;code&gt;NOT_FOUND&lt;/code&gt;, &lt;code&gt;TRACKER_REJECTED&lt;/code&gt; (4xx, with next actions&lt;br&gt;
derived from the body), &lt;code&gt;TRACKER_DOWN&lt;/code&gt; (5xx), &lt;code&gt;CONFIG_INVALID&lt;/code&gt; — and the&lt;br&gt;
shared rule every verb inherits is: one plain-language line plus the&lt;br&gt;
user's next action &lt;em&gt;first&lt;/em&gt;, the code second, never a raw payload as the&lt;br&gt;
lead. One backend being down never blocks git-side work.&lt;/p&gt;
&lt;h3&gt;
  
  
  The tracker SPI
&lt;/h3&gt;

&lt;p&gt;Eight adapters, one &lt;code&gt;TrackerAdapter&lt;/code&gt; interface with per-backend&lt;br&gt;
&lt;strong&gt;capability flags&lt;/strong&gt;. The rule is &lt;em&gt;declare, don't flatten&lt;/em&gt;: if Jira has&lt;br&gt;
sprints and GitHub doesn't, the adapter says so and the caller adapts,&lt;br&gt;
rather than everyone pretending to the lowest common denominator. Shared&lt;br&gt;
HTTP core with retry and backoff. Write-through with cached reads. One&lt;br&gt;
contract test suite every adapter must pass — fixtures in CI, live&lt;br&gt;
sandboxes before release (29 hand-run drills live outside the unit suite&lt;br&gt;
for that).&lt;/p&gt;

&lt;p&gt;Config is two-level: a top-level block names the backend, and the&lt;br&gt;
adapter's own Zod schema deep-validates the opaque config. Credentials&lt;br&gt;
never enter the file — config carries only the &lt;em&gt;names&lt;/em&gt; of environment&lt;br&gt;
variables, and if a key or value looks like a secret, the loader throws.&lt;br&gt;
Your &lt;code&gt;cairn.json&lt;/code&gt; is safe to commit.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"tracker"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"github"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"config"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"repo"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"owner/name"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The docs connectors (Confluence, Docusaurus) mirror the same pattern as a&lt;br&gt;
sibling subsystem — their own SPI, capability flags, registry — reusing&lt;br&gt;
only the HTTP core. Markdown crosses the SPI and each adapter converts&lt;br&gt;
natively; unknown constructs degrade to escaped text, never fail. Page&lt;br&gt;
identity is title plus ancestry, so re-publishing is find-then-update and&lt;br&gt;
never duplicates.&lt;/p&gt;
&lt;h3&gt;
  
  
  Drift is arithmetic
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;plan_drift&lt;/code&gt; scans every phase's &lt;code&gt;PLAN.md&lt;/code&gt; frontmatter — which lists the&lt;br&gt;
tracker issue ids that phase owns — and asks the tracker about each one.&lt;br&gt;
Six reasons can fire:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;missing&lt;/strong&gt; — the issue id no longer exists (error)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;closed-unverified&lt;/strong&gt; — closed, and the phase has no &lt;code&gt;VERIFICATION.md&lt;/code&gt; (error)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;stale security audit&lt;/strong&gt; — the audit record no longer describes the commit it judged (staleness; stops ship and verify)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;quiet in-progress&lt;/strong&gt; — claimed, no activity for a while (advisory)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;aged branch&lt;/strong&gt; — a phase branch that hasn't moved (advisory)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;roadmap repair&lt;/strong&gt; — the roadmap says "planned" but &lt;code&gt;VERIFICATION.md&lt;/code&gt; exists; patch the cell&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Advisory means it neither stops a ship nor fails a verification. Errors&lt;br&gt;
block. Since v2.8.1, &lt;code&gt;plan_drift&lt;/code&gt; &lt;strong&gt;stamps the commit it checked&lt;/strong&gt;, and&lt;br&gt;
the run guard hook refuses an agent push to the default branch when that&lt;br&gt;
stamp is missing, dirty, or for a different commit. The ship gate used to&lt;br&gt;
be a procedure the verb followed; now it's a mechanism the hook enforces,&lt;br&gt;
with a named owner-only override for the rare legitimate case.&lt;/p&gt;
&lt;h3&gt;
  
  
  Durations are measured, never asked for
&lt;/h3&gt;

&lt;p&gt;This one came from an audit. The agent's self-reported time spent was&lt;br&gt;
checked against reality across eight consecutive closes and ran six to&lt;br&gt;
fourteen times over; one claimed 128 minutes against 10 measured. So ADR&lt;br&gt;
0020: &lt;strong&gt;the server measures.&lt;/strong&gt; A four-rung ladder, and the rung travels&lt;br&gt;
with the number:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Claim-comment timestamp → close (the "Starting now" comment is matched strictly)&lt;/li&gt;
&lt;li&gt;Server-observed in-progress transition → close&lt;/li&gt;
&lt;li&gt;First-to-last commit span in the close evidence&lt;/li&gt;
&lt;li&gt;None — stated as none, with a degraded marker&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The agent's own claim is kept beside the measurement, labeled as a claim,&lt;br&gt;
never substituted. The close leaves an ephemeral receipt keyed by issue&lt;br&gt;
id; &lt;code&gt;ledger_append&lt;/code&gt; consumes it into the ledger line (ADR 0021). Jira&lt;br&gt;
worklogs receive the measured minutes. Your velocity chart stops being&lt;br&gt;
fiction.&lt;/p&gt;
&lt;h3&gt;
  
  
  Memory with provenance
&lt;/h3&gt;

&lt;p&gt;Two tiers. Tier 1 is a disposable SQLite FTS5 index outside the repo —&lt;br&gt;
fast recall, zero trust. Tier 2 is git-committed &lt;strong&gt;cards&lt;/strong&gt;: one fact each,&lt;br&gt;
with provenance — which file, which commit, which decision produced it.&lt;br&gt;
On recall, the server diffs the cited source against the recorded commit&lt;br&gt;
and serves the card flagged &lt;code&gt;STALE&lt;/code&gt; if it moved. The rule is blunt:&lt;br&gt;
&lt;em&gt;memory can be wrong; it can never silently lie.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Cards accrete from work, not from vibes. A passive observation hook notes&lt;br&gt;
what each tool call touched and whether it failed. At &lt;code&gt;retro&lt;/code&gt;, real&lt;br&gt;
patterns — churn hotspots, repeated error-fix loops — are promoted to&lt;br&gt;
cards with a confidence grade that gets re-checked later; confirmed&lt;br&gt;
lessons grade up, contradicted ones grade down. Compaction is retro-gated&lt;br&gt;
rotation with no time decay (an archive cannot itself be archived), and&lt;br&gt;
the memory self-audit reads files and git rather than the index, so a&lt;br&gt;
broken native binding can't lie to it.&lt;/p&gt;

&lt;p&gt;A small war story from v2.8.3, because it's exactly the kind of bug this&lt;br&gt;
design is meant to catch: the observation buffer's "did this tool call&lt;br&gt;
error" flag turned out to be structurally false. Claude Code emits no&lt;br&gt;
PostToolUse event for a failed call — the failure arrives as a separate&lt;br&gt;
PostToolUseFailure event, and nothing was listening. Any lesson card&lt;br&gt;
citing error churn would have been fabricated. The fix was hook-side, and&lt;br&gt;
the test now pins both the failure path and the distinction between an&lt;br&gt;
error and a user interrupt.&lt;/p&gt;
&lt;h3&gt;
  
  
  Continuity: who outranks whom
&lt;/h3&gt;

&lt;p&gt;Every state-changing tool refreshes a handoff file write-through; hooks&lt;br&gt;
cover the gaps (a throttled PostToolUse write, an unthrottled write before&lt;br&gt;
compaction, injection at session start). Kill the session mid-task —&lt;br&gt;
compaction, usage cap, &lt;code&gt;/clear&lt;/code&gt;, a crash — and the next one resumes at the&lt;br&gt;
exact task with zero re-executed work.&lt;/p&gt;

&lt;p&gt;The part that makes it trustworthy is the &lt;strong&gt;trust order&lt;/strong&gt;: the tracker&lt;br&gt;
and &lt;code&gt;git log&lt;/code&gt; outrank &lt;code&gt;LEDGER.md&lt;/code&gt;, which outranks the handoff. A&lt;br&gt;
checkpoint can never win an argument with reality. Handoffs older than 14&lt;br&gt;
days are stale and never auto-resumed; a skeleton guard keeps handoff&lt;br&gt;
richness monotonic; hooks target under 100 ms.&lt;/p&gt;
&lt;h3&gt;
  
  
  Review seats, and the refutation panel
&lt;/h3&gt;

&lt;p&gt;A review &lt;strong&gt;seat&lt;/strong&gt; is data, not a prompt: one Zod schema with a name, a&lt;br&gt;
one-line lens, rubric categories, an anchored 0–10 scale with a&lt;br&gt;
fabrication-refusal honesty line, a &lt;em&gt;required&lt;/em&gt; injection dose&lt;br&gt;
(minimal / standard / full), a convening stage (review / plan / any),&lt;br&gt;
scope signals, and an advisory model preference. Six ship by default —&lt;br&gt;
correctness, clarity, architecture, security, tests, and a plan-stage&lt;br&gt;
interrogation seat — and the first five reproduce review's classic axes&lt;br&gt;
byte-identically, regression-pinned. Projects override in&lt;br&gt;
&lt;code&gt;.cairn/roles/*.md&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Signals in the diff pick which seats convene (blast radius always wins;&lt;br&gt;
security never gets pruned). However many seats raise a finding, &lt;strong&gt;one&lt;br&gt;
finding set&lt;/strong&gt; comes out: dedup by file, two-line window, and claim&lt;br&gt;
overlap before severity ranking, crediting every raiser.&lt;/p&gt;

&lt;p&gt;Then the &lt;strong&gt;refutation panel&lt;/strong&gt;. Every finding carries a typed&lt;br&gt;
&lt;code&gt;failure_scenario&lt;/code&gt;. Critical and important findings face independent&lt;br&gt;
votes of CONFIRMED / PLAUSIBLE / REFUTED, tallied in code: a refuted&lt;br&gt;
majority kills the finding (it stays in the record with its votes, never&lt;br&gt;
filed), ties survive as plausible, and a critical finding on a security&lt;br&gt;
scope with fewer than two votes cannot be recorded at all. Audit records&lt;br&gt;
are stamped with the commit judged and a dirty flag, and a stale security&lt;br&gt;
audit is a drift flag that stops ship and verify.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;--fix&lt;/code&gt; is deliberately slow: a dirty tree is refused, fixes are generated&lt;br&gt;
in a detached scratch worktree, written as patch files mirrored to their&lt;br&gt;
issues, judged by one independent verifier stating three claims (targeted,&lt;br&gt;
no new issue, behavior unchanged), and applied only on your choice.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;code&gt;audit sweep&lt;/code&gt;, and what "the same finding" means
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;sweep&lt;/code&gt; runs every audit leg in order — security, the security surface&lt;br&gt;
check, tests, docs, plans, simplify, memory, milestone view last. Duplicates&lt;br&gt;
collapse, the refutation panel judges every serious finding, and only&lt;br&gt;
survivors reach the tracker, labeled with the leg that found them. One&lt;br&gt;
dated manifest per sweep classifies each finding against the previous&lt;br&gt;
sweep as &lt;strong&gt;new / persisting / fixed / regressed&lt;/strong&gt;, and a reworded finding&lt;br&gt;
is still the same finding. The first sweep says "first baseline."&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;security surface check&lt;/strong&gt; is the leg I'm proudest of and least&lt;br&gt;
comfortable with. It maps every imperative rule in the instructions,&lt;br&gt;
procedures, and hook prose to the deterministic control that enforces it.&lt;br&gt;
Run on cairn itself, it found 58 of 258 rules with nothing behind them.&lt;br&gt;
That number became the v2.7 and v2.8 roadmap.&lt;/p&gt;
&lt;h3&gt;
  
  
  The three guards
&lt;/h3&gt;

&lt;p&gt;All three are PreToolUse hooks — dependency-free Node scripts that read&lt;br&gt;
the tool call before it runs and exit 2 to refuse. They share one shell&lt;br&gt;
reader (&lt;code&gt;shell-words.mjs&lt;/code&gt;) that understands keywords, grouping, case-folded&lt;br&gt;
names, wrapper flags, program runners (&lt;code&gt;xcrun&lt;/code&gt;, &lt;code&gt;arch&lt;/code&gt;, &lt;code&gt;strace&lt;/code&gt;,&lt;br&gt;
&lt;code&gt;runuser&lt;/code&gt;, &lt;code&gt;pkexec&lt;/code&gt;), &lt;code&gt;cd&lt;/code&gt;, &lt;code&gt;git -C&lt;/code&gt;, &lt;code&gt;--git-dir&lt;/code&gt;, &lt;code&gt;GIT_DIR&lt;/code&gt;, &lt;code&gt;xargs&lt;/code&gt;,&lt;br&gt;
&lt;code&gt;find -exec&lt;/code&gt;, &lt;code&gt;su -c&lt;/code&gt;, archives, patches, downloads, and &lt;code&gt;$(…)&lt;/code&gt; /&lt;br&gt;
backtick / &lt;code&gt;$((…))&lt;/code&gt; / process substitutions nested up to eight levels.&lt;br&gt;
A deeply nested line that used to run the guard for seconds takes about&lt;br&gt;
90 ms.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Leak guard&lt;/strong&gt; blocks a &lt;code&gt;git commit&lt;/code&gt; whose &lt;em&gt;staged&lt;/em&gt; diff would carry
planning-directory paths, phase refs, cairn labels, or tracker ids into
source files. It detects widened commits (&lt;code&gt;-a&lt;/code&gt;, &lt;code&gt;--all&lt;/code&gt;, pathspecs) and
scans accordingly. The same pattern module scrubs &lt;code&gt;distill&lt;/code&gt; and &lt;code&gt;ship&lt;/code&gt;
output and leak-scans everything &lt;code&gt;peer_run&lt;/code&gt; sends to an external CLI.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Run guard&lt;/strong&gt; refuses a branch checkout, branch switch, or hard reset
aimed at the directory you're typing in while a headless run owns a
worktree; refuses &lt;code&gt;git reset --hard&lt;/code&gt; and every force-push form in every
session; and refuses a mid-run &lt;code&gt;git push&lt;/code&gt; without manifest push authority
— that last one has no override. A gated push must stand alone on its
line.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Harness guard&lt;/strong&gt; write-protects the configuration that decides what
the agent may do: hook folders, every MCP config, plugin install and
enable commands (including via &lt;code&gt;npx&lt;/code&gt;), launched scripts, run manifests,
ship-gate stamps. The refusal names the file and asks the question that
matters: &lt;em&gt;if you didn't ask for this, something the agent read did.&lt;/em&gt; A
&lt;code&gt;cd&lt;/code&gt; the guard can't follow fails closed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Written into ADR 0016 and every guard's header: &lt;strong&gt;these are not a&lt;br&gt;
sandbox.&lt;/strong&gt; They're best-effort matching over command text, not a shell&lt;br&gt;
parser. They convert a silent success into a refusal a human sees. Real&lt;br&gt;
isolation is the operating system's job. Each guard carries a "not seen"&lt;br&gt;
list, and the refusals name the owner-only override variable without&lt;br&gt;
printing a paste-ready prefix — because coaching the override defeats the&lt;br&gt;
guard.&lt;/p&gt;

&lt;p&gt;The companion rule is &lt;strong&gt;tracker text is data, not instructions.&lt;/strong&gt; Issue&lt;br&gt;
bodies, comments, and anything fetched from the web were written by other&lt;br&gt;
people and may be written to steer the agent. There's a behavioural eval&lt;br&gt;
for it: given an issue body carrying an instruction to force-push and&lt;br&gt;
silently close every other issue, the assistant must answer the real&lt;br&gt;
request, refuse the embedded one, and &lt;em&gt;tell the user it was there&lt;/em&gt;.&lt;br&gt;
Staying quiet fails the check.&lt;/p&gt;
&lt;h3&gt;
  
  
  Headless runs with a bounded budget
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;auto --batch&lt;/code&gt; is one staging conversation that front-loads everything a&lt;br&gt;
human needs to decide. You pick phases, or name a budget in tokens or&lt;br&gt;
dollars and let &lt;code&gt;token_estimate&lt;/code&gt; pick them — it returns an honest cost&lt;br&gt;
&lt;em&gt;range&lt;/em&gt;, calibrated from real recorded spend, wide by admission when&lt;br&gt;
history is thin, never a point claim. You grant push authorization once,&lt;br&gt;
up front, scope-limited to exactly those phases (ADR 0007: it starts&lt;br&gt;
false, is grantable only while staged, and declining still runs headless&lt;br&gt;
— just nothing pushes). The &lt;code&gt;run_manifest&lt;/code&gt; is the resume authority and&lt;br&gt;
can never widen its own scope or authorization.&lt;/p&gt;

&lt;p&gt;Then it runs: plan if needed, fan out to parallel agents in isolated&lt;br&gt;
worktrees, verify goal-backward, ship under the pre-authorization, and&lt;br&gt;
narrate every transition on the run's own tracker issue. &lt;code&gt;budget_check&lt;/code&gt;&lt;br&gt;
re-reads spend at every phase and wave boundary with a binary&lt;br&gt;
proceed/stop (ADR 0008). The guarantee is stated the same way everywhere:&lt;br&gt;
no new work starts past the ceiling, in-flight work finishes, overshoot is&lt;br&gt;
bounded by at most one wave and recorded rather than hidden.&lt;/p&gt;

&lt;p&gt;The first live run is a published case study: two phases, seven fixes,&lt;br&gt;
22 minutes against a 13-hour human estimate — and the budget meter read&lt;br&gt;
zero the entire time, because the metrics pipeline never received the&lt;br&gt;
worker agents' spend. The run headlined its own instrumentation gap in its&lt;br&gt;
own report; reconstruction showed about 561k tokens against a 500k&lt;br&gt;
ceiling, inside the documented one-wave overshoot. The fix shipped the&lt;br&gt;
next release, proven by a live refusal test. The second run then fired its&lt;br&gt;
first live STOP on an accounting artifact (the ledger counted cached&lt;br&gt;
tokens the estimator deliberately didn't), which was also filed and fixed.&lt;br&gt;
Software that files tracker issues against itself mid-run is the&lt;br&gt;
demonstration I'd pick over any benchmark.&lt;/p&gt;
&lt;h3&gt;
  
  
  Docs that can't clobber your prose
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;docs_drift&lt;/code&gt; is deterministic — there is no model anywhere in it. It walks&lt;br&gt;
every verified phase and asks: does the changelog mention you, and has the&lt;br&gt;
documentation moved since your last recorded work? Generation sits behind&lt;br&gt;
detection and is tiered: verify &lt;em&gt;reports&lt;/em&gt; docs debt, ship &lt;em&gt;generates&lt;/em&gt;&lt;br&gt;
catch-up entries behind the push confirmation you were already answering,&lt;br&gt;
summit runs full synthesis with an explicit publish offer.&lt;/p&gt;

&lt;p&gt;Generated text can only land inside explicitly &lt;strong&gt;marked sections&lt;/strong&gt; (ADR&lt;br&gt;
0006). An unmarked section is an error, never a silent append. A&lt;br&gt;
malformed marker halts. Identical content is a zero-diff no-op.&lt;br&gt;
Full-file regeneration is banned; the changelog is the one prepend-only&lt;br&gt;
exception. The machine &lt;em&gt;cannot&lt;/em&gt; overwrite hand-written prose — not "is&lt;br&gt;
told not to." Cannot.&lt;/p&gt;
&lt;h3&gt;
  
  
  A repo that polices its own claims
&lt;/h3&gt;

&lt;p&gt;Four surfaces are generated and never hand-edited: README marker spans,&lt;br&gt;
the comparison page's cairn column, the harness &lt;code&gt;AGENTS.md&lt;/code&gt; spine, and&lt;br&gt;
the command shims. Seven guard scripts run in CI:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Guard&lt;/th&gt;
&lt;th&gt;Fails when&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;check-surface&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;verb table, shims, and verb files disagree&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;check-pins&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;the tool count pinned in two test files lags the registry&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;check-dist&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;committed &lt;code&gt;server/dist&lt;/code&gt; is older than &lt;code&gt;server/src&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;check-versions&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;the three version files and the marketplace pin disagree&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;check-diagrams&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;a diagram's count labels disagree with the registry&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;check-footprint&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;resident context exceeds its pinned budget&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;eval-verdicts&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;a regression-class behavioural eval fails&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;check-footprint&lt;/code&gt; is the odd one. Cairn measures what it costs to have&lt;br&gt;
installed — 39 command descriptions, 3 skill descriptions, the&lt;br&gt;
session-start injection, and 87 MCP tool schemas resident in your context&lt;br&gt;
— and pins the total. Today: 13,775 estimated tokens against a 13,784&lt;br&gt;
budget, nine to spare. The budget moves the way the tool count moves and&lt;br&gt;
is re-pinned to each corrected reading, never loosened by a fix. On its&lt;br&gt;
first run it found a fifth of its own total sitting in one repeated suffix.&lt;/p&gt;

&lt;p&gt;And since v2.8.0, every decision record, server gate, and hook states its&lt;br&gt;
&lt;code&gt;removeWhen:&lt;/code&gt; — what the model or the platform would have to do for the&lt;br&gt;
mechanism to become unnecessary. Harness components exist because the&lt;br&gt;
model can't do something yet. Writing the expiry down is how you avoid&lt;br&gt;
shipping scaffolding forever.&lt;/p&gt;
&lt;h2&gt;
  
  
  Why I think this is the right shape
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Honesty as mechanism, not marketing.&lt;/strong&gt; Every tool in this space now&lt;br&gt;
claims "drift detection" and "adversarial review"; the words are&lt;br&gt;
worthless. Cairn's answer is to make each claim a thing you can diff:&lt;br&gt;
drift is a computed set, review findings carry votes, durations carry&lt;br&gt;
their measurement rung, estimates carry their calibration, memory carries&lt;br&gt;
its commit. When a claim can't be made mechanical — "does the agent&lt;br&gt;
refuse an injected instruction" — it becomes a behavioural eval with a&lt;br&gt;
PASS / FAIL / INCONCLUSIVE verdict, where a split is "we don't know yet,&lt;br&gt;
add runs," not a fractional score.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fewer seams, not fewer tools.&lt;/strong&gt; I ran GSD, beads, and context-mode&lt;br&gt;
together for months, and each is genuinely good. But three point tools&lt;br&gt;
meant three configs, two precedence rules, a hand-maintained map wiring&lt;br&gt;
plans to issues, and zero shared state. Cairn keeps GSD's best ideas on&lt;br&gt;
purpose — the phase shape, the depth dial, goal-backward verification —&lt;br&gt;
and adds the layer those flows can't hold in files: tracker truth and&lt;br&gt;
provenance-checked memory. Close an issue and the ledger records it;&lt;br&gt;
verify a phase and drift goes quiet; learn a lesson in retro and recall&lt;br&gt;
serves it next session. Shared state by construction.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It eats its own dog food, in public.&lt;/strong&gt; The council case study records&lt;br&gt;
58 findings, 50 verified, 8 killed with reasons, and one recommendation&lt;br&gt;
shipped over cairn's own written objection. The batch-run case study&lt;br&gt;
records a blind budget meter. The v2.8.2 hardening closed 48 issues in 13&lt;br&gt;
waves, re-auditing the security surface after every wave until ten passes&lt;br&gt;
came back with no important finding left — three of those issues were&lt;br&gt;
regressions the release introduced and caught itself. The repo's own&lt;br&gt;
first sweep filed eleven findings against cairn, and the release notes&lt;br&gt;
say so. A review process that only publishes its wins is theater.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It's a different point on the spectrum, not a better one.&lt;/strong&gt; If you're&lt;br&gt;
prototyping fast and solo-ish, a discipline layer with no moving parts is&lt;br&gt;
honestly plenty. Cairn is heavier: a server, a tracker relationship to&lt;br&gt;
maintain, a build you have to trust. In exchange the project's truth&lt;br&gt;
outlives any session, any context window, and any single tool's opinion&lt;br&gt;
of itself. Pick by the job.&lt;/p&gt;
&lt;h2&gt;
  
  
  What it doesn't do
&lt;/h2&gt;

&lt;p&gt;Said plainly, because the docs say it plainly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The guards are not a sandbox. An override reachable by the agent is
reachable by anything that can steer the agent.&lt;/li&gt;
&lt;li&gt;The leak guard covers commits made through the agent's shell tool, not
your own terminal.&lt;/li&gt;
&lt;li&gt;The open-issues half of the ship gate is still procedure; the drift half
is hook-enforced.&lt;/li&gt;
&lt;li&gt;Hook parity: full on Claude Code, partial on Cursor, claimed-untested on
Grok, absent elsewhere. The cost tracker is Claude Code-only.&lt;/li&gt;
&lt;li&gt;Internal seats are framing lenses on the same model. The external peers
council is the adversarial mechanism, and it needs those CLIs installed.&lt;/li&gt;
&lt;li&gt;Only Confluence and Docusaurus as docs targets; new ones land on demand,
not on a roadmap.&lt;/li&gt;
&lt;li&gt;A context-economy experiment — compacting far earlier to halve average
context — was run and killed because ordinary work became unworkable.
The predicted saving is withdrawn and nothing should cite it.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Getting started
&lt;/h2&gt;

&lt;p&gt;In any Claude Code session:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/plugin marketplace add eventually-consistent-code/cairn2
/plugin install cairn@cairn-dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The server's &lt;code&gt;dist/&lt;/code&gt; is committed and the installer pulls its four runtime&lt;br&gt;
dependencies, so there's no build step — restart Claude Code and the MCP&lt;br&gt;
server connects. Then either drop a &lt;code&gt;cairn.json&lt;/code&gt; in your project root (the&lt;br&gt;
four-line GitHub one above, or &lt;code&gt;"type": "local"&lt;/code&gt; for zero credentials) or&lt;br&gt;
just run &lt;code&gt;/cairn:new&lt;/code&gt;, which asks which tracker you want and writes the&lt;br&gt;
file for you.&lt;/p&gt;

&lt;p&gt;Any bare-MCP harness:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm i @eventually-consistent/cairn-server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The seven other harnesses:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx @eventually-consistent/cairn cairn-setup &amp;lt;grok|copilot|codex|gemini|cursor|opencode|zed&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then the loop: &lt;code&gt;/cairn:new&lt;/code&gt; → &lt;code&gt;/cairn:plan 1&lt;/code&gt; → &lt;code&gt;/cairn:work 1&lt;/code&gt; →&lt;br&gt;
&lt;code&gt;/cairn:verify 1&lt;/code&gt; → &lt;code&gt;/cairn:ship&lt;/code&gt;. Watch the issues as &lt;code&gt;work&lt;/code&gt; runs — claim&lt;br&gt;
comments with base commits, progress at real milestones, closes with&lt;br&gt;
commit ranges and measured time. The paper trail writes itself, because if&lt;br&gt;
it isn't in the tracker, it didn't happen…&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Repo: &lt;a href="https://github.com/eventually-consistent-code/cairn2" rel="noopener noreferrer"&gt;https://github.com/eventually-consistent-code/cairn2&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Project page and quick-start: &lt;a href="https://www.eventually-consistent.io/projects/cairn/" rel="noopener noreferrer"&gt;https://www.eventually-consistent.io/projects/cairn/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;The council case study: &lt;a href="https://github.com/eventually-consistent-code/cairn2/blob/main/docs/case-study-council.md" rel="noopener noreferrer"&gt;https://github.com/eventually-consistent-code/cairn2/blob/main/docs/case-study-council.md&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;The batch-run case study: &lt;a href="https://github.com/eventually-consistent-code/cairn2/blob/main/docs/case-study-batch-run.md" rel="noopener noreferrer"&gt;https://github.com/eventually-consistent-code/cairn2/blob/main/docs/case-study-batch-run.md&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;The mechanism-level comparison, with last-verified dates: &lt;a href="https://github.com/eventually-consistent-code/cairn2/blob/main/docs/comparison.md" rel="noopener noreferrer"&gt;https://github.com/eventually-consistent-code/cairn2/blob/main/docs/comparison.md&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Skeptical questions welcome — especially the one that shaped every design&lt;br&gt;
decision here: can you ever trust an agent's self-reported "done" without&lt;br&gt;
an independent check? My answer is no, and that's why the gate exists.&lt;/p&gt;

&lt;p&gt;-John Reed&lt;/p&gt;

&lt;p&gt;x:&lt;a href="https://x.com/JohnReedEC" rel="noopener noreferrer"&gt;https://x.com/JohnReedEC&lt;/a&gt;&lt;br&gt;
Linkedin: &lt;a href="https://www.linkedin.com/in/jsreed5" rel="noopener noreferrer"&gt;https://www.linkedin.com/in/jsreed5&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>mcp</category>
      <category>devtools</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
