Exam Drill
Workflow philosophy (critical — do not break)
The user does not type math into the CLI — it is too slow. All interactions obey:
-
Generation side (Claude → file). Problems, variants, and clean reference derivations are written as markdown files to
quizzes/,twins/,chain/,derivations/. The user views them; no math dialogue in the terminal. -
Answer side (user → PDF). The user solves on paper, scans as PDF, uploads to
answers/<name>.pdf. Theanswer-processingskill (auto-loaded by/grade) converts the PDF to markdown and grades. -
Strategy checks (when user is online) — when a command asks the user to verify understanding without producing a full written solution, it asks only for the strategy in 3–5 lines of prose (written in
INTERFACE_LANGfrom.course-meta, defaulten): which pattern(s), which variables are fixed/expanded, what form the answer takes. Strategy matching is stronger evidence of mastery than line-by-line algebra.
Drill targeting philosophy (critical — do not break)
HW density = exam probability. The professor has already told you, through HW, where the exam points live. Every drill command must bias toward HW-emphasized sections (🔥🔥 Exam-primary > 🔥 Exam-likely > 🟡 Exam-possible). Sections with no HW (⚪ Low-risk) are not "blind spots waiting to bite" — they are the professor's signal of what is off the exam. Do not treat low-HW sections as high-risk.
Concretely:
/twin,/blinddefault to the highest-HW-density problems when the user doesn't specify one./chaincomposes patterns drawn from Exam-primary sections; avoid pulling patterns from ⚪ sections unless the user explicitly asks./mockproblem weighting follows HW density (seecommands/mock.md)./quiz allsamples ≥70% from 🔥🔥, ~25% from 🔥, ≤5% from 🟡, 0% from ⚪.- If the user requests a ⚪ section drill, comply once but warn that exam probability is low.
Prerequisites
This skill assumes /ingest and /analyze have been run. If course-index/patterns.md or course-index/coverage.md don't exist, tell the user to run those first.
Files read
course-index/patterns.md— recognition cards P1, P2, ...course-index/coverage.md— HW↔§ map, 🔥 exam tiers + ⚠weak flagscourse-index/summary.md— topic treeconverted/homework/*.md— original HW problemsconverted/solutions/*.md— HW solutions (ground truth for grading)errors/log.md— user's error history (append-only)
Files written
<ts> is always date +%Y%m%d_%H%M%S (e.g. 20260611_213627) — one canonical
timestamp format for every drill artifact (/quiz, /twin, /chain, /mock).
Use underscores, not a - between date and time, and do not improvise a per-run
format. The stem you save (<id>_<ts>_sol.md) must be the exact <ts> you print
in the upload instruction (answers/…_<ts>.pdf) so /grade resolves it and the
course folder doesn't accumulate mixed-format filenames. (Generate it once with
date +%Y%m%d_%H%M%S and reuse that string for both the saved files and the
printed upload name.)
quizzes/<topic>_<ts>.md— problem statements (answers in_answers.mdsibling)twins/<origin>_<ts>.md— variant problemschain/<ts>.md— integration problemsderivations/<topic>.md— clean reference derivations (post-success)errors/log.md— append error entries
Command patterns
/twin <problem-id>
- Locate
<problem-id>inconverted/homework/andconverted/solutions/. - Identify patterns used via
course-index/patterns.md. - Apply twin-recipe.md rules: hold pattern and topic invariant; vary system, numbers, direction, names.
- Save problem to
twins/<id>_<ts>.mdand solution totwins/<id>_<ts>_sol.md. Do not reveal solution unless user either (a) uploads their answer PDF, or (b) describes a correct strategy.
/blind <problem-id>
- Present the problem verbatim from
converted/homework/. - Ask for strategy (3–5 lines, in $INTERFACE_LANG):
- which pattern(s) from
course-index/patterns.md - what variables are fixed vs. varied
- expected form of the final answer
- which pattern(s) from
- Compare against
converted/solutions/. Three checks: pattern / variable-choice / end-form. - On success, copy the relevant solution section into
derivations/<stem>-<n>.md. On failure, flag the specific axis and log toerrors/log.md.
/chain <N>
- Pick N patterns from different source problems (per
course-index/coverage.md). - Design a problem that requires composing them sequentially in parts (a), (b), (c).
- Bias toward user's weak zone (sections flagged
⚠weakincourse-index/coverage.md, or the latest weakmap's top entries). - Save problem and solution; prompt for part-by-part strategy or PDF upload.
/pattern [§ or keyword or "all"]
Read-only. Filter course-index/patterns.md by the query and return compact pattern cards.
/hwmap [§ | "hot" | "all"]
Read-only. Project course-index/coverage.md by the query. hot ranks 🔥🔥/🔥 sections by HW density with their HW drill anchors and a per-§ recommendation (blind is accepted only as a legacy alias for hot — there is no blind-spot listing mode; ⚪ no-HW sections are low-risk by design).
Twin recipe (invariance rules)
Hold invariant:
- The pattern(s) required — a twin that uses a different method is not a twin, it's a new problem.
- The number of reasoning steps (±1).
- The course topic/section being tested.
- The difficulty tier (recall / calculation / derivation / analysis).
Vary:
- Numerical values.
- Variable names.
- System/model specification (if course admits multiple — ideal gas → vdW, ODE → PDE of same order, matrix 3×3 → 4×4).
- Direction of the ask: "show X = Y" ↔ "given X = Y, verify Z" ↔ "compute X".
Quality check before presenting:
- The target pattern is clearly required (not avoidable by a shortcut).
- The answer differs from the original (if it matches, it's not a twin).
- No filename or wording directly references the original problem ID.
- Final answer exists and is not pathological.
Error logging schema
When any drill reveals an error, write to errors/log.md through the
deterministic writer — one call per graded source, entries as stdin:
python3 "${CLAUDE_PLUGIN_ROOT}/scripts/log_tool.py" append --source=<source> <<'YAML'
- problem_id: <HW#-P#, twin-id, or chain-ts>
pattern: <Pk from patterns.md>
error_type: pattern-missed | wrong-variable | wrong-end-form | algebraic | sign | definition
summary: "<one-line description>"
source: <answers/converted/<name>.md | blind/<id> | chain/<ts>>
date: <ISO8601>
YAML
This is the same canonical schema as skills/answer-processing/SKILL.md Step 6 — keep every key, including source: (the statusline's mock-phase detection regexes on it, and it doubles as the --source= idempotence key: re-grading a source replaces its entries instead of piling up duplicates). The tool schema-validates and writes atomically; never hand-edit the log's appended entries. /weakmap (top-level command) consumes this log; this skill just produces entries.
Cross-skill coordination
/grade→ loadsanswer-processingskill (PDF → MD → compare withconverted/solutions/)./ingestor/analyze→ loadscourse-builderskill.- Any PDF read/write → loads
pdfskill. - All drill outputs (twins/, chain/, quizzes/) use plain markdown — no PDF creation inside drill commands. The user uploads answer PDFs; Claude doesn't make PDFs during drilling.
Prose conventions
- Explanations in
INTERFACE_LANG(en or ko) from.course-meta. Defaultenif the field is absent. - Math in LaTeX (
$...$inline,$$...$$display). - Pattern IDs stay Latin (P1, P2, ...) regardless of language.
- Section IDs follow the course's convention from
course-index/summary.md(§, Ch., Ch 3.1, etc.) regardless of language. - File paths, slash command names, YAML keys, and section anchors downstream