Skip to content

Repository files navigation

reflect

License: MIT

A Claude Code skill that decides, at the end of a session, whether anything is worth remembering — and if so, writes it down properly instead of just appending to a pile.

The problem

Auto-memory tools have one failure mode in common: they only grow. Turn one on and the first couple of weeks are great. Then sessions start opening with a memory file full of things that stopped mattering — a bug fixed a month ago, a preference that's now also written in CLAUDE.md, a paragraph re-explaining something the code already says plainly. Nobody goes back and prunes it, because pruning was never the interesting part of building the thing. So it keeps growing, and every session after that pays to load it.

reflect is the part that was missing. At the end of a session it looks back at what actually happened, asks whether any of it clears a fairly high bar, and in most cases decides the answer is no and says so. When something does survive, it doesn't just tack a new file onto the end — it edits the entry that's already there, folds in near-duplicates, deletes what's gone stale, and keeps the result lean enough to justify the tokens every future session will spend loading it.

It also separates two kinds of lesson that most memory tools conflate. "The integration tests silently no-op unless you run them from the workspace root" isn't a fact about you, it's a fact about the repo, and it belongs in CLAUDE.md where the next person who opens the project sees it — not locked away in your personal memory where only you ever benefit from it. reflect tells these apart and routes each one to where it actually helps.

Install

Project-scoped:

npx skills add LorcanChinnock/reflect

Global, so it's available in every project:

npx skills add LorcanChinnock/reflect -g

Usage

/reflect

Or just say something like "reflect on this session" or "save what you learned" — it's wired to fire on those too, so you don't have to remember the slash command.

What it actually does

It scans the session transcript for five things: detours that burned several turns before landing on the right answer, multi-step workflows worth repeating verbatim, blockers and how they got resolved, assumptions that turned out wrong and had to be corrected, and direct feedback you gave about how it should work. Then it filters hard. A candidate only survives if it's both recurring — it'll plausibly come up again — and non-obvious — you couldn't just re-derive it by reading a file. Everything else is dropped on purpose, including anything borderline. A missed marginal note costs nothing; a bad one costs every session that has to load it afterward.

Whatever survives gets sorted into one of two homes. Personal stuff — your own working habits, quirks of an external API, gotchas that are about you or your tools rather than the repo — goes to auto-memory, where reflect will edit or delete an existing entry rather than pile a new one on top of it. A convention the whole team needs goes to the repo's project instructions instead, and the routing is structure-aware: if CLAUDE.md already @-references a sub-file that covers the topic (or, in an AGENTS.md-only repo, a section of AGENTS.md does), reflect amends that section in place. If nothing already fits, it doesn't bloat CLAUDE.md's own body with a learned note — it writes a .claude/memories/ entry instead, wired in with a single @.claude/memories/index.md line at the bottom of CLAUDE.md. That folder gets curated the same way auto-memory does — edited and pruned rather than piled onto — so a hand-authored CLAUDE.md stays the curated front door it was, instead of quietly turning into the landfill reflect exists to prevent.

Either way, it shows you the full change list before writing anything, and waits.

Example

Say a session burned several attempts getting an internal API's auth working, and separately turned up a deploy convention nobody had bothered to write down — and nothing in this repo's CLAUDE.md already covers deploys. reflect would propose something like this:

Proposed memory changes:
  NEW   acme-api-auth — API requires an X-Client-Id header on every request,
        not just login; 401s otherwise. Not documented anywhere but the
        support forum.
  EDIT  acme-api-quirks — fold in the new auth note above instead of a
        separate file; same topic.
  DROP  acme-api-rate-limits — superseded, the API removed rate limiting in
        their March changelog.

Proposed project-instructions changes (you land these via a normal PR):
  MEMORY  .claude/memories/deploy-env.md  [+ new file]
          Deploy scripts require DEPLOY_ENV set explicitly, or they ship to
          production silently.
          wiring: + .claude/memories/index.md › @.claude/memories/deploy-env.md
                  + CLAUDE.md › @.claude/memories/index.md
          why team-durable: anyone running a deploy script in this repo can
          hit the silent prod push, not just this session.

If docs/testing.md had already existed and CLAUDE.md already @-referenced it, a repo-wide testing convention would have landed there instead, under its existing "Running tests" section — reflect only reaches for .claude/memories/ when nothing already fits.

Nothing gets written until you say go. And the project-instructions block only ever touches your working tree — reflect will not stage, commit, push, or open a PR for you. Landing it is yours to do.

