This week, two different coding agents did three things on my machine. One asked whether it could operate the browser, although I had granted that permission days earlier. One answered a question about my desktop cleanup with a status line I wrote on July 22. It had been out of date for six weeks. One ran a shell heredoc with double backslashes three times in one day while the rule against it sat in the instruction file.
If you use Claude Code or Codex daily, some of this will look familiar. People usually diagnose the problem as forgetting, then add more memory: extract more, embed it, retrieve the top matches. Sometimes that is the right fix. It would not have fixed these three. The first needed my "yes" captured from my own words. The second retrieved the memory and still got the answer wrong. The third had the rule in writing and ignored it. Remembering the right fact is not the same as acting on it. Epitype is a governance layer for that gap, built for Claude Code and Codex. It also clears a pile of small annoyances you would otherwise wire yourself: the right context injected at session start, relevant cards recalled on every prompt, a recovery map written before context compaction, the gate before each tool call, host files backed up first. One install command, and none of those needs separate attention.
It does not build a second warehouse
Epitype leaves your host's native memory directory as the storage authority. It does not copy cards into its own database, sends nothing to a hosted service, and depends on nothing outside the Python standard library. During installation it backs up any host file it touches and merges only entries it marks as its own. Uninstall removes what it owns and leaves every card where it was. I start here because it is the first thing I would ask about a memory plugin: will it eat the memory I already have?
Three jobs need separate rules
Agent memory has at least three different governance jobs. A single warehouse treats them all the same.
Habits are rules the agent should follow every time without stopping to decide. Their governance problem is size. Epitype keeps them in primary memory, and the session-start index that carries them is bounded, so they stay visible without turning into a wall of text.
Scars are lessons from incidents. When your hand moves toward a hot stove, the flinch comes before the decision. A scar card in Epitype can carry a trigger made from a tool pattern plus an input pattern. When a tool call matches, the hook blocks it before it runs, returns a safer route, and writes an audit row. The matcher examines the executable and the unquoted argument positions. It follows shell and interpreter wrappers while ignoring quoted strings, comments, and heredoc bodies, so a comment containing a forbidden word does not block a legitimate command. After I turned the heredoc rule into a scar with a trigger, the gate blocked my next attempt. A scar retires when the hazard gets a mechanical guard somewhere better than prose.
Pending work has another lifecycle. It needs an owner and a next check, and it should disappear when done. The July 22 line that misled my agent was a pending item with no exit. Left in place, it quietly hardened into "the current state". Epitype keeps pending work in its own block, and a lint reports the entries that have gone stale.
Two rules apply across all three. Every decision has exactly one current version. Its decision card carries a stable key, a status of active or superseded, an effective time, and who decided. By default, every read path excludes superseded cards while retaining them for provenance, so last week's decision cannot return as today's. And a permission you grant is stored in your words and tied to you, instead of depending on whether the agent remembered to take a note.
Where it runs
Epitype uses four host events. At session start, it provides a bounded index of the vault. Each prompt gets a few relevant cards. Before each tool call, the gate runs. Before context compaction, it writes a recovery map so the next context knows where things stand. Every injection is capped at 10 KiB, fails open within three seconds, and is labelled as advisory data that cannot override instructions or grant tool authority. That label matters because injected memory is itself a prompt injection surface.
In practice, a run looks like this:
old decision superseded -> excluded from recall
new decision active -> surfaces on a matching prompt
tool call scar match -> denied, safer route returned, audit row written
What I measured, and what it does not prove
The repository ships 17 component selftests covering the tools, both host adapters, the installer, the exam engine, and the privacy gate. Before tagging 1.0.0, the release gate also passed a strict 300-case behavior corpus and a 15-seed review written from the incidents above. Those two are not in the repository, and all of this evidence is synthetic. It proves that the mechanisms behave as specified in a small vault. It does not prove that they improved anyone's agents over months.
One number came from my own machine, produced by a tool you can run yourself. The pending lint found 54 stale pending lines across 32 cards, the oldest 80 days old. That is what a memory looks like when nothing governs exits.
Hooks can only govern the events and tools the host exposes. The budgets mean the agent never sees the whole vault, so selection can be wrong. Gate precision depends on the triggers people write, and a malformed card fails open instead of taking control. Two hosts are tested. The bundled tests are synthetic.
Look before it changes anything
Read the repository, then run:
pip install epitype
epitype-graft install --dry-run
The dry run prints what would be written, which hosts it found, and where the vaults are. If that matches what you expect, the README walks through install, doctor, and the Codex trust check. If it does not, nothing has changed.
Top comments (0)