Memory for AI agents that forgets like a human — and resurfaces like one.
humemory is a memory engine that does not behave like a database. It behaves like a brain. Traces decay through five levels (full detail → summary → essentials → keywords → lost/merged), recall reinforces them, and — this is the part that matters — the right memory comes back to you before you ask for it.
Most "agent memory" is a searchable log. You query it, it returns rows. humemory's reason to exist is the opposite move: a memory that surfaces the relevant trace on a contextual cue, the way you remember to buy milk when you walk past the shop, not when you run a full-text search for "milk".
humemory is built in two halves. The first is shipped. The second is its destiny.
Past learnings are encoded, then degraded over time on a human curve:
| Level | Name | Lifespan | Holds |
|---|---|---|---|
| L0 | full detail | fresh (<24h) | complete content |
| L1 | summary | days | LLM-generated résumé |
| L2 | essential | weeks | the gist |
| L3 | keywords | months | BM25 retrieval tokens |
| L4 | lost / merged | beyond | folded into a sibling trace |
Recall resists decay. Saillance (mnemonic strength, 0–100) and recall count slow the curve. A photographic flag pins critical traces so they never fade.
Inverse search queries the degraded layers first (cheap, L3 keywords) and escalates toward full content only on a match — the human recall pattern, fast by construction.
A Claude Code Stop hook already auto-encodes the learnings of each dev session.
The second half (see AGENTS.md → Phase 5) is what gives humemory its life:
- Prospective memory — store an intention that fires on a cue (a time, or an event: opening a file, switching branch, hitting an error), not on a search.
- Zeigarnik effect — an open loop stays salient near consciousness until it
is closed. A
git commitis the synaptic release that purges it. - Cognitive scripts — context-triggered routines, pre-loaded, ready to run.
Concretely: on SessionStart, humemory reads the open loops and the
decayed-but-relevant traces for the current directory/branch and injects them as
context — "yesterday you left refactor fn X open" — instead of waiting to be
queried.
pnpm install
pnpm build:web # bundle the React front (bun's own bundler, no extra tooling)
pnpm start:api # API + dashboards → http://localhost:3456
pnpm cli status # state of the memory palace
pnpm test # bun test — backend and React components, one runnerThe React app is served at / (and /app). The original vanilla dashboard
has been removed — the React front reached parity first, and git keeps the old
one if it is ever needed.
The visualisations are wrapped, not rewritten: d3 owns its SVG subtree and
three.js its WebGL canvas, so they stay imperative inside a useEffect. Only the
parts built from innerHTML strings — the trace dashboard, the replay player,
the merge panel — became JSX. Each visualisation is code-split and loaded on
demand; three.js alone is half a megabyte, and nobody who never opens the
promenade should download it.
Run pnpm build:web before pnpm start:api, or / answers 503 telling you so.
# arm a loop, with a file cue and a weekly reminder
pnpm cli intent add "refactor token validation" -d ./src/auth \
-c 'event:file_open:src/auth/service.ts' -c 'cron:0 9 * * 1' -e 2026-12-31
pnpm cli intent list # armed loops (--all for every status)
pnpm cli intent close loop-a1b2c3d4 --commit deadbee
pnpm cli intent resolve # expire overdue loops, fire due deadlinesCue formats: time:<ISO>, cron:<5-field expr>, event:file_open:<path>,
event:branch_switch:<branch>, event:error_pattern:<regex>.
Directories are resolved to absolute paths on write — a loop armed on a relative
path would never match the SessionStart hook, which looks the project up by
process.cwd().
Over HTTP: POST /intentions, GET /intentions?status=armed&directory=…,
GET /intentions/:id, POST /intentions/:id/close, POST /intentions/:id/fire,
DELETE /intentions/:id, POST /cues, GET /cues, POST /events,
POST /cues/resolve.
git config core.hooksPath .githooks # in this repoFor another project, copy .githooks/post-commit into it and point
HUMEMORY_HOME at your humemory checkout — the database is shared across
projects, the code is not:
export HUMEMORY_HOME=/path/to/humemoryWrite Closes loop-a1b2c3d4 in a commit message and that loop is closed, its
SHA recorded, its remaining cues cancelled. Everything else is only suggested:
the hook scores the overlap between the files you touched and the loop's text,
and prints candidates. It never closes on a guess — closing the wrong loop costs
more than leaving one open.
💡 Loops this commit may have touched:
loop-e99166cd — Refactor the auth middleware
overlaps: auth, middleware
To close: pnpm cli intent close loop-e99166cd
Two hooks, both optional and both fail-open — neither will ever block a session:
SessionStart reads the current directory and git branch, expires stale loops,
fires any due time cues, and writes a markdown block on stdout — which Claude Code
injects into the session. Nothing relevant means nothing written.
| Env var | Default | Effect |
|---|---|---|
HUMEMORY_DB |
data/humemory.db |
database path |
HUMEMORY_DIR |
cwd |
mental place to scope loops and traces to |
HUMEMORY_SESSION_BUDGET |
10 |
max items listed per section |
HUMEMORY_SAILLANCE_MIN |
60 |
salience floor for recalling a decayed trace |
HUMEMORY_VERBOSE |
unset | 1 logs a one-line summary on stderr |
A log remembers everything and reminds you of nothing. A human memory forgets most of it and hands you the one thing that matters, at the moment it matters. humemory is an attempt to give an AI agent the second kind.
TypeScript · bun:sqlite (WAL) · flexsearch (BM25) · hono (API) ·
commander (CLI) · @anthropic-ai/sdk (level generation).
pnpm installThe CLI provides several commands to interact with humemory:
-
Encode a new memory trace:
pnpm cli encode "Your memory content here"Options:
-d, --directory <dir>: Mental space (project)-s, --session <id>: Encoding context-k, --keywords <tags>: Retrieval cues (comma-separated)-l1, --level1 <summary>: Summary for consolidation N1-l2, --level2 <essential>: Essential for consolidation N2-l3, --level3 <keywords>: Trace for fast search N3-t, --type <type>: Memory type (episodic/semantic/procedural)--auto: Auto-generate N1/N2/N3 via LLM (requires ANTHROPIC_API_KEY)--photographic: Photographic mode — disable degradation
-
Search for memory traces:
pnpm cli search "your query"Options:
-d, --directory <dir>: Filter by mental space-s, --session <id>: Filter by context-l, --level <max>: Max consolidation state (0-4)-n, --limit <n>: Number of traces-t, --type <type>: Filter by type (episodic/semantic/procedural)--from <date>: Start date YYYY-MM-DD--to <date>: End date YYYY-MM-DD--min-saillance <n>: Minimum mnemonic strength (0-100)--min-recalls <n>: Minimum reactivations
-
Reactivate a memory trace:
pnpm cli recall <id>
-
List memory traces:
pnpm cli list
Options:
-n, --limit <n>: Number of traces-l, --level <level>: Filter by state (0-4)-t, --type <type>: Filter by type (episodic/semantic/procedural)
-
Update decay:
pnpm cli decay
-
Toggle photographic mode:
pnpm cli photo <id>
Options:
--off: Disable photographic mode
-
Find similar traces:
pnpm cli similar <id>
Options:
-n, --limit <n>: Number of results-t, --threshold <n>: Minimum score (0-100)
-
Merge traces:
pnpm cli merge <sourceId> <targetId>
Options:
--auto: Merge content via LLM
-
Delete a memory trace:
pnpm cli delete <id>
-
Show memory palace status:
pnpm cli status
-
Import a Claude Code session:
pnpm cli import-session <file>
Options:
-d, --directory <dir>: Project mental space-n, --max <n>: Max learnings to extract
Start the API server:
pnpm start:apiThe API will be available at http://localhost:3456. You can interact with it using the following endpoints:
POST /memories: Add a new memoryGET /memories: List memoriesGET /memories/:id: Fetch a specific memoryPOST /memories/:id/recall: Bump recall and saillancePOST /memories/:id/similar: Find similar memoriesPOST /memories/:id/merge: Merge memoriesPOST /memories/:id/photo: Toggle photographic modeDELETE /memories/:id: Forget a memoryGET /search?query=X: Inverse searchPOST /decay: Run consolidationGET /status: Pool stats
The dashboard is available at http://localhost:3456 when the API server is running. It provides a visual interface to interact with humemory.
pnpm cli encode "Fixed the critical bug in the authentication module" \
-d "my-project" \
-k "bug,authentication,critical" \
-t "episodic" \
--autopnpm cli search "authentication bug" \
-d "my-project" \
--min-saillance 50pnpm cli recall "memory-id-here"pnpm cli list -l 0 -t "episodic"pnpm cli decaypnpm cli photo "memory-id-here" --offpnpm cli similar "memory-id-here" -n 3 -t 70pnpm cli merge "source-memory-id" "target-memory-id" --autopnpm cli delete "memory-id-here"pnpm cli statuspnpm cli import-session "session-file.txt" -d "my-project" -n 5pnpm buildpnpm testpnpm test:watchpnpm cli <command>pnpm consolidate| Field | Cognitive term (French, as in the code) | Meaning |
|---|---|---|
createdAt |
Encodage | trace formation |
lastRecalled |
Dernière réactivation | last conscious retrieval |
recallCount |
Réactivations | recalls (reinforce) |
saillance |
Force mnésique | trace strength 0–100 |
decayRate |
Taux d'oubli | degradation speed |
sessionId |
Contexte d'encodage | encoding context |
directory |
Lieu mental | conceptual space (project) |
currentLevel |
État de consolidation | decay stage 0–4 |
keywords |
Indices de récupération | retrieval cues |
memoryType |
Type | episodic / semantic / procedural |
Decay thresholds: L0→L1 ~24h · L1→L2 ~1 week · L2→L3 ~1 month · L3→L4 beyond.
Slowing factors: recallCount * 0.3, saillance >70 → 1.5× slower, content >500 chars,
keywords >5. photographic: true disables decay entirely.
Memory types: episodic (events), semantic (facts), procedural (skills).
- Core decay + inverse search;
bun:sqlitestore (WAL, write-queue serialization) - CLI + Hono API + web dashboard ("palais de mémoire")
- Nightly cron consolidation (
0 3 * * *) - LLM auto-generation of L1/L2/L3 (Claude Haiku + prompt caching)
- Similar-detection + merge (L4); enriched search (type/period/saillance/recalls)
- Photographic mode; Claude Code
Stophook → session learning capture
Corrected plan in PHASE5_PLAN.md. Summary:
- 5.0 Preconditions — cross-process SQLite advisory lock and injectable event bus in the test env, both shipped (S5-00a, S5-00b).
- 5.1 Data model — dedicated
intentionstable (not a newMemoryType, intentions don't follow the retrospective decay curve) +cuestable with typedtrigger_spec. One intention → N cues. - 5.2 Cue resolver — time cues (ISO/cron) and event cues (file_open,
branch_switch, error_pattern). Decay rule:
armed→ saillance pinned at 100;firednotclosed→ normal decay (Zeigarnik fades);closed→ archived. - 5.3 Hooks —
SessionStartinjects context (scripts/hook-session-start.ts, budget viaHUMEMORY_SESSION_BUDGET); gitpost-commitcloses loops via the explicitCloses loop-<id>marker, and only suggests on file-overlap. - 5.4 CLI/API —
pnpm cli intent {add,list,close,fire,resolve},POST /intentions,POST /cues,POST /events,POST /cues/resolve.
Deferred to Phase 6 — Cognitive scripts (spec needed before code).
- Shared multi-project DB with concurrency lock (WAL + advisory) — done (Sprint 5 / S5-00a)
- OpenCode / other-agent integration; export/import memories between projects
SQLite multi-process: advisory lock— fixed in Sprint 5 (S5-00a): WAL + write-queue (Sprint 4) plus file-based cross-processAdvisoryLock.tests/fixtures/missing — suites seed ad hoc literals (BUG-05, due with S5-00b).vitest.config.tsorphaned; suite runs underbun test(BUG-06).tscglobal can shadow local —pnpm buildistsc -p tsconfig.json.
- Shared DB:
data/humemory.db· API port3456(PORTenv) - Stack: TypeScript ·
bun:sqlite·flexsearch·hono·commander·@anthropic-ai/sdk CLAUDE.mdis a thin Claude-Code-specific quick-start that delegates toAGENTS.md;AGENTS.mdremains the canonical source of truth.