Full behavior spec, if you want the precise rules instead of the summary above: SKILL.md.

Requirements

reflect only makes sense inside Claude Code, since auto-memory is a Claude Code feature and SKILL.md is only loaded there. Auto-memory itself doesn't have to be switched on — a team-durable lesson can still land as a CLAUDE.md/.claude/memories//AGENTS.md proposal without it. If neither applies to a given session, reflect says so and does nothing. That's a normal outcome, not a failure of the skill.

Context-rot recovery (below) needs nothing beyond SKILL.md itself — it reads Claude Code's own on-disk session transcript, so there's no companion file to copy and nothing extra to wire up after npx skills add.

Reliability & evals

Restraint is easy to claim and hard to verify, so the actual contract is pinned down as gradeable cases in evals/evals.json: a real detour becomes one lean NEW entry, a trivial session gets nothing manufactured for it, an already-covered topic gets EDITed instead of duplicated, a contradicted memory gets DROPped or fixed rather than left stale, nothing is ever written before the change list is shown, a repo-wide convention lands in the right @-referenced sub-file when one already fits, a convention with no existing home lands in .claude/memories/ instead of bloating CLAUDE.md's own body, and AGENTS.md still gets found correctly when auto-memory is off.

An earlier benchmark, in evals/results/2026-07-10/, runs the version that introduced project-instructions routing against the version that predates it — same 7 fixtures, same model (claude-opus-4-8), 14 runs total:

Eval Checks that... Current Pre-rewrite
1. acme-api-auth-detour a real detour gets saved as one lean entry 4/4 4/4
2. trivial-readme-typo a boring session gets no memory at all 3/3 3/3
3. already-covered-npm-test an existing topic gets EDITed, not duplicated 3/3 3/3
4. stale-deploy-pipeline a contradicted memory gets fixed or dropped 3/3 3/3
5. ask-dont-guess-feedback personal feedback stays in memory, doesn't over-route 3/3 3/3
6. team-convention-atref-subfile a repo convention lands in the right @-ref sub-file 4/4 1/4
7. memory-off-agents-md still finds AGENTS.md with auto-memory off 4/4 2/4
Total 100% 82%

Cases 1 through 5 pass on both versions — the routing rewrite didn't disturb anything that already worked, it just costs a bit more to run (168.9s / 38.1k tokens on average, versus 142.6s / 36.4k before — call it +1.7k tokens for the extra check). All the daylight is in cases 6 and 7:

  • Case 6 drops reflect into a pnpm monorepo where integration tests silently no-op unless run as pnpm -w test from the repo root — exactly the kind of thing that belongs in docs/testing.md, which this fixture's CLAUDE.md already @-references. The pre-rewrite skill had no concept of that home and filed it as a personal memory instead, so the lesson would have sat in one person's memory file, invisible to the next teammate who hit the same silent skip.
  • Case 7 turns auto-memory off and drops in a deploy script that ships to production silently if DEPLOY_ENV isn't set — again a whole-team gotcha, in a repo that uses AGENTS.md. With no routing concept and no memory store to write to, the pre-rewrite skill proposed a memory entry anyway, into a store the fixture had explicitly switched off.

Open eval-review.html in that results folder for the full transcripts rather than the summary above.

The most recent benchmark, in evals/results/2026-07-13/, runs the current SKILL.md — which replaces that routing's root-CLAUDE.md-body fallback with a .claude/memories/ folder — against the version right before this change, across cases 1-7 plus a new case 10, 3-4 runs each:

Eval Checks that... Current Pre-rewrite
1. acme-api-auth-detour a real detour gets saved as one lean entry 2/4¹ 4/4¹
2. trivial-readme-typo a boring session gets no memory at all 3/3 3/3
3. already-covered-npm-test an existing topic gets EDITed, not duplicated 3/3 3/3
4. stale-deploy-pipeline a contradicted memory gets fixed or dropped 3/3² 0/3²
5. ask-dont-guess-feedback personal feedback stays in memory, doesn't over-route 3/3 3/3
6. team-convention-atref-subfile a repo convention lands in the right @-ref sub-file 4/4 4/4
7. memory-off-agents-md still finds AGENTS.md with auto-memory off 4/4 4/4
10. no-home-convention-memories-folder a convention with no home lands in .claude/memories/, never CLAUDE.md's body 4/4 0/4
Total 93% 75%

