Latch

Could a model reword a passage freely while every locked fact stays exactly the same (who did what to whom, the numbers, the dates) and could software prove it? Seven designs and two blind tests later, the answer was not reliably, so I stopped.

Made
Written by
Claude Code, directed by me, with Codex as an adversarial reviewer
Built with
Python, spaCy, a semantic role labelling model
Status
Concluded

The question

When a model writes text for you, it decides what varies. I wanted to flip that: write down a contract of the facts that must not move, let the wording change as much as it likes, and check every output against the contract.

The locked parts are specific:

The question was whether that could be made materially more reliable than careful prompting alone.

How it works

It started as a generation harness. A contract goes to a model, which renders it many times, and a different model checks each rendering claim by claim. I ran the models through their command-line tools (Claude Code, Codex and Antigravity) rather than through an API.

That harness produced the first surprise. When two models disagreed about whether a claim survived, I read every disagreement by hand. One model, acting as the checker, flagged about ten times as many false violations as the other. It even flagged the unmodified reference text itself. A model marking another model's homework needed checking too.

So the work became a verifier. Given a reference and a rewrite, it tries to prove each locked dimension was kept, or prove it wasn't. When it can't prove either, it says so and abstains rather than guessing. Abstaining is allowed. A confident wrong "yes" is the failure that matters.

How I tested it

The ladder

DesignWhat changedFalse accepts
ADeterministic checks for entities, values and negation24.4%
B+ dependency parsing, to catch swapped rolesnot kept
CA + semantic role labelling (in place of B)28.9%
C2Same model, stricter rule for combining evidence3.0%
C2 v2Three general bug fixes1.0%
C3Scope judged by meaning, not by category names0.67% blind
C3The same design, second blind set1.34% blind
C4Every declared dimension must be proven5.9–7.0% blind

Rows A to C2 v2 are measured on my holdout sets. Rows marked "blind" are measured on the unseen sets. Design B fixed the templated role swaps in HANS but barely changed results on real prose. It also added twelve new false rejections, so it didn't earn its place.

The biggest single lesson is the jump from C to C2. The model and the representation were identical; only the rule for combining evidence changed. Under C2, the deterministic checks could reject a rewrite on their own but never accept one on their own, and every locked dimension needed positive proof. False accepts fell about tenfold. How you combine evidence mattered more than which representation you pick.

7designs, one change at a time
5,440test cases, 1,800 of them blind
0.67%best false-accept rate, first blind set
1.34%on the second blind set, over the bar

What didn't work

The pattern is the finding. Three designs in a row fixed the problem they targeted and exposed a new, equally serious one a layer deeper. That isn't a sequence converging on a working system. It's a reason to stop rather than build C5.

What's worth keeping

When to reopen it

Only if something genuinely new appears. That could be a much better way to represent who does what to whom, or a way to prove preservation without recreating the evidence-combining problem that sank C4. I won't reopen it out of an obligation to finish what I started.

The most durable result was the discipline itself: letting the evidence kill an attractive idea instead of rescuing it.