Harness Engineering / The Comprehension Standard / v0.1, forkable

Don't merge a change you can't explain

An agent can produce more correct-looking code in a day than a team can understand in a week. Nothing stops that except a rule about what you are allowed to merge. Every team says it wants to understand its own code. A standard is what turns that sentiment into something you can adopt, cite in a policy, check in a pull request, and argue about when it gets inconvenient. This is that document, and it is deliberately short.

spec and reference implementation · github.com/tacoda/fulcorum-comprehension-standard
who it's for · any team merging agent-written code, and the lead who has to set the bar
adoption cost · one afternoon to wire up, then the ongoing cost of meaning it
license · CC BY 4.0. Fork it, rename it, change the fields. Keep the law.
The claim
What the person merging asserts about the change. Four fields, written by a human, in a pull request.
The gate
What the harness refuses. It can check that a claim was made. It cannot check that the claim is true.
The evidence
The test that goes red if the claim is wrong. This is the part that turns an opinion into a fact.
0 Adoption

Adopt it in an afternoon

The whole standard is one law, one block of four fields, and a bar for when it's enforced. Three moves put it into a repo. Read the rest of the page afterward if you want the reasoning.

file .github/pull_request_template.md gate hooks/comprehension-gate.py charter CLAUDE.md
the three movesone afternoon
git clone https://github.com/tacoda/fulcorum-comprehension-standard.git

# 1. the claim: every PR now asks for four fields
cp fulcorum-comprehension-standard/.github/pull_request_template.md .github/

# 2. the gate: refuse a PR whose block is missing or unfilled
cp fulcorum-comprehension-standard/hooks/comprehension-gate.py .github/scripts/

# 3. the law: put it where the agent reads it, not just where people do
cat fulcorum-comprehension-standard/LAW.md >> CLAUDE.md

Then decide one thing as a team and write it down: which changes require which level (section 4). That decision is the standard. Everything else is plumbing.

The honest cost

Wiring this up takes an afternoon. Meaning it takes longer, because the first week it will block a change somebody wants merged, and the standard is only worth anything if it holds that week. A gate the team routinely waves through is worse than no gate: it teaches people that written rules here are decorative.

1 The law

One law, and it is not negotiable

Everything below is machinery for enforcing a single sentence.

The law

Don't merge a change you can't explain. Not to a reviewer, not to the agent, not out loud in your own words. If you cannot say what it does, you have not finished reading it.

"Explain" is doing real work in that sentence, so pin it down. Explaining is not summarizing the diff back. A diff summary is a restatement of syntax, and the agent will write you a beautiful one on request. Explaining means you can say what the change does to the system, where it enters and where it leaves, what rule it obeys, and what would have to be true for it to be wrong. Those four things are section 2.

The law binds the person who merges, not the person or process that wrote the code. This is the point. When an agent writes the change, authorship stops being a useful place to put accountability, because the author has none: it doesn't get paged, doesn't sit in the postmortem, doesn't answer for the outage. Merging is the last human decision in the chain, so that is where the obligation lands.

Why a law and not a guideline

Guidelines lose to deadlines, quietly and every time. The one obligation that cannot be delegated to a tool is the obligation to understand, so it gets stated as an absolute and the exceptions get written down in advance (section 4) rather than invented under pressure.

2 The claims

Four claims, made in the pull request

"I understand it" is unfalsifiable. Four short fields are not. This block goes in the pull request body, written by the person asking for the merge.

the comprehension blockwritten by a human, in the PR
comprehension:
  does:      <what this change does to the system, in one sentence>
  seam:      <where it enters> -> <where it leaves>
  policy:    <the rule or doc this obeys>   | CHARTER-GAP
  falsifier: <the case that would make this wrong>
             covered by: <test name>         | NONE
  1. does One sentence, about behavior, not about code. "Adds a helper and updates two callers" is a description of the diff. "Cash totals now round down to the nickel instead of to the nearest one" is a description of the change. If the sentence needs an "and" you may be merging two changes.
  2. seam Entry and exit. Where does data reach this code, and where does the effect land: a response, a row, a file, a charge. This is the field that catches "I read the function but not its callers," which is the most common way a change looks understood and is not.
  3. policy Cite the rule this obeys. A charter rule, a doc, a ticket, an ADR. If nothing anywhere in the repo answers "why is it written this way," write CHARTER-GAP and open the gap as an issue. That is a finding, not a failure, and it is one of the more valuable things a junior produces.
  4. falsifier Name the case that would make this wrong, then name the test that covers it. This is the field that separates reading from understanding. If you cannot describe a world in which this change is incorrect, you don't yet know what it does. NONE is permitted, and it means you shipped a declared risk instead of a hidden one.

Four fields, well under a minute when you actually understand the change, and genuinely hard when you don't. That asymmetry is the entire mechanism. The block is not paperwork about the work, it is the shortest test that the work was understood.

