Persists context across conversations as plain markdown so every future session can enrich a topic-scoped memory (e.g. `project-acme`). Four operations: `write` (extract candidates, resolve as ADD / UPDATE / DELETE / NOOP per Mem0), `read` (load a ≤ 200-line INDEX, fetch detail on demand), `consolidate` (sleep-style merge + prune), `forget` (delete or redact with audit). Three storage tiers: home (`~/.agent-memory/<scope>/`, default), project-local (gitignored), project-shared (committed). Enforces a never-store list (secrets, keys, financial and identity numbers) and a consent preview before every write. `rules/scaling-tiers.md` covers scaling to SQLite FTS, vector DB, and managed memory, plus the LoreKit backend the self-improvement loops run on: scope mapping, the `loop::<skill>-lessons` tag and key convention, and the shared lesson schema. Triggers on "remember this", "save to memory", "recall memory", "what do you remember about", "consolidate memory", "forget that", "/persistent-memory".
67
84%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
Low
Low-risk findings worth noting
Capture, recall, consolidate, and forget memories scoped to a user-chosen
topic (e.g. parenting, work, relationship-anna) as plain markdown
files, so any future conversation can pick up where the last one left off.
This
SKILL.mdis a thin index. Operation pipelines, taxonomy, privacy rules, integration patterns, and scaling guidance live inrules/*.mdand load on demand. Literal artefact templates live intemplates/*.md. Worked examples and citations live inreferences/*.md. Read only what the current operation asks for.
Parse $ARGUMENTS (first token) and detect the operation:
| Operation | Default | Trigger phrases |
|---|---|---|
write | yes | "remember", "save to memory", "add to memory", $0 == "write" |
read | "recall", "load memory", "what do you remember about", $0 == "read" | |
consolidate | "consolidate memory", "compress memory", $0 == "consolidate" | |
forget | "forget that", "delete memory", "redact", $0 == "forget" | |
list | "list memory", "what scopes do I have", $0 == "list" |
State the detected operation and resolved scope in one line before continuing. Example:
Operation: write
Scope: parenting
Storage tier: home (~/.agent-memory/parenting/)If no scope is provided, ask once (single batched message) — never guess.
Load on demand — do not preload.
rules/storage-layout.md)Three tiers; the user picks per invocation, or accepts the default.
| Tier | Path | Committed? | Default for |
|---|---|---|---|
home (default) | ~/.agent-memory/<scope>/ | No | Personal scopes (parenting, work) |
project-local | <repo>/.agent/memory/<scope>/ | No (gitignore) | Per-project private notes |
project-shared | <repo>/memory/<scope>/ | Yes | Team-shared project knowledge |
Per-scope directory layout (identical across tiers):
<storage-root>/<scope>/
├── INDEX.md # Curated, ≤ 200 lines; always loaded by `read`
├── entries/ # Individual memory entries; loaded on demand
│ └── <yyyy-mm-dd>-<slug>.md
├── archive/ # Consolidated / superseded entries (audit trail)
└── AUDIT.log # Append-only ledger of write / consolidate / forgetEvery operation is gated. Do not proceed to the next phase until the prior phase's gate passes.
write (default)| Phase | Name | Rule | Gate |
|---|---|---|---|
| 0 | Resolve scope + tier | rules/storage-layout.md | Scope name + storage tier confirmed; directory created |
| 1 | Privacy pre-flight | rules/privacy-and-consent.md | No secrets / PII on the never-store list slip through |
| 2 | Extract candidates | rules/write-pipeline.md | Candidate list produced with type, confidence, source per item |
| 3 | Compare to existing | rules/write-pipeline.md | Each candidate tagged ADD / UPDATE / DELETE / NOOP |
| 4 | Consent preview | rules/privacy-and-consent.md | User saw the diff and approved (unless --auto flag) |
| 5 | Write + audit | rules/write-pipeline.md | INDEX updated, entry files written, AUDIT.log line appended |
read| Phase | Name | Rule | Gate |
|---|---|---|---|
| 0 | Resolve scope | rules/storage-layout.md | Scope directory exists; INDEX.md present (or report empty) |
| 1 | Load INDEX | rules/read-pipeline.md | INDEX content surfaced to current conversation |
| 2 | On-demand fetch | rules/read-pipeline.md | Detail entries fetched only when INDEX points to them |
consolidate| Phase | Name | Rule | Gate |
|---|---|---|---|
| 0 | Snapshot | rules/consolidate-pipeline.md | Pre-consolidation state captured (path + file count) |
| 1 | Group + merge | rules/consolidate-pipeline.md | Semantically similar entries grouped; merge plan drafted |
| 2 | Prune stale | rules/consolidate-pipeline.md | Entries past staleness cutoff flagged for archive |
| 3 | Preview + apply | rules/consolidate-pipeline.md | User saw before / after summary and approved |
| 4 | Rewrite INDEX | rules/consolidate-pipeline.md | INDEX reflects new state; AUDIT.log appended |
forget| Phase | Name | Rule | Gate |
|---|---|---|---|
| 0 | Resolve target | rules/forget-pipeline.md | Memory id, slug, or query resolves to exactly one entry set |
| 1 | Show + confirm | rules/forget-pipeline.md | User saw the entries and explicitly confirmed |
| 2 | Delete or redact | rules/forget-pipeline.md | Entries removed (or redacted); INDEX + AUDIT.log updated |
listWalk every storage tier the user has enabled, print every scope with entry counts and last-updated timestamps. No writes.
This skill is model-invocable (disable-model-invocation: false)
so host workflows can call it programmatically. Two ways to invoke it:
/persistent-memory write parenting
or /persistent-memory read parenting.SKILL.md
contains a one-line pointer block that calls
Skill("persistent-memory", "read <scope>") when the host runs.The second form is the canonical integration. Runtime Skill() calls
require disable-model-invocation: false — without it the Skill tool
refuses the call at the harness layer (you'd see
Skill X cannot be used with Skill tool due to disable-model-invocation).
See
rules/integration-with-skills.md
for the full contract and the literal snippet at
templates/pointer-snippet.md.
| Pattern | Token cost | Magic | Best for |
|---|---|---|---|
| Pointer | INDEX only, on skill load | None | The default. Explicit, debuggable, no hook. |
| Hook | INDEX every session | High | Always-on scopes (e.g. a personal assistant). |
For the parenting example: add one block to parenting/SKILL.md:
> **Persistent memory:** Before responding, run
> `Skill("persistent-memory", "read parenting")` to load accumulated
> context for this scope.rules/scaling-tiers.md)| Tier | Backend | Use when |
|---|---|---|
| 1 | Plain markdown (this skill, default) | ≤ ~500 entries per scope, single user, no semantic search needed |
| 2 | Markdown + SQLite FTS index (this skill, opt-in) | Up to ~5k entries per scope, keyword search beats full-INDEX scan |
| 3 | Markdown blobs + local vector DB (Chroma, Qdrant) | Semantic recall ("what did we discuss about X") matters |
| 4 | Managed memory layer (Mem0, Letta, Zep) | Multi-user, multi-tenant, > 10k entries, graph relationships, hosted SLA |
Graduate one tier at a time. The skill ships a migration recipe in
rules/scaling-tiers.md for moving from
markdown to SQLite, and from SQLite to a vector DB, without losing
entries.
--auto is passed; secrets and PII on the never-store
list are refused outright.forget operation is part of
the surface, not an afterthought. Required for privacy and for
pruning entrenched mistakes (see Reflexion entrenchment warning).parenting, health, work etc. so the INDEX stays under 200 lines.rules/anti-patterns.md)~/.agent-memory/ to a public repo.A write run is done when:
--auto flag was explicit).A read run is done when:
A consolidate run is done when:
A forget run is done when:
--confirm flag).39b3f44
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.