---
name: quiz-generator
description: "Create quizzes, edit questions, or change quiz settings (attempts, time limit, dates, access code)."
---

# Quiz Generation Skill (Canvas Knowledge Checks)

> **HPI/ID standard** — this skill applies the HPI/ID practitioner standard automatically (CLAUDE.md §Operating Standard: HPI/ID Practitioner). Ground decisions in `standards/instructional-design.md` — design sections 1–12 and the HPI diagnostic layer in Section 13. Name the framework behind every judgment; every design recommendation carries gap → data → principle → mechanism.

> **Assurance by design.** This skill applies `standards/assessment-assurance-design.md` automatically (CLAUDE.md §Operating Standard: Assurance by Design). Design quiz items AI-aware using the Quizzes and Exams moves; run the by-design self-check before returning.


> **Plugin**: ASU Canvas Course Builder
> **References**: syllabus-generator/SKILL.md (for objective alignment)

## Purpose
> **Edit discipline**: On regeneration, preserve question count, formatting, and feedback structure. Regenerate only the specific questions or fields the user named.
One skill for all quiz operations: generate practice knowledge checks, graded scenario-based quizzes, edit/add/remove questions on existing quizzes, or change quiz settings.

## When to Use — Mode Routing

| User says... | Mode |
|---|---|
| "Create a quiz for Module 3" | **Ask: practice or graded?** then Mode 1 |
| "Knowledge check for Module 5" | **Mode 1A** (Practice) |
| "Graded quiz for Module 2" | **Mode 1B** (Graded) |
| "Practice quizzes for all modules" | **Mode 1A × N** (Batch) |
| "Add questions to the Module 3 quiz" | **Mode 2** (Edit Questions) |
| "Change the answer on question 4" | **Mode 2** (Edit Questions) |
| "Change attempts to 3" / "Set time limit to 30 min" | **Mode 3** (Edit Settings — fast-path) |
| "Set due date on the Module 2 quiz" | **Mode 3** (Edit Settings — fast-path) |
| "Add access code to the midterm" | **Mode 3** (Edit Settings — fast-path) |
| "Move quiz to Exams group" | **Mode 3** (Edit Settings — fast-path) |
| "Show me the questions on the Module 2 quiz" | **View mode** |
| "Regenerate the Module 3 quiz" / "These questions are too easy" | **Mode 4** (Regenerate) |
| "Try different questions" / "Make this harder" / "Different angle" | **Mode 4** (Regenerate) |
| "Course fit quiz" / "Find your starting point" / "Module 0 self-assessment" | **Course Fit Quiz Mode** |

**Fast-path rule:** If the user asks for a narrow settings change (attempts, time, dates, access code), skip the generation questionnaire and go straight to Mode 3.

---

## Pre-Generation Prompt — Question Count

Before generating any quiz, **always ask the user how many questions they want**. Present the defaults but let them override:

> "How many questions for this quiz?"
> - Practice quiz default: **5 questions** (0 pts each)
> - Standard graded quiz default: **5 questions × 3 pts = 15 pts**
> - Or specify a custom count (e.g., "10 questions at 2 pts each")

Adjust the question type mix proportionally. After the user confirms the count, confirm points per question for graded quizzes so the total is explicit: "5 questions × 3 pts = **15 pts total**. Sound right?"

---

## Tier-Aware Defaults

Before generating any quiz, read `course.tier` from `course-config.json`. The tier calibrates Bloom's ranges, question complexity, distractor design, and feedback style. See `standards/assessment-best-practices.md` → "Course Tier System" for the full reference.

**If tier is empty/missing**: Fall back to current defaults (no tier adjustment). Note to the user that tier-aware calibration is available if they set the course level.