Don't let the agent fill this in

Asking the agent to write your comprehension block produces four fluent, plausible, often correct sentences and teaches you nothing, which inverts the point of the exercise. Write it first, in your own words. Then, if you like, ask the agent to argue with it. Getting corrected after you have committed to an answer is how the judgment actually forms.

3 The levels

Four levels of comprehension

Understanding is not binary, so the standard grades it. Each level is defined by evidence somebody else can check, not by how confident the author feels.

CS v0.1 comprehension levels
LevelThe claimObservable evidence
L0 Passing "The tests passed." A green pipeline. No claim is made about the change itself, and none should be inferred from green.
L1 Restatement "I can say what it does and where it lands." does and seam filled and accurate. The author can restate both without opening the diff again.
L2 Falsification "I can say how it would be wrong, and I checked." All four fields filled. falsifier is covered by a named test, and that test goes red when the change is reverted or broken.
L3 Defense "I can say why this way and not the other way." L2, plus the author names the alternative that was not taken and why this one is the choice the codebase's policy requires. Survives a reviewer arguing the alternative.

The jump from L1 to L2 is the one that matters and the one people skip. L1 is a description, and an agent can hand you a correct description of code that is quietly wrong. L2 requires you to have imagined the failure and gone looking for it. That is the habit the whole standard exists to install, and it is exactly the habit that shipping-fast erodes first.

L3 is where architecture lives. Most contested engineering decisions have several answers that all work, and the right one is the one consistent with how this system already does things. An agent optimizes for a working answer and has no stake in that consistency, which is why drift compounds silently in agent-heavy codebases.

Levels grade diffs, not people

A level describes a change at merge time, not an engineer's seniority. A staff engineer merges an L1 dependency bump on Tuesday. A first-year engineer merges an L3 change to a pricing rule on Wednesday. Reading the levels as a career ladder is the fastest way to turn a useful tool into an insult.

4 The bar

The merge bar, and its exemptions

A standard that demands maximum rigor everywhere gets ignored everywhere. Set the bar at L2, raise it to L3 where being wrong is expensive, and write the exemptions down before you need them.

  1. Default L2 for ordinary changes. All four fields, a real falsifier, a test that covers it. This is the working bar and it should feel routine, not ceremonial.
  2. Raise to L3 Money, security and authorization, data integrity and migrations, anything with a written policy, and anything you cannot cheaply roll back. These are the changes where a plausible answer and a correct answer diverge quietly and expensively.
  3. Drop to L1 Changes with no semantics: formatting, generated files, copy edits, dependency bumps with an unchanged lock. Name the categories explicitly in your charter. An unwritten exemption list expands to fit the deadline.
  4. Never L0 L0 is a description of what green means, not a bar anyone is allowed to merge at. It exists in this document so that "the tests passed" has a name and can be recognized as the non-claim it is.

One rule of thumb keeps the L3 list honest: ask what the cost is of being confidently wrong. If the answer is a refund program, an incident, a regulator, or a migration you cannot reverse, it is L3. If the answer is a follow-up commit, it is L2.

The failure mode to watch

The bar does not erode by being argued down. It erodes by exemption creep: one urgent change waved through, then the next one citing the first as precedent. If you skip the bar, record that you skipped it and why, in the PR, in the same block. A logged exception is a decision. An unlogged one is a new default.

5 Conformance

What it means to conform

Conformance is a property of a team's process. There is no auditor, no badge, and no way to fail it other than by not doing it.

A team conforms to CS v0.1 if all five of these hold:

  1. 1 · The law The law is written in the charter the agent reads, not only in a wiki page humans have bookmarked. If the agent never sees it, it is not part of the system.
  2. 2 · The claim Every merged pull request carries a filled comprehension block, written by the person requesting the merge.
  3. 3 · The bar The merge bar is written down, including the L3 list and the exemption list, and exceptions are logged in the PR rather than taken silently.
  4. 4 · The gaps CHARTER-GAP is routed somewhere a human owns and answers. If it is only typed into a box and never read, field three of the block is theater.
  5. 5 · The review Reviews examine the claims, not only the diff. A reviewer who never disputes a falsifier is not reviewing comprehension. Reverse-review is the exercise that trains this.
Team-level, on purpose

Every conformance item describes something the team does, never something a person scores. This is not politeness. A standard that produces per-person numbers becomes a performance instrument within a quarter, and the moment it does, people optimize the number instead of the understanding, and you have paid for the ceremony without buying the comprehension.

6 Reference impl

Reference implementation

A template that asks for the claim, and a gate that refuses a pull request without one. Both are short enough to read in full, which is deliberate.

template .github/pull_request_template.md gate comprehension-gate.py

1 · The template asks

.github/pull_request_template.mdthe claim
## What and why

