Encrypted, fully offline agentic memory. This release is a correctness and
hardening pass across the whole product, plus a cleaner on-disk format.
Storage and integrity
The journal tells a torn write apart from corruption. Each entry is framed
with a checksum over its length prefix. The length is the only thing that says
where the next entry begins, so a damaged one has to be recognised as damage: a
write interrupted by a crash is discarded and provably loses nothing that was
ever acknowledged, while a corrupt prefix refuses to open rather than being
mistaken for a crash and quietly discarding everything after it.
The audit log detects truncation of its own tail. A forward walk of a hash
chain cannot see a truncation, because what is left is still internally
consistent. The head and length are anchored in the sealed payload at creation
and on every save, and verification requires the chain to extend that anchor.
The repair command refuses to run on a log shorter than its anchor, so it can
never rewrite the chain around a deletion and report it as intact, and every
repair it does perform is recorded permanently.
Vault files are written owner-only. The atomic rename hands the vault the
temp file's permissions, so the mode is set before the rename rather than
after.
Cryptography and access
Memory packs are verified against a trusted key. A signature checked
against the key carried inside the pack proves only that the pack is
self-consistent, since anyone can mint a keypair and sign anything. The
verifying key now comes from a trusted set: the project key ships in the
source, and a third-party key is named deliberately with
compartment pack install --trusted-key HEX.
The unlock credential is keyed by real entropy. The wrap key is HMAC
keyed by 32 random bytes held in a volatile kernel object, a POSIX shared
memory segment on macOS and Linux and a volatile registry key on Windows. It
is never written to any filesystem, so it is not present in a backup, snapshot
or disk image, and a restart destroys it. A copy of the credential file on its
own is useless. Where no volatile holder exists, storing a credential is
refused rather than falling back to values an attacker would already hold.
Namespace grants resolve most-specific-first and are enforced on reads. A
broad * no longer outranks a narrower rule depending on key order, a grant of
none denies reads as well as writes, and a caller entry that exists is used
as written instead of inheriting the wildcard.
rekey validates the keyfile against the enrolled one before re-wrapping,
so pointing it at the wrong file can no longer leave the real keyfile unable to
open the vault.
Passphrase attempts are paced five seconds apart. Flat, with no escalation
and no lockout: both would hand an attacker a denial of service against the
only person who can open the file. The interval starts on a failed attempt, so
a correct passphrase is never delayed.
Offline guarantee
The runtime guard covers name resolution and the raw C socket type underneath
socket.socket, not just the Python socket class. A DNS query needs no socket
object and carries caller-chosen bytes in its labels, which was enough to empty
a vault one label at a time. Activation from the environment now seals the
guard so in-process code cannot switch it off.
Fixes
compartment integrate claudecrashed on every run.- The one-command installers aborted on a clean machine, because the user
scripts directory is not onPATHimmediately afterpip install --user. compartment benchdeleted every record in thebenchnamespace rather than
the ones it created, and bypassed the audit log doing it.- The dashboard wrote to the vault while describing itself as read only, and
could display memories its own search refused to return. Viewing the vault
now changes nothing in it. - The MCP server reported every unlock failure as a locked vault, hiding the
embedding-model mismatch whose actual remedy isreindex --re-embed. Tool
failures are protocol errors instead of successful-looking JSON, the panic
lock drops the key and clears credentials even if the flush fails, and
blocking work runs off the event loop. recent(limit=0)returned the entire vault.- A near-duplicate check that inspected only the nearest neighbour missed real
duplicates sitting one rank below a match in another namespace. - The bundled starting memories were cleaned and the pack rebuilt: 6,665
records, after removing 53 exact duplicates and repairing 117 wrong articles
and 311 sentences the generator had mangled. - Reported search latency reads lower than before. The percentile helper was
returning the maximum of its sample rather than the 95th percentile.
Install
pip install compartment && compartment initOn macOS, open Compartment-3.0.pkg instead: Python, the embedding model and
every dependency are inside it.
Test suite: 364 tests.