Authoring Memory Packs
July 28, 2026 · View on GitHub
A memory pack is a signed, versioned .mpack file of knowledge that
installs into any Compartment vault fully offline, with precomputed vectors.
Build
- Prepare records -
.jsonl(one{"text": "...", "tags": [...], "id": "stable-id"}per line),.csv(columnstext,tagssemicolon-separated), or a directory of.mdfiles (one record per file). - Build and sign:
compartment pack build facts.jsonl \
--name my-pack --version 1.0.0 \
--description "What this pack knows" \
--creator "Your Name" \
--identity ~/.compartment/identity.json # created on first use - KEEP PRIVATE
The build embeds every record with the bundled default model, so consumers
install with zero compute. --encrypt additionally seals the body with a
pack passphrase (private distribution).
- Distribute the
.mpackfile however you like - signature and content hash make tampering in transit detectable. Tell your users your public key (pub_hexin your identity file) over a channel they trust: they need it to install your pack (see Trust, below).
Consume
compartment pack install my-pack-1.0.0.mpack # verifies signature + hash FIRST
compartment pack list
compartment pack remove my-pack
Records land read-only in packs/my-pack for every caller. Reinstalling a
pack replaces it wholesale (semver replace, never merge). A pack signed by
anyone other than the Compartment project only installs once you name the
author's key yourself - see Trust, below.
Trust: a pack cannot vouch for itself
Every pack carries a signer_pub field. That field is a hint only and is
never used to verify anything - a pack that supplied its own verification key
would prove nothing, since anyone can mint a keypair and sign a malicious
pack with it.
Verification resolves the key from a trusted set instead, in this order: signature (trusted key) → content hash → decrypt → parse.
- The only key trusted by default is the Compartment project's own verify
key,
packs.PROJECT_PACK_KEYinsrc/compartment/packs.py. It ships in the source tree so the bundled starter pack can be verified without trusting the file it arrived in. - Anything else is refused, loudly, with the untrusted key printed.
To install a third-party pack, get the author's public key over a channel you trust (their site over HTTPS, a signed release, in person - not from the pack itself) and name it deliberately:
from compartment import packs
packs.install_pack(vault, blob, trusted_keys=["<64-hex author key>"])
packs.read_pack(blob, trusted_keys=["<64-hex author key>"]) # inspect only
trusted_keys accepts one hex key or a list, applies to that call only, and
adds to the project key rather than replacing it. Naming a key is the whole
consent step: if you have not verified where the key came from, you have not
verified the pack.
Signing a rebuild (maintainers)
The project's Ed25519 private seed lives in tools/pack_identity.json,
which is gitignored and must never be committed, copied into the source tree,
or pasted anywhere. tools/build_starter_pack.py reads it to sign the pack.
Only the public half (pub_hex) belongs in packs.py; the two must match or
the shipped pack stops verifying. If that file is lost, packs signed by the
old key can no longer be produced; if it leaks, rotate the keypair and
publish PROJECT_PACK_KEY afresh.
Rules of the road
- Keep
identity.jsonprivate. It contains your Ed25519 seed. Publish only the public key (pub_hex), and publish it somewhere consumers can check independently of the pack: the copy inside the pack is a hint and buys them nothing. - Stable
idfields let you ship regression queries against your pack (the ids survive install asid:tags - this is exactly how the built-in starter memories'selftestworks). - Never change published content within a version. Version bumps are cheap; silent mutations defeat the signature's purpose.
- Facts should stand alone (one self-contained statement per record) - retrieval returns records, not documents.
Built-in starter memories (maintainer notes)
Compartment ships a signed starter pack whose contents are SEEDED at init -
verified like any pack (signature + content hash), then stored as
ordinary, fully editable memories in the main namespace. There is no
separate read-only starter section: starting memories sit beside (and
behave exactly like) everything the agent stores later. Vaults created
by older versions that still have a packs/starter section are
reorganized automatically the next time they open - every record moves
to main untouched. Canonical hand-editable source:
tools/starter/starter_facts.jsonl - one JSON object per line,
{"id": "akc-00001", "tags": ["akc", "measurements"], "text": "The body mass of an African elephant (adult) is typically about 6,000 kg (ranging from 4,000 to 7,000 kg)."}
Editing the starter memory
- Edit
tools/starter/starter_facts.jsonlin any editor: insert, delete, reword, append. Line position is irrelevant to retrieval; only ids must stay unique. Keep idscore-001..core-260textually intact (they are the frozencompartment selftestcorpus). - Rebuild (re-embeds every line with the bundled model and re-signs):
python tools/build_starter_pack.py 1.0.1 # arg = new pack version - Every future
compartment initthen seeds your edited facts (intomain, as ordinary editable memories). To refresh an EXISTING vault, export your organic memories, init a fresh vault (which seeds the new starter), and import them back:
(Then shredcompartment export mine.jsonl --plaintext compartment --vault ~/.compartment/memory2.vault init compartment --vault ~/.compartment/memory2.vault import mine.jsonl compartment --vault ~/.compartment/memory2.vault selftest # must stay 20/20mine.jsonl- it is plaintext.) Already-present facts simply coexist; forget the ones you replaced.
The AKC-derived section can be regenerated from upstream with
tools/build_akc_pack.py (writes tools/starter/akc_regenerated.jsonl
for merging). Any other pack can be dumped for editing with
compartment pack export <file.mpack> <out.jsonl> and rebuilt with
compartment pack build.