← Back to Blog

Coherence checks: making the corpus falsify itself

A weekly review is not a memory exercise. If I am relying on my Tuesday-morning self to notice that a project has not moved in three weeks, or that a principle I claim to hold has zero evidence behind it, I am relying on the exact faculty that failed everywhere else. So I stopped. Six checks run before I sit down. The judgment part comes after, and it is much shorter.

That is the whole thesis of this post: a review that depends on human vigilance to catch drift is not a review. The corpus should catch its own drift and hand you a list.

Six coherence checks in a row, five styled as script checks and one in purple as persona judgment, all feeding a box labeled findings, never edits, which flows into a green box labeled you decide.

Earlier in this series I described what happened when nothing enforced the schema. The other half of that argument is that every frontmatter field in a SpecSelf record exists to make some check mechanical. This is the post where those checks actually run. Everything below is defined in one public file, steering/coherence.md in the Starter, and most of it now executes as one stdlib Python script you can point at your own corpus.

The six checks#

The records in a SpecSelf corpus form a stack: principles and a vision at the top, goals under them, projects under those, journal evidence at the bottom. Every non-ground artifact declares what it serves in frontmatter, and those serves: links are a graph. Coherence is the property that the graph actually connects: every project ladders up to a goal, every goal serves the vision or a principle, every area gets enough attention to hold its standard. Incoherence is the normal entropy of a life. You take on projects that serve nothing, set goals that quietly betray a principle, and starve a domain for a month without noticing.

The six checks walk that graph in order. The orphan check goes upward: does every active project serve an active goal, and every active goal serve the vision or a principle? The contradiction check asks whether any active goal pushes against a principle you claim is revealed by your own behavior. The starvation check goes downward: which area got no evidence at all this period? The capacity check counts active projects against realistic bandwidth, because seven active projects with five stalled is not ambition, it is a coherence failure where nothing actually moves. The staleness check is the pruning loop: any artifact past its review cadence with no new evidence is a candidate for contested. And the drift check watches the evidence itself: has an aspirational principle quietly earned promotion, or a revealed one stopped being true?

Each check produces findings, never edits. That rule is load-bearing and I will come back to it.

Why these six and not a seventh#

The set is closed on purpose. These six are the drift the schema can actually see: each one reads a specific frontmatter field, which is exactly why those fields exist. Orphans fall out of serves:. Staleness falls out of last_reviewed:. Drift falls out of kind: plus the dated evidence sections. A seventh check, "is this principle still true," is not mechanical, and pretending it is would be worse than not running it.

The split showed its edge when the checker was built. Five of the six checks reduced cleanly to code. The contradiction check did not, because deciding that a goal pushes against a principle requires actually reading both and understanding what they cost each other. The script does not fake it with keyword matching. It prints one line saying the check is deferred to persona review, and a rotating persona lens, the subject of its own post in this series, carries it instead. Everything the schema can catch, the validator catches. Everything it cannot, a persona interrogates. Judgment and mechanics do not overlap, and the boundary between them is written down.

What running it feels like#

Sunday morning, the report comes first, before any prose, before any reflection. The format is deliberately small. This one is illustrative, built from the fictional example corpus that ships with the Starter, not from my records:

Coherence - 2026-05-30 (your-life)

Orphans:        1
  project: redesign-portfolio serves no active goal
Contradictions: not mechanically checkable, deferred to persona review
Starved areas:  1
  health: 0 evidence in 21d
Over-capacity:  yes (7 active projects, 5 stalled)
Stale:          1
  goal: learn-piano, past cadence with no evidence, recommend contested
Drift:          1
  aspirational -> revealed candidate: give-feedback-i-d-want

The script stops there, at the findings. The reviewing persona takes over for the part the steering doc reserves for judgment: rank the findings instead of treating all six as equally urgent, and end with one sharp question. For a report like the one above, that question writes itself: seven active projects and a starved health area for three weeks, so what comes off the list?

