memory-os
Multi-project memory layer for Claude Code — zero-dep Python stdlib, JSON source of truth, audited writes, routing, BM25 retrieval, Obsidian render, dashboard, Supabase sync
memory-os
A multi-project memory layer for AI agents — a disciplined operating system for memory, not a giant notebook. It knows which project is active, retrieves only what a task needs, preserves why decisions were made, keeps operational state current, blocks unsafe writes, and routes work to the right agent with a minimal context packet.
Zero runtime dependencies — pure Python 3.11+ stdlib. JSON is the source of truth; SQLite is a rebuildable index; Obsidian Markdown and a local dashboard are read-only views; Supabase is an optional remote mirror.
Core principles
- Accuracy first — prefer verified, project-scoped, source-backed memory over broad recall.
- Minimal effective context — never load all memory; build the smallest packet that completes the task.
- Project isolation by default — each project has its own store; no cross-project bleed without an explicit shared-context record.
- JSON is the source of truth — SQLite/Markdown/Supabase are derived and disposable.
- Audited writes — proposals pass a pipeline (secret scan → scope check → schema validation → autonomy class) before they persist.
- Supersede, don't delete — outdated records are marked superseded with a pointer to their replacement; deletion is reserved for invalid/secret/accidental data.
- Never store secrets — private keys, passwords, tokens, and seed phrases are hard-blocked from the memory layer and from any remote sync.
Layout
memory_layer/
global/ lightweight cross-project state (registries, policies)
projects/<slug>/ per-project JSON: project, state, decisions, constraints,
entities, tasks, audit_log, memory_updates, …
rendered/ read-only Obsidian Markdown views
schemas/ JSON schemas (the write contract)
indexes/ memory.sqlite + sync_state.json (rebuildable, gitignored)
engine/ the implementation (stdlib only)
supabase/ schema.sql for the optional remote mirror
scripts/ sync-all.sh (cron-friendly)
.claude/agents/ memory-manager, project-router, skill-router
The mem CLI
mem() { python3 memory_layer/engine/cli.py "$@"; }
mem init # scaffold global config + index
mem project add <slug> --name N --type coding --objective "…"
mem project open <slug> # resume packet (where you left off)
mem propose <slug> decision '<json>' # audited write (decision|constraint|entity|task)
mem packet <slug> --task T --objective "…" [--skill S --agent A]
mem search <slug> "<query>" # BM25 + relationship + staleness ranking
mem route "<request>" [--packet] # project → skill → agent
mem skill add '<json>' | mem skill list
mem agent add '<json>' | mem agent list
mem index sync # rebuild SQLite from JSON
mem audit <slug> # self-audit (duplicates, stale, leaks, …)
mem render [<slug>] # JSON → Obsidian Markdown views
mem dashboard [--port 8765] # local read-only browser dashboard
mem sync status <slug>
mem sync push <slug> [--live] [--force] # local → Supabase (dry-run by default)
mem sync pull <slug> [--live] [--apply] # Supabase → local (conflict-safe merge)
Quickstart
mem init
mem project add my-project --name "My Project" --type coding --objective "ship v1"
mem propose my-project decision '{"topic":"db","decision":"Postgres via Supabase","impact":"high","confidence":"high","source":"user_confirmed"}'
mem packet my-project --task coding --objective "set up the database"
mem render && mem dashboard # open http://127.0.0.1:8765
Agents
The Memory Manager is the gate: no specialized agent receives raw project memory — it gets a compact context packet built for its task.
- project-router — fixes the active project; refuses to guess when ambiguous.
- skill-router — picks the skill + agent and loads the skill's memory-access policy.
- memory-manager — builds packets, runs the audited-write pipeline, supersedes, keeps the index in sync, and self-audits.
Supabase sync (optional)
JSON stays authoritative; Supabase is a mirror for multi-device / multi-agent / a hosted dashboard.
- Run
memory_layer/supabase/schema.sqlin the Supabase SQL editor (creates 9ms_*tables with RLS enabled, default-deny). - Put credentials in a gitignored
.env(see.env.example). The CLI uses theservice_rolekey (bypasses RLS for a trusted backend job); keep RLS protecting any public/browser path. mem sync push <slug> --live
push fingerprints the payload and skips when nothing changed; --force overrides.
Automate with cron via memory_layer/scripts/sync-all.sh (only pushes on change).
Development
After cloning, activate the repo's git hooks once:
bash memory_layer/scripts/install-hooks.sh # sets core.hooksPath=.githooks
The tracked pre-push hook (.githooks/pre-push) blocks force-pushes and deletions
of master from your clone — a local stand-in for server-side branch protection,
which GitHub gates behind a paid plan for private repos. It is client-side only.
Security
Credentials live only in .env (gitignored), never in the memory layer or git.
The audited-write pipeline and sync both run a secret scan and refuse anything that
looks like a credential. Rejected proposals are logged with their secret content
redacted.
Status
Phases 1–6 complete: schemas & audited writes → routing → retrieval → context-packet
gate → Obsidian rendering → local dashboard → Supabase sync + cron automation.
Deferred (each marked ponytail: in the code): real embeddings, a hosted Next.js
dashboard, editable memory cards, and graph visualization.
How to Install
- Download the dashboard markdown file from GitHub
- Drop it into your vault (anywhere)
- Install the Homepage plugin and point it at the file
- Enable any listed CSS snippets for the intended look
Stats
Stars
0
Forks
0
Last updated 14d ago
Categories