
goldentrii/agentrecall-x
Developer toolsCorrect your agent once. It remembers next session — and we measure whether it actually stopped.
Overview
Correct your agent once. It remembers next session — and we measure whether it actually stopped.
README
English · 中文
AgentRecall
Correct your agent once. It remembers next session — and we measure whether it actually stopped.
Local-first memory for AI agents, built around a corrections ledger and math you can audit. MCP · SDK · CLI · Skill.
claude mcp add --scope user agent-recall -- npx -y agent-recall-mcp
Contents
- The problem · What it does · The session loop · MCP tools
- The nature of memory — 5 layers · How memory compounds · The math
- Measured, not promised · Compared to other memory tools
- Install · Optional extras · Architecture · Platforms · Community · Links
The problem
You tell your agent “don’t bump the version without asking.” It apologizes, fixes it, and the session ends. Next week a fresh session does it again — the correction lived in a chat log nobody reads.
AgentRecall turns that sentence into a structured, persistent rule, puts it in front of the next agent before it acts, and records whether the mistake came back.
── session 3 ─────────────────────────────────────────────
you › no — never bump the version without asking me first
agent › remember(type: "correction")
✓ saved · severity p0 · applies_when: [release, npm]
── session 9 · new agent, no chat history ───────────────
session_start › project "my-app" · 1 critical correction
watch_for: version bump → ask the owner first
you › ship the fix
agent › Fix is merged. Want me to bump to 1.4.1, or leave the version?
outcome recorded: heeded
Illustrative transcript.
What it does
AgentRecall is two things:
- A governed corrections ledger. Every correction (“not that version”, “put this section first”, “ask before you assume”) becomes a structured record — severity, evidence,
applies_when, retraction, outcome — that persists across sessions, projects and agent restarts. Export format:corrections-export/v1, scrubbed on egress. - A measurement instrument. Each correction accumulates
retrieved_count, and every time the agent meets the same situation the outcome is logged asheededorrecurred. No public benchmark measures that step; we built the harness first and publish what it finds, including the unflattering numbers.
The session loop
flowchart LR
A([session start]) --> B["/arstart · session_startload rules + context"]
B --> C{work}
C -->|need past knowledge| D["/arrecall · recall"]
D --> C
C -->|corrected| R["remembertype: correction"]
R --> L[(correctionsledger)]
C -->|risky action| K["check"]
L -.-> K
C --> E["/arsave · session_endjournal + compound"]
E --> F([session end])
L -. watch_for .-> B
F -. every K sessions .-> G["/arreflectconsolidate"]
G -.-> A
| Command | When | What it does |
|---|---|---|
/arstart |
First — every session | OPEN. No args → status board across all projects → pick → load that project’s rooms, corrections and task recall. /arstart loads directly; /arstart bootstrap imports existing projects. |
/arsave |
Last — every session | SAVE. Journal + palace consolidation + awareness compounding. /arsave all merges every parallel session of the day. |
/arrecall |
Mid-session | SEARCH. Prior fixes, decisions, patterns for the current task. |
/arreflect |
Every K sessions | CONSOLIDATE. Confirm recurrences, cluster new error classes, propose rule re-abstractions (rule edits stay owner-gated). |
Without
/arstart, a fresh agent has zero orientation. Without/arsave, nothing compounds.
MCP tools
Five tools ship by default. Each description is written for the agent and says when to call it.
| Tool | Call it | What it does |
|---|---|---|
session_start |
First, before acting | Loads corrections, insights and watch_for warnings for the project |
remember |
The moment something is decided or corrected | Saves one fact; auto-routes to journal / palace room / corrections / awareness |
recall |
Whenever past context would help | Ranked search across every store (RRF), with useful feedback that re-weights future ranking |
check |
Before risky or irreversible actions | Matches the plan against known corrections; returns verdict: "blocked" when one overrides it |
session_end |
On save / exit | Writes the journal, promotes insights, records trajectory, optionally opens/closes a pipeline phase |
[!IMPORTANT] The Automaticity Law — why only 5. Memory only compounds if it fires without being asked. Across 44 projects and weeks of real use, the pull tools (
recall,memory_query) saw zero organic calls — including from the agent that built them. Push channels (session_start,session_end, correction hooks) are what change behavior. Every extra default tool costs definition tokens every session for no return. (Self-measured on the owner’s store, 2026-06-12.)So on Claude Code, wire the hooks — the loop then runs without agent discipline:
ar hook-start SessionStart load context, show watch_for warnings ar hook-correction UserPromptSubmit capture corrections silently ar hook-ambient UserPromptSubmit inject relevant memories (≥2-word overlap floor) ar hook-save UserPromptSubmit "save"/"retain" → prompt session_end ar hook-pretool PreToolUse warn on npm publish, git push, rm -rf, deploy, DROP TABLE ar hook-end SessionEnd auto-save journal if not saved today ar health — recent hook failures (fail-loud)
The nature of memory — 5 layers
The cognitive-psychology taxonomy, mapped to plain files. Each layer forgets at a different speed, because human memory does.
| # | Layer | Holds | Path | Forgets |
|---|---|---|---|---|
| 1 | Episodic | What happened, per session | journal/ |
fast — $S = 2$ days |
| 2 | Semantic | Topic facts with [[wikilinks]]: architecture, goals, blockers |
palace/rooms/ |
barely — $S = 9999$ days, salience-ranked |
| 3 | Procedural | IF-THEN production rules | palace/skills/ |
by use |
| 4 | Narrative | Phases: goal → what was hard → how solved → synthesis | palace/pipeline/ |
never (history) |
| 5 | Correction | Rules the agent must follow — severity, evidence, outcomes | corrections/ |
never by time — only by retraction |
| + | Awareness | Cross-project insights promoted from repeated corrections | palace/awareness |
confirmation-weighted |
~/.agent-recall/
├── projects//
│ ├── journal/ episodic — one entry per session
│ ├── corrections/ behavioral rules + outcome ledger
│ └── palace/
│ ├── rooms/ semantic
│ ├── skills/ procedural
│ ├── pipeline/ narrative
│ ├── identity.md
│ └── awareness cross-project insights
├── dreams/ nightly consolidation reports
├── dashboard.html human-readable
└── dashboard.json agent-readable snapshot
All layers share one naming grammar, so an agent can compose a retrieval path from intent. Older files keep working through a legacy_path view — no migration.
How memory compounds
flowchart LR
C["correction(remember / hook)"] --> L[(ledger)]
L --> S["session_startranked by severity,proof, recency"]
S --> O{"same situationagain?"}
O -->|heeded| P["proof_count +1stability × 1.3"]
O -->|recurred| X["phantom→ /arreflectrewrites the rule"]
P --> A["≥ 3 confirmations→ awareness(cross-project)"]
X --> L
A correction gets stronger each time it is confirmed, weaker when it is marked unhelpful, and graduates to every project once it has been confirmed on three distinct (day, project) occasions. A rule that was saved but whose mistake came back is a phantom — the write cost was paid and behavior never changed — and gets re-written, not just re-saved.
The math
Most of the field ships “AI memory” as a black box. Every mechanism in AgentRecall is a formula you can read, with its constants in the source and an honest label:
| Label | Meaning |
|---|---|
| 🟢 GROUNDED | A published result restated exactly, or a constant tuned on real data with a reported metric |
| 🟡 HAND-TUNED | Principled functional form; constants chosen by judgment, not fit to recall outcomes |
| 🔴 ASPIRATIONAL | The claim is ahead of the math present — stated so, with the model that would close the gap |
1 · Rank fusion — Reciprocal Rank Fusion 🟢
Palace, journal, insight and corrections each rank their own candidates; the lists are merged by rank, never by raw score, because the raw scores live on incomparable scales (Cormack, Clarke & Büttcher 2009 — the same $k$ Elasticsearch ships):
\mathrm{RRF}(d) \;=\; \sum_{\ell \,\in\, \text{lists}} \frac{w_\ell}{k + \mathrm{rank}_\ell(d)}, \qquad k = 60,\;\; w_\ell = 1
The optional semantic leg is just one more list with $w = 1.0$ — a weight measured, not chosen: 1.1 and 1.3 flooded the top-5.
[!NOTE] The math found a bug. Adjacent RRF ranks differ by only $
\frac{1/(60+r)}{1/(61+r)} \approx 1.6\%$, so any post-fusion multiplier above ≈1.02 vaults an off-topic item over every on-topic one. The old ×3 / ×2 / ×1.3 “recent-item boost” did exactly that — top-5 filled with the last 72 h of diary lines. Removing it: 55.0% → 75.0% top-5 hit-rate on the golden set (twin-clone control, 2026-09-12).
2 · Forgetting — Ebbinghaus per source 🟢 form · 🟡 constants
R(t) = e^{-t/S}, \qquad S_{\text{journal}} = 2,\;\; S_{\text{knowledge}} = 180,\;\; S_{\text{palace}} = 9999 \text{ days}
3 · Spaced reinforcement — FSRS-lite 🟢 form · 🟡 constants
A two-component (stability, retrievability) simplification of FSRS-6 / SuperMemo — no difficulty term, because we never run review sessions:
R = e^{-\Delta t / S}, \qquad S_0 = 7\text{ d}, \qquad \underbrace{S' = 1.3\,S}_{\text{confirmed}}, \qquad \underbrace{S' = \max(1,\; 0.5\,S)}_{\text{marked wrong}}
Buckets: $R \ge 0.85$ hot · $\ge 0.6$ warm · $\ge 0.3$ cool · else archive candidate — surfaced on a dashboard, never auto-deleted.
4 · Salience — what a palace room is worth 🟡
\text{salience} = 0.30\,\text{recency} + 0.25\,\text{access} + 0.20\,\text{connections} + 0.15\,\text{urgency} + 0.10\,\text{importance}
with $\text{recency} = \max(0.05,\; \rho_c^{\,\text{days}})$, where the decay rate depends on category: goal $\rho = 0.99$ · architecture $0.98$ · decision / lesson $0.97$ · observation $0.95$ · blocker $0.90$. Self-reported importance is deliberately the weakest term — people mis-estimate it; what you actually use is the stronger signal.
5 · Learning from feedback — Beta–Bernoulli 🟢
Every recall result can be rated useful / not useful. The item’s score is multiplied by twice its Laplace-smoothed posterior mean (neutral = ×1.0; the only post-fusion score change on default paths):
\mathbb{E}[\theta] = \frac{\text{pos}+1}{\text{pos}+\text{neg}+2}, \qquad \text{multiplier} = 2\,\mathbb{E}[\theta] \in (0, 2)
6 · Association — ACT-R activation 🟡 (opt-in AGENT_RECALL_ACTIVATION=1)
Memories cited together become linked. The associative term of ACT-R’s declarative-memory equation (Anderson & Lebiere):
A_i = B_i + \sum_j W_j\, S_{ji}, \qquad S_{ji} = w_{ji}\, e^{-\Delta d / 30}, \qquad W_j = \tfrac{1}{|\text{context}|}
Re-rank: $\text{score}' = \text{score}\cdot\bigl(1 + 0.2\,\tfrac{x}{x+1}\bigr)$ — the $\tfrac{x}{x+1}$ squash keeps two incompatible scales from being summed, and is an exact no-op when there is no evidence.
7 · Paraphrase matching — set cosine 🟡 metric · 🟢 threshold
\cos(A,B) = \frac{|A \cap B|}{\sqrt{|A|\,|B|}}, \qquad \text{sim} = \max\bigl(\cos_{\text{concepts}},\; \cos_{\text{char-trigrams}}\bigr) \ge 0.20
Over stems + 13 hand-curated synonym groups (“publish / ship / release” collapse to one concept). It is fuzzy-lexical, not meaning. The 0.20 threshold is tuned by leave-one-out (predict-loo) as the highest-recall point that still holds 0% false positives.
8 · Promotion — admit, then vote 🟢
Nightly consolidation used to gate on $\tfrac{\text{obs}}{7}\times\text{recency} \ge 0.8$. At 2 AM the freshest journal is yesterday, so recency $\le 0.85$ and “3 observations in 7 days” scored $\tfrac{3}{7}\times 0.85 = 0.36$ — silently discarded for 22 nights, while uptime monitoring stayed green. The replacement separates admission from promotion:
\text{promote} \iff \#\{(\text{day},\,\text{project}) \text{ confirmations}\} \ge 3
and every night now writes a yield record, so a zero-output night is classified (empty-corpus · filtered · already-known · errored) instead of looking healthy.
9 · Measuring behavior change — heed rate + Wilson interval 🟢
\text{heed} = \frac{\text{heeded}}{\text{heeded} + \text{recurred}}, \qquad
\text{CI}_{95} = \frac{\hat p + \frac{z^2}{2n} \;\pm\; z\sqrt{\frac{\hat p(1-\hat p)}{n} + \frac{z^2}{4n^2}}}{1+\frac{z^2}{n}}, \quad z = 1.96
Small $n$ gets an honest, wide interval instead of a confident point. Events are tiered by evidence (heeded_verified · heeded_checkaction · heeded_default · recurred_verified · recurred_selfreport), and every KPI surface shows both tiers as a range — absence of evidence is not credited as “heeded.”
10 · Calibrated confidence 🟡
\text{conf} = \frac{\text{score}}{0.12}\;(\text{local RRF}) \;\;\big|\;\; \frac{\text{score}}{0.049}\;(\text{Supabase RRF}) \;\;\big|\;\; \cos\;(\text{vectors}) \;\;\longrightarrow\;\; \text{high} \ge .66,\; \text{med} \ge .40,\; \text{low} \ge .20
Open problem 🔴 — does redundancy reconstruct intent?
Today, accumulated corrections are clustering + decay + set-cosine: a tally, not a posterior. Calling that “intent reconstruction” would overstate it. The model that would earn the phrase treats each correction as a noisy sample of a latent preference $\theta$, with $x_i = \theta + \varepsilon_i,\; \varepsilon_i \sim \mathcal N(0, \sigma^2 I)$ and prior $\theta \sim \mathcal N(\mu_0, \tau^2 I)$:
\operatorname{Var}[\theta \mid x_{1..N}] = \Bigl(\frac{1}{\tau^2} + \frac{N}{\sigma^2}\Bigr)^{-1} = O\!\left(\frac{\sigma^2}{N}\right),
\qquad \mathrm{SNR}_N = \frac{\lVert \mu_N \rVert^2}{\operatorname{tr}\operatorname{Var}[\theta \mid x_{1..N}]}
Falsifiable claim: $\mathrm{SNR}_N$ rises monotonically for a consistent correction stream and stalls when corrections conflict. Want to build it? This is the most important open problem in the repo.
Full derivations, inputs, and every constant’s provenance: packages/core/src/MATH.md.
Measured, not promised
Agent-memory benchmarks test retrieval. None tests whether a correction changes what a fresh agent does. Here is what our own instrument says — including the parts that make us look bad.
| Metric | Value | Source | |
|---|---|---|---|
| 🔁 | Retrieval hit@5, golden fixture v1 (26 queries, hash-locked) | 73.1% keyword [53.9, 86.3]80.8% + local embeddings [62.1, 91.5] | npm run bench:golden |
| 🔁 | session_start context injected, median |
244 tokens | npm run bench:injection |
| 🔁 | session_start p95 warm / recall p95 |
97 ms / 209 ms | npm run bench:latency |
| 🔁 | Correction-transfer fixture gate | exact match | npm run bench |
| 🔒 | Real corrections captured (dual-blind audit, n = 59) | 35.3% [17.3, 58.7] | UPDATE-LOG.md §M2 |
| 🔒 | Heed rate, evidence-grounded | 0 / 3 events | scripts/eval/baselines/rmr-baseline-2026-07-03.json |
| 🔒 | Offline correction-transfer recall | 0 / 4 [0, 49] | scripts/eval/baselines/correction-transfer-real-2026-07-03.json |
| 🔒 | Golden eval on a lived-in store (keyword → embeddings) | 75% → 90% | fix7 report, 2026-09-12 |
| 🔒 | session_start on a lived-in store |
1,489 tokens · 363 ms p95 | UPDATE-LOG.md §C2 |
🔁 regenerates from this repo · 🔒 self-measured on the owner’s private store, not reproducible here. Brackets are 95% intervals. The 80.8% embeddings leg is measured locally with the opt-in model (CI never downloads it, so no artifact is committed). Timings are machine-dependent; CI gates schema and determinism, never timing values.
Compared to other memory tools
| Typical agent memory (Mem0, Zep/Graphiti, Letta, Supermemory) | AgentRecall | |
|---|---|---|
| Optimizes for | Recalling facts | Not repeating mistakes |
| Corrections | Another memory row | Governed ledger: severity, evidence, retraction, outcome |
| Measures | Retrieval (LongMemEval, LoCoMo) | Retrieval and behavior change across sessions |
| Storage | Hosted service or DB | Markdown on your disk; Supabase mirror optional |
| Ranking | Usually opaque | Every formula and constant labelled (see The math) |
| Per-session cost | ~7k tokens/query (Mem0’s published figure) | ~244 tokens at session_start (fixture) |
Competitor figures are their own published numbers, not measured side by side. Landscape: docs/research/agent-memory-landscape-2026-07.md.
Install
MCP server — for agents
# Claude Code
claude mcp add --scope user agent-recall -- npx -y agent-recall-mcp
# Codex
codex mcp add agent-recall -- npx -y agent-recall-mcp
// Cursor — .cursor/mcp.json · Windsurf — ~/.codeium/windsurf/mcp_config.json
{ "mcpServers": { "agent-recall": { "command": "npx", "args": ["-y", "agent-recall-mcp"] } } }
// VS Code — .vscode/mcp.json
{ "servers": { "agent-recall": { "command": "npx", "args": ["-y", "agent-recall-mcp"] } } }
Skill — Claude Code
mkdir -p ~/.claude/skills/agent-recall
curl -o ~/.claude/skills/agent-recall/SKILL.md \
https://raw.githubusercontent.com/Goldentrii/AgentRecall-X/main/SKILL.md
SDK — JS/TS apps
import { AgentRecall } from "agent-recall-sdk";
const memory = new AgentRecall({ project: "my-app" });
await memory.capture("What stack?", "Next.js + Postgres");
const ctx = await memory.recall("rate limiting");
Each instance gets its own isolated root (AsyncLocalStorage), so concurrent instances never share state.
CLI — terminal, CI, hooks
npx agent-recall-cli recall "rate limiting"
ar bootstrap # scan git repos, Claude AutoMemory, CLAUDE.md files (read-only, secrets untouched)
ar bootstrap --import # import what it found
Optional extras
Architecture
packages/
├── core/ storage, retrieval, math, tool logic agent-recall-core
├── mcp-server/ thin MCP wrappers agent-recall-mcp
├── sdk/ programmatic API agent-recall-sdk
└── cli/ the `ar` command + hooks agent-recall-cli
flowchart LR
Q[query] --> T[tokenize · stemsynonyms · IDF]
T --> P[palace0.9 key + 0.1 salience]
T --> J[journal0.5 recency + 0.5 exact]
T --> I[insightsrelevance · exact · confirm]
T --> K[correctionsexact · severity · proof]
Q -. opt-in .-> V[local embeddingscosine top-8]
P & J & I & K & V --> F["RRF Σ w/(60+rank)"]
F --> B["× Beta feedback"]
B --> C[calibrated confidence]
C --> R[results + alsoLinked]
All memory is local markdown. An optional Supabase mirror adds pgvector recall with the same RRF fusion; all-local stays the default. Writes go through a progress-aware file lock with NTFS-safe release; alignment and feedback logs are append-only NDJSON.
Platforms
| Platform | Mechanism | Status |
|---|---|---|
| Claude Code | MCP + skill + hooks | Primary |
| Codex · Cursor · Windsurf · VS Code (Copilot) | MCP | Supported |
| Any JS/TS app | agent-recall-sdk |
Supported |
| Terminal / CI | ar |
Supported |
CI runs build + regression + tests on ubuntu-latest and windows-latest.
Community
- 💬 Telegram — questions, feedback, requests
- 🗣️ GitHub Discussions — field reports, benchmark numbers, adapters, 中文区
- 🐛 GitHub Issues — bugs and features
- 📦 npm: agent-recall-mcp · agent-recall-sdk · agent-recall-cli
[!TIP] The 15-minute contribution that matters most. The field has vendor-selected positives and no external baselines for behavior change. Use AgentRecall for a week, then:
git clone https://github.com/Goldentrii/AgentRecall-X.git && cd AgentRecall-X npm ci && npm run bench # reads your local ~/.agent-recall corpusPost the result in Discussions → Benchmark Numbers — a low score is a valid result. More in CONTRIBUTORS-WANTED.md.
Contributors
Thanks to @buer5, @lonelyhty and 雷昊 for the Windows portability work and fixes that shipped in 3.5.x.
Links
- README.full.md — full reference: SDK API, CLI, every tool parameter
- packages/core/src/MATH.md — every formula, constant and label
- docs/eval/REPRODUCE.md — regenerate every 🔁 number
- CHANGELOG.md · UPDATE-LOG.md — what changed, and the reasoning
- Correction-transfer benchmark spec · Agent-memory landscape 2026
- SKILL.md — Claude Code skill · AGENTS.md — for agents working on this repo
- Previous README: docs/archive/README-2026-10-13.md
Contributing
PRs welcome. Open an issue first for anything substantive — the design is opinionated and grounded in published research, and we want changes grounded the same way: a formula, a label, and a measurement.
License
MIT — see LICENSE.
Install
npx -y agent-recall-mcpConfiguration
// Cursor — .cursor/mcp.json · Windsurf — ~/.codeium/windsurf/mcp_config.json
{ "mcpServers": { "agent-recall": { "command": "npx", "args": ["-y", "agent-recall-mcp"] } } }
// VS Code — .vscode/mcp.json
{ "servers": { "agent-recall": { "command": "npx", "args": ["-y", "agent-recall-mcp"] } } }