
The Reviewer Told to Write Nothing: Independence as a Prompt Constraint
'You are an INDEPENDENT REVIEWER. You did not write this code. Change nothing — no edits, no commits.' Independence in a review loop is a property you have to spend tokens to buy.
View companion repoChange nothing is the whole job
I opened a withagents-forge session from 2026-08-06 expecting a reviewer persona, a named subagent, some harness flag that marked a loop as independent. What I found was a sentence at line 3 of the session file.
Line 3 of .claude/projects/-Users-nick-dev-withagents-forge/78686d81-ee99-40ea-8b53-e2a162ad6a3a.jsonl, file mtime 2026-08-06 15:50:
You are an INDEPENDENT REVIEWER. You did not write this code. Change nothing — no edits, no commits. Report findings only.
That is the finding. Independence in an agent review loop is not a property of the spawn. It is a constraint you write into the prompt, and the constraint is negative. Do not edit. Do not commit. Report. A reviewer that honors it is doing the job it was hired for. A reviewer that patches is doing a different job, one whose output is a diff rather than a claim.
One boundary before I go further. I counted the instruction. I did not audit compliance. I have not inspected the repo diff or the tool history for those runs, so I cannot tell you that any given reviewer actually wrote nothing. Everything below is about what the instruction establishes and what the arrangement implies, not about observed obedience.
I then counted how often that instruction appears across thirty days of Claude Code sessions. The first number I got was 300. That number is wrong. The honest number is 14. The gap between those two figures is the same lesson as the prompt itself: you cannot trust a count, or a verdict, until you know what the instrument was allowed to do with copies.
Three hundred occurrences that were fourteen
The corpus is 1,019 Claude Code session files, 615,198,221 bytes, exact window 2026-08-04T18:32:11 to 2026-09-03T18:32:12. Manifest: .planning/mine-30d-exact-manifest.json. Stats: .planning/mine-30d-exact-stats.json. Every count in this entry is deduped by unique tool_use_id for tool results, or by unique message id for text blocks. Raw byte-level regex overcounts because transcripts replay the same event across lines.
A naive grep for the independent-reviewer instruction hit 300 raw occurrences. Deduped by unique message id, it is 14 unique text blocks. The inflation factor is about 21x. Report 14. Do not report 300. 300 is the replay. 14 is the event.
The cause is visible in the same file that carries the prompt. After line 3 states the instruction, the file repeats it as last-prompt records at lines 12 and 26. Transcript replay copies one instruction into later records. A byte-level scan treats each copy as a new event. It is not a new event. It is the same prompt, written down again. Last-prompt echoes are how a session file stays coherent for the runtime. They are not how you count invocations.
One instruction, three records, is the unit of the error. The diagram is the same collapse at corpus scale.
Fourteen is the number of distinct text blocks that carry the constraint in the window. Three hundred is the number of times those bytes appear when you refuse to collapse replays. If I published 300, I would be claiming a density of independent review that the sessions do not support. The instruction is rare enough to be a method someone has to remember to invoke, not a default the harness applies. Fourteen unique text blocks in 1,019 session files, over thirty days, is a practice. It is not a background process.
I am not going to invent which fourteen text blocks they were, or which models produced them, or whether every one of those fourteen produced a finding worth keeping. The pack names a count, a raw overcount, a file, and two replay line numbers. Count: 14. Raw: 300. File: 78686d81-ee99-40ea-8b53-e2a162ad6a3a.jsonl. Replay lines: 12 and 26. That is the inventory. Treating the inventory as 300 would be the vacuous version of this post: a large green number produced by counting the same sentence until the dashboard looked busy.
The same discipline, one level up
This is a post about trusting a reviewer's verdict. The evidence about the reviewer had to be deduped before I could trust it. Same discipline, applied to the meta-level.
A review loop that reports "we found this" is making a claim about the subject. A mining pass that reports "the instruction appeared 300 times" is making a claim about the loop. Both claims fail the same way. The instrument counts copies as instances. Transcript replay is the reviewer's last-prompt echo. Three identical probes of one misconfiguration, which I will come back to, are the same failure inside the verdict itself.
If I cannot say whether 300 is 14, I cannot say how often the constraint actually landed. The constraint is only as real as the unique message that carries it. Replay is not a new invocation. Echo is not a second reviewer. A last-prompt record at line 26 of the same file is not a new decision to review. It is the original decision, stored again.
The method is mechanical. Collapse by message id. Name the raw number as the wrong one. Keep the deduped number as the one you will defend. I am using 14, and I am naming 300 so the next person who greps the same string does not "correct" me upward. Correction in that direction is how you staff a process on noise.
The reviewer prompt and the mining pass are doing analogous work. Both are asked to look at a tree and return a count of what matters. Both will lie if you let them treat a copy as a case. Dedup is not a polish step you run before publishing. Dedup is how you find out whether you had a fact.
What the constraint buys
The prompt does three pieces of work in one paragraph.
"You are an INDEPENDENT REVIEWER" names the role so the model does not inherit the author's context as its own. "You did not write this code" severs authorship. Authorship is the usual excuse for a quiet patch: I wrote it, I see the bug, I will just land the fix. The sentence takes that excuse away. "Change nothing — no edits, no commits. Report findings only." is the load-bearing clause. Without it, independence is a mood. With it, the reviewer has no permitted path to a patch.
Subject pinning is the second piece. A variant of the same instruction names the tree and the commits:
Repo: /Users/nick/dev/withagents-forge
Commit under review: b1bfa7c1 (and 43652461, th…
Independence without a pin is a reviewer of whatever happens to be in the worktree when the session starts. The pin makes the verdict about named commits rather than the ambient tree. The line is truncated after the second hash, so what it establishes is at least those two, not exactly those two. I am not going to finish th… into a third hash, and I am not going to call it a pair when the source does not close the list.
I did check the pin. Both hashes resolve in withagents-forge: b1bfa7c1 is "test(browser): emit VERDICT=PARTIAL when the live path never ran" and 43652461 is "refactor(browser): split the session API instead of guarding a boolean", both dated 2026-08-06. That is what a pin is for. The subject of the verdict is checkable by someone who was not in the session, which is the whole property I am after.
What the constraint buys, stated only as far as the transcripts go: the reviewer's output is prose, attributed to a named subject, that a second party can independently verify or refute. I did not run the other arm. I have no transcript of a reviewer with edit rights working the same commits, so I am not going to describe one.
The left column is the loop I am refusing. The right column is the loop the prompt installs. Same operator, same gap, different permission, different artifact. Crimson is the patch you never asked to see. Violet is the sentence you can act on.
What it costs
The reviewer cannot fix anything. Applying a fix needs a write-authorized actor. That is the trade.
The second actor might be me. It might be another agent with write permission, pointed at a specific finding, not at "make the review pass." Those are different jobs, and the contract keeps them separate by construction: a reviewer held to this instruction is not supposed to merge finding and fix into one unlogged step.
The cost shows up as latency and as ceremony. A finding sits in a report until someone else picks it up. Whatever the finding describes stays as it is for the length of that handoff. The temptation is to let the reviewer "just fix the obvious ones." The constraint exists because the reviewer's idea of obvious is not an operator decision, and because a claim in prose can be audited by a third party in a way a self-approved edit cannot.
There is a second cost, and it follows from the contract rather than from anything I observed downstream. A reviewer that honors the instruction can only emit a report. Whatever quality that report has is the entire quality of the review, because there is no accompanying diff to inspect. That is a property of the arrangement, not a claim about how any of these fourteen turned out. It is also why the counting discipline belongs here. Deduping does not make a reviewer independent; the instruction is what asks for that, and I did not measure whether it was honored. What deduping decides is whether my evidence about the practice is worth anything. Counted raw, the constraint shows 300 raw occurrences. Counted by unique message id, it is 14.
I did not read the fourteen reports, and I did not check whether the fourteen reviewers obeyed. I counted the instruction, not the outcomes. What the corpus gives me is the instruction itself, a pinned-subject variant whose commits I resolved independently, and the replay arithmetic. The trade is legible from the contract alone: a reviewer held to the sentence stops at the sentence. Stopping is the feature. It is also the bill.
What the window actually supports
The honest picture, for this window, is small. Fourteen unique text blocks carry the constraint. One file shows the instruction at line 3 and again as last-prompt at lines 12 and 26. One variant pins the subject to commits I resolved independently against the repo. Everything in this post comes from those session files and from the commit lookups I ran against them. That is enough to state the trade and not enough to grade those fourteen blocks. I am not going to invent a success rate.
Independence is bought with an explicit constraint. The price is that the reviewer cannot fix what it finds. Allowing writes would combine the reviewer and implementer roles and remove the guarantee that the output is findings-only. Keeping them apart buys something narrower than correctness: a finding stated in a form a third party can check. What I can show you is the instruction, counted honestly, pinned to commits that resolve. Whether the reviewers obeyed it is a separate audit, and it is the one I would run next.
Continue the series
- 64SeriesThe Keyboard Trap Video.js Hid: A Control Bar You Cannot Tab ToWCAG 2.1.1 and 2.4.3 both fail when a player hides its own control bar from the keyboard. The fix was three lines of CSS and one line of reasoning.
- 63SeriesRead Exists But Is Not Enabled: The Difference Between Absent and WithheldA tool that does not exist and a tool that exists but is switched off produce different error text, and only one of them is a configuration problem you can fix.
- 62SeriesRanking by the Only Field You Have: When the Schema Silently Picks Your MetricTwo independent agents, same model, same session tree, reached the same conclusion within minutes: the fields they needed to rank by did not exist, so they ranked by message count.
- 61SeriesThe Tool That Was Never There: Two Ways an Agent Misses a Tool, Only One Emits an ErrorSixteen unavailable-tool events in 30 days, every one a structured tool error an orchestrator can catch. Then a separate turn that answered in prose and produced no tool event at all, which needs a different check.