You close the session in four steps. Don't just dump — audit. Everything you write, you announce briefly; anything promoted to rules/concepts needs the user's verbal "yes" first.
Step 1 — Capture what's new
Scan this session for observations worth keeping. Append each to .claude/memory/MEMORY.md
as a ONE-LINE [YYYY-MM-DD]-prefixed entry. Short, scannable, no essays (long rationale
belongs in a concept article, step 2).
- File each line under a TOPIC heading of the patterns section (engineering, process,
infra, the domain…) — create the topic if none fits. Never open a heading named after the
session or the date (
### s66 (2026-09-25),## Session 65 wrap): the date lives in each line's prefix, the session narrative lives in the handoff (step 4). The SessionStart hook flags such headings. - Don't capture what the always-loaded layer already says (
CLAUDE.md, rules withoutpaths:) or a number whose source of truth lives elsewhere (a price table, a config) — point at the source instead of copying the value.
Step 2 — Audit & promote (the valuable part)
Read the date-tagged entries in MEMORY.md. Look for repetition: did this pattern appear on 3+ different dates? Surface 2-4 candidates, be specific: "noticed [date], [date], [date] you said X — codify as a rule or a concept article?"
- User says yes → write
knowledge/concepts/<topic>.md(facts + rationale; frontmatter perknowledge/index.mdspec) or.claude/rules/<name>.md(mechanical always/never constraint; only for patterns stable 6+ months). Updateknowledge/index.md(one line per concept). - Promoted or long-absorbed entries get PRUNED from MEMORY.md — that's how it stays under its caps (180 lines / 32 KB / 3000 chars per line).
- Writing a fact into a second place?
reference/doc-governance.md— one SSOT per fact, and when a fact changes you grep its restatements in the same pass. A product or architecture decision goes to the ledger instead —projects/<name>/decisions-log.md, format inreference/decisions-log.md. A plan, a spec, a research finding or a QA record is NOT memory: it belongs in that project's folder, per the map in itsREADME.md.
Step 3 — Refresh the MEMORY.md header
The header (everything above the first ---) is «current state of work», 2-3 sentences,
REPLACED every close — never a chronicle of past sessions. Per-session detail lives in the
handoff, not stacked in the header.
Step 4 — Write the handoff
Copy context/handoffs/HANDOFF-TEMPLATE.md → context/handoffs/<topic>-<YYYY-MM-DD>.md and
fill its five sections (what was done · where things stand · memory updates · next steps ·
opening note). The SessionStart hook injects the newest handoff next time — this file IS the
"remember where we left off" mechanism.
Also check (30 seconds)
- Experiment hygiene: any
experiments/*-YYYYMMDD/older than 30 days → ask: still active or close (distill → delete)? - Backlogs:
projects/*/BACKLOG.mdtask statuses reflect today's reality — aDONEnobody verified is stillIN PROGRESS. - Project map: anything you wrote today into a project folder is a row in that project's
README.mdmap, and the map'sLast verifiedis today's date. - Specs vs code: any spec still
buildingafter a merge, or anyassumedspec → run/memory-kit:code-sync(it reconciles statuses from repo evidence; this ritual does not). - Caps: if MEMORY.md is near any cap, do a deeper prune now, not "next time".
What NOT to do
- Don't promote without the user's yes. Repetition makes a CANDIDATE, not a rule.
- Don't stack "Prior session" paragraphs in the MEMORY header — replace it.
- Don't group today's lines under a session heading — see Step 1.
- Don't write a handoff longer than ~1 screen. It's a note, not a transcript.