| Dimension | Introductory (100-299) | Advanced (300-499) | Graduate (500+) |
|---|---|---|---|
| **Practice Bloom's range** | Remember → Understand → Apply | Understand → Apply → Analyze | Apply → Analyze → Evaluate |
| **Graded Bloom's range** | Apply → Analyze | Analyze → Evaluate | Evaluate → Create |
| **Practice question mix (5 Qs)** | 2 concept MC, 1 T/F, 1 Matching, 1 Fill-in-Blank | 2 scenario MC, 1 Multiple-Answer, 1 Matching, 1 Fill-in-Blank | 2 evidence-appraisal MC, 1 Multiple-Answer, 1 scenario MC, 1 short justification prompt |
| **Graded question mix (5 Qs)** | 2 scenario MC (single-step), 1 Multiple-Answer, 1 Matching, 1 T/F | 3 scenario MC (multi-step), 1 Multiple-Answer, 1 Matching | 3 complex scenario MC (competing valid interpretations), 1 Multiple-Answer, 1 evidence-evaluation item |
| **Scenario complexity** | 1-2 sentences, single decision point, direct cause-effect | 2-3 sentences, layered data, competing explanations, multi-step reasoning | 3-4 sentences, ambiguous data, competing scholarly interpretations, requires synthesis across concepts |
| **Distractor design** | Based on direct misconceptions, single-concept errors | Based on multi-step reasoning errors, partially correct chains of logic | Competing theoretical frameworks, methodologically defensible alternatives, nuanced disciplinary debates |
| **Feedback style** | Explicit content references, encouraging ("Review Section 2.3 on membrane transport") | Deeper-thinking prompts ("Consider how X relates to Y — what does this imply about Z?") | Collegial, scholarly ("This is where the literature diverges — consider how [framework] would reframe the interpretation") |

Apply these defaults to all Mode 1A and 1B generation below. The tier overrides the hard-coded Bloom's ranges — use the tier-specific range instead.

---

## Mode 1A: Practice Quiz (Knowledge Check)

Ungraded formative assessment — lets students self-check understanding. Low stakes, unlimited attempts, encouraging feedback.

### Practice Quiz Parameters (ASU Canvas Standards)

| Setting | Default | Notes |
|---|---|---|
| **quiz_type** | `practice_quiz` | |
| **Questions** | 5 | User can override |
| **Points per question** | 0 (ungraded) | |
| **points_possible** | 0 | |
| **Attempts** | Unlimited (`allowed_attempts: -1`) | |
| **Time limit** | None | |
| **Shuffle answers** | true (except T/F and Ordering) | |
| **Show correct answers** | Immediately after submission | |
| **scoring_policy** | `keep_latest` | |

### Question Design (Practice)
- **Bloom's level**: Use the tier-specific range from the Tier-Aware Defaults table above. Introductory: Remember → Understand → Apply. Advanced: Understand → Apply → Analyze. Graduate: Apply → Analyze → Evaluate. (If no tier set, default to Remember → Understand → Apply.)
- **Tone**: Encouraging — feedback should teach, not penalize. Introductory: point to specific content sections by name. Advanced: prompt deeper thinking connections. Graduate: collegial and scholarly — reference conceptual debates, not module sections.
- **Feedback** (all three levels required on every question):
  1. `correct_comments` — shown when the student answers correctly. Reinforce the concept briefly.
  2. `incorrect_comments` — shown when the student answers incorrectly. Address the likely misconception and redirect to the relevant content section.
  3. `answer_comment` (per-answer) — on every individual answer option, explain why that specific choice is right or wrong.

### Recommended Mix (scales with question count)

| Questions | MC (concept) | T/F | Matching | Fill-in-Blank |
|---|---|---|---|---|
| 3 | 1 | 1 | 1 | 0 |
| 5 (default) | 2 | 1 | 1 | 1 |
| 7 | 3 | 1 | 2 | 1 |
| 10 | 4 | 2 | 2 | 2 |

---

## Mode 1B: Graded Quiz (Scenario-Based)

Summative assessment — tests applied reasoning with real-world scenarios. Higher stakes, limited attempts, detailed per-answer feedback.

### Graded Quiz Parameters (ASU Canvas Standards)

