TL;DR: Honest software isn't software that tells the truth. It's software that can't lie. This is the 72-hour story of finding every place ours could — and welding each one shut.
With apologies to C.S. Lewis — though our wardrobe is a fail gate, and it only opens for the truth.
Part I — The Lying
Nobody writes a lying program on purpose. Lies accrete. Here's the honest inventory of what we found in our own codebase — a codebase whose literal brand is FAF don't lie:
- The guesser. A legacy extractor that, faced with an empty context slot, would infer a value from the project name and write it down as if it knew. Plausible. Confident. Made up.
- The file-wiper. Sync tools that overwrote your hand-written AGENTS.md, CLAUDE.md, .cursorrules — wholesale. Your words, gone, replaced by generated ones wearing your filename.
- The filename judge. Our format detector saw
manifest.jsonand declared: JavaScript. Chrome Extension. Chrome Web Store. From the name alone. Every MCP server ships amanifest.json— so our own fleet mis-identified itself. - The stale pointer. A registry entry labeled with the new, patched version — silently serving the old, vulnerable bundle. The worst kind of lie: a true label on the wrong box.
None of it malicious. All of it drift. And drift compounds: five servers, five hand-maintained copies of the same logic, five trajectories slowly forking away from one truth. The AI consuming that context was working blind while claiming sight.
Part II — The Switch
It started with someone else's honesty. A researcher at Worcester Polytechnic Institute reported a path-confinement vulnerability — privately, properly, coordinated. We patched four servers, published the advisories after the fixes were installable, credited him by name on exactly the repo he tested and no others, and when the severity looked inflated, we re-rated it down. High to Medium, because the transport math said so.
That set the bar for the whole stretch: don't claim, demonstrate. And it forced the real question — patching lies one at a time is whack-a-mole. The switch was deciding to remove the ability to lie instead. Four editions, one per day, each one closing a category:
- Trust — every score carries a parity hash any engine reproduces; every claim gets a
✪receipt a third party can re-derive. Quiet, typed, verifiable. - Grounded — the claim "AI works better with context" became
faf bench: a benchmark where your own repo grades the answers. No judge. No rubric. The .faf is the answer key. - Composed — the engines exported once, from one source. The forked copies that drifted? Deleted, not reconciled.
- Sourced — the guesser, deleted. The filename judge, made to read content before judging. Every fill comes from real evidence or stays honestly empty.
Part III — The Trust Code
Here's the part that earns the title. Each fix shipped with the code that makes the regression impossible, not just absent:
✪ MCPB SHA Gate: real + verified — or NO PUBLISH
TRUST SEAL: raw context-file write → BUILD FAILURE
server.json version ≠ release tag → BLOCKED
answer key in public output → cannot be constructed The write-guard makes the file-wiper a compile error. The SHA gate makes the stale pointer an un-publishable state. The bench API physically cannot hand out its own answer key. A lesson isn't learned until it can't be unlearned.
And the doctrine proved it polices itself, live: hours after the sourced-only release shipped, its first consumer caught the release violating its own rule — the filename judge. Patched same day, with a contract test, verified by the consumer before publish. The system caught the system.
Two Claudes, One Board
One more thing made this stretch different. Two AI sessions worked it in parallel — one on the CLI, one on the MCP server — relaying through a folder of handoff specs on local disk. No shared memory. Just written contracts.
They caught each other. The server session caught the CLI's filename-judging guess. The CLI session caught the server session planning against a version that had already shipped. One's scar was a stale pointer; the other's was a placeholder that nearly published. The gate that now exists kills both — and neither session will ever get to make its mistake again, because the gate doesn't know whose lesson it was.
Five handoffs, receipts in both directions, zero fumbles.
The Receipts
- 5 releases in 72 hours — every one verified coherent across npm, git tag, GitHub release, and registry before being called done
- 4 editions — Trust · Grounded · Composed · Sourced, every name earned mechanically
- 1 coordinated disclosure — patched first, credited honestly, severity corrected downward
- 8/15 → 15/15 — the fleet, benched cold vs with-context, graded by its own .faf files
- 843 + 567 tests, 0 fail — including the contract tests that make the old lies unbuildable