¹ ² Both footnotes point at the same thing: a grading-strictness split between two independent grading passes, not a real behavior difference — reading the raw transcripts, both SKILL.md versions made the identical correct routing decision in every run of cases 1 and 4. Case 1's split is over whether printing an empty Proposed project-instructions changes: (none — ...) header counts as omitting the block (§7 says to omit it outright); case 4's is over the literal label EDIT vs. the assertion's wording of DROP or FIX, when §4 documents EDIT as the correct verb for fixing a stale memory in place. Correcting for that noise, both land at 100% on cases 1-7 — cases 1 through 7 are unaffected by this change (it only touches routing, prune scope, house style, and the propose template), so an identical pass rate there is the expected regression-guard result. All the real daylight is in the new case 10:

  • Case 10 discovers a repo-wide migration-locking convention in a repo whose CLAUDE.md has no @-referenced sub-file and no section that already covers it. Under the old routing rules, with no fitting sub-file, the only fallback was the root CLAUDE.md body — so every pre-rewrite run proposed a new section inlined directly into it. The current version instead proposes a new .claude/memories/<slug>.md file, wired in via .claude/memories/index.md and a single @.claude/memories/index.md line in CLAUDE.md, in all 4 runs, never touching CLAUDE.md's body — exactly the landfill-avoidance behavior this change adds.

This run used a lighter methodology than 2026-07-10's (no separate executor/grader split, no aggregate_benchmark.py/viewer) given the size of the sweep; see evals/results/2026-07-13/benchmark.md for the full notes and caveats.

Run the suite yourself with the skill-creator plugin:

/plugin install skill-creator@claude-plugins-official
evaluate the reflect skill with skill-creator

Each case runs in an isolated subagent and gets graded pass/fail with evidence attached, so a green run means something. Run it before merging any change to SKILL.md's behavior, and use skill-creator's version-comparison mode to confirm an edit is a real improvement and not a regression with a tidier diff.

allowed-tools in SKILL.md is deliberately narrow — Read, Grep, Glob, Edit, Write, Agent — enough to read the memory index, write memory files, edit a CLAUDE.md/AGENTS.md in the working tree, and spawn the one fresh-context rescan agent described below, all without a permission prompt on every run. Deleting a memory file still needs Bash(rm ...), which is intentionally left off, so a DROP always stops and asks. Staging, committing, or opening a PR needs Bash/gh, also excluded by design — reflect can propose and write the edit, but landing it stays a manual step.

reflect itself also has to run inline, never forked (no context: fork). By default it works entirely off the session transcript and memory index already sitting in context when it runs; a forked subagent starts with neither, so it would have nothing real to reflect on and would either come back empty or invent something.

The one exception is deliberate, not a loophole: when the on-disk transcript shows a compaction boundary, reflect spawns a single Agent — but pointed at that on-disk transcript, not run cold. That agent isn't reflecting on nothing; it's reading the same session's authoritative, pre-compaction history from a context that isn't rotted, which is exactly what the in-context copy can no longer give you. reflect still runs inline itself and still does all the filtering, routing, and proposing from its own context — the sub-agent is a fresh pair of eyes on ground truth, used only when the cheap path is already compromised.

Surviving context-rot at end-of-session

A long session's biggest risk to reflect is running at exactly the moment it's least reliable: after compaction, the in-context transcript is a lossy summary, and a model reasoning from a near-full context window also follows its own filter less reliably — the "recurring and non-obvious" bar in Section 2 is weakest exactly when it matters most. A caveat alone doesn't fix that; it just labels the loss.

Claude Code's on-disk transcript for a session is append-only and survives compaction intact — it never gets rewritten down to the lossy summary, only the in-context copy does. Every compaction also leaves a marker line behind on disk. So reflect locates this session's transcript itself (derived from the working directory, under ~/.claude/projects/) and counts those markers: none found, it takes the cheap in-context path exactly as before; one or more found, it spawns the fresh-context Agent above to rescan the untouched on-disk history and hands the result back into the normal filter/route/propose pipeline. If the transcript can't be located or read but the session was clearly long enough to have been summarized anyway, reflect says so, raises the bar, and reports what it found as partial rather than pretending the in-context copy is complete.

Contributing

Bug reports and small, focused proposals are welcome — see CONTRIBUTING.md.

License

MIT

Links

Built by Lorcan Chinnock.

About

A Claude Code skill that curates your auto-memory store — pruning and sharpening it, not just growing it.

Topics

Resources

Code of conduct

Contributing

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages