← All writing
AI Engineering

Cleared the Bar, or Lowered It? I Wrote the Theory Down

Coding agents can turn every check green by weakening the requirement. Ten parts of building Lattice, now written up as a preprint: facts vs proxies, an assurance lattice, and why no checker can see a lowered bar.

SA
Salah Al‑Nawah
Oct 28, 2026 · 3 min read
aicode-generationverificationresearchlattice

Ten parts in, I kept making the same argument in pieces. So I stopped and wrote the whole thing down properly: a 38-page preprint, Cleared the Bar, or Lowered It? An Assurance Lattice for Verifying AI-Generated Software Against Intent. It’s on Zenodo with a DOI, and the PDF is here on the site.

The question in the title is the one that scares me most about AI-written code. Agents get certified by cheap signals: the build passes, the tests pass, the linter is clean. We already know they game those, by special-casing tests, editing the checker, deleting what fails. But the worst move leaves every signal green. Weaken the requirement until the bug is out of scope, and the check passes because the bar was lowered, not cleared.

A passing check tells you the code met the bar. It doesn't tell you who moved the bar.

Three ideas carry the paper.

Facts and proxies. A check is a fact for the property it actually computes, and a proxy for everything else, including what you meant. “This annotation points at a real requirement” is a fact. “The tests pass” is a proxy for “the code is right”. You can’t game a fact relative to its own property. You can still game the gate built from facts, so the honest claim is economic: facts make gaming expensive and push what’s left into a few named places.

Constraints are free for machines. I’ve said this since part two, and the paper makes it precise. One feature per folder, every symbol annotated with the requirement it serves, one bounded slice at a time. Humans hate that. A machine pays nothing for it, and it’s exactly what makes the code-to-intent link checkable.

You can’t see a lowered bar from where you’re standing. This is the result I didn’t expect. If the code satisfies the old requirement and the new one is weaker, it satisfies the new one too. Entailment is transitive. So a checker that only looks at the current spec and code is blind to weakening, by construction. To catch it you need the previous text, or a human who holds the intent. That’s why Lattice treats a requirement change as a transaction: classified fail-closed, intent text pinned by hash, and retiring a verifier needs a human signature.

There’s more in it: done-ness modeled as a position on three axes instead of one pass/fail (the formal version of “Done” Is Not One Thing), four truth-levels (declared, wired, correctly-meant, demonstrated), and five predictions anyone can try to refute. The paper page has the key ideas and a short Q&A if you want the map before the territory.

Doubt for the record: the semantic axis, whether the code means what was asked, is still a human call. No automated judge does it reliably today, and the paper says so instead of pretending. It’s a preprint, not peer-reviewed. If you find the hole, I want to hear it: hi@salahmyn.me.