[← Blog]

Prove It To Land

A green pull request is not proof the thing works. It is proof that some code compiled, some tests passed, and nobody objected. When agents are the ones writing and merging that code — as ours are, most hours of most days — the gap between “the PR merged” and “the capability works” stops being an academic point. It is the exact place bugs ship from.

So we closed it. Nothing lands in LastDB unless it carries a filled-in proof that the user-visible capability works — and that proof was produced by something other than the author. This post is about the gate, and about the two ways a change lies to you about being finished.

The bug that made the rule

A user could set a master password on their node. After a restart, that password would not unlock it. Each half had shipped in its own tidy pull request; each one looked complete in isolation. Set: done. Unlock: also, apparently, done. The capability — “set a password, then later get back in with it” — was never whole, because no single check ever asked for the whole thing at once.

That is failure number one: the half-built feature. It hides between pull requests. Every diff is defensible; the seam between them is where the user falls through.

The tell: write-only validation

Failure number two is subtler and lives inside a single change. The write half gets exercised — setting the password is tested, and the test is green. The read half never is. setPassword() has a test; unlock(password) does not. “Can be set but doesn’t actually work” is, every single time, a missing round-trip assertion wearing a green check mark.

Both failures share a root: the proof, where it existed at all, was anchored to the diff instead of the user. “Adds set_master_password” is a description of code. “A user can set a password and later unlock with it” is a description of a capability — and you cannot honestly write that sentence as your proof unless unlock actually exists and actually works. Anchoring the claim to the user’s seat turns completeness from a hope into a precondition of landing.

Cross a boundary, or you’ve proven nothing

The master-password bug survives every in-process test, and it always will. Set the value, read it straight back — it’s right there in memory, of course it matches. The thing holding the value never went away, so the test never had a chance to catch that the value doesn’t survive the thing going away.

A real proof of a stateful capability has to cross a boundary: act (write the value), then restart the node, re-open the app, or re-fetch on a fresh connection — and only then assert the read-back. The boundary is not a detail of the test. It is the entire point of the test.

ACT set a password THE BOUNDARY restart · re-open · re-fetch ASSERT unlock with it SET→GET IN MEMORY NEVER CROSSES — IT PASSES WHILE THE APP IS BROKEN
Fig. 1 — the boundary is the test; an in-memory round trip skips it

And the check has to include the unhappy path: a wrong password rejected, a missing permission denied, invalid input errored. A gate that only ever passes the happy case is a gate that always says yes — which is the same as no gate.

Proof, proportional to blast radius

A universal “demonstrate it works” rule dies one of two deaths if you apply it flatly. Make it heavy for everything and people route around it; a bypassed gate is worse than none, because it still looks like coverage. So the principle is universal but the form of the proof scales with how far a change can reach.

BLAST RADIUS NO BEHAVIOR CHANGE rename · docs · refactor tests still green — one line why LOGIC WITH A UNIT a new rule or branch a test + a negative case USER-VISIBLE / STATEFUL auth · settings · sync · a data write the real-app round trip
Fig. 2 — the same rule, three weights; heavier when in doubt
  • No behavior change — a rename, a comment, a refactor. Existing tests still green, plus one line saying why it’s behavior-preserving. That’s the whole obligation.
  • Logic with a testable unit — a test of the new behavior and a negative case.
  • User-visible or stateful — auth, settings, sync, a data write. The real-app round trip, across a boundary, with a negative case. No exceptions, and when you’re unsure which tier you’re in, you’re in this one.

The cheap tier stays cheap on purpose. What keeps the gate from eroding isn’t severity — it’s consistency: every change carries a proof, even if the proof is a single honest sentence.

The author does not get to certify themselves

Every pull request carries a short, machine-greppable block — a claim written from the user’s seat, the tier, exactly how it was checked, and what confirmed it. The last field is the load-bearing one: the proof has to be reproduced by something other than the author. A fresh agent that runs the actual app on a throwaway data directory. A CI job. Not the author’s own say-so. If a verifier can’t reproduce the claim, the change doesn’t merge.

## PROOF claim · tier · how verified-by WRITTEN BY THE AUTHOR reproduce VERIFIER a different agent RUNS THE THING MERGE opens only if it reproduces
Fig. 3 — claim written by the author, confirmed by someone else, before the gate opens

Why this is affordable here

A prove-it-to-land policy is normally too heavy for a human team — the toil of demonstrating every change works, from the user’s seat, every time, is exactly the tax nobody wants to pay. But the toil here is paid by the fleet of agents, not by a person. So the discipline that human teams can only aspire to becomes the natural default: the only path we’ve left to “done” is the one that runs the thing.

A merged pull request is a milestone. The capability demonstrably working — across a boundary, checked by someone other than the person who wrote it — is the finish line. We stopped letting the milestone masquerade as the finish line, and the seam between the two is where we stopped shipping bugs.

Part of the same system that lets an autonomous agent loop merge its own work — safely.

[← Blog]