mirror of
https://github.com/alirezarezvani/claude-skills.git
synced 2026-09-10 22:41:16 +00:00
Turns DESIGN.md from a spec into a working plugin. Five stdlib scripts, three
hooks, agent, command, three references, plugin manifests.
The gates are the design:
L1 -> L2 >= 3 distinct sessions spanning >= 2 distinct calendar days
(`stated` = 2 sessions, day rule still applies; `verified` = 1
observation and is the only day-exempt path)
L2 -> L3 >= 2 distinct projects, >= 30 days, uncontested
Two gates refuse rather than guess. `redacted: true` blocks promotion on any
volume of evidence -- a durability-independent barrier, since a secret restated
across five sessions passes every recurrence gate; the flag firing means the
text was altered, a lexical filter finding one secret is not proof it found all
of them, and L2/L3 are committed to git. An open contradiction freezes both
claims, found by reverse join because the newer atom carries no flag.
All three hooks fail open: a broken memory system costs memory, never a session.
SessionEnd stages promotions to .memory/staged/ and never touches a CLAUDE.md;
only an explicit human adopt does, after backing both files up.
Verified, not asserted:
- all three pinned atom ids from DESIGN.md reproduce exactly
- both blocking gates demonstrated on sample input, named in the output
- end-to-end: two transcripts across two calendar days -> merged L1 atom ->
staged L2 promotion with the path prefix stripped
- reverse join blocks the unflagged newer atom
- cross-tier L2/L3 collision marked at injection time
- recall p50 29ms / p95 31ms / max 35ms spawn-to-exit, scoring itself 2-3ms
over 500 atoms -- interpreter cold start is the entire cost
- validate_examples.py 69 checks 0 failures; SKILL.md 6/6 PASS
- derive_counters --check, check_plugin_json --all, check_paths all clean
DESIGN.md 10.1's "+6" tool estimate corrected to +8 -- the delivered surface is
5 scripts + 3 hooks. README.md's deviations list is authoritative for that and
five other divergences from the pre-implementation spec.
Concept from TencentCloud/TencentDB-Agent-Memory (MIT). No upstream code.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EM5xmJ7AmTMg31rq68BCym
126 lines
6.1 KiB
Markdown
126 lines
6.1 KiB
Markdown
# agent-memory
|
||
|
||
A four-tier memory ladder for Claude Code. **Promotion is earned by recurrence,
|
||
never asserted by confidence**, and nothing reaches a committed file without a
|
||
human adopting it.
|
||
|
||
Concept derived from [TencentCloud/TencentDB-Agent-Memory][tencent] (MIT). No
|
||
upstream code is included — see
|
||
[`.claude-plugin/authoring-notes.json`](.claude-plugin/authoring-notes.json) for
|
||
what was taken and what was deliberately rejected.
|
||
|
||
[tencent]: https://github.com/TencentCloud/TencentDB-Agent-Memory
|
||
|
||
---
|
||
|
||
## What it does
|
||
|
||
| Tier | Holds | Injected | Committed |
|
||
|---|---|---|---|
|
||
| **L0** | raw session transcripts | never | already on disk |
|
||
| **L1** | candidate atoms | on relevance, per prompt | no (gitignored) |
|
||
| **L2** | this project's context | every session start | yes, after adopt |
|
||
| **L3** | stable cross-project persona | always | yes, after adopt |
|
||
|
||
**L1 → L2** needs ≥ 3 distinct sessions spanning ≥ 2 distinct calendar days. A
|
||
claim stated outright needs 2 sessions — the day rule still applies. A
|
||
deterministically verified claim promotes on one observation and is the only
|
||
day-exempt path. **L2 → L3** needs ≥ 2 distinct projects and ≥ 30 days.
|
||
|
||
Two gates refuse rather than guess: a **redacted** claim never promotes on
|
||
evidence alone, and a claim with an **open contradiction** freezes until a human
|
||
resolves it.
|
||
|
||
## Install and use
|
||
|
||
The three hooks in [`hooks/hooks.json`](hooks/hooks.json) run the loop
|
||
unattended. Each is disabled independently:
|
||
|
||
```bash
|
||
AGENT_MEMORY_SESSIONSTART=0 # stop injecting L2 + L3
|
||
AGENT_MEMORY_USERPROMPTSUBMIT=0 # stop L1 recall
|
||
AGENT_MEMORY_SESSIONEND=0 # stop capture
|
||
```
|
||
|
||
```bash
|
||
cd skills/agent-memory/scripts
|
||
python3 memory_inspect.py --tier L1 # what's stuck, and why
|
||
python3 memory_inspect.py --why "<claim>" # full provenance + source line
|
||
python3 memory_inspect.py --contested # disputed claims, both directions
|
||
python3 memory_promote.py # dry-run the gates; writes nothing
|
||
python3 validate_examples.py # 69 checks over the spec + schema
|
||
```
|
||
|
||
Every script takes `--sample` and `--output json`. `/cs:memory` wraps all of it;
|
||
`/cs:memory adopt` is the only path that writes to a `CLAUDE.md`, and it backs
|
||
both files up first.
|
||
|
||
## Contents
|
||
|
||
```
|
||
DESIGN.md the spec: schema, gates, hook contracts, open decisions
|
||
hooks/hooks.json three hook contracts
|
||
hooks/session_start.py inject L3 + L2, mark cross-tier conflicts
|
||
hooks/user_prompt_submit.py recall L1 on a 100 ms internal budget
|
||
hooks/session_end.py capture, redact, detect, merge, stage
|
||
skills/agent-memory/SKILL.md 6/6 PASS on the write-a-skill checklist
|
||
scripts/memory_core.py shared: ids, redaction, locking, contradictions
|
||
scripts/memory_extract.py L0 → L1, rule-based, no LLM
|
||
scripts/memory_promote.py L1 → L2 → L3, stages proposals
|
||
scripts/memory_inspect.py read-only: --tier / --contested / --why
|
||
scripts/validate_examples.py 69 checks in seven families
|
||
assets/memory_schema.json 13 required fields, five conditionals
|
||
references/ three references, 6–7 sources each
|
||
agents/cs-memory-curator.md refuses to adopt what it cannot cite
|
||
commands/cs-memory.md status | why | contested | adopt | forget
|
||
```
|
||
|
||
## Deviations from `DESIGN.md`
|
||
|
||
`DESIGN.md` was written before the implementation and reviewed at length. Where
|
||
the built thing differs from the planned thing, **this list is authoritative**.
|
||
|
||
1. **`memory_core.py` exists.** §10's planned tree lists four scripts and no
|
||
shared module. Building it that way would have duplicated the redaction
|
||
patterns, the id algorithm and the lock protocol across seven files — which
|
||
is precisely the drift class the spec exists to prevent. The module has no
|
||
CLI and is not a plugin-facing tool.
|
||
2. **The tool count in §10.1 is wrong.** It says `+6` (3 scripts + 3 hooks).
|
||
The delivered surface is 5 scripts + 3 hooks = **8**. Corrected in the
|
||
counters; §10.1's text is left as the historical record of the estimate.
|
||
3. **`mark_contradictions()` was added to the core.** §4.2.1 specifies detection
|
||
running at merge time in `SessionEnd` but assigns it to no file. It lives in
|
||
the core so the promoter and the inspector share one definition of "open
|
||
contradiction" rather than three.
|
||
4. **Cross-tier conflict marking marks both sides.** §5.1 requires that an L2
|
||
and an L3 claim colliding must not both appear as plain assertions, and says
|
||
all three candidate policies satisfy it. The implementation marks both and
|
||
picks no winner — the least committal option, and the one that does not have
|
||
to be undone if the open decision lands on specificity-wins.
|
||
5. **The 100 ms recall budget is met, on this machine.** §9.5 asserted the
|
||
budget without measurement and offered dropping the hook as option (c).
|
||
Measured: spawn-plus-recall p50 ≈ 29 ms, p95 ≈ 31 ms, max ≈ 35 ms against a
|
||
populated store; the scoring pass itself 2–3 ms over 500 atoms. Interpreter
|
||
start-up is the whole cost. **This does not close §9.5** — one machine is not
|
||
a portability claim, and a slower host may still force option (c).
|
||
6. **`--why` quotes the source line.** Not specified anywhere; added because
|
||
"cite, don't invent" is unfalsifiable if a human cannot see the cited line.
|
||
It prints nothing when the back-pointer resolves `ambiguous`.
|
||
|
||
## What would make this worth deleting
|
||
|
||
Stated plainly because §9.3 permits it and the trial is the point:
|
||
|
||
- **Recall is too low to matter.** Rule-based extraction is deliberately
|
||
high-precision. If a two-week trial produces a handful of atoms and none
|
||
reach L2, the honest response is to remove the folder — not to loosen gates
|
||
until something passes.
|
||
- **Nobody reviews the staged promotions.** The entire security argument rests
|
||
on a human at the `adopt` gate. If staged items are accepted unread, the gate
|
||
is theatre.
|
||
- **`--why` is never run.** Provenance nobody checks is provenance nobody needs.
|
||
|
||
## License
|
||
|
||
MIT. Concept attribution: TencentDB-Agent-Memory (MIT, © Tencent). See
|
||
[`../../LICENSE`](../../LICENSE).
|