<!-- Required by the Comprehension Standard v0.1. Write this yourself,
     before you ask the agent for anything. Level: L2 default, L3 for
     money, security, data integrity, or a written policy. -->

```comprehension
does:
seam:
policy:
falsifier:
           covered by:
```

level: L2
exception: none

2 · The gate refuses

hooks/comprehension-gate.py, run in CI on the PR bodyexit 1 blocks the merge
import re, sys

REQUIRED = ("does", "seam", "policy", "falsifier")
PLACEHOLDER = re.compile(r"^(todo|tbd|n/?a|\.+|\?+)$", re.I)

def check(body):
    block = re.search(r"```comprehension\n(.*?)```", body, re.S)
    if not block:
        return ["no comprehension block in the PR body"]

    text = block.group(1)
    # [ \t] not \s: \s spans newlines, so an empty field eats the next one
    fields = dict(re.findall(r"^[ \t]*(\w+):[ \t]*(.*)$", text, re.M))
    problems = []
    for name in REQUIRED:
        value = fields.get(name, "").strip()
        if not value:
            problems.append(f"{name}: empty")
        elif PLACEHOLDER.match(value):
            problems.append(f"{name}: placeholder ({value!r})")

    falsifier = fields.get("falsifier", "").strip()
    if falsifier and falsifier.upper() != "NONE":
        if not re.search(r"covered by:[ \t]*\S+", text):
            problems.append("falsifier: named, but no covering test")
    return problems

if __name__ == "__main__":
    found = check(sys.stdin.read())
    for p in found:
        print(f"comprehension-gate: {p}")
    sys.exit(1 if found else 0)

Roughly twenty-five lines, and that is the whole enforceable surface. Everything else in this document is a decision a team makes, which is the correct division of labor: machines are good at insisting a step happened, and bad at judging whether it happened well.

What this gate cannot do

It checks that four fields exist and are not placeholders. It has no opinion about whether the sentences are true. A confident, articulate, entirely wrong block passes cleanly, and any honest description of this standard has to say so. The gate buys one thing: nobody merges without making the claim, and a claim on the record is something a reviewer can dispute. Disputing it is human work. Reverse-review is how a team gets good at that work.

7 Non-goals

Scope, non-goals, and known weaknesses

What this standard refuses to be, and where it is most likely to fail you. Both stated before you adopt it rather than after.

Non-goals

  • Not a certification. No badge, no exam, no auditor, no registry. If someone sells you compliance with this, they made that up.
  • Not a performance metric. Block fill rate never belongs in a review packet. Score it and you will get four true sentences guarding a change nobody read.
  • Not a replacement for tests, types, static analysis, or review. It sits on top of those and assumes they exist.
  • Not a maturity model. There are no organizational tiers to ascend. A team either does the five things in section 5 or does not.
  • Not anti-agent. Use the agent for everything, including as a tutor on the code it just wrote. The standard governs what you merge, not what you generate.

Where it is weakest

  • falsifier is the field people fake first. The tell is a falsifier that restates the happy path inverted ("it would be wrong if it returned the wrong value"). A real falsifier names a specific input and a specific wrong outcome.
  • It is uncomfortable on very large diffs. One sentence for a 900-line change is either a lie or an argument for splitting the change. Usually the second.
  • It does nothing for code already merged. This is a bar on new changes. Comprehension debt already in the tree needs a different instrument.
  • v0.1 is small-team evidence. It has been used on small teams. There is no data on how it behaves across a large organization, and claiming otherwise would be exactly the kind of plausible, unfalsifiable statement this document exists to catch.
The one thing it does grade

Diffs and reviews. Never people. If your adoption of this standard ends with a dashboard ranking engineers, you have built something else and should stop calling it this.

8 Version

Version, license, and how to fork it

v0.1, CC BY 4.0. Forking is the expected case, not the exception.

Forking

  • Keep the law. Everything else is implementation. A fork that drops the law is a different document and should have a different name.
  • Change the fields to fit your domain. A team shipping infrastructure might swap seam for blast-radius. A team on regulated data might add data-class. Four to five fields is the working range; past that, people stop reading them.
  • Set your own L3 list. The one in section 4 is a starting point, not a claim about your business.
  • Version your fork and date it. A standard nobody can cite by version cannot be argued with, and being arguable is most of the value.

What would move this to v0.2

  • Field names that survived contact with teams that did not write them.
  • An exemption list that stopped needing constant patching, which is the signal it finally describes reality.
  • Actual evidence about faking: how often blocks are filled fluently and wrongly, and whether reviewers catch it. That is the number that decides whether this standard does anything at all.
Where to go next

The standard sets the bar. Reverse-review is the weekly exercise that trains people to clear it and to dispute a claim that only looks cleared. The junior-to-senior workshop is the one-hour lab where the whole idea starts, with a green test suite and a customer quietly overcharged a nickel.