# Stop Defending Your Moat with Policy (3/5)

Source: https://lodos.md/en/blog/make-your-moat-a-ratchet
Published: 2026-08-11 · Author: Samet Samyeli · Language: en · Reading time: 8 min

Policy moats rot the moment a junior engineer or a late-night refactor arrives. Two assertions run on every commit, one that fails the build on a refusal regression and one that fails the wiki on a forgotten lesson, both sealed in the same HMAC chain.

---

> Most AI products defend their moat with policy documents that quietly rot the moment a junior engineer or a late-night refactor arrives. I defend mine with two hard assertions that run on every commit: one that fails the build if I ever ship the things I swore I would never build, and one that fails the wiki if I ever let a hard-won lesson become unqueryable or contradictory. Both are sealed in an HMAC chain. The result is the only kind of moat that actually ratchets every refusal and every lesson makes the system strictly harder to regress and strictly more useful over time.

I run two scripts on every commit.

The first greps the entire codebase for things I have sworn never to ship: dynamic evaluators, value-returning secret tools, raw provider modules, the lethal trifecta of agentic exfiltration. If any of them appear, the build fails hard.

![Two mirrored columns over a shared HMAC chain: the refusal side runs code through grep for negative checks until the build fails, the knowledge side runs the wiki through lint for absence checks until integrity fails, and both write their events into the same tamper-evident log.](/blog/make-your-moat-a-ratchet/2a.webp)

The second walks the wiki and asks the opposite question. What should exist here that does not? A claim with no source. A concept page with zero inbound links. A contradiction between two pages written months apart. The first script stops the system from turning into a CVE. The second stops it from forgetting what it already learned.

I built lodos around one rule. Every refusal that matters is a grep in the build. Every piece of knowledge that matters is a versioned, queryable page.

Both live inside an HMAC chain that breaks loudly the moment anything is tampered with. Write what you refuse to add. Write what you refuse to forget. Make the build refuse to ship without both. Most AI products write down what they want to be and defend it with policy. A smaller group writes down what they refuse to become and defends it with code. The rarest group also writes down what they refuse to forget and defends it with a wiki that fails its own integrity check the moment a page drifts. That last group is building the only kind of moat that compounds.

![Policy moat versus ratchet moat: on the left a written promise passes through a junior engineer, a refactor, and silent drift with nobody noticing, and its trust curve decays toward zero; on the right grep and wiki lint fail loud on every commit, and the trust curve steps upward over the same twelve months.](/blog/make-your-moat-a-ratchet/3a.webp)

## What decays and what does not

Policy moats die quietly. "We never log secrets." "We sandbox every tool output." "We validate before the LLM sees it." These sentences live in SOC 2 documents. They are true the day they are written. Then a junior engineer adds a debug logger. A refactor moves the sanitizer behind a feature flag. The sentence stays in the document. The system no longer behaves like the sentence. Nothing fails. Nobody notices.

Knowledge moats die even faster. A founder learns at 2 a.m. why a customer churned, drops the insight in Slack, and forgets it within a week. The lesson exists nowhere that can be queried. Three months later the same pattern returns and the founder pays the same tuition again. This is the most expensive decay because the founder does not even know it is happening.

Both failures share the same cure. Bind the thing to a structure that breaks when the thing breaks. Make the build fail on a refusal regression. Make the wiki fail its own lint when a page goes orphan, drifts off-topic, or contradicts itself. The fix is not process. The fix is an assertion the system runs against itself every single time.

![The three-operation loop: ingest turns raw sources into a proposed page reviewed in a diff modal before it becomes canonical, query synthesizes answers with citations that can be saved back as pages, and lint audits for orphans, unsourced claims, and contradictions, with the three lodos deviations listed underneath: encrypted SQLite storage, propose-only autonomy, and an HMAC-chained audit log.](/blog/make-your-moat-a-ratchet/4a.webp)

## The Karpathy pattern, commercialized

The knowledge half is not original. Andrej Karpathy described an LLM wiki with three operations and one claim: the wiki is the executable, the raw sources are the code, the LLM is the compiler, the lint is the tests, the queries are the runtime.

