From grading-toolkit
Use when transcriptions exist and you are ready to grade all students on a specific question. Students with existing non-null grades for that question are skipped. Usage: /grade-question Q1a
How this skill is triggered — by the user, by Claude, or both
Slash command
/grading-toolkit:grade-questionThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Grade all student submissions for a specified question. Takes a question ID as argument.
Grade all student submissions for a specified question. Takes a question ID as argument.
Read every one of these before grading a single student:
workflow.yml — questions list, comment_strategy, run_prefix, pathsrubric.md — all category definitions verbatimcomments.md — the entire section for this question (search for ## <QuestionID>)decisions.md — all prior rulings for this questioninstructor_profile.md — strictness calibrations, priority misconceptions, comment styleanswer_key.md — the correct answer for this questionConfirm the question ID exists in workflow.yml. If it doesn't, stop and report the available question IDs.
Run:
<run_prefix> scripts/check_progress.py
Show how many students have null grades for this question.
Show: "Current comment strategy: [value from workflow.yml]. Override for this session? (strict / collaborative / relaxed / keep)"
Record the active strategy for this session.
For each student whose grade for this question is null in workspace/grades/<SID>_grades.json:
Open workspace/transcriptions/<SID>.md. Find the section matching ## <QuestionID>.
Compare the response against the answer key and rubric. Apply instructor_profile.md calibrations:
Search comments.md for a comment under ## <QuestionID> / <category> that matches this error. Reuse verbatim if found.
If no matching comment exists:
"<QuestionID>: comment needed — [1-sentence error description]"comments.md under the appropriate headinginstructor_profile.md, save it to comments.mdComment rules (always apply regardless of strategy):
Read the existing workspace/grades/<SID>_grades.json, update only this question's fields, and write back:
{
"grades": { "<QuestionID>": "<rubric category string>" },
"comments": { "<QuestionID>": "<comment string or empty string>" },
"explanations": { "<QuestionID>": "<1–2 sentence rationale citing rubric and answer key>" }
}
Merge carefully — preserve all other questions' existing data.
Write after every single student. Never batch.
Every 10 students, run:
<run_prefix> scripts/check_progress.py
When genuinely uncertain (the response sits between two categories, or raises a new edge case not covered by the rubric or prior decisions), stop and ask:
"Student [name]: '[brief excerpt]' — I'm uncertain between [Category A] and [Category B] because [specific reason]. Which applies here?"
After receiving the ruling, append to decisions.md:
## <QuestionID> — <YYYY-MM-DD>
**Case:** [description of the ambiguous response]
**Ruling:** [Category] — [brief justification]
**Applied to:** [student name]
After all students for this question are graded:
decisions.md during this session (today's date, this question)For each inconsistency:
flags:
"flags": ["<QuestionID>: grade updated from '<old>' to '<new>' — ruling: <brief description>"]
Run check_progress.py one final time. Confirm zero nulls remain for this question.
Scan every student graded this session. For each whose comment for this question is an empty string and whose grade is not Correct or Blank:
comments.md under ## <QuestionID> / ### <category>. Update the grade stub with the new comment and remove the flag entry.Creates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.
npx claudepluginhub justin-graham/grading-toolkit --plugin grading-toolkit