Twenty-three catches across eleven drains, and the executor caught the planner more often than I expected

September 18, 2026

My workflow has a split. Cowork plans, Claude Code executes. Cowork drafts a plan file, CC reads it, posts a pre-implementation check-in, executes commits, posts a completion report. Cowork verifies the report and signs off.

That’s unidirectional trust-and-verify. Planner checks executor. It’s the obvious direction and it’s the one most workflows codify.

Across eleven drains in Phases 3 and 4 I logged twenty-three catches. They did not all point the direction I expected.

The direction I wasn’t watching

Plan text said “no rm in the command.” CC’s grep found rm -f was present.

Plan text said the rule doesn’t require a recursive flag. CC read the regex and found the character class [rRdf] was accepting -f as if it were recursive. So the fix wasn’t adding a missing gate. It was removing f and d from the class.

Plan text said the ledger-aware skip wires into dispatch.ts. CC read that file and found it was a static map, not a runtime dispatcher. The right home was the orchestrator.

Each of those is an error a competent planner makes from a high-level mental model. Each was caught because the executor’s discipline included reading actual source before executing on plan text.

Three in three consecutive drains stopped being coincidence.

Then a third direction

I’d been thinking of it as two surfaces. Planner checks executor, executor checks planner.

Then in P4-01, CC’s pre-implementation check-in claimed tests/log.test.ts didn’t exist — based on a find that missed it. That claim went into the check-in and I approved it at sign-off. Commit 1’s path change then broke two assertions in the file that didn’t exist.

The executor’s reading of the codebase is itself a self-report. And self-reports drift.

That one hides well, because a pre-implementation read feels like reality rather than a claim. A planner writes plan text knowing it’s a mental model. An executor reads source and reports “the file isn’t here,” and that feels like a fact about the codebase. It isn’t. It’s a read performed at a specific moment with specific search patterns, and if either was off the report is confidently wrong.

The rule underneath all three

Every one of these resolved the same way: find the source that doesn’t pass through the claimant’s narrative.

Plan text is a claim. Completion reports are claims. Pre-implementation readings are claims. Verification means consulting something the claimant didn’t write — the file system, git history, the audit log, running the tests yourself.

Naming this is slightly uncomfortable, and I want to be straight about why. “The executor has to double-check the planner” can read as “the planner doesn’t know what they’re talking about.” That’s not the framing. Plan text is a written representation of a mental model, and mental models drift from code over time and across abstraction levels. A planner who hand-codes every implementation detail isn’t planning anymore. A planner who never reads source will write plan text that drifts. The executor’s check is a stability check, not a competence check.

Same in the other direction. “Planner verifies executor” isn’t “the executor lies.” It’s that a self-report is a self-report.

What it bought

Plans can be written from a high-level mental model without exhaustive code reading during drafting, because the executor’s check catches the drift. My energy goes into intent and sequencing rather than double-checking every code claim.

And errors surface at pre-implementation, where they’re cheap. Without the check they propagate into implementations and surface later as bugs.

One honest limit on the number. Twenty-three catches across eleven drains is a real count from a real ledger, but it’s my workflow, my codebase, and two specific models. I’d expect the mechanism to hold in any planner/executor split — cross-team spec handoffs, human plans plus AI execution, code review where the reviewer trusts the implementer’s summary. I wouldn’t expect the rate to transfer.

SOs

SOs — standing orders you can lift and prime your own agent with. Paste them into a session for a one-time dose, or commit them to your CLAUDE.md / AGENTS.md and they stay in force.

STANDING ORDERS — Bidirectional trust and verify
  Source: "Twenty-three catches across eleven drains" — bensimon.dev

  1. Treat plan text as claims to verify, not facts to execute on.
     Statements about file structure, mechanism, historical state and
     coverage each get checked against source before you act on them.

  2. When plan text and source disagree, surface it before executing. Do
     not silently correct, and do not execute on the disagreement.

  3. Treat your own pre-implementation reading as a claim too. "I checked
     and the file doesn't exist" is a claim you can recheck with a second
     pattern before reporting it.

  4. When verifying any report, find the source that doesn't pass through
     the claimant's narrative — git show, the audit log, running the tests
     yourself. A self-report is evidence, not authority.

  5. At each commit sign-off, re-enumerate the full scoped change list even
     when most items are obvious. Scope drops out when it falls outside the
     commit's headline change, and that gap is hard to self-catch.