Your repo is the store, recall is $0 per prompt, staleness is git-drift, and team memory lands through review.
I lean on Claude Code for real engineering work every day, and the single most expensive failure mode isn't a wrong answer — it's amnesia. Every new session, the agent re-derives decisions I already made, re-hits gotchas I already documented, and re-argues tradeoffs I already settled. The harness comes with a memory file, but a flat always-loaded doc doesn't scale, and its only freshness signal is calendar age ("N days old") — which is uncorrelated with whether a note is actually still true.
I wanted durable agent memory that met four hard constraints at once. It had to be local and git-native — memories are versioned markdown, diffable and reviewable like code, no external database or vector service. It had to recall silently and instantly on every prompt, which in the Claude Code hook model means an ironclad contract: a UserPromptSubmit hook that exits 0 no matter what, never blocks, and — critically — never triggers a synchronous model download mid-prompt. It had to know when a memory had gone stale for the right reason — because the code it describes drifted, not because a clock ticked. And it had to be testable without a network, because a suite that downloads a 130MB embedding model isn't a suite you actually run.
Releasing it added a fifth constraint the private version never had: a memory tool injects text into an agent's context, so an untrusted corpus is an injection surface. Opening the repo meant building a real trust model, not just cleaning up the README.
hippo is a markdown-in-git corpus plus a Python engine, distributed as a Claude Code plugin — the repo doubles as its own plugin marketplace. On every prompt, a recall hook runs hybrid retrieval: BM25 lexical scores and dense cosine similarity over bge-small embeddings, fused by weighted Reciprocal Rank Fusion, with a calibrated relevance floor so an off-topic query surfaces nothing instead of the least-irrelevant thing. The dense model loads strictly offline from a pre-warmed cache; a cache miss degrades to BM25, which degrades to empty. Nothing in that path can raise into the hook.
Freshness is git-drift staleness: each memory records the source_commit it was written against and the cited_paths it depends on, and it's stale when a cited file changed after that commit — computed for the whole corpus in exactly two git calls. The drift signal feeds recall-triggered reconsolidation: memories that are both recently recalled and now stale form the worklist for re-grounding, because those are the ones actively steering the agent with a concrete reason for doubt.
Around that engine sits the operational layer the launch demanded: a trust gate whose consent step shows what would actually inject (not just file names) and re-prompts when a trusted corpus materially changes, write-gated MCP tools, secret lint over everything the plugin ships, and 15 /hippo:* skills covering the lifecycle — bootstrap, init, recall, doctor, audit, consolidate, promote. Bootstrapping the venv and embedding model stays a deliberate, explicit /hippo:bootstrap step, so the one online moment in the tool's lifecycle can't race a hook timeout.
The repo ships its own reproducible benchmark: on the 50-memory golden corpus and 18 deliberately cross-vocabulary queries that live in the repo, bench/run.sh reports recall@10 = 1.0 in both BM25-only and dense modes, with MRR@10 0.912 → 0.9213 as the dense half earns its keep on ranking quality — deterministic to the digit, at $0 per prompt (the hot path calls no model API and sends nothing off the machine). Those numbers come from the golden corpus in the repo, not a general claim — bench/run.sh can be pointed at another one.
The test suite grew from 279 tests at extraction to 1,603 in the default hermetic run — offline, every test against a throwaway git repo with pinned commit times — and passes locally as of v1.8.0. The corpus behind the design has been in daily use since 2026-06 and stands at 180+ memories (self-reported, not an independent benchmark). Thirty reviewed PRs took it from extraction to release-ready, with a version-sync test at PR time and a four-way tag/manifest/changelog check at release time.
The discipline that mattered most is the robustness contract, enforced top to bottom: the hook exits 0 (on UserPromptSubmit, exit 2 erases the user's prompt — a recall failure must never eat your input), recall() never raises and returns [] on any failure, and dense retrieval is wall-clock-bounded so a cold model cache aborts to BM25 instead of hanging. What changed since the first private version is that the same "make the failure modes boring" standard now covers the parts strangers touch: a written stability contract freezing the skill and tool surface, a threat model that treats memory text as untrusted input, and a benchmark anyone can re-run.