A clean report is boring, and I have learned to appreciate boring. A report with findings in it is the review's whole agenda. Nothing subjective happens until the mechanical audit is done. Readers of the SDD posts will recognize the flow, because it is the same one: the discipline lives in the specs, the automation lives in the pipeline, and the human shows up for the part that needs a human.

The report also carries the system's manners. A starved area is a question, not a verdict, because a deliberately starved area during a known season, a new baby, a crunch, is a choice and not a failure. The check's job is to make the choice visible, not to moralize about it. The steering doc is explicit: ask before judging.

What breaks if you skip it#

I know exactly what my review defaults to without the mechanical layer, because I ran reviews that way for years. It defaults to whichever concern was loudest that week. The project that happens to be on fire gets the attention; the area that went silent gets nothing, because silence is precisely what vigilance cannot hear. That is anxiety-driven review. It feels thorough while systematically missing everything that fails quietly.

The checks invert that. Silence becomes a finding. A goal nobody has touched in two quarters becomes a line in a report instead of a fact I rediscover in November. The validator does not make me wiser on Sunday morning; it makes the quiet failures exactly as loud as the loud ones, and then judgment can be about the whole field instead of the squeaky corner of it.

There is a second failure mode it prevents, subtler than the first. Findings, never edits. The script recommends contested; it never flips a status. The persona surfaces the contradiction; it never rewrites the goal. Resolution is the human's act of will, every time. An auto-fixing checker would be tidier and it would slowly dissolve the one property that makes the corpus worth keeping, which is that every word of it is mine. The same rule that governs the whole system governs its smallest script.

Steal the shape#

You do not need SpecSelf for any of this. You need three ingredients: records with a little structure, a closed list of mechanical checks over that structure, and a hard line between what the checks may find and what only you may decide. The six checks and the script are in the Starter under MIT if you want a working example to fork, and the report format fits in a terminal screen on purpose.

The move generalizes past personal systems. Any corpus that accumulates, a backlog, a decision log, a runbook collection, drifts in exactly these ways: orphans, contradictions, starvation, staleness. If your review of it depends on someone remembering to look, you already know which failures it misses.

Externalized memory only works if it is consulted by default, which is the whole argument of institutional memory for a team of one. Coherence checks are that idea at the review layer. The corpus does not just hold the record; it audits the record on a schedule. What I do is decide. What the schema does is refuse to let me not-decide.


Related:

Keep reading

Demo

Watch the agent write

A polish agent drafts an essay against a pre-approved topic.

Read
Post

Lesson 1: The spec directory

First lesson in a series on running an AI-powered software team of one. Before you ask an agent to build, give your project a home for intent: a small directory of numbered specs grown from one template your agent fills in and you approve. Directory skeleton, spec template, worked example, and a fifteen-minute exercise included.

Read
Post

When your method repo and your product repo don't talk to each other

I built a method as a public repo and the product that runs it as two private ones, and none of them treated the others as a source of truth. The domain enum lived in four places. A persona drifted between its lens file and its API contract. Here is what that cost, and the one structural change that turned the whole class of bug into a failing test.

Read
Post

I Keep My Whole Life in Spec Files. My Agent Reads Them and Never Writes Them.

Spec-driven development, pointed at a life. Why my principles and goals live as markdown an AI agent reasons over, and the one rule that makes handing an agent your life safe: it can challenge the record, but it never writes it.

Read
Post

Context architecture beats documentation dumps

Dumping the whole corpus into an AI agent makes it worse, not better. The fix is architectural: each task loads a curated slice, not everything you have. Here is the method, and the same move at three different layers: specs, sensor data, and evaluation lenses.

Read
Post

SDD isn't about managing AI agents, it's about managing context

Spec-driven development reads like a methodology for controlling AI agents. It isn't. It's a methodology for managing context across stateless sessions. The spec is the persistent memory.

Read

Follow the work

New tools and writing as they ship — pick a channel.

Written by Eric Caskey. I build AI tools you can actually use. Explore the Tools or see the case studies.