| Setting | Default | Notes |
|---|---|---|
| **quiz_type** | `assignment` | |
| **Questions** | 5 | User can override |
| **Points per question** | 3 | User can override |
| **points_possible** | questions × pts_each | Auto-calculated |
| **Attempts** | 2 (`allowed_attempts: 2`) | |
| **Time limit** | None (or ~5 min if instructor prefers) | |
| **Shuffle answers** | true (except T/F and Ordering) | |
| **Show correct answers** | After last attempt | |
| **scoring_policy** | `keep_highest` | |

### Question Design (Graded)
- **Bloom's level**: Use the tier-specific range from the Tier-Aware Defaults table above. Introductory: Apply → Analyze (simpler, single-step scenarios). Advanced: Analyze → Evaluate (multi-step, layered scenarios). Graduate: Evaluate → Create (competing scholarly interpretations, evidence appraisal). (If no tier set, default to Apply → Analyze.)
- **Scenario-based format**: Every MCQ must open with a real-world scenario. Never ask bare definition questions. Introductory scenarios use 1-2 sentences with one clear decision point. Advanced scenarios use 2-3 sentences with layered information requiring integration of multiple data points. Graduate scenarios use 3-4 sentences with ambiguous or contested data requiring synthesis across concepts or frameworks.
- **Feedback** (all three levels required on every question):
  1. `correct_comments` — reinforce the concept and explain why the answer is correct
  2. `incorrect_comments` — address the most common misconception; reference the relevant content section
  3. `answer_comment` (per-answer) — explain why each specific choice is right or wrong; tie to module concepts

### Recommended Mix (scales with question count)

| Questions | MC (scenario) | Multiple Answer | Matching | T/F |
|---|---|---|---|---|
| 5 (default) | 3 | 1 | 1 | 0 |
| 7 | 4 | 1 | 1 | 1 |
| 10 | 5 | 2 | 2 | 1 |
| 15 | 8 | 3 | 2 | 2 |

---

## Available Question Types (Canvas New Quizzes)
Use a MIX of these types per quiz — do not default to all multiple choice:

| Type | Canvas API `question_type` | Best For |
|---|---|---|
| **Multiple Choice** | `multiple_choice_question` | Scenario-based reasoning, cause-effect |
| **Multiple Answer** | `multiple_answers_question` | "Select all that apply" — multiple correct elements |
| **Ordering** | `ordering_question` | Sequence of events (process steps) — NEVER shuffle |
| **Matching** | `matching_question` | Pairing concepts (categories ↔ examples, terms ↔ definitions) |
| **True/False** | `true_false_question` | Testing common misconceptions — NEVER shuffle |
| **Fill in the Blank** | `fill_in_multiple_blanks_question` | Key terms, equation components |
| **Numeric** | `numerical_question` | Calculation-based questions |

## Question Design Standards

### Bloom's Taxonomy Alignment
Target **Apply** and **Analyze** levels primarily (not Remember/Understand):

| Level | Question Pattern | Example Stem |
|---|---|---|
| **Apply** (primary) | Scenario → predict outcome | "Given [scenario], what would you expect to happen to...?" |
| **Analyze** (primary) | Compare mechanisms, identify causes | "Which of the following best explains why...?" |
| **Understand** (secondary) | Explain relationships | "How does increasing [X] affect [Y]?" |
| **Remember** (minimal) | Only for critical vocabulary | "The [key equation/principle] accounts for..." |

### Scenario-Based Question Format
For Multiple Choice questions, use a scenario-based format appropriate to your discipline:

**For Health Sciences (NBME-Style Clinical Vignette):**
1. **Stem**: Brief clinical scenario (2-3 sentences) with relevant patient data
2. **Lead-in**: Clear question asking what to predict, explain, or identify
3. **Answer choices**: One best answer + 3-4 plausible distractors

**For Other Disciplines:**
1. **Stem**: Applied scenario (real-world situation, case study, data interpretation)
2. **Lead-in**: Clear analytical question
3. **Answer choices**: One best answer + 3-4 plausible distractors

