Releases: MaxFreedomPollard/Compartment
Release list
Compartment 3.0
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.
Compartment 2.3
Improvements
-
compartment audit verifystays true across restarts and across agents. The audit log is a hash chain, so each entry names the one before it and any edit to history breaks the link at a detectable point. Two things could leave that link dangling in ordinary use, and both are fixed: a write is now re-linked to the log's real head when it is replayed after a crash, and it keeps the time it actually happened. -
compartment audit repairfor a log an older build already broke. It rebuilds the links forward from the first break and nothing else. What the log says is untouched: time, caller, operation and detail all stay exactly as written, and the repair records itself as an entry. If any entry fails its own content hash it refuses outright, because that is tampering rather than a dangling link, and re-linking would destroy the evidence.
Downloads
| File | For |
|---|---|
| Compartment-2.3.pkg | macOS, one click, with the optional menu bar utility. Start here. |
| Compartment-2.3.dmg | macOS, drag to Applications |
| compartment-2.3-py3-none-any.whl | pip / offline installs, any OS |
| compartment-2.3.tar.gz | source distribution, packagers, air-gapped builds |
pip install compartment
Upgrading from 2.1 or earlier: once 2.2 or later has opened a vault, older
builds cannot, so upgrade every install that shares one together - the MCP
server your agent launches, the menu bar app, and any copy on your PATH.
macOS blocks the first launch of anything not signed with a paid Apple
Developer ID. The .pkg handles that; with the .dmg you allow it once in
System Settings > Privacy & Security > Open Anyway.
Compartment 2.1
Improvements
- Change your passphrase from the panel, on both apps. Both boxes, the Save button, and the reason an attempt failed are on screen together, on the menu bar and in the system tray.
- The panel scrolls when there is more to show than fits it. A long list of recent memories, a wrapped error, a form: none of it ends at the window edge any more, and the buttons along the bottom stay reachable.
- The PyPI page links back to the project. Source, issues, changelog, documentation and the security model, plus classifiers so the package is findable by Python version and topic.
- A documentation site at maxfreedompollard.github.io/Compartment.
Bug fixes
- macOS and Windows: the panel was drawn at a fixed maximum height and anything past that line was dropped, with no scrollbar or any other sign it was there. The change-password form showed one of its two boxes as a result.
- The published package, the repository and the MCP registry record each declared a different version, and the registry pointed at a PyPI version that no longer exists.
Downloads
| File | For |
|---|---|
| Compartment-2.1.pkg | macOS, one click, with the optional menu bar utility. Start here. |
| Compartment-2.1.dmg | macOS, drag to Applications |
| compartment-2.1-py3-none-any.whl | pip / offline installs, any OS |
| compartment-2.1.tar.gz | source distribution, packagers, air-gapped builds |
pip install compartment
macOS blocks the first launch of anything not signed with a paid Apple
Developer ID. The .pkg handles that; with the .dmg you allow it once in
System Settings > Privacy & Security > Open Anyway.
Compartment 2
Improvements
- Change your passphrase from the menu bar or the system tray, without opening a terminal.
- A Windows app. The same panel, in the notification area: whether the vault is open, how much it has learned, the three settings worth changing day to day, and the last five things it remembered.
pip install "compartment[tray]", thencompartment tray. - Unlock and lock from the panel itself, on both Mac and Windows. Opening your vault no longer means finding a terminal.
- The Windows panel draws sharp on a high-DPI display instead of being stretched by the system.
COMPARTMENT_UI_SCALEoverrides the scale if you want it larger or smaller. - Plain version numbers from here - 2, then 3, with 2.1 and 2.2 for small adjustments in between.
- Documentation: a rewritten opening, both panels shown side by side, and the MCP tool names corrected to
memory_store/memory_forget.
Bug fixes
- Windows:
compartment initended in aUnicodeEncodeErroron a console using a legacy code page - after the vault had already been created, leaving it locked. All console output is UTF-8 now, including memory text you stored. - macOS: the menu bar icon could be created without ever appearing in the bar.
- macOS: the app could not read its own vault status, and reported an open vault as needing a 2FA keyfile that was never set up.
- The screenshots never appeared on the PyPI page, because the README pointed at them by a path only GitHub could resolve.
- The local dashboard identified itself by the old project name in its HTTP
Serverheader.
Downloads
| File | For |
|---|---|
| Compartment-2.pkg | macOS, one click, with the optional menu bar utility. Start here. |
| Compartment-2.dmg | macOS, drag to Applications |
| compartment-2-py3-none-any.whl | pip / offline installs, any OS |
| compartment-2.tar.gz | source distribution, packagers, air-gapped builds |
pip install compartment
Compartment 1.15.3
Improvements
- Change your passphrase from the menu bar or the system tray, without opening a terminal.
- A Windows app. The same panel, in the notification area: whether the vault is open, how much it has learned, the three settings worth changing day to day, and the last five things it remembered.
pip install "compartment[tray]", thencompartment tray. - Unlock and lock from the panel itself, on both Mac and Windows. Opening your vault no longer means finding a terminal.
- The Windows panel draws sharp on a high-DPI display instead of being stretched by the system.
COMPARTMENT_UI_SCALEoverrides the scale if you want it larger or smaller. - Documentation: a rewritten opening, the Windows panel shown beside the macOS one, and the MCP tool names corrected to
memory_store/memory_forget.
Bug fixes
- Windows:
compartment initended in aUnicodeEncodeErroron a console using a legacy code page - after the vault had already been created, leaving it locked. All console output is UTF-8 now, including memory text you stored. - macOS: the menu bar icon could be created without ever appearing in the bar.
- macOS: the app could not read its own vault status, and reported an open vault as needing a 2FA keyfile that was never set up.
- The local dashboard identified itself by the old project name in its HTTP
Serverheader.
Downloads
| File | For |
|---|---|
| Compartment-1.15.3.pkg | macOS, one click, with the optional menu bar utility. Start here. |
| Compartment-1.15.3.dmg | macOS, drag to Applications |
| compartment-1.15.3-py3-none-any.whl | pip / offline installs, any OS |
| compartment-1.15.3.tar.gz | source distribution, packagers, air-gapped builds |
pip install compartment
Compartment 1.15.2
Error correction only.
Downloads
| File | For |
|---|---|
| Compartment-1.15.2.pkg | macOS, one click, with the optional menu bar utility. Start here. |
| Compartment-1.15.2.dmg | macOS, drag to Applications |
| compartment-1.15.2-py3-none-any.whl | pip / offline installs, any OS |
| compartment-1.15.2.tar.gz | source distribution, packagers, air-gapped builds |
pip install compartment
Compartment 1.15.1
engRAM -> Compartment rename
Downloads
| File | For |
|---|---|
| Compartment-1.15.1.pkg | macOS, one click, with the optional menu bar utility. Start here. |
| Compartment-1.15.1.dmg | macOS, drag to Applications |
| compartment-1.15.1-py3-none-any.whl | pip / offline installs, any OS |
| compartment-1.15.1.tar.gz | source distribution, packagers, air-gapped builds |
pip install compartment
Compartment 1.15.0: engRAM, renamed
engRAM is now Compartment
engramis still a working command. It is what sits in every MCP client
config, shell alias and Hermes setup already written, so it keeps working.
Nothing you have installed breaks.compartmentandcmptare the new names
for the same thing.- Your vault does not move. Compartment prefers
~/.compartment, but falls
back to~/.engramwhenever that is the directory that exists. Nothing is
copied, moved, or rewritten. ENGRAM_VAULTand every otherENGRAM_*variable still work.- Old GitHub links redirect.
MaxFreedomPollard/engRAM→…/Compartment.
The dangerous part of a rename, for anyone doing one
Sixteen of the 878 occurrences replaced in this release were not names. They
were AEAD associated data, KDF context labels and file-format tags baked into
every vault already written - engram-keyslot, engram-record:,
engram-payload:, the 2FA keyfile separator, the macOS Keychain service and
account, and others.
engram-keyslot is the associated data that wraps the master key. Renaming it
does not rename anything: the keyslot stops unsealing, and the vault cannot be
opened again by anyone, with any passphrase. Every memory in it is gone.
All sixteen are restored to their original spelling and frozen by
tests/test_ondisk_format.py, which fails if a future rename touches them.
Verified against a real 6,835-memory vault written before the rename: it
opens, unlocked, every record intact.
Downloads
| File | For |
|---|---|
| Compartment-1.15.0.pkg | macOS, one click, with the optional menu bar utility. Start here. |
| Compartment-1.15.0.dmg | macOS, drag to Applications |
| compartment-1.15.0-py3-none-any.whl | pip / offline installs, any OS |
| compartment-1.15.0.tar.gz | source distribution, packagers, air-gapped builds |
pip install compartment
macOS blocks the first launch of anything not signed with a paid Apple
Developer ID. The .pkg handles that; with the .dmg you allow it once in
System Settings → Privacy & Security → Open Anyway.
engRAM 1.14.0: the Mac app actually works now
The Mac app was broken. It is fixed.
If you downloaded engRAM.app before this release, it could not run on your
Mac. Not "ran badly" - could not start at all, and said nothing at all when
you clicked it. Two separate defects:
It had no Python standard library. The bundle was built as a virtual
environment, and a virtualenv does not contain a stdlib - it contains a
pointer to the interpreter it was built from, which was a path inside the
build machine's home directory. The app ran where it was built and nowhere
else.
Its signature could not survive being downloaded. A stray pyvenv.cfg in
the bundle root made codesign store that file's signature in extended
attributes, and extended attributes do not survive .dmg, .zip, or cp.
Every downloaded copy therefore read as unsigned, so macOS killed it the
instant it launched - silently, with no dialog and no crash report, because a
menu bar app has no dock icon to bounce.
Both are fixed at the root. The interpreter's entire runtime now ships inside
Contents/Resources, nothing sits loose in the bundle root, and the build
refuses to produce an app that fails any of four new checks: signature valid,
nothing on sys.path outside the bundle, no xattr-only signatures, and the
signature still valid after actually running the app.
You can find it now
A full menu bar hides whatever does not fit behind the notch, and an icon you
cannot see is indistinguishable from an app that does not work.
- Open engRAM.app again and the panel appears - as a window, not a
popover, so it stays put instead of vanishing the moment focus moves. - The first launch opens the panel by itself, so you see it once before
ever having to find the icon. - Launching a second copy hands off to the one already running instead of
quietly adding a second icon.
"Could not connect to system service engram"
Gone. The installer registered the login item as root, which has no GUI
session to register into. It now finds the console user and registers in
their session, strips quarantine, and removes stale copies claiming the same
bundle identifier.
Downloads
| File | For |
|---|---|
| engRAM-1.14.0.pkg | macOS, one click, with the optional menu bar utility. Start here. |
| engRAM-1.14.0.dmg | macOS, drag to Applications |
| engram_memory_vault-1.14.0-py3-none-any.whl | pip / offline installs, any OS |
| engram_memory_vault-1.14.0.tar.gz | source distribution, packagers, air-gapped builds |
Or, for the CLI and MCP server without the app:
pip install engram-memory-vault
macOS blocks the first launch of anything not signed with a paid Apple
Developer ID. The .pkg handles that for you; with the .dmg you allow it
once in System Settings → Privacy & Security → Open Anyway.
engRAM 1.13.0: one-click Mac install
Install on a Mac - one click
⬇︎ engRAM-1.13.0.pkg · 101 MB · macOS 13+
Open it. The installer asks what you want:
| engRAM | The app, your encrypted memory vault, and the engram command line tool. |
| Menu bar utility (optional) | Puts engRAM in the menu bar and starts it when you log in. Click the icon for your settings and your latest memories. Turn it off any time in System Settings → General → Login Items. |
Nothing to install first - the interpreter, the embedding model, and every dependency are inside the app.
First open: this build is not signed with an Apple Developer ID, so macOS will object. Right-click the installer → Open, then confirm. If it still refuses:
xattr -dr com.apple.quarantine /Applications/engRAM.app
All downloads
| Download | Size | For |
|---|---|---|
| engRAM-1.13.0.pkg | 101 MB | macOS, one click, with the optional menu bar utility |
| engRAM-1.13.0.dmg | 122 MB | macOS, drag to Applications yourself |
| engram_memory_vault-1.13.0-py3-none-any.whl | 33 MB | pip / offline installs, any OS |
| engram_memory_vault-1.13.0.tar.gz | 33 MB | source distribution, packagers, air-gapped builds |
Or from PyPI - the CLI and MCP server, any platform:
pip install engram-memory-vault && engram init && engram integrate claudeWhat the menu bar item shows
Click the icon and a popover gives you, at a glance:
- State - whether the vault is open, how many memories it holds, and how many you actually stored as opposed to the built-in reference facts.
- Three settings - the capture hook (saves memories Claude Code writes, automatically), whether starter facts join your searches, and auto-lock (15 / 30 / 60 min / Never).
- Your last five memories - text, time, and tags, newest first.
No dock icon, no window to manage. It holds no vault open, so an idle menu bar app costs you nothing.
Can't find the icon? On a crowded menu bar - a notched MacBook with a lot of status apps - new items land immediately right of the notch rather than over on the right with everything else. ⌘-drag it wherever you want; engRAM remembers the spot. ENGRAM_MENUBAR_DEBUG=1 makes the app report where its item actually landed.
Why this needed to be a real app
The menu bar worked when launched from a terminal and was invisible any other way.
A status bar item belongs to the process that created it, and macOS decides what that process is from where its executable lives. A launcher that exec'd a Python living outside the bundle produced NSBundle.mainBundle() equal to the interpreter's directory - no identifier, no name, no icon. An anonymous process like that sorts last in the menu bar and shows up in System Settings as a nameless "legacy agent".
So engRAM.app embeds its own interpreter and the app is what runs. Login registration goes through SMAppService, so System Settings → General → Login Items lists engRAM by name, with its icon and description. From the command line: engram menubar --login on|off|status.
Building it yourself
See RELEASING.md. tools/build_macos_app.py produces the bundle, the .dmg, and the .pkg; tools/make_icon.py draws the icon - a sealed ring around three linked memories, geometric enough to stay legible at the 16 pixels the login-items list allows.
The build must embed a non-framework Python. A framework build is a stub that redirects to Python.framework's own Python.app, which reintroduces the identity problem as org.python.python; the script detects that and refuses.
Two bugs came out of testing the built artifact rather than the source: macOS filesystems are case-insensitive, so the app looking for engram beside its interpreter found its own engRAM launcher and shelled out to itself instead of the CLI; and PyObjC ships a test suite plus 142 .dSYM bundles - 71 MB no shipped app needs.
158 tests green on Linux, Windows, and macOS.