exam-quiz — question drilling and grading
Purpose
Present one chapter/phase-scoped bank item at a time, grade against its stored answer, archive wrong/skipped items through state, and return control to exam-cram. Never invent a question or answer.
Activation
Use after teaching when a checkpoint is needed, or when the student asks for drills or a mock exam.
Inputs
- Existing
references/quiz_bank.json, whose items havetype, answer/provenance fields, andchapterorphase; subjective items also havekeywords. - Current chapter/phase and
study_state.jsonmastery/scope. An untagged item cannot enter a chapter checkpoint. - Optional
difficulty(1–5) anddifficulty_reasonfromscore_difficulty.py: a structural lower bound, never semantic truth or a per-student score.
Workflow
-
Select only eligible bank items. Filter both
chapterandphase. A missing bank is an incomplete workspace and returns toexam-ingest; an existing but empty usable pool produces no substitute and caps completion atcovered_unverified.The default source pool is mixed. Persist a student restriction and select it with
scripts/select_questions.py; exclude and count items lackingsource_type. Before any one-turn exception say 「⚠️ 临时覆盖你的 范围偏好」 or⚠️ Temporarily overriding your <scope> scope preference; do not silently change the stored scope.For targeted/checkpoint selection run
python "${CLAUDE_SKILL_DIR}/scripts/select_hard_questions.py" --workspace <ws> --chapter <current> -n <k>.--chapteris the only exact chapter filter;--from-chapter Nmeans every numeric chapter ≥N and is only forshore_up, never a checkpoint. Explicit cross-chapter practice may omit chapter. The selector combines structural difficulty (usingscore_difficulty.pyon the fly when needed) with mistake/confusion/window mastery, mode, and stored scope.fill_gapsserves weak points先易后难, then mastered items先难挑战;from_scratchis globally先易后难.shore_uprequires explicit chapter/from-chapter. Ordering is deterministic, not LLM ranking. -
Show prompt assets first (fail-closed). For
requires_assets=trueormaybe_requires_assets=true, before asking, explaining, hinting, or solving, actually render every question-sidequestion_context/figure/diagram/tableasset, labelled题面图orQuestion-side asset. A path is not an image. Showanswer_context/worked_solutiononly later, labelled答案图orAnswer-side asset. Preserve but never displaystudent_attempt: one occurrence taints the same physical path across the complete quiz, teaching, and content-unit layers, so an official-looking duplicate declaration is also unusable. Missing/unreadable files block the structured workspace; an existing asset that the UI cannot render causes an item-level skip. Prefer a safe, self-containedfullitem.stubandpage_referencealso require the prompt asset or original page first. Always usepython <package-root>/scripts/show_question_assets.py --workspace <ws> --id <qid> --lang <zh|en>so the shared three-layer policy is applied; exit 1 means skip. Do not bypass it by rendering a raw bank path yourself. Seedocs/file-format.md§4. -
Grade by type.
choice: stored option.subjective: requiredkeywords/steps with equivalent wording accepted and coverage reported.fill_blank: stored fill with valid synonyms.true_false: verdict plus one-line reason.code: required edits/output.diagram: run the standard algorithm fromrender_hint, derive the structure, then compare; teacher convention prevails. -
Use the escape hatch. First wrong answer gets the logic gap, stored explanation, and a hint. On the second consecutive wrong answer offer view hint / skip and archive / continue.
-
Persist evidence and feedback. Before any write, if
study_state.jsonis absent and Python works, runpython "${CLAUDE_SKILL_DIR}/scripts/update_progress.py" --workspace <ws> init; only when Python truly cannot run may the generated Markdown be maintained directly. For every handled item recordrecord-phase-evidence --kind checkpoint --ref <qid> --outcome passed|wrong|skipped; an ID alone is not mastery. Wrong/skipped items also usepython "${CLAUDE_SKILL_DIR}/scripts/update_progress.py" --workspace <ws> add-mistake --id <qid> --chapter <ch> --note <reason>. A nonzero state command is a fail-loud write error, not permission to edit the generated view.Before replying, pipe full verdict, gap, explanation, and source line to
python "${CLAUDE_SKILL_DIR}/scripts/notebook.py" --workspace <ws> add-entry --chapter <ch> --type feedback --id <qid> --title <gist>. Same chapter/id replaces in place. Wrong/skipped feedback also passes--mistaketo mirrormistakes/chNN.md; that supplements, never replaces, the state row. Then send a short digest and language-pack link. If notebook writing fails, say so and give the full feedback in chat; file-less clients use chat/text breakpoints. -
End every graded item with one source line:
题目来源:<file/page/source_type>|答案来源:<material/AI>|<label>orQuestion source: <...> | Answer source: <...> | <label>. Missing metadata says 「来源未知」 /Source unknown(orSource page unknown), never an invented filename/page. The label is one complete canonical sentence fromdocs/language-policy.md: 🟢 来自资料; 🟡 AI补充,可能与你老师讲的不完全一致; or ⚠️ AI生成答案,非老师/教材提供, with its English counterpart. When no material answer exists, both the解析/参考答案title and source line carry the full ⚠️ sentence; without a stored answer, do not force a verdict.
Output Contract
- One item at a time; pass/not-pass plus key-point feedback; finish with the source line and refreshed progress panel.
- Persist feedback before the digest; wrong/skipped items need checkpoint evidence, state mistake row, and notebook mistake mirror.
exam-cram/exam-tutor, not this skill, calls evidence-gatedcomplete-phase.- Student prose follows the persisted language with single-language purity: English by default, Simplified Chinese if the opening was Chinese, or explicit bilingual blocks.
Language packs
Load before student-visible output:
中文→../../locales/zh/skills/exam-quiz.mdEnglish→../../locales/en/skills/exam-quiz.md双语→ compose both blockwise, zh then> EN:, underdocs/language-policy.md
Display aliases are normalized to zh, en, or bilingual; unset language follows the merged first ask.
Boundaries
study_state.jsonis the source of truth. Update it only viapython "${CLAUDE_SKILL_DIR}/scripts/update_progress.py" --workspace <ws> ...;study_progress.mdis generated. Fail writes loudly; initialize state whenever Python works.- Never create a replacement item, invent a source/answer, grade a diagram from memory, or serve a visual-dependent prompt whose image was not shown.
- For visual statistics, report both quiz-bank visual items via
scripts/list_image_questions.py(total/requires/maybe/suspects) and material figure pages viascripts/list_figure_pages.py. If the index is absent, build it withscripts/build_visual_index.py; never count by hand.