### Distractor Design Rules
1. **All distractors must be plausible** — based on common misconceptions or partially correct reasoning
2. **Avoid "none of the above" and "all of the above"**
3. **Keep answer length similar** — don't make the correct answer obviously longer
4. **Use parallel grammatical structure** across all choices
5. **Avoid absolute terms** ("always," "never") unless testing that understanding
6. **Each distractor should test a different misconception**

### Feedback Requirements
Every question MUST include:
- **Correct answer feedback**: Explain WHY it's correct, connecting to the module's core concepts
- **Incorrect answer feedback**: For each wrong answer, explain WHY it's wrong and what concept the student should review
- **Module reference**: Point back to specific content: "Review this concept in the lecture video at [topic]" or "See the [resource name] for more detail"

## How to Generate a Quiz

### Step 1: Identify Key Concepts
From the module's learning objectives and lecture content:
- List the 5-7 most important concepts
- Identify which Bloom's level each concept naturally targets
- Note any quantitative relationships that could be tested
- Identify common misconceptions for distractor design

### Step 2: Select Question Types
For each concept:
- Match the concept to the best question type (not all MC)
- Ensure the mix follows the recommended distribution
- Include at least one process/sequence question if the module has temporal content
- Include at least one quantitative question if the module has equations

### Step 3: Write Questions
For each question:
1. Start with the learning objective it addresses
2. Write the scenario (appropriate to discipline)
3. Write the correct answer
4. Write 3-4 distractors based on specific misconceptions
5. Write detailed feedback for every answer choice
6. Tag the Bloom's level

### Step 3.5: Apply Assurance by Design

Apply the Quizzes and Exams moves from `standards/assessment-assurance-design.md`: default to application items drawn from a randomized or parameterized pool, bound to course-specific content. Note in the output when the design is an unproctored, auto-graded recall quiz; it is a weak assurance anchor. Offer a verify-the-AI variant (students correct an AI-generated answer) paired with TILT model examples. Run the by-design self-check before returning the quiz.

### Step 4: Stage and Push

Stage the quiz JSON before pushing to Canvas.

**Step 4a: Create the quiz shell on Canvas first** (if this is a new quiz):
```
POST /api/v1/courses/:course_id/quizzes
Body: {
  "quiz": {
    "title": "Module N: Knowledge Check",
    "quiz_type": "practice_quiz",  // or "assignment" for graded
    "points_possible": 15,
    "allowed_attempts": -1,        // -1 = unlimited; 2 for graded
    "shuffle_answers": true,
    "show_correct_answers": true,
    "scoring_policy": "keep_latest",  // or "keep_highest" for graded
    "published": false
  }
}
```

Note the returned `quiz_id`.

**Step 4b: Stage the quiz content as JSON:**
```bash
${ASUCB_PLUGIN_ROOT:-${CODEX_PLUGIN_ROOT:-${CLAUDE_PLUGIN_ROOT}}}/bin/python3 scripts/staging_manager.py --course-id {COURSE_ID} --stage --type quizzes --id {quiz_id} --html-file <path>
```

Staged to: `courses/{COURSE_ID}/staging/quizzes/{quiz_id}.json`

**Staged quiz JSON format:**
```json
{
  "quiz": {
    "title": "Module 3: Knowledge Check",
    "time_limit": 5
  },
  "questions": [
    {
      "question_name": "Q1 — Scenario Question",
      "question_text": "<p>A 45-year-old patient...</p>",
      "question_type": "multiple_choice_question",
      "points_possible": 3,
      "correct_comments": "Correct! The baroreceptor reflex...",
      "incorrect_comments": "Not quite. Review the compensatory mechanisms...",
      "answers": [
        {"answer_text": "Option A", "answer_weight": 100, "answer_comment": "Correct — ..."},
        {"answer_text": "Option B", "answer_weight": 0, "answer_comment": "Incorrect — ..."}
      ]
    }
  ]
}
```

Both `quiz` (settings) and `questions` (question list) are included. The push script handles both.

**Step 4c: Show the user** all questions, answers, and feedback for review. Wait for explicit approval.

**Step 4d: Push:**
```bash
${ASUCB_PLUGIN_ROOT:-${CODEX_PLUGIN_ROOT:-${CLAUDE_PLUGIN_ROOT}}}/bin/python3 scripts/push_to_canvas.py --type quiz --id {quiz_id} --course-id {COURSE_ID}
```

The push script atomically:
1. Backs up the current quiz (settings + existing questions)
2. Updates quiz settings from `content.quiz`
3. Creates/updates all questions from `content.questions`
4. Syncs `points_possible` on the quiz (Canvas doesn't auto-calculate)
5. Syncs `points_possible` on the linked assignment for graded quizzes
6. Verifies the result (question count, points match)
7. Clears staging ONLY after successful verification

If any question fails to push, the entire operation returns `ok: false` and staging is preserved.

**Key API rules:**
- `answer_weight`: 100 = correct, 0 = incorrect (not boolean)
- Per-answer feedback field: write with `answer_comment` (singular), reads back as `comments` (plural) — always write `answer_comment`
- For T/F and Ordering: NEVER use `shuffle_answers: true`
- Practice quizzes use `quiz_type: "practice_quiz"` — they do NOT appear in the gradebook
- Graded quizzes use `quiz_type: "assignment"` — they create a linked assignment and appear in the gradebook

## Discipline-Specific Notes

### Health Sciences
- Use NBME-style clinical vignettes with realistic patient data
- Include vital signs, lab values, and chief complaints
- Test clinical reasoning, not just factual recall
- Distractors should reflect common diagnostic errors

### STEM / Engineering
- Use real-world engineering or scientific scenarios
- Include data interpretation from graphs, tables, or datasets
- Test problem-solving process, not just final answers
- Include unit analysis and order-of-magnitude reasoning

### Social Sciences / Humanities
- Use case studies, policy scenarios, or historical situations
- Test analytical frameworks and theory application
- Include perspective-taking and evidence evaluation
- Distractors should reflect common analytical errors

## Intra-Module Alignment Check

Before generating a Knowledge Check, verify alignment with the other assessments in the same module:

1. **Reference the syllabus** for this module's objectives and the Assessment-to-Objective Alignment Matrix
2. **Review the module's Artifact and Discussion**: Which objectives do they assess? The Knowledge Check should preview skills those summative assessments require
3. **Verify Bloom's level**: Knowledge Check questions should primarily target **Apply** and **Analyze** — formative preparation for the higher-order thinking in the Artifact (Analyze/Evaluate) and Discussion (Evaluate/Create)
4. **Ensure objective coverage breadth**: The KC should touch 3-4 different module objectives across its questions, prioritizing objectives that are also assessed in the Artifact
5. **Document alignment** in the output: list covered objectives by ID and note how the KC previews Artifact skills

---

## Mode 2: Edit Existing Quiz (Add/Remove/Change Questions)

Triggered when the user wants to modify questions on an existing quiz.

### Step 1 — Identify the Quiz

Ask: "Which quiz would you like to edit?"

Resolve via search:
```
GET /api/v1/courses/:course_id/quizzes?search_term=<query>&per_page=20
```

### Step 2 — Show Current Questions

```
GET /api/v1/courses/:course_id/quizzes/:quiz_id/questions
```

Display each question with: number, type (MC/TF/SA/MA/MT/FB/NM), points, question text, and correct answers marked.

### Step 3 — Get Edit Instructions

Common operations:
- **Add questions** — type, text, answers, points, feedback
- **Edit question text** — update prompt
- **Change answers** — modify text or correct answer
- **Adjust points** — change point value
- **Add feedback** — add correct/incorrect comments
- **Delete questions** — remove from quiz
- **Change question type** — requires delete + recreate

### Step 4 — Apply Changes

Use POST (create), PUT (update), or DELETE on:
`/api/v1/courses/:course_id/quizzes/:quiz_id/questions[/:id]`

After any question change, **always sync `points_possible`** (see Step 4 in Mode 1 — Canvas does not auto-calculate).

### Step 5 — Verify

Re-fetch and display the updated quiz. Show the Canvas link:
`https://{CANVAS_DOMAIN}/courses/{COURSE_ID}/quizzes/{id}`

---

## View Mode: Inspect Existing Quiz

When the user asks to see a quiz's questions without editing.

```
GET /api/v1/courses/:course_id/quizzes/:quiz_id/questions
```

Display:
```
Quiz: Knowledge Check 3 (15 pts, 5 questions)
  Settings: 2 attempts, no time limit, shuffle answers, show correct answers after last attempt

  Q1 (MC, 3 pts): "Which membrane protein is responsible for..."
    a) Channel protein  b) Carrier protein ✓  c) Receptor  d) Enzyme
    Feedback (correct): ...
    Feedback (incorrect): ...
  Q2 (T/F, 3 pts): "Active transport requires ATP."
    True ✓ / False
  ...
```

---

## Mode 3: Edit Quiz Settings (Fast-Path)

For changing quiz-level settings on an existing quiz. **Skip the generation questionnaire** — go straight to the edit.

### Step 1: Identify the quiz
```
GET /api/v1/courses/:course_id/quizzes?search_term=<query>&per_page=20
```

### Step 2: Display current settings

Show in a table: title, quiz type, points, allowed attempts, time limit, shuffle answers, show correct answers, scoring policy, one question at a time, can't go back, access code, assignment group, due date, available from, available until, published.

### Step 3: Apply edits

Direct PUT — no staging required for settings:
```
PUT /api/v1/courses/:course_id/quizzes/:quiz_id
Body: { "quiz": { <only the fields being changed> } }
```

Confirm with the user before pushing.

**Supported settings:**

| Field | API Parameter | Notes |
|---|---|---|
| Allowed attempts | `quiz[allowed_attempts]` | -1 = unlimited |
| Time limit | `quiz[time_limit]` | Integer minutes, null = unlimited |
| Due date | `quiz[due_at]` | ISO 8601, `-07:00` for Arizona |
| Available from | `quiz[unlock_at]` | |
| Available until | `quiz[lock_at]` | |
| Assignment group | `quiz[assignment_group_id]` | Lookup: `GET /courses/:id/assignment_groups` |
| One question at a time | `quiz[one_question_at_a_time]` | Boolean |
| Can't go back | `quiz[cant_go_back]` | **Requires `one_question_at_a_time: true`** |
| Access code | `quiz[access_code]` | String, or `""` to remove |
| Shuffle answers | `quiz[shuffle_answers]` | Boolean |
| Show correct answers | `quiz[show_correct_answers]` | Boolean |
| Scoring policy | `quiz[scoring_policy]` | keep_highest / keep_latest |
| Published | `quiz[published]` | Boolean |

**Validation:** If setting `cant_go_back: true`, you MUST also include `one_question_at_a_time: true` in the same PUT request.

For graded quizzes: if you changed `points_possible`, also update the linked assignment (see Mode 1, Step 4).

---

## Post-Push Verification (Required)

After creating or editing a quiz, always run verification:

```bash
${ASUCB_PLUGIN_ROOT:-${CODEX_PLUGIN_ROOT:-${CLAUDE_PLUGIN_ROOT}}}/bin/python3 scripts/post_write_verify.py --type quiz --id {quiz_id} --course-id {COURSE_ID}
```

This fetches the quiz back from Canvas and confirms: title, question count, points_possible, attempts, time limit, published status, and Canvas link.

Display the verification result to the user, including any warnings. Always include the direct Canvas link: `https://{CANVAS_DOMAIN}/courses/{COURSE_ID}/quizzes/{id}`

---

## Mode 4: Regenerate Quiz

Triggered when the user wants to replace all questions on an existing quiz with a different difficulty or fresh content.

**How this differs from Mode 2 (Edit Questions) and Mode 3 (Edit Settings):**
- Mode 2 modifies individual questions in place (add/remove/change one question via POST/PUT/DELETE on `/quiz/:id/questions`)
- Mode 3 changes quiz metadata only (attempts, time limit, dates via PUT on quiz)
- **Mode 4 replaces the entire question set** — generates a full new set of questions targeting the same objectives, stages them as a replacement draft, and pushes only after user approval

### Step 1: Identify the target quiz

Same as Mode 2 Step 1:
```
GET /api/v1/courses/:course_id/quizzes?search_term=<query>&per_page=20
```

Fetch current questions:
```
GET /api/v1/courses/:course_id/quizzes/:quiz_id/questions
```

### Step 2: Determine regeneration type

Classify user intent:

| User says... | Type |
|---|---|
| "too easy" / "make it harder" / "need more rigor" | **Bump Up** |
| "too hard" / "simpler" / "students will struggle" | **Bump Down** |
| "different angle" / "try again" / "fresh questions" | **Different Angle** |

### Step 3: Calculate new parameters

Reference the Regeneration Bloom's Range table in `standards/assessment-best-practices.md`:

- **Bump Up**: Shift Bloom's range up one step within tier ceiling. Increase scenario complexity. Make distractors more subtle (partially correct reasoning chains). Reduce scaffolding in feedback.
- **Bump Down**: Shift Bloom's range down one step within tier floor. Simplify scenarios. Make distractors more distinct (direct misconceptions). Add more explicit content references in feedback.
- **Different Angle**: Keep the same Bloom's range, question count, and point value. Generate entirely new scenarios, stems, and answer choices targeting the same objectives. Do not reuse any question stems or scenarios from the original.
- **At ceiling/floor**: Tell the user: "This is already at the [highest/lowest] difficulty within the [tier] range. To go further, you'd need to change the course tier."

Preserve question count and `points_possible` from the original quiz.

### Step 4: Generate replacement question set

Write all new questions following the adjusted parameters. Follow the same question design standards, feedback requirements, and question type mix rules as Mode 1.

### Step 5: Stage for comparison

Write the new question set to `courses/{COURSE_ID}/staging/quizzes/{quiz_id}.json`.

Present the user with a **side-by-side comparison**:

```
CURRENT (5 questions, Bloom's Apply-Analyze):
  Q1: [stem summary] — MC (Apply)
  Q2: [stem summary] — T/F (Apply)
  Q3: [stem summary] — Matching (Understand)
  Q4: [stem summary] — MC (Analyze)
  Q5: [stem summary] — Fill-in-Blank (Apply)

REGENERATED (5 questions, Bloom's Analyze-Evaluate):
  Q1: [stem summary] — MC (Analyze)
  Q2: [stem summary] — Multiple Answer (Analyze)
  Q3: [stem summary] — Matching (Apply)
  Q4: [stem summary] — MC (Evaluate)
  Q5: [stem summary] — MC (Analyze)
```

### Step 6: User approval gate

User must explicitly approve before any Canvas write. Options:
- **"Looks good"** → proceed to push
- **"Keep the original"** → clear staging, no changes
- **"Change Q3 but keep the rest"** → switch to Mode 2 (Edit Questions) for targeted fixes on the regenerated set

### Step 7: Push as atomic replacement

```bash
${ASUCB_PLUGIN_ROOT:-${CODEX_PLUGIN_ROOT:-${CLAUDE_PLUGIN_ROOT}}}/bin/python3 scripts/push_to_canvas.py --type quiz --id {quiz_id} --course-id {COURSE_ID}
```

The push script automatically backs up all current questions before overwriting. It DELETEs all existing questions and POSTs the new set. Then syncs `points_possible`.

### Step 8: Verify

```bash
${ASUCB_PLUGIN_ROOT:-${CODEX_PLUGIN_ROOT:-${CLAUDE_PLUGIN_ROOT}}}/bin/python3 scripts/post_write_verify.py --type quiz --id {quiz_id} --course-id {COURSE_ID}
```

Run the intra-module alignment check on the regenerated questions to ensure they still align with module objectives and complement the Artifact and Discussion.

---

## Mode 5: From-Bank

Triggered when the user wants to create a quiz that pulls questions from an existing Canvas Question Bank.

### Inputs

- `bank_id` numeric value, or a Canvas Question Bank URL containing the bank ID. Parse the ID out of the URL before calling Canvas.
- `pick_count` — how many questions to pull per attempt.
- `points_per_question` — point value for each pulled question.
- Module association for placement — the module where the resulting quiz should appear.

### Workflow

1. Verify the bank via `get_question_bank(config, bank_id)`. If Canvas returns 404, abort with: "Bank ID {X} not found in course {Y} — confirm the bank lives in this course, not a different one."
2. Invoke `scripts/ensure_staging_server.py` to start the local preview server, per the v7.5.3 staging gate.
3. Announce the action per `CLAUDE.md` §Write Safety Guard: state the course name and the specific action being taken. This is object creation — steps 2-4 of the 6-step gate apply even though there is no stageable HTML body.
4. Show the preview URL from the staging server, normally `http://127.0.0.1:8111/...` or the equivalent URL returned by `ensure_staging_server.py`.
5. Wait for an explicit Canvas-write verb before executing any Canvas API write. Accept only `push`, `approved`, `deploy`, `ship it`, `looks good push`, or an equivalent affirmative with clear deployment intent.
6. On approval: call `create_quiz()` to create the quiz shell, then `create_quiz_group()` to link the bank.
7. Surface the resulting Canvas quiz URL: `https://{CANVAS_DOMAIN}/courses/{COURSE_ID}/quizzes/{quiz_id}`.

---

## Course Fit Quiz Mode

Use this mode when the user asks for a Module 0 course fit quiz, diagnostic self-assessment, or "Find Your Starting Point" activity.

### Suitability Gate

Confirm this is appropriate before building. It is best for open-enrollment, mixed-background, foundational, or review courses where students may already know some modules. If all students should complete every module in order, exit without building.

### Diagnostic Question Design

Use `course-config.json` for module titles, topics, objectives, course level, and audience. For each module, create 2-3 multiple-choice diagnostic questions that test prerequisite knowledge a student would already have if they could skim or review the module.

Questions must:
- Test concepts through applied scenarios where possible.
- Avoid recall-only prompts.
- Use four options with clear correct answers.
- Make wrong answers reflect common misconceptions.
- Take about 30 seconds each.

Store questions with module number/title, prompt, options, correct index, and concept tested.

### Interactive HTML

Build a self-contained accessible HTML activity using `interactive-content` patterns:
- Welcome screen explaining that the quiz is a non-graded 5-minute self-assessment.
- Question flow grouped by module or shuffled, with progress indicator.
- Results screen with per-module recommendations.
- 100% = strong foundation/review optional; 50-99% = review recommended; 0-49% = focus area.
- Module names link to their Canvas overview pages.
- Color is not the only indicator; include text/icons, keyboard access, ARIA labels, focus management, and 44x44 px touch targets.

### Canvas Deployment

1. Upload the HTML file to Canvas Files in the Module 0 folder.
2. Create a Canvas page titled "Find Your Starting Point" or "Course Fit Guide".
3. Embed the file using an iframe with `sandbox="allow-same-origin allow-scripts allow-forms"`, a descriptive title, and lazy loading.
4. Add the page to Module 0.
5. Report question count, Canvas page URL, file ID, and saved diagnostic-question artifact.

## Output
The skill produces:
1. Complete quiz with all answer choices and detailed feedback
2. Question type and Bloom's level tags for each question
3. Canvas setup instructions (points, attempts, time limit)
4. Alignment map showing which objectives each question addresses
5. Formative→summative alignment note explaining how the KC previews the Artifact
