01. What a harness is
A chat window with a good model in it will write you a component. It will not move 1,600 files across 42 libraries while four colleagues keep merging, and it will not tell you afterwards what that cost or which of its own suggestions were wrong. The difference is not the model. It is everything around the model that decides what it knows, what it may do, what has to be true before it is allowed to say "done", and what gets written down.
I call that a harness. Mine has seven layers, and the article walks through them in order:
- Rules: instruction files loaded every turn, or when a path is touched. Invariants only, present tense, one home per fact.
- Skills: knowledge loaded on demand by a trigger. Some I wrote, most I did not (section 2).
- Agents: eight roles, each with its own model, effort, tool list, preloaded skills and a report contract.
- Hooks: deterministic scripts on tool events. They block; they do not advise.
- Tools: a verification script that runs every gate in one command, a ledger summariser, a dead-path checker.
- Record: specs, plans, ADRs, run reports with token ledgers, an append-only progress file per run, a handover document when a session has to stop.
- Memory: a small file-per-fact store for rulings, machine facts and diagnostic recipes. Never for ticket state.
02. The layer I did not write
Most of the process knowledge in this harness is other people's, installed as Claude Code plugins and switched on or off per skill. The repository-specific layer on top is thin on purpose: it says where this repo departs from the generic skill, and nothing the generic skill already says.
superpowers
Jesse Vincent's superpowers plugin is the spine of the workflow. brainstorming
runs before any design work and refuses to start implementation until a design is approved.
writing-plans is what the planner agent invokes, with two repo overrides (specs are
written alongside, and tasks carry this repo's tags). subagent-driven-development is
the dispatch loop, and its task-brief script is how a brief is assembled: the plan's
header block plus one task's section, never a path to the plan. test-driven-development,
systematic-debugging, verification-before-completion ("evidence before
assertions") and using-git-worktrees are used as they ship. The rule that a skill is
invoked before any response, even a clarifying question, is also theirs, and it is what makes the
rest of the stack fire reliably.
Matt Pocock's skills
Matt Pocock's skill set covers the parts of engineering that happen before and around code, and four of them shaped how this harness keeps its record:
domain-modelinggives the repo its document layout: a single-contextCONTEXT.md(here still carried by the rules file until it exists) and sequentially numbered ADRs underdocs/adr/. The eleven ADRs in this harness follow its shape, and the rule "if a piece of work would contradict an ADR, say so and ask, never override silently" is its discipline.researchis the pattern behind the 68 research notes: a background agent investigates a question against primary sources, every claim carries its source, and the note lands where the repo already keeps such notes. The Nx improvements survey, the architecture review against Manfred Steyer's published material, and the AI-tooling survey were all written this way.writing-for-agentsis the reference I reach for whenever a rule file or an agent prompt is edited. Its vocabulary (context load versus cognitive load, a pointer per branch, progressive disclosure, "cut identity the body already carries") is the vocabulary the audit in section 8 used to cut the always-loaded layer from 11,500 words to under 3,000.grilling(andgrill-with-docs) is the design-tree interview: rounds of questions, each with a recommended answer, until nothing is silently assumed. It is how the bigger specs got their open-decisions list down to three or fewer before the spec-writer ran.
prototype, codebase-design (deep modules, where a seam goes),
resolving-merge-conflicts, wizard and handoff are on and used
when they fit. Three of his skills are deliberately switched off: tdd and
diagnosing-bugs overlap superpowers' versions, and his code-review overlaps
the official plugin's; two skills with the same trigger is one skill firing at random.
Framework and tooling skills
- The Angular team's
angular-developerskill (forty reference files: signals,resource,linkedSignal, signal forms) is preloaded into the implementer agent, so the generic Angular guidance costs nothing per task to look up. - The Nx plugin's
nx-workspaceandnx-generateskills replaced a hand-written library census: the list of projects by tag is onenx show projectsaway and is never restated in a document. Nx's own stance, "skills for knowledge, MCP for connectivity", is the rule here too. - Two vendored MIT skills for accessibility and performance (WCAG 2.2 AA, measure-first) are used for design-system work.
- The official
code-reviewplugin runs once per branch;typescript-lspgives diagnostics after every edit and real go-to-definition across 43 projects instead of grep; Context7 answers library-version questions. - MCP servers, all read-only in effect: the Angular CLI server (docs search, the OnPush migration tool), Azure DevOps (work items, repositories, PR threads; its six write tools are denied so the shell's "no pipeline queueing" rule cannot be bypassed through a different door), Figma, SonarQube.
The repo layer says where this codebase departs from the generic skill. It never repeats what the generic skill already says.
03. Rules, skills and eight roles
Rules
Four files are loaded every turn: the global preferences (138 words), the tracked persona the team
wrote (324), the local rules file (2,170 words, ten numbered rules and a table of what each
unmerged branch adds), and a shell-rules file (319) that carries the git and process invariants. A
fifth, the web rules (945), loads only when a file under apps/ or libs/ is
read or edited. Every one of them is present tense and describes the checkout, not a branch. That
sentence sounds obvious; section 8 is about how it stopped being true.
Repo skills
Five skills are repo-authored: web-conventions (where things live, the rules this repo
adds, where it departs from the generic skills, a done-when list; 4,200 words plus eleven reference
files), typescript-style (the recipe table: union states for loaded data, no loose null
checks, as const satisfies for configs, pure sort and search helpers),
ado-conventions (how to read and write the issue tracker, commit and PR style),
writing-feature-spec (two templates and a 1,500-word cap) and syncing-docs
(a diff-to-document mapping, run before every PR). Each has a trigger sentence that names the
situation, because a skill that does not fire is a document nobody reads.
Eight roles
| Agent | Effort | Tools | Preloaded | Must return |
|---|---|---|---|---|
| investigator | high | read, grep, glob, git reads, spawn | investigating-codebase, tracker conventions | a one-page facts note: files, flow, constraints; no code, no offer to implement |
| spec-writer | medium | read, write under docs/ only | writing-feature-spec, diagrams, ADRs | spec path, specs amended, open decisions (more than three means the brainstorm is not finished) |
| planner | high | read, write the plan file only | web-conventions, typescript-style, angular-architecture | plan path and a task list with tags; at most 300 words per task, 12 tasks per plan |
| implementer | inherits | all | angular-developer, web-conventions, typescript-style | Files: Checks: Deferred: Plan edits: or Blocked:, hook-enforced |
| mechanical implementer | inherits | all | web-conventions, typescript-style (no generic Angular preload) | the same contract; for tasks whose brief carries the complete code or an exact copy rule |
| conventions reviewer | — | read-only | web-conventions, typescript-style | a fixed 16-row checklist and a verdict; the mechanical rows are n/a because the verification script owns them |
| code reviewer | — | read-only | none, deliberately | an 11-row "second file" table: the translation twin, the flag's getter, the action's handler, the route's title key; verdict paired / one file missing / request changes |
| pr-creator | — | read, git, tracker CLI | tracker conventions | the PR URL and title, after a five-step preflight; it runs only when told a human verified the branch |
Three things in that table do most of the work. Model and effort live in the agent's
frontmatter and nowhere else; after the audit the three document-writing roles moved off
the most expensive model, and the spec-writer dropped to medium effort because, in its own
prompt's words, "you write down decisions that are already made; you do not design".
The code reviewer preloads nothing, because loading the conventions skill would
pull it onto the other reviewer's checklist and the two would find the same things twice.
Every report is a contract: the implementer's four headings are checked by a hook on
the agent's stop event, and a report missing Deferred: is sent back. Manual checks used
to be deferred silently; now the dispatcher sees the word every time.
an agent's frontmatter, the shape---
name: spec-writer
description: Turns a read ticket and an agreed approach into a spec under docs/, and reports the path plus the open decisions.
model: opus
effort: medium
tools: Read, Grep, Glob, Bash, Write, Edit
skills: writing-feature-spec, drawing-architecture-diagrams, writing-adr
---
04. The workflow: tiers and dispatch
For the first five weeks there was one pipeline for every size of change. A three-agent fix cost 246k tokens because it still went through investigator, spec, plan, two reviewers and a docs sync. A lint-config change cost 550k. The pipeline floor was the price of any ticket.
Three tiers, sized at the brainstorm and written into the rules:
- S: at most three files, no new copy, no contract change. The main session or one implementer, the official code review, a human verifies, the PR is opened. No spec, no plan; the run is one line in a monthly file.
- M: one screen or one contract, no new library. The ticket plus the brainstorm decisions in the brief stand in for the spec; the planner writes at most five tasks; one reviewer per new shape.
- L: a new library, a cross-scope change, a wave of components. Investigator → brainstorm → spec-writer → planner → implementers → reviews → docs sync → a human verifies by hand → pr-creator. Every migration phase in the first article was an L.
Dispatch
The dispatcher is the main session. It never implements an L task itself; it assembles briefs, reads reports, makes rulings and writes them down. The rules it follows:
- The brief is the plan's header block plus the task's section. The header carries the verification command, the commit recipe, the message rule and the report format once; a task never repeats them. An agent is never handed a path to the plan, because it would read all of it.
- Same-shape tasks are one dispatch with a per-unit table and one commit per unit. An implementer run costs about 70k tokens before it touches a file, so ten five-minute renames as ten dispatches is 700k tokens of start-up.
- Parallel only when nothing is shared. Two tasks run side by side only if they share no file and no measured number; the two translation files count as shared. A shared file no check guards is committed once by the dispatcher after the wave.
- One working tree, pathspec commits. Implementers share a checkout and commit with
git commit --only -- <paths>, never a bare commit, so two agents' half-edits never land in each other's commits. - An implementer that changes a shape a later task depends on edits that task in the plan, and says so under
Plan edits:. - Manual checks batch into one click-through list at the end of the branch, done by a human.
- Ask before adding a dependency, changing the lint config or the test runner, restructuring a domain folder, or queueing any pipeline. A queued build is outward-facing and is not the agent's call.
- A PR opens only after a human has verified the change. The pr-creator's preflight checks that it is not on main, the tree is clean, commits exist, no local-only file is in the range and no PR is already open. It once refused a generalised "go on" because the verification step had not been named.
05. Gates, not prose
A rule an agent might forget is a rule a script should hold. The harness has two kinds of script: a verification command every implementer runs before it may report, and hooks the platform runs on tool events whether anyone remembers or not.
One command, eight steps
| # | Step | Compared against | Fails when |
|---|---|---|---|
| 1 | Type-check the app | zero | any error |
| 2 | Type-check the specs, plus every library's own tsconfig | a baseline file keyed on file, code and message (line numbers ignored) | a new error; the 53 pre-existing ones are not printed |
| 3 | strictNullChecks on the app | a list of folders that are already clean | an error inside a listed folder; a folder at zero joins the list and never leaves it |
| 4 | Jest, related tests only | — | a red test in anything that imports a touched file |
| 5 | Module boundaries lint | the tag table | an upward or cross-layer import, a cycle |
| 6 | ESLint parity per touched file | the base branch's version of the same file, linted through stdin | any rule whose count grew; a new file must be clean. Lint is parity, not zero: main carries about 280 errors |
| 7 | Conventions (70 ms, zero tokens) | the base branch | a translation key missing in one language, an added comment, an added eslint-disable, a new component without OnPush or the prefix, AI attribution in a commit message, a stale reference to a moved file, a local-only file in the commit range |
| 8 | Production build (on demand) | — | only when a config, route or style entry file changed; otherwise once per branch |
Two of those rows are ratchets, and ratchets are the most useful shape of gate I know. The spec type-check baseline means an agent sees only the errors it introduced, not the 104 lines of pre-existing noise that, before the baseline existed, every agent read in full on every run. The strict-null folder list means strictness only ever grows: 1,218 errors in 233 files on the day the ratchet started, eight folders clean today, none of them ever allowed to regress.
Row 7 used to be rows in a reviewer's checklist. Translation-key parity, added comments, a trailer in the commit message: an agent reading a diff for them is slow, costs tokens and misses some. The conventions reviewer spent 434k tokens on one run and changed nothing.
Every mechanical row moved into the verification script, where it costs 70 milliseconds and
cannot be skipped. The reviewer's checklist now marks those rows n/a and keeps only
the judgement rows: placement, the signals contract, TypeScript style.
Four hooks
hook wiring, the shape{
"hooks": {
"PreToolUse": [{ "matcher": "Bash", "hooks": ["git-guard.mjs"] }],
"PostToolUse": [{ "matcher": "Edit|Write", "hooks": ["prettier.sh"] }],
"SubagentStop": [
{ "matcher": "web-implementer(-mechanical)?", "hooks": ["implementer-report.mjs"] },
{ "matcher": "spec-writer", "hooks": ["spec-cap.mjs"] }
]
}
}
- git-guard, before any shell command: if the command commits or pushes, resolve the directory it runs in (a leading
cdorgit -Ccounts), read the branch, and block a commit or push onmain, a commit that names a local-only harness path, or a push whose range carries one. Exit 2, with the reason. This replaced four paragraphs of prose that four files repeated. - prettier, after every edit or write, skipping the docs and harness folders. Formatting is never a review finding.
- implementer-report, when an implementer stops: the last message must carry the four headings, or the agent is sent back to finish.
- spec-cap, when the spec-writer stops: today's spec files are word-counted, tables included, and 1,500 is the limit. A prose cap no hook checked is what produced a 16,800-word spec.
The deny list
Twenty-one denied commands, each with an incident behind it. pkill -f and
pgrep -f, because a pattern like ng serve matches the shell running the
command and kills the tool call; that happened 181 times in one week before the rule. git reset
--hard, because one moved the wrong branch in a checkout shared with other sessions; every
commit, push or reset now runs git branch --show-current in the same command. Stash
pop, drop and clear, because the stashes hold uncommitted local tooling and the indices shift.
rm -rf. Any command that queues a pipeline. And the six write tools of the issue-tracker
MCP server, because a shell deny list does not cover MCP tool names, and a rule with a second door
is not a rule.
06. Review economics
Every run report ends with a ledger, and the ledger has two columns most harnesses do not keep: findings that changed code and findings later refuted. The first report said why: "the ratio of code-changing findings per 100k tokens, per agent type, is the number to steer the review budget by." It took five weeks to act on it.
| Reviewer | Runs | Tokens | Code-changing findings / 100k |
|---|---|---|---|
| Conventions reviewer (per task) | 124 | 12.0 M | 1.29 |
| Code reviewer (per task) | 125 | 10.3 M | 0.89 |
| Generic task reviewers (per task) | 23 | 2.4 M | 0.00 – 0.48 |
| Official code review (once per branch) | 19 | 3.1 M | 3.4 – 3.9 |
The two custom reviewers cost 22.3 million tokens for 247 code-changing findings. The one review that reads the whole branch at the end, scoped to the files that carry logic, finds three to four times as much per token. In the migration's CI story the gap was 0.31 against 4.76.
A reviewer under 1.0 code-changing findings per 100k tokens over two consecutive runs leaves the per-task dispatch.
That is now a rule, and the tiering follows from it. A task that introduces a new shape gets the conventions reviewer (judgement rows only) and the code reviewer. Repeats of a shape get one batched pass per wave. The whole-branch review runs once. The mechanical rows went into the verification script (section 5). What the ledger also shows is where reviewers are worth it: the "second file" reviewer, which looks only for the file a diff forgot (the other language's translation key, the feature flag's getter, the action's handler), finds real omissions on new shapes and nothing on repeats, which is exactly what you would want it to do.
And reviewers are sometimes wrong with confidence. Two of them agreed with each other that two lazy-load sites of the same feature share one injector; a throwaway spec of under a thousand tokens refuted both. Eight findings of one whole-branch review on the shared rework were refuted on inspection. The ledger's second column exists so that a reviewer's finding is treated as a claim to verify, not a change to apply.
07. Run reports, ledgers, handovers
Every M or L run ends with a report under the research folder. By convention it carries:
- Outcome: what merged, the commits, the acceptance criteria and how each was proven.
- Rulings, in order, each with what it costs if wrong. "Tasks 1–3 run in parallel in the one shared tree; costs a transient verify failure on another task's half-edit, re-run." The cost clause is cheap to write and is what made two architecture rules easy to reverse later: the price of the original rule had been written down when it was made.
- Departures from the spec, named, so the spec can be amended by appending rather than rewritten.
- Deferred: the click-through list for a human.
- Tool-shell facts for the next run: that the Nx daemon's graph goes stale after a rename, that lint-staged after a pathspec commit leaves the index dirty, that the coverage folder is root-owned when the container writes it.
- The token ledger: one row per agent run with model, task, tokens, tool uses, wall time, findings that changed code, findings refuted. A 48-line script totals it by agent type and prints findings per 100k.
The dispatcher's own context is never in the ledger, and a resumed agent reports a cumulative total, so raw sums overstate. One run's raw 14.2 million tokens was 9.2 million after de-duplication; the 125 million in the headline is the raw figure, and the reports say so.
Resuming
A dispatching session hit its context limit in the middle of a multi-lane upgrade. Claude Code's automatic compaction at 94 % produced a summary, and the summary had lost the agent ids, the exact rulings and which commits already existed. The next session re-dispatched a task whose commit was already on the branch.
Two artefacts and one rule. Each run has an append-only progress.md: the plan, the
spec, the branch and base commit, a pre-flight table of what each task produces and consumes,
then one line per task (DONE, DONE_WITH_CONCERNS, BLOCKED,
with commit hashes and verify counts) interleaved with rulings as they are made. A handover
document, written when a session must stop, carries the git state per lane, the agents that were
running, a numbered resume procedure and the line "never re-dispatch a task whose commit already
exists". And the rule: stop at 80 % of context and start a new session from the ledger, never let
compaction decide what to keep.
08. The audit: what six weeks of sediment looks like
With 28 run reports behind it, the harness was audited the way it audits code: the always-loaded files read in full, three subagents sweeping for staleness, duplication and contradiction, and the ledger script run over every report. The verdict was fair: unusually well instrumented, and three things had grown past the point where they cost more than they returned.
A. The rules described a branch, not the checkout
The harness lives in the main checkout, and the work lived on a stack of unmerged branches. The
rules file had been kept current for the furthest branch. A session starting on main
was briefed for a different codebase: 17 of 91 cited paths did not exist, and five version facts
were wrong.
The always-loaded files describe main only. One table at the top carries the stack:
branch, what it adds on top of the row above, where that is written down. When a branch merges,
its row is deleted and the rules it introduced are written in the present tense. A dead-path
checker runs over every backticked path in the harness and fails on a missing one.
B. Fifteen facts in six to twelve places, thirteen of them disagreeing
The library count appeared as 35, 37, 41, 42, 43, 44 and 46 in different files. There were three different commit syntaxes across three agent prompts. One agent prompt said "nothing in this repo enforces layer direction" a week after the boundaries gate went into CI. Every rule change had become a six-file edit that missed one, and an agent picked whichever copy it read last.
One home per fact. The rules file went from 5,362 words of changelog to 2,170 words of present-tense rules; the web rules from 2,912 to 945; the history moved to a dated research note. Counts and alias lists are environment facts, printed by a command and never restated. Agent prompts name a rule; they never repeat it.
C. Four agents re-read what they already had
Non-fork subagents receive the instruction hierarchy automatically. Four prompts nevertheless began with "read the rules file first". That was about 11k tokens per run, roughly 200 runs, about 2.2 million tokens for nothing. Four sentences deleted.
D and E. The document writers were the expensive stage
The spec-writer ran on the most expensive model at the highest effort, 104k to 614k tokens per spec, and five specs ran to 10,000 – 16,800 words against a 600-word prose cap nobody enforced. The planner cost 19.8 million tokens across 45 runs, 2,100 – 3,600 words per task, 99 % prose, each task restating the verification command, the commit recipe and the report format that the brief script already prepends. The three document roles were 22 % of all tokens.
Model and effort by role: the spec-writer to a cheaper model at medium effort, since it transcribes decisions already made; the planner to high effort with a 300-word cap per task and 12 tasks per plan, boilerplate once in the header. A second spec template for refactors (goal, inventory, rules the code must satisfy, the guard that fails if violated). A word cap a hook enforces. Specs are amended by appending a dated section, never by rewriting the body. The brief carries the investigator's note and the brainstorm decisions verbatim so the writer reads code only to confirm a name exists.
F to I, briefly
- Review budget (section 6): the mechanical rows into the script, the 1.0 rule, one whole-branch review.
- One pipeline for every size (section 4): the S/M/L tiers.
- Memory had become a ticket tracker. 33 of 77 files described a PR that was completed or abandoned; the index was at 19.6 KB of a 25 KB cap, past which new memories silently stop loading. The rule now: PR state is never stored, it is one tracker command away; memory keeps rulings, machine facts and diagnostic recipes.
- Hygiene. 46 registered worktrees, about 20 of them dead; 300 MB of ignored build copies; a permission for a build command that no longer existed; two agents told to use a Figma server they had no tools for. Thirty-nine worktrees removed, six unused global skills disabled, the rest a half-hour list.
| Measure | Before the audit | After |
|---|---|---|
| Words loaded every turn | ≈ 11,500 | ≈ 2,950 (+ 945 path-scoped) |
| Rules file | 5,362 words, 79 dates | 2,170 words, ten rules, one branch table |
Harness paths missing on main | 17 of 91 | 0, checked by a script |
| Document-writing roles | top model, effort xhigh | cheaper model; medium / high effort; caps enforced by hooks |
| Agents re-reading the rules file | 4 | 0 |
| Memory files | 77 (33 stale) | 34 |
| Registered worktrees | 46 | 7 |
| Pipeline tiers | 1 | 3 |
09. Keeping the harness out of git
The repository belongs to a team of eight, on a company tracker, and PRs carry product and
pipeline changes only. The first time a spec and a plan reached a pull request they had to be
rebased out, and the reviewers had rightly asked what they were. So the first ADR of the harness
is that the harness is untracked: the agents, skills, rules, hooks, tools, the local rules file,
the ADRs and every spec, plan and report. The mechanism is .git/info/exclude, the local
ignore file, never the tracked .gitignore a well-meaning agent would otherwise "fix".
Two files are tracked, because the team wrote them: a short persona and the architecture blueprint. The docs-sync skill reports drift in those two instead of editing them; changing them is a team decision and its own PR. Before every push, a diff of the range against the local-only paths must print nothing, and since the audit that check is the git-guard hook, not a sentence.
The consequences are accepted and written down: no CI check guards the harness, so its
verification is local; a worktree session still loads the main checkout's harness; and the whole
thing is one git add away from being shared if the team ever wants it. Until then it
is one person's tooling and carries no team commitment.
10. What it cost, what it bought
| Agent type | Runs | Tokens | Avg / run |
|---|---|---|---|
| implementer | 308 | 48.5 M | 157k |
| planner | 45 | 19.8 M | 439k |
| general-purpose (research, sweeps) | 86 | 12.8 M | 149k |
| conventions reviewer | 124 | 12.0 M | 97k |
| code reviewer | 125 | 10.3 M | 83k |
| mechanical implementer | 87 | 9.4 M | 108k |
| spec-writer | 19 | 4.8 M | 253k |
| official code review | 19 | 3.1 M | 162k |
| investigator | 12 | 2.9 M | 241k |
| generic task reviewers | 23 | 2.4 M | 105k |
| pr-creator | 13 | 0.4 M | 33k |
| Total, 28 run reports | 858 | ≈ 125 M raw | 246k – 19.2 M per branch |
What that bought, in the same six weeks: the Nx migration (ten PRs, 42 libraries, feature work never paused), a framework major upgrade with a UI-library swap across 41 libraries, the first two waves of an RxJS-to-signals migration, and the foundation plus three component waves of a new design-system kit, each with a spec, a plan, a report and a ledger. The alternative I compare against is not "the same work by hand in six weeks". It is the two of those four that would have happened at all.
The honest caveats: the dispatcher's context is uncounted; resumed agents overstate; and the largest single cost, the 19.2-million-token component wave, is the run whose review stage the audit later judged least worth its tokens.
11. Failure modes, recorded
- Confidently wrong reviewers. Two agreed on an injector-lifetime claim with no evidence; refuted by a throwaway test. Eight findings of one branch review refuted on inspection. A reviewer's finding is a claim.
- A planner with no edit tool rewrote the whole plan on every revision: two full writes, 303k tokens, on the first run. Fixed by giving it one, and later by caps.
- Output nobody asked for. 104 pre-existing type errors printed per run, read in full by every agent, until the baseline. Plans that were 99 % prose. A 16,800-word spec.
- Blocked on the environment. A branch whose
node_modulesbelonged to another branch's framework version: every first verification failed until the dispatcher ran a clean install. "Blocked (environment)" is now a report state. - Stale caches that look green. A lint cache replaying a stale pass; the Nx daemon dropping a renamed library from a run. The verification script disables the daemon.
- Refusals, some right. A subagent's own harness refused to edit the lint config as a "CI bypass"; the rule became that only the main session edits it. The pr-creator refused a vague "go on". The platform's permission classifier refused a subagent's file deletion during the memory prune, and the deletion was handed to the human as one command. Each of those is the system working.
- History surgery in a shared tree. One implementer rewrote history with low-level git commands to tidy a commit. The ruling: no implementer touches refs beyond a pathspec commit, ever; two untidy commits stay untidy because the repo squash-merges.
- The dispatcher's own hands. A string replacement with an unescaped
$`corrupted an ADR's addendum, caught by a review. The dispatcher is not exempt from the gates. - Context exhaustion, twice: once into a handover document, once into the 80 % rule. A weekly budget on the top model ran out mid-run and forced a model switch; the ledger row says so.
- Ledger holes. An accidental interrupt and an API outage lost rows; resumed agents double-count. The totals are honest about being raw.
12. Principles, and what is next
- One home per rule. A fact lives in one file; everything else points at it. The audit is what happens when you do not.
- Hooks over prose. If a rule can be a script, it is a script. "A deterministic guard for the two git rules prose used to carry."
- A structural rule names the guard that fails when it is broken, or says plainly that none exists.
- Lint is parity, not zero. A touched file comes back no worse. A ratchet only moves one way.
- Skills for knowledge, MCP for connectivity. And every MCP server read-only unless the write path is already a deliberate, human-gated command.
- Model and effort per role, in frontmatter, nowhere else. The transcription job does not get the reasoning budget.
- Rulings carry a price. "Cost if wrong" next to every decision makes reversing it a sentence instead of an argument.
- Measure the reviewers. Findings that changed code, per 100k tokens, per agent type. Then act on it sooner than five weeks.
- The human verifies; the agent never opens the PR first.
- No AI attribution in commits or PR bodies. The work is the team's; the tooling is a detail of how it was done.
Next, in the order I would do them:
- The Nx plugin's census commands fully replacing the last hand-written layout tables.
- A Playwright CLI click-through subagent as a pre-check before the human one, on the one app that has no login wall.
- Evals: a scorer over the run reports so a change to a prompt or a tier can be judged by findings per 100k and tokens per merged task, not by feel.
- Memory kept under the cap by a hook, not by an audit.
- Sharing the harness with the team, which is one
git addand a conversation.
The model is the easy part. The harness is the part you keep.