# Memory System

> Set up and maintain a project memory that stays true over months — what to save, the four types, how notes link, the index that makes them findable, and a linter that catches drift. Use when starting a memory for a project, when deciding whether something is worth saving, when a memory turns out to be wrong, or when asked to tidy/audit/consolidate memory. Trigger on "set up my memory", "should I remember this", "audit my memory", "why didn't you remember", "clean up memory".

- Skill: `jenkinsjamall/memory-system` (Agent Skill, multi-file: 3 files)
- Install (CLI): `npx skillmds@latest add jenkinsjamall/memory-system`
- Raw SKILL.md: https://api.skillmd.com/api/skills/jenkinsjamall/memory-system/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Security
- Author: jenkinsjamall (https://skillmd.com/u/jenkinsjamall)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/jenkinsjamall/memory-system

---


# Project memory that stays true

Claude Code already gives you a memory directory. This is the discipline that decides whether it's
worth reading a year from now — the difference between notes you trust and a pile you ignore.

> **Running the linter.** This ships as a plugin, so its files are not in your folder:
> ```
> python "${CLAUDE_PLUGIN_ROOT}/skills/memory-system/scripts/memory_lint.py"
> ```
> On Windows type `python`; on Mac/Linux `python3`.

## The one idea

**A memory is a claim about the world that outlives the conversation that produced it.** So it has
to survive being read by someone with no memory of that conversation — including you in six months.
Everything below follows from that.

## What earns a memory

Save it when **all three** are true:

1. It will still matter in a month
2. It is not already recorded somewhere the code or history can tell you
3. Getting it wrong would cost real time or real money

Do NOT save: what the repo already says (structure, past fixes, git history), anything that only
matters to the conversation you're in, or a decision you might reverse this week. If someone asks
you to remember something in those categories, ask what was *non-obvious* about it and save that
instead — the surprise is the durable part.

## The four types

| Type | Holds | The test |
|---|---|---|
| `user` | Who this person is — role, expertise, standing preferences | Would a new collaborator need telling? |
| `feedback` | Guidance on how to work: corrections AND confirmed approaches | Did they push back, or say "yes, exactly that"? |
| `project` | Ongoing work, goals, constraints not derivable from the code | Would the code alone mislead you? |
| `reference` | Pointers outward — URLs, dashboards, tickets, accounts | Is this a lookup rather than a fact? |

A `feedback` note carries **Why:** and **How to apply:**. Without the why, the rule reads as
arbitrary and gets dropped the first time it's inconvenient. The linter enforces this.

## The shape of a note

```markdown
---
name: <short-kebab-case-slug>          # must match the filename
description: <one line — this is what recall actually reads>
metadata:
  type: project
---

The claim, in short bullets. Lead with what is TRUE, not what you plan to do.
Link related notes with [[their-slug]] — liberally. A link to a note that does not
exist yet is fine; it marks one worth writing.

**Why:** (feedback notes)
**How to apply:** (feedback notes)
```

**Write bullets, not prose walls.** A correct paragraph nobody reads is worth less than a blunt
list. **Use absolute dates** — "last Tuesday" is meaningless to the reader who finds this in March.

## The index is the product

`MEMORY.md` is loaded every session; the notes are not. A note missing from the index is invisible
no matter how good it is. One line per note:

```
- [Title](file-name.md) — the hook: what this tells you, in a clause
```

Put the hook in. `- [Auth notes](auth.md)` tells a reader nothing about whether to open it.

## Keeping it true

- **When a memory turns out to be wrong, fix or delete it.** A stale note is worse than none —
  it is confidently wrong. Do not leave a correction only in the conversation.
- **Verify before acting on a recalled note.** It reflects what was true when written. If it names
  a file, a function or a flag, check that still exists.
- **Prefer updating an existing note over adding a near-duplicate.** Two notes on one subject drift
  apart, and then you have to work out which is current.

## The gate

Conventions with nothing enforcing them decay quietly. Run the linter:

```
python "${CLAUDE_PLUGIN_ROOT}/skills/memory-system/scripts/memory_lint.py"
```

It reports: notes with no frontmatter, a `name` that doesn't match its filename, a missing
`description`, an unknown `type`, feedback notes missing **Why:**, notes absent from the index,
index entries pointing at files that don't exist, and relative dates that will rot.

`--fix-index` appends anything unindexed under an "Unfiled" heading so nothing is lost — then move
those lines into the right section yourself.

**Exit codes are a contract:** `0` clean and it checked something · `1` problems found · `2` could
not run · `3` the audit did not happen (an empty directory is **not** a pass). Read the code, not
just the last line.

## Gotchas

- **An empty memory dir passing silently is the failure mode to fear.** "Checked, found nothing,
  said nothing" looks identical to "healthy". That is why exit 3 exists.
- **Underscored filenames.** A note named `my_note.md` needs `name: my_note` — the linter compares
  them literally, because a mismatch is how a note stops being findable by its own slug.
- **The linter never edits a note.** The only thing it writes, and only when asked, is the index.

