v0.7.0
0.7.0 — 2026-07-27
First release since 0.5.0. It bundles four versions that were tagged but never
published (0.5.1, 0.6.0–0.6.4) plus this one — several of them fix defects that
destroy data, so if you are running 0.5.0 this is worth reading.
Upgrading — read this first
- Do not run 0.6.3 and 0.6.4+ against the same store at the same time. The state
lock changed from "the lock file exists" to a kernel lock on an open descriptor, and
the two schemes cannot see each other, so both writers can enter the critical section
and one update is lost. There is no fix that keeps interoperability without
reintroducing the bug it removes. .codex/engramory/engramory_sync.pyis a COPY made at install time. After
upgrading, re-runengramory_init.py codex --install-hooks --force, then re-trust the
handlers in Codex's/hooks(their content hash changed).- Nothing else needs migrating. No note format changed; no store is rewritten.
New: a runbook for the agent installing this
AGENT-SETUP.md — every other document assumes a human reader, or an agent that is
already set up (SKILL.md is the protocol you follow after installation). The common
case is a user telling an agent "install this for me", and that agent then improvising
the entire diagnosis. Nothing carried that procedure, and the improvisation failed in
consistent, reproducible ways.
It was written against a non-Claude agent actually attempting the install, repeatedly.
Every rule in it exists because a real run got it wrong first — offering to "fix" a
legacy note it should not touch, calling a perfectly working store "90% correct",
proposing a second store next to the user's existing one, or asking for approval nobody
was there to give and therefore doing nothing at all.
The runbook ships with --install-skill, and each host's standing-rules block points at
it, so an agent asked to check or repair an install can find it later — when the original
checkout is usually long gone.
Data-loss and correctness fixes (0.6.4)
- An index pointer into
archive/was resolved through a basename map: with both
foo.mdandarchive/foo.mdpresent, the archive pointer marked the live note as
indexed and the doctor called the store clean while a real orphan sat in it. - The installer deleted user content around a block marker. A duplicated
BEGIN
spliced from the first begin to theEND, dropping every line between them; a file
that merely quoted a marker in prose was treated as malformed, skipping the real
replacement and deleting that line. - A dangling
MEMORY.mdsymlink was written through —exists()is False for a
broken link, so the refusal was skipped and the template was created at the link's
target, outside the store. - A miscased
[[wikilink]]was reported broken while an equally miscased index pointer
resolved, so a clean store exited 1 on Windows/macOS. - Frontmatter quotes were stripped from every value:
description: he said "hi"lost
its trailing quote, andcreated: 2026-01-01"was quietly repaired into a valid date. mailto:pointers were treated as local paths.
Concurrency (0.6.4)
The Codex state lock declared itself stale after 30s of mtime age and unlinked it — true
of a dead owner, and equally true of one that merely paused on a slow disk or a suspended
laptop. Both processes then ran the same read/modify/write. Release made it worse: it
unlinked by path unconditionally, so the displaced writer deleted the new owner's lock.
It is now a kernel lock (flock / msvcrt), which cannot be taken from a live holder and
is released by the OS if that process dies.
Earlier, unpublished (0.5.1 – 0.6.3)
- 0.6.3 — documentation-drift sweep; two items turned out to be code bugs.
- 0.6.2 — bounded reads, gitignore ownership transitions, untrusted-text fencing.
- 0.6.1 — fail-closed gaps, a self-contradicting rule, read-side store confinement.
- 0.6.0 — Codex lifecycle adapter (
SessionStart/UserPromptSubmit/PreCompact). - 0.5.1 — install overlap + symlink-escape preflight, doctor duplicate-key ISSUE,
honest hook-scope docs.
Full detail for every version is in CHANGELOG.md.
Tests
CI now runs what it appeared to be running. tests/test_tools.py doubles as a
dependency-free script and its __main__ block sat mid-file, so the 14 tests defined
below it — including everything added in 0.6.1 — were silently skipped in CI while
passing locally. A new tests/test_state_lock.py covers the lock across all three
platforms, using a real second process.