Quiz yourself on the code you just wrote — before it ships.
RecallCheck is a Claude Code plugin that runs a short, friendly comprehension self-check on your current diff: 3–5 questions grounded in the actual functions, guards, and sensitive paths you just touched. It's built to catch vibe-coded or half-understood changes before they reach a pull/merge request.
It does not review your code (tests, lint, security scanners already do that). It checks your understanding of it. No scoring, no gating — this is for you.
/recallcheck:quiz
Plenty of tools check the code. Nothing asks "can you explain what you just built?" RecallCheck fills that gap with the lightest possible mechanism: it reads your diff, flags the interesting hunks, and lets Claude — which already reasoned through the change in this session — ask you about them conversationally. No second LLM call, no extra latency, no cost.
Via the mannutech marketplace:
/plugin marketplace add mannutech/claude-plugins
/plugin install recallcheck@mannutech
The whole plugin is shell + git plumbing — no npm package, no daemon, no network calls of its own. Requires git, jq, and awk on PATH (all standard on a dev machine).
Run it whenever you want a self-check — after finishing a feature, mid-refactor, or right before opening an MR:
/recallcheck:quiz
Plugin commands are namespaced, so it's always
/recallcheck:quiz— therecallcheck:prefix is required (there's no bare/quizor/recallcheck). Just type/recallor/quizand the fuzzy menu will surface it.
Claude runs the shared summarizer, then asks you 3–5 questions about the flagged changes — new/changed functions, removed error handling, touched auth/payment/secret/migration paths, and large single-file edits. You answer in plain language. Claude reacts briefly, flags anything that sounds off, and never blocks or scores anything.
You can focus it: /recallcheck:quiz src/payments.ts.
The quiz is manual; hooks only suggest it. That split is deliberate — it keeps all the blocking/timing/false-positive risk out of your workflow:
/recallcheck:quizis the only place Q&A happens. Developer-invoked, any time, no timing heuristics.- Hooks are a thin, non-blocking nudge layer. They can inject a one-line "you could run a recall check" suggestion — always
permissionDecision: "allow", neverask/block. Worst case if the timing is stale: one slightly-off sentence. Yourgit push/gh pr create/glab mr createalways proceeds untouched.
v1 works with the slash command alone. The hooks are a pure add-on.
Two nudge points, each independently toggleable in config/quiz.config.json:
| Hook | When | Default |
|---|---|---|
pre-push (PreToolUse on Bash) |
you run git push / gh pr create / glab mr create with meaningful unshipped changes |
on |
stop (Stop) |
end of a turn with meaningful unshipped changes (with a politeness cooldown) | off |
Neither ever pauses or blocks. The PreToolUse matcher is just "Bash"; the script itself inspects tool_input.command and self-filters to push/PR/MR commands, so behavior is correct regardless of which host matcher features are available. If jq is missing, the pre-push hook degrades to a plain allow — a push is never broken.
Extend sensitiveKeywords to flag your own risky paths. No scripts to touch.
scripts/build-quiz-context.sh — shared by the command and the hooks:
- Diff scope:
git diffagainst the merge-base of your branch and the mainline (origin's default branch, else the tracking upstream); falls back togit diff HEADif there's no upstream. This means it sees committed-but-unpushed work even when your working tree is clean — exactly the pre-push case. - Flag interesting hunks heuristically: new functions/exports, removed error handling, sensitive keyword paths, and any file changed by more than
diffSizeThresholdlines. - Emit plain text. The actual question-writing is Claude's job in the live conversation — the script stays dumb.
It does not read your transcript (that field isn't guaranteed to hooks) and never makes a network call.
- Never blocks or delays a git/gh/glab command. Every hook path ends in
permissionDecision: "allow"(pre-push) or nodecisionfield (stop). - No external LLM call. Quiz generation happens inside your existing Claude conversation.
- No answer content stored. Optional logging records only timestamp / file count / question count, locally, never transmitted.
- Degrades gracefully: no
gh/glab→ still catches plaingit push; nojq→ hooks no-op safely.
bash test/recallcheck.test.shHermetic — spins up throwaway git repos in $TMPDIR and asserts: manifest validity, the real hooks schema (no invented handlers/if), diff flagging on both the fallback and merge-base paths, that every command shape yields allow, that nudges appear only for push-like commands over threshold, that toggles and the stop cooldown work, and that a missing jq still allows the push.
recallcheck/
├── .claude-plugin/plugin.json # manifest
├── commands/quiz.md # the quiz mechanism (the only place Q&A happens)
├── hooks/hooks.json # optional suggestion layer
├── scripts/
│ ├── build-quiz-context.sh # shared diff/flag summarizer
│ ├── suggest-on-pre-push.sh # PreToolUse nudge (self-filters to push/PR/MR)
│ └── suggest-on-stop.sh # Stop nudge (cooldown-guarded)
├── config/quiz.config.json # thresholds, keywords, hook toggles
└── test/recallcheck.test.sh
MIT.
{ "questionCount": { "min": 3, "max": 5 }, "sensitiveKeywords": ["auth", "payment", "pii", "token", "password", "secret", "migration", "credential"], "diffSizeThreshold": 40, // min changed lines before a hook nudges "vcs": ["github", "gitlab"], "hooks": { "stop": false, "prePush": true }, "log": false // append a local, answer-free line per run }