Simple Context Memory is a Claude Code plugin with three slash commands — /opening, /closing, and /report — that give AI sessions structured, decision-focused memory using a surgical shift handoff model so each session starts oriented, not cold. Built by Robert Evans.
Run /opening at the start of any session. No cold start. No re-explaining.
Each command solves a different scale of the same problem. Together, no session starts cold and no decision gets re-litigated from scratch.
Reads session archaeology documents — structured markdown files written by /closing that preserve decisions, reasoning, and guard rails from each work session — from docs/sessions/ and gives you a structured brief: what the project currently is, what decisions are settled, what's pending, and what threads were live when you left off.
Think of it like reading the previous surgeon's handoff note before you scrub in. You don't read the patient's full chart — you read what changed on the last shift and what's still unresolved.
When 3+ files need to be read, delegates to a subagent — raw archaeology never enters your context window. Only the distilled brief does. The main context stays clean for actual work.
/closing is the session close command: it writes a structured handoff document capturing decisions, reasoning, and guard rails before the context window fills. Claude Code compacts the context window when it fills up — compaction is lossy, it summarizes rather than preserves, and once it happens, the fine-grained reasoning about why decisions were made is gone.
Run /closing before that happens. Think of it like saving a document: you don't wait until your computer crashes. If the session has been long, run it while the context is still intact, then keep going.
Use /closing [scope] to capture a single decision or topic rather than the full session — useful when a session covered multiple unrelated things and you only want to preserve one cleanly.
SBAR-C is a five-component clinical handoff reasoning framework — Situation, Background, Assessment, Recommendation, Contingency — adapted from medical shift changes to structure what /closing extracts and records before writing the session document.
SBAR-C doesn't produce extra sections — it surfaces content for the sections that already exist, and catches contingencies before they get buried. A contingency lands as a conditional in the Do Not line: Do not X because Y — unless Z, in which case reconsider.
/report is the history synthesis command: it reads all session documents and produces one current-state document listing every still-open deferral and every Do Not constraint, each linked to the session that created it. At 20+ sessions, the problem shifts — one session document answers “what happened last time?” but thirty session documents answer a harder question: “what is the accumulated state of all deferred work and locked constraints across the entire project history?”
Loading the report plus 2-3 most recent sessions gives the same orientation as loading everything — with a fraction of the token cost. The cursor mechanism (last_session in frontmatter) means subsequent runs only process new sessions.
Run /report full after a /closing that may have resolved items the report has as open, or any time you want a clean rebuild from scratch.
Seven sections. Each one answers a question your future session will have. The code already shows you what was built. Only this document shows you why.
2-3 sentences. What was this session about, what is the most important thing that changed, and what does the next session pick up? Written to orient in ten seconds without reading anything else.
Removed the local idempotency table and switched to Stripe's native idempotency key support. The table was duplicating protection Stripe already provides for free. Next session: decide whether to log the Stripe idempotency keys we send for audit purposes.
Concrete list of what was built, changed, or decided. File paths, function names, design choices. Not "we improved the flow" — exactly what changed and where.
- Removed the `idempotency_keys` table and `IdempotencyKey` model entirely - Switched to Stripe's built-in Idempotency-Key header on all POST requests to Stripe — passed directly from the incoming webhook payload's stripe_event_id - Updated `app/services/payment_processor.rb` to pass key on charge creation - Removed the `20260518_create_idempotency_keys.rb` migration (rolled back)
The reasoning behind the key decisions. Not just what was chosen but why the alternatives were worse. The section that prevents future sessions from re-litigating settled questions.
We were maintaining a local idempotency table to prevent double-charging on retried webhooks. Stripe already does this natively — passing the same `Idempotency-Key` header returns the original response without re-executing the charge. Our table was duplicating protection Stripe provides for free and adding a write on every payment path. Deleting it was the right call.
Everything considered but deliberately rejected. The most important section — it's what won't appear in code or git history. Each entry ends with a forward-binding Do Not constraint that a future session sees before it starts reasoning about the problem.
Questions answered during the session, as Q→A pairs. Root causes traced, misconceptions corrected. What a future session needs to know so it doesn't re-discover it.
Does Stripe's idempotency window cover our retry policy? → Yes. Stripe's window is 24 hours; our policy retries within 6 hours. Safe. Would need revisiting if the retry window ever expands past 24 hours. What does Stripe actually do with a duplicate idempotency key? → Returns the original response without re-executing the charge. No side effects. This is the core reason the local table was redundant.
What was explicitly deferred, left unresolved, flagged for next time, or suggested but not acted on. Action items, half-decisions, and review findings noted for later.
- Do we want to log the `Idempotency-Key` values we send to Stripe for audit purposes, or is Stripe's dashboard sufficient? Deferred — not a blocker for the current release. - No action items outstanding.
What changed and where, plus any constraint a future session needs before touching that file again. Specifically anything that looks like it could be safely reverted but shouldn't be.
- `app/services/payment_processor.rb` — added idempotency_key: param to charge. [Constraint: key must be the incoming stripe_event_id, not a generated UUID — ensures replay safety.] - `app/models/idempotency_key.rb` — deleted - `db/migrate/20260518_create_idempotency_keys.rb` — deleted - `spec/services/payment_processor_spec.rb` — removed idempotency table fixtures
Six months from now, when someone wonders "did we ever consider a Redis cache here?" — the answer is one grep away.
The reversal condition — unless Z, in which case reconsider — makes it a living constraint, not a dead rule. The guard rail carries its own expiry condition.
This is the section that preserves the reasoning that was hard to arrive at the first time. Without it, every new session starts from scratch on problems already solved.
Three scripts work as a layered defense against compaction. The first gives you time to act. The second acts automatically if you don't. The third reorients you afterward.
Warns at 60% and 75% context fill — early notice to run /closing manually. Reads the actual JSONL transcript to calculate context usage precisely.
The CONTEXT_WINDOW constant defaults to 200,000 (claude-sonnet-4-6). Update it for other models.
Safety net: prints the full session document format as an instruction immediately before compaction runs. Claude writes the archaeology file before compaction proceeds.
Fires even if you forgot to run /closing. The document is written before the context is compressed.
After compaction, reads cwd from the hook payload, checks docs/sessions/ for the most recently written file, names it, and prompts you to run /opening.
If no session file exists, tells you to run /closing immediately to capture what remains in the compressed context.
Each command operates at a different scale. Together they cover the full lifecycle from a single session to a project's entire decision history.
The shift handoff. Before the context window fills. The structured format — seven named sections, each signaling what's load-bearing — does the compression work before the document enters context. Claude doesn't figure out what matters; the format already told it.
Reads the handoff and orients the new session. Claude treats explicit decisions differently from musings — the archaeology format plays into this. Every section ends with something settled or something open, which Claude slots directly into its working model of the project.
At 20+ sessions, the problem shifts. The report collapses accumulated history into one document: every still-open deferral, every Do Not constraint, each linked to its source. Subsequent runs only process new sessions — you don't re-pay the synthesis cost on history already captured.
Most memory systems save everything. The reflex solution is to dump the whole context into files. But Claude loads it and re-litigates anyway — because it can't tell which of the forty remembered facts is the one that matters right now.
The archaeology format extracts the signal so Claude doesn't have to. Each section tells Claude what role the content plays — not just what it says. Contrast this with raw chat history: Claude sees a wall of text with no signal about what matters. The structured document does the compression work before the document enters context.
Simple Context Memory is not a memory recall system — it is a decision archaeology system. Every alternative saves what happened. Only this one saves why it was done this way, what was explicitly rejected, and what a future session must not undo.
| Approach | Decision archaeology |
Rejected alternatives |
Project-scale synthesis |
Compaction hooks |
|---|---|---|---|---|
| Simple Context Memory | ✓ | ✓ | ✓ | ✓ |
| CogniLayer | — | — | Partial | — |
| /handoff skill | — | — | — | — |
| CLAUDE.md | — | — | — | — |
| Raw context dumps | — | — | — | — |
CogniLayer uses vector-DB recall for last-session context but does not capture why decisions were made or what was rejected. The /handoff skill solves single-session agent-to-agent transfer, not multi-session project continuity. CLAUDE.md stores persistent preferences but has no session structure and no mechanism to accumulate or synthesize session history. Raw context dumps save everything — Claude re-litigates anyway because there is no signal about what matters.
Install globally — these commands are useful in every project, not just one. Claude Code picks up .md files in commands/ directories automatically. No config, no restart.
git clone https://github.com/revans/simple-context-memory
bash simple-context-memory/init.sh
Copies commands to ~/.claude/commands/ and hook scripts to ~/.claude/hooks/. Prints the settings.json snippet for hook wiring if not already configured.
⚠ Existing files are overwritten without prompting. Back up customized copies before running.
{
"hooks": {
"UserPromptSubmit": [{
"hooks": [{ "type": "command",
"command": "python3 ~/.claude/hooks/context-watch.py" }]
}],
"PreCompact": [{
"hooks": [{ "type": "command",
"command": "python3 ~/.claude/hooks/pre-compact.py" }]
}],
"PostCompact": [{
"hooks": [{ "type": "command",
"command": "python3 ~/.claude/hooks/post-compact.py" }]
}]
}
}
cp simple-context-memory/commands/*.md your-project/.claude/commands/
Three commands. Five minutes to install. Every session after that starts oriented instead of asking "wait, where were we?"