Clear due memory reviews with free recall โ the two-minute habit that makes learning permanent. Use when reviews are due, or the user wants to review, practice, or "do my engram reviews".
Installs just this skill. Get the whole plugin for auto-invocation.
โก How it fires
How this skill gets triggered: by you, by Claude, or both.
Fires itselfClaude auto-loads it when your prompt matches the work.
You can call itInvoke it directly when you want it.
Slash command/review
๐๏ธ Context preview
The summary Claude sees to decide when to auto-load this skill.
Clear due memory reviews with free recall โ the two-minute habit that makes learning permanent. Use when reviews are due, or the user wants to review, practice, or "do my engram reviews".
๐ Stats
Stars1,099
Forks91
LanguagePython
LicenseMIT
๐ฆ Ships with engram
</> SKILL.md
review.SKILL.md
---name: review
description: Clear due memory reviews with free recall โ the two-minute habit that makes learning permanent. Use when reviews are due, or the user wants to review, practice, or "do my engram reviews".
argument-hint: [quick | <topic>]
---# /review โ the retention loop
Read `skills/_shared/dialogue-grammar.md` (hard rules, confidence integrity, park-and-resume, and the rating map apply here verbatim). Set:
```bash
# Resolve the engine. RUN THIS BLOCK VERBATIM โ do not substitute a path you guessed.
for d in "$OPENCODE_PLUGIN_ROOT" "$CLAUDE_PLUGIN_ROOT" "$CODEX_PLUGIN_ROOT" "$ENGRAM_ROOT" \
"${OPENCLAW_STATE_DIR:-$HOME/.openclaw}/extensions/engram" \
"$HOME/.gemini/config/plugins/engram" \
"$PWD" "$(git rev-parse --show-toplevel 2>/dev/null)"; do
[ -n "$d" ] && [ -f "$d/scripts/engram.py" ] && ENGRAM="$d/scripts/engram.py" && break
done
[ -n "$ENGRAM" ] || echo "engram: engine not found โ set ENGRAM_ROOT to your engram checkout" >&2
```
If none are set, resolve the plugin root as the directory containing `.claude-plugin/plugin.json` (or `.codex-plugin/plugin.json`). **Never inline a learner's answer into a shell command** โ pass productions via `--production-file` (or `--production-file -` on stdin); a stray quote or `$(โฆ)` in what they typed would otherwise execute.
**Spawning agents.** "Spawn **engram-โฆ**" means a *fresh-context* child running that agent's definition โ via your platform's subagent/Task tool (the type may be namespaced, e.g. `engram:engram-assessor`). **If your only mechanism is a generic `sessions_spawn`, read `skills/_shared/subagents.md` first.**
python3 "$ENGRAM" stash count # a previous session's ungraded work?
python3 "$ENGRAM" due --limit <cap>
```
If stash > 0, settle it first (assessor โ `receipt` โ `stash clear`, per /learn step 4) with one explanatory line. Caps: `quick` โ 5 items; otherwise mode default (Standard โ 12). `--topic <t>` if the user named one, but note interleaving across topics is the default *on purpose* โ don't undo it for tidiness. Open with the session ticket. Empty queue โ one line of honest celebration, then stop (suggest `/learn continue` only if a topic has frontier nodes). Never invent reviews.
**Return-after-absence (the amnesty protocol โ the highest-evidence Layer 2 move; `docs/05-affective-layers.md` P14).** If the due queue is large after a gap (roughly `due > 2ร the mode cap`, or the last session was many days ago), do **not** dump the debt. This is the #1 SRS churn trigger, and a wall of overdue reviews reliably makes people quit (Silverman & Barasch 2023; a single missed day does not actually harm memory โ Lally 2010). Instead, one calm line of amnesty + load renegotiation, then a real choice:
- Frame it as normal, owed nothing: *"You've got 40 due after the break โ that's just spacing doing its job, not a debt. FSRS handles backlog fine."*
- Offer (arrow-key): **clear a capped set today** (this mode's cap, most-overdue first โ recommended) / **a longer catch-up** / **just the highest-value topic**. Never a marathon; the two-minute floor is a floor, not a target.
- Then run only the chosen cap. What's left stays due and un-guilted. Zero shame in either the offer or the close.
**The honest number, exactly once (v0.6).** Amnesty removes the guilt; it must not also remove the *stakes*. After the amnesty line and **before** the arrow-key offer, read the engine and state what the decay actually costs โ one line, then move on:
```bash
python3 "$ENGRAM" decay --topic <t> # or bare, for everything
```
Its `read` field is already written for a human. Say it flatly, in the register of a lab notebook reporting a result: *"Those seven are at ~70% and still falling โ four minutes today is the difference between keeping them and re-learning them."*
The rules that keep this from becoming the thing this project despises:
- **Information, never pressure** (`docs/05` P13; Deci/Koestner/Ryan 1999: controlling praise nets **d = โ0.78** on adult motivation). It reports a forgetting curve because that is what the curve says. **No "should." No scold. No "don't lose your progress!"**
- **Once, on return.** Not every session, not per item. The engine's ambient hook already rations it (it fires only on a never-closed loop or a real absence); do not re-say what the hook already said.
- **Amnesty first, always.** The order is: *nothing is owed* โ *here is what it costs* โ *here is a two-minute path*. Reversed, it is a debt collector.
- **`settings.decay_notice = "off"` means silent.** The learner opted out; honor it without comment.
- If a line would read to a skeptic as *"the tutor is trying to make me feel guilty,"* it is a defect. Cut it.
## 2 ยท Per item โ the retrieval protocol
The `due` payload gives you `probe`, `claim` (canonical answer), and `rubric` โ plus `node_kind` and `practice` (v1.1). Show a progress marker per item: `[3/6] ยท residual-stream โ `. The order of operations is sacred:
**`node_kind: "procedure"` items first take a detour** (Read `skills/_shared/problem-grammar.md` once per session when one appears): serve a **fresh algorithmic variant** generated from `practice.problem_frame` โ new values, same structure and cover story; never the stored numbers, and never a re-clothed isomorph (that is `transfer_probe`'s job) โ computing the answer key by execution before showing anything. When a `practice.discriminates_from` sibling is co-due (or mature), serve the pair **adjacently** and open with the naming step ("which technique, and why?") โ and until it's answered, the progress marker shows the topic, never the node id (the id would answer the question). Grade the solve with the problem grammar's table โ method-wrong caps the grade regardless of the answer; a slip-only miss is `partial`/`hard` with `--error-class slip`, a wrong-method one carries `--error-class conceptual`. A procedure node with no usable `practice` falls back to the stored probe, concept-style. Everything below (confidence pick, stash-or-rate flow, transfer, momentum) applies unchanged.
1. Show the **probe only**. Free recall โ no options, no hints in the prompt, no "remember when we...". Do **not** ask them to type a confidence number.
2. They produce. (Silence is fine; "no idea" is an answer โ treat as lapse, warmly.) **Then collect confidence by calling `AskUserQuestion` (the four-band Confidence picker โ exact call in grammar โ ), BEFORE the reveal.** Skip only if they volunteered a number unprompted; "Other"โexact number; dismiss/skip โ null, never estimated.
3. Reveal: canonical `claim` + a one-line gap analysis against `rubric` โ specific, about the work. If they gave consequence-only, run the terse-production move (one "and the mechanism?" โ grammar file) *before* the reveal. (Confidence picker, if any, comes first โ sureness before feedback.)
4. Map to a rating with the shared table (round down when torn) and commit **immediately**. Pass the learner's answer via a file (write it, then reference it) so their text never lands on the command line:
# procedure items only: append --error-class slip|conceptual per the problem-grammar
# table (omit the flag entirely on concept/fact items and on recalled grades).
# If the engine rejects --error-class (an older engine than these skills), RETRY the
# same command without the flag โ the rating must never be lost to a version skew.
```
Relay the returned due date in passing, not ceremonially ("back in 12 days"). **When the `rate` output's durability crosses a threshold** (first reps, or `s_after` clearing ~7 or ~30 days, or roughly a doubling โ a milestone, not every review; grammar file, Pillar 13), add *one* flat growth line โ *"that jumped from ~4 days to ~17; it'll hold now."* A mature node creeping up says nothing new โ stay silent; a `hard`/`again` gets honest task-feedback, never a manufactured win; silent too if `settings.momentum` = `off`.
The `due` payload now carries `transfer_ready` and `transfer_probe`. When it is `true`, the node is **mature** (stability over 21 days across 3+ retrievals) and the architect wrote a probe that asks the same idea **wearing different clothes** โ usually from the learner's own world.
**Serve the `transfer_probe` INSTEAD of the `probe`**, and rate it with `--kind transfer`:
--grade <g> --production-file <tmp-answer.txt> --kind transfer --source self
```
Say what you're doing, plainly and once: *"You've held this one for a month, so let's not ask you to recite it. Let's see if it fires."*
**Why this exists, and why it is not decoration.** `transfer_probe` has been authored by the curriculum architect since v0.1 and **read by nothing** โ 12 of the 13 nodes in the founder's own graph carry one, and zero transfer receipts existed anywhere, ever. Engram measured *memory* and claimed *capability*. There is a sharper version of that critique which `docs/07` ยง8 takes seriously rather than deflecting: **transfer-appropriate processing** says practice should match use. If the learner's goal is *to do* โ write the code, make the call โ and every review is verbal free recall, Engram may be training a different skill from the one that was paid for. This is the answer to that.
**Grade it honestly, and separately.** A transfer receipt is **never pooled into retention** โ `stats.transfer` is its own number with its own denominator, because "did the memory survive?" and "does the capability fire?" are different questions. A lapse here is **not** a memory failure and must never be framed as one: *"you remember it fine โ it just doesn't fire yet. That's a different muscle, and it's the one that matters."* Do not manufacture a failure out of a hard question.
**And the engine now backs that sentence up (v0.8.1).** A failed transfer probe **leaves the memory schedule completely untouched** โ same stability, same due date, no lapse recorded. Until v0.8.1 it did not: one failed probe deleted **97% of a mature memory's durability** (s 443 โ 12), flipped the node to `learning`, and dropped it below the transfer bar forever. **Answering a harder question wrong demolished the schedule for the original concept** โ the exact "fabricated setback" the maturity gate was built to prevent. A successful probe still strengthens the memory, because applying an idea *is* a retrieval, and a strong one.
- **High confidence (โฅ70) + lapse** โ hypercorrection gold: pause the queue, have them re-derive the claim from its `why_chain` prerequisites (or rebuild the mnemonic if `arbitrary`), log `misconception add`. Two minutes here is worth ten elsewhere.
- **Second+ lapse on the same node** (`lapses โฅ 2` in payload) โ the encoding failed, not their memory. After rating, re-encode *differently*: new analogy (use their interests), a contrast case, or an explorable โ and on a **procedure** node, prefer a find-explain-fix erroneous example (problem grammar). The payload's `artifact` flag tells you which case you're in: `true` โ the *current explorable also isn't holding* โ offer to regenerate it differently (spawn **engram-artifact-smith** in the background with the node's current state + open misconceptions; it re-registers on completion; hand off at the close, never mid-queue); `false` โ offer to build one (same background spawn) if `settings.artifacts` โ `off` or the learner asks. Say the move plainly either way: "this card keeps dying, so we're changing the card, not blaming you."
- **Instant + correct + low confidence** โ note it aloud; their calibration data will show it at `/coach`.
## 3 ยท Assessor audit (keep self-grading honest)
If the session had โฅ8 items, any disputed grade, or โฅ3 `partial`s: stash `{topic, node, probe, claim, rubric, production, confidence, kind:"audit", tutor_rating:"<r>"}` (plus `node_kind:"procedure"` on procedure items, so the auditor step-grades) (the engine mints the `sid`; the assessor must return it) for each such item, then spawn **engram-assessor** on `stash list` for an audit verdict, and `stash clear` after. Report disagreements to the learner and log a `misconception add` or a note โ do **not** re-rate already-committed items (scheduling stands; drift is the coach's monthly business). Disputes from the learner: same path, once.
Close with the **receipt strip**: items โ outcomes, streak, one meaningful number (e.g., month-bucket recall rate), next due date. Prefer a **momentum** number from `stats.momentum` as that meaningful number when there was real growth โ *"+31 days of durability added this week"* or *"most durable now: residual-stream, 42 days"* โ informational, never a score (Pillar 13). If the queue was large and they stopped early โ fine, say what's left, zero guilt. The two-minute floor exists to protect the habit, not to grow the session.