I copied the pattern and then changed three things on purpose.

- **Storage.** Karpathy uses a folder of markdown files and git. I use SQLite plus a per-section encrypted vault. The trade is interop for confidentiality. A clean markdown export still gives me Obsidian when I want it.
- **Autonomy.** Karpathy lets the LLM write directly. I force every change through a propose-and-approve diff modal. The agent never touches the canonical page itself. I spend five to ten seconds on each approval. In exchange the agent cannot quietly rewrite my behavior.
- **Audit.** Karpathy keeps a plain markdown log. I keep an HMAC chain signed against a sub-key of the master password. A tampered log surfaces as a chain break on the next startup.

These are not philosophical differences. They are commercial adaptations of a personal-knowledge pattern. They keep the spirit and charge compliance-buyer prices.

## Both sides ratchet the same way

The refusal side and the knowledge side have identical shape. One greps for things that must never exist. The other greps for things that must never be missing. Both are absence checks. Both fail loud. Both are sealed in the same HMAC chain.

When I ask the wiki a question and the answer is good, the interface offers a one-click "save this as a page." If I take it, the answer becomes durable. The next session finds it. The same question never needs to be asked again. The metric is save-rate. It rises over time. The wiki is the only part of the system that gets strictly stronger the more I use it.

The refusal side works the same way. Every new feature that threatens an invariant gets a new invariant written into the verify script. The script grew from seven checks to thirty-two in eight months. Each capability ships with the grep that closes its abuse class. The codebase becomes monotonically more refused with every feature that ships.

Most teams treat these as separate concerns. They are the same discipline applied to two different absences: what must never exist, and what must never be forgotten.

## What it costs and why the cost is the point

I lose velocity on exactly the features that fight the refusals and on the rewrites that would ignore the wiki. A power user wants an inline expression evaluator. Declined. A customer wants a value-returning secret tool. Declined. Future me will be tempted to rip the approval loop out because it feels slow. The build will not allow it.

The release notes look different from every competitor's. Mine name the refusals as often as they name the features. There is no clean growth story that omits the things I deliberately refused to build.

What I gain does not fit on a landing page. It fits in a sales conversation with a regulated buyer. That buyer hears "we cannot" differently from "we promise not to." A compliance officer treats a tamper-evident HMAC chain differently from a markdown log. The founder reading the wiki today is being read by the founder who will need it in six months. None of those people are reachable through marketing claims.

![The five pieces laid out as cards, then wired together: the code repository feeds the invariant script on the refusal side, the wiki lint covers the knowledge side, both write into the shared HMAC chain, and every change in the propose-only loop travels through a diff modal before it becomes canonical.](/blog/make-your-moat-a-ratchet/5a.webp)

## Five pieces you can steal

None of them requires the others. Together they form the pattern.

1. A declarative workflow engine that contains no expression evaluator of any kind.
2. A two-store vault in which the AI literally cannot return a plaintext secret.
3. A build-time invariant script written with negative-proof discipline.
4. A wiki that implements the three Karpathy operations and wraps the log in an HMAC chain.
5. A propose-only learning loop in which the agent never writes its own behavior.

Run them in any order. The only thing they share is the discipline: write the things you refuse to ship and the things you refuse to forget, assert both in the build, and prove the asserts by trying to violate them on purpose. Everything else is engineering.

![The next loop as a six-step chain: the agent observes the conversation, notices a skill gap, and drafts a proposal, which stops at a side-by-side diff modal marked as the chokepoint, where a human approves or rejects before anything becomes canonical and ships, with every proposal and decision written to the HMAC chain.](/blog/make-your-moat-a-ratchet/6a.webp)

## What comes next

*The final loop is the one that took the longest to get right. The agent watches the conversation, notices when its own skill catalog could be improved, and proposes an edit. I approve or reject. The edit travels through the same diff modal as every wiki proposal. The agent never writes its own behavior. The chokepoint between proposal and approval is the actual moat. The next post is about that loop and about one short passage in the disposition prompt that justified the entire engineering effort.*

[Join the waitlist](https://lodos.md/)
