---
name: assignment-generator
description: "Create or edit assignments — full generation or quick metadata edits (points, dates, groups, attempts)."
---

# Assignment Skill (Create or Edit)

> **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 assignments AI-aware using the Papers and Written Assignments and Projects moves; run the by-design self-check before returning.


> **Plugin**: ASU Canvas Course Builder
> **References**: syllabus-generator/SKILL.md (for objective alignment), rubric-creator/SKILL.md (for rubric generation)
> **Scripts**: `scripts/push_to_canvas.py`, `scripts/post_write_verify.py`, `scripts/staging_manager.py`

## Purpose
One skill for all assignment operations: generate "Create an Artifact" assignments, edit metadata (points, dates, groups), or revise assignment descriptions via staging.

## Staging-Server Preview (Write Safety Guard)

Every Canvas write in this skill follows `CLAUDE.md` §Write Safety Guard. Do not skip the preview step:

1. **Stage first** — write the content to `courses/{id}/staging/assignments/{key}` via `scripts/staging_manager.py`. Never call a Canvas body write without a staged artifact.
2. **Start the preview server** — run `scripts/ensure_staging_server.py` (idempotent; returns the base URL whether or not the server was already up).
3. **Show the preview URL** — print `http://127.0.0.1:8111/courses/{id}/preview/assignments/{key}` on its own line. Always `127.0.0.1`, never `localhost`.
4. **Require an explicit push verb** — accept only `push`, `approved`, `deploy`, `ship it`, or an equivalent affirmative with deployment intent. Do NOT accept `ok`/`yes`/`sure`/`confirm` alone — re-ask if the reply is ambiguous.
5. **Push via the script** — `scripts/push_to_canvas.py` only (backup → push → verify → clear-staging). Never call `canvas_api.update_*` directly.

## When to Use — Mode Routing

| User says... | Mode |
|---|---|
| "Create an assignment for Module 4" / "Generate artifact" | **Mode 1: Create** (full generation flow) |
| "Change points on the M3 assignment to 50" / "Set due date" | **Mode 2: Edit Metadata** (fast-path, no generation) |
| "Fix the instructions on the Module 5 assignment" | **Mode 2: Edit Description** (staging workflow) |
| "Move assignment to Homework group" / "Change to 3 attempts" | **Mode 2: Edit Metadata** (fast-path) |
| "Regenerate the Module 4 assignment" / "This is too hard" | **Mode 3: Regenerate** |
| "Try a different approach" / "Make this easier" / "Different angle" | **Mode 3: Regenerate** |

**Fast-path rule:** If the user asks for a narrow metadata change, skip the generation questionnaire entirely and go straight to Mode 2.

---

## Tier-Aware Defaults

Before generating any assignment, read `course.tier` from `course-config.json`. The tier calibrates Bloom's defaults, word counts, and scaffolding level. 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+) |
|---|---|---|---|
| **Default Bloom's level** | L3 (Apply); late modules may reach L4 | L4 (Analyze); late modules reach L5 | L5 (Evaluate) / L6 (Create); scholarly or professional product orientation |
| **Word count** | 300-500 words (or 2-4 min video) | 500-800 words (or 4-7 min video) | 800-1,200 words (or 8-12 min presentation); research proposals and policy briefs may exceed this |
| **Task description style** | Step-by-step guidance ("First, identify... Then, explain... Finally, connect...") | Goal-and-constraints framing — set the objective and let students determine approach | Goal + deliverable format only. No steps, no checklist. Student determines scope, evidence, and structure. |
| **Deliverable checklist** | Granular checklist items, break each requirement into sub-points, include formatting guidance | Higher-level checklist items, fewer but broader requirements | No checklist. State the deliverable and evaluation criteria only. |
| **Success criteria** | Concrete examples of what "good" looks like, explicit rubric preview | Focus on analytical expectations, less hand-holding | Scholarly or professional standards — contribution, rigor, synthesis. Rubric criteria use disciplinary language. |
| **Deliverable orientation** | Concept application artifact (summary, explanation, comparison) | Analysis artifact (case analysis, annotated argument, comparative evaluation) | Scholarly or professional product (literature synthesis, research proposal, policy brief, professional recommendation memo) |

Tier sets the baseline; module position adjusts within it. An early module in an Advanced course still has more scaffolding than a late module, but both have less than their Introductory counterparts. Graduate courses use no scaffolding at any module position.

---

## Mode 1: Create Assignment

### Pre-Generation Questionnaire

Before generating any assignment, **walk through these questions with the user** using `AskUserQuestion`. Ask in order — each answer shapes the next.

#### Question 1: Assignment Format

> "What type of assignment is this?"

| Label | Description |
|---|---|
| **Video assignment** | Students record and submit a video (presentation, demonstration, reflection) |
| **Written assignment** | Students write and submit a document (analysis, report, problem set) |
| **Discussion** | Students post and respond to peers → *Route to `discussion-generator` skill instead* |

If the user picks **Discussion**, hand off to the discussion-generator skill seamlessly.

#### Question 1.5: AI Design Mode

> "How should this assignment handle AI? Both keep the work authentic — they differ on whether students use AI or work around it."

| Label | What it means |
|---|---|
| **AI-resistant** *(default)* | The task is built so AI cannot do it for the student. The prompt binds to specific course material, a personal or local context the AI cannot source, and staged process evidence (proposal, draft, revision). AI use is discouraged or off-limits; the design makes substitution visible. |
| **AI-forward** | Students are expected to use AI, then graded on their judgment about it — verifying, correcting, or critiquing AI output and documenting what they accepted, rejected, and why. Ships with the rubric and 2-3 annotated model examples up front (TILT), so it does not penalize students who do not already know the target. |
| **Both (paired variants)** | Generate one AI-resistant and one AI-forward version of the same assignment, each labeled, for comparison or faculty review. |

**Infer, don't ask, when the direction is already stated.** If the user's request already contains "AI-forward", "AI-resistant" (or a clear equivalent like "let them use AI and grade the judgment" / "make it AI-proof"), skip this question and use that direction. Only ask when the request is silent on AI handling.

The named move for the chosen direction comes from `standards/assessment-assurance-design.md` (each of the five assessment categories defines an AI-resistant move, an AI-forward move, and a secured anchor). Apply it in Step 2.5.

#### Question 2: Bloom's Complexity Level

> "What cognitive complexity level should this assignment target?"

| Label | Description |
|---|---|
| **Apply (Level 3)** | Use knowledge in new situations — solve problems, demonstrate, implement |
| **Analyze (Level 4)** | Break down information, find patterns, explain relationships and causes |
| **Evaluate (Level 5)** | Judge, assess, critique, defend a position with evidence |
| **Create (Level 6)** | Design, build, propose something new by synthesizing knowledge |

**Default recommendation**: Use the tier-specific default from the Tier-Aware Defaults table above, adjusted by module position. Introductory: default L3 (Apply), late modules may suggest L4. Advanced: default L4 (Analyze), late modules may suggest L5. Graduate: default L5 (Evaluate), late modules suggest L6 (Create). Always let the user override.

#### Question 3: Assignment Subtype

**For Video assignments:**

| Label | Description |
|---|---|
| **Presentation** | Student presents analysis or findings (with slides or visuals) |
| **Demonstration** | Student demonstrates a skill, process, or technique |
| **Reflection** | Student reflects on learning, connects to experience |
| **Explainer** | Student explains a concept as if teaching it to someone else |

**For Written assignments:**

| Label | Description |
|---|---|
| **Case Analysis** | Analyze a real-world scenario using module concepts |
| **Concept Map** | Visualize relationships between interconnected concepts |
| **Calculation Problem Set** | Apply formulas/quantitative reasoning to real problems |
| **Comparison/Contrast** | Structured analysis of parallel systems or approaches |

#### Question 4: Points, Word Count, Rubric

> **Points** — "30 points is our default. Does this fit your grading scheme?"
>
> **Word count / Video length** — Use tier defaults: Introductory = "300-500 words (or 2-4 min video)", Advanced = "500-800 words (or 4-7 min video)", Graduate = "800-1,200 words (or 8-12 min presentation)". Present the tier default and let the user adjust.
>
> **Rubric structure** — "3 criteria × 10 pts each (default), or different?"
>
> **Submission type** — "Text entry, file upload, media recording, or combination?" (default: file upload for video, text + upload for written)

#### Question 5: Page Design

> "Should the assignment description use the ASU page design system (styled HTML), or plain HTML?"

| Label | Description |
|---|---|
| **Plain HTML (default)** | Clean, unstyled HTML — standard for assignment descriptions in the Canvas assignment body |
| **Styled (Page Design System)** | Uses the ASU page design system — for when the assignment has its own Canvas wiki page |

If "assignments for all modules," ask these once and apply consistently.

---

### Required Instruction Sections

Every generated assignment MUST include all of the following sections:

1. **Context / Hook** (1-2 paragraphs)
   - Set the scene: why does this topic matter in the real world or in their discipline?
   - Connect to current events, professional scenarios, or personal relevance

2. **Task Description** (1-2 paragraphs)
   - Clearly state what the student must do, using verbs matched to the Bloom's level
   - Be explicit about scope: what to include and what NOT to include
   - Reference specific module concepts, readings, or videos they should draw from

3. **Deliverable Checklist** ("Your Submission Should Include:")
   - Bulleted list of every required component
   - Word counts, video lengths, format requirements
   - Required references, diagrams, or supporting evidence

4. **Peer Interaction Expectations** (if applicable — especially for video assignments)
   - How many peer responses are required
   - What constitutes a substantive response
   - Specific prompts for peer feedback

5. **Success Criteria** ("How You'll Be Evaluated:")
   - Brief summary of rubric criteria in plain language
   - What distinguishes excellent from adequate work
   - Common pitfalls to avoid

6. **Closing Motivation** (1-2 sentences)
   - Tie back to why this matters — professional growth, skill building, or real-world application

---

### Assignment Parameters (ASU Canvas Standards)

| Setting | Default | Notes |
|---|---|---|
| **Points** | 30 | User confirms or overrides |
| **Time** | ~20 minutes | Scales with points |
| **Submission type** | Online (text + upload) | User can narrow |
| **Rubric** | 3 criteria × 10 pts | User confirms criteria count |
| **Due date** | End of module period | Instructor sets specific date |
| **Word count** | 400-600 words | User confirms or overrides |

### Assignment Types

#### Type 1: Case Analysis
**Best for**: Modules with strong professional/clinical connections
- Present a real-world or clinical scenario with relevant data
- Students analyze the underlying mechanisms using module concepts
- Must trace cause-effect chains from foundational principles to observable outcomes
- Often includes "what would happen if..." prediction questions

#### Type 2: Concept Map / Mechanism Diagram
**Best for**: Modules with complex interconnected concepts
- Students create a visual representation of concept relationships
- Must show directional cause-effect arrows with labeled explanations
- Connects module concepts to prior knowledge

#### Type 3: Calculation Problem Set
**Best for**: Quantitatively-focused modules
- Students solve 3-4 problems using module equations/relationships
- Each problem includes a real-world or professional context
- Must show work and explain reasoning

#### Type 4: Comparison/Contrast Analysis
**Best for**: Modules with parallel systems or approaches to compare
- Students create a structured comparison of related concepts
- Must go beyond listing differences — explain WHY they differ
- Connects structural differences to functional/practical outcomes

### Assignment Design Principles

1. **Backward Design Alignment**: Directly assess 2-3 module objectives at Apply/Analyze/Evaluate Bloom's level
2. **Scaffolded Difficulty**: Tier sets the baseline scaffolding level (see Tier-Aware Defaults); module position adjusts within it. Early modules get more structure; later modules get more independence — but the tier determines the overall range
3. **Authentic Professional Context**: Realistic scenarios, not abstract textbook problems
4. **Clear Deliverables**: Word counts, required components, submission format stated explicitly

### Step-by-Step: Generate → Stage → Push

#### Step 1: Select type and identify objectives
Based on module content and pre-generation questionnaire answers.

#### Step 2: Write the assignment
Follow the template for the selected type. Include all 6 required instruction sections.

#### Step 2.5: Apply Assurance by Design

Apply the move for the **AI Design Mode** chosen in Question 1.5, using the matching category in `standards/assessment-assurance-design.md` (Papers and Written Assignments, or Projects):

- **AI-resistant** — build in the AI-resistant move: bind the prompt to specific course material or a personal/local context the AI cannot source, stage process evidence (proposal, annotated draft, revision with version history), and grade the process, not just the product. State that AI is not permitted for the graded thinking.
- **AI-forward** — build in the AI-forward move: students use AI, then document which suggestions they accepted or rejected and justify each, graded alongside the work. Ship the rubric and 2-3 annotated model examples up front (TILT). State task-level AI use explicitly.
- **Both** — generate the two variants described in Question 1.5, each labeled, sharing the same objectives and secured anchor.

Either way, secure at least one anchor for the grade (documented process, or graded judgment about AI), and run the by-design self-check before returning the assignment.

#### Step 3: Generate rubric
Use the rubric-creator skill. Pass `assignment_id` after creation — rubric-creator owns the Canvas rubric API call.

#### Step 4: Stage the assignment description

**Stage the assignment description HTML before pushing to Canvas:**

```bash
${ASUCB_PLUGIN_ROOT:-${CODEX_PLUGIN_ROOT:-${CLAUDE_PLUGIN_ROOT}}}/bin/python3 scripts/staging_manager.py --course-id {COURSE_ID} --stage --type assignments --id {assignment_id} --html-file <path>
```

Staged to: `courses/{COURSE_ID}/staging/assignments/{assignment_id}.html`

Show the user a preview of the staged content. Wait for explicit approval.

#### Step 5: Push to Canvas

After user approval:

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

This atomically: backs up current → pushes staged content → verifies → clears staging.

**Canvas API for creating the assignment (before staging the description):**
```
POST /api/v1/courses/:course_id/assignments
Body: {
  "assignment": {
    "name": "Module N: Create an Artifact — [Title]",
    "description": "<p>staged HTML content</p>",
    "points_possible": 30,
    "submission_types": ["online_text_entry", "online_upload"],
    "published": false,
    "assignment_group_id": <id>,
    "grading_type": "points",
    "allowed_attempts": -1,
    "due_at": "2026-03-15T23:59:00-07:00",
    "unlock_at": "2026-03-01T00:00:00-07:00",
    "lock_at": "2026-03-17T23:59:00-07:00"
  }
}
```

Only include optional fields when the user provides them or `course-config.json` specifies defaults.

#### Step 6: Verify

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

Display: name, points, submission types, rubric attached (yes/no), Canvas link.

## Intra-Module Alignment Check

Before generating an Artifact assignment, verify alignment:

1. **Reference the syllabus** for this module's objectives and alignment matrix
2. **Review the module's Knowledge Check**: The Artifact should build on KC-assessed skills at a higher Bloom's level
3. **Review the module's Discussion**: The Artifact and Discussion should assess different facets — avoid testing the same skill the same way
4. **Verify Bloom's level**: Artifact = Analyze/Evaluate; KC = Apply/Analyze; Discussion = Evaluate/Create
5. **Check integration requirement**: For M2+, verify cross-module connection references a specific prior module
6. **Document alignment** in the output

---

## Mode 2: Edit Existing Assignment

For editing an existing assignment's metadata or description. **Skip the full generation questionnaire.**

### Step 1: Identify the assignment

```
GET /api/v1/courses/:course_id/assignments?search_term=<query>&per_page=20
```

### Step 2: Display current settings

| Field | Current Value |
|---|---|
| Name | Module 3: Create an Artifact — Membrane Analysis |
| Points | 30 |
| Grading type | points |
| Submission types | online_text_entry, online_upload |
| Allowed attempts | -1 (unlimited) |
| Assignment group | Assignments (id: 12345) |
| Due date | 2026-03-15T23:59:00-07:00 |
| Available from | (not set) |
| Available until | (not set) |
| Published | false |
| Rubric | Yes (3 criteria) |
| Description | 2,400 chars |

### Step 3: Apply edits

**For metadata (points, dates, attempts, groups, grading type, submission types):**

Direct PUT — no staging required:
```
PUT /api/v1/courses/:course_id/assignments/:assignment_id
Body: { "assignment": { <only the fields being changed> } }
```

Confirm with the user before pushing.

**Supported metadata fields:**

| Field | API Parameter | Notes |
|---|---|---|
| Points | `assignment[points_possible]` | |
| Due date | `assignment[due_at]` | ISO 8601, `-07:00` for Arizona |
| Available from | `assignment[unlock_at]` | |
| Available until | `assignment[lock_at]` | |
| Assignment group | `assignment[assignment_group_id]` | Lookup: `GET /courses/:id/assignment_groups` |
| Allowed attempts | `assignment[allowed_attempts]` | -1 = unlimited |
| Grading type | `assignment[grading_type]` | points / percent / letter_grade / pass_fail / not_graded |
| Submission types | `assignment[submission_types][]` | Array: online_text_entry, online_upload, etc. |
| Published | `assignment[published]` | |
| Omit from grade | `assignment[omit_from_final_grade]` | |

**For description (HTML body) — use staging workflow:**

1. Fetch current description: `GET /api/v1/courses/:id/assignments/:id` → `description` field
2. Apply the user's requested edits to the HTML
3. Stage: `${ASUCB_PLUGIN_ROOT:-${CODEX_PLUGIN_ROOT:-${CLAUDE_PLUGIN_ROOT}}}/bin/python3 scripts/staging_manager.py --course-id {COURSE_ID} --stage --type assignments --id {assignment_id} --html-file <path>`
4. Preview the staged content for user approval
5. Push: `${ASUCB_PLUGIN_ROOT:-${CODEX_PLUGIN_ROOT:-${CLAUDE_PLUGIN_ROOT}}}/bin/python3 scripts/push_to_canvas.py --type assignment --id {assignment_id} --course-id {COURSE_ID}`

### Step 4: Verify

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

Provide the Canvas link: `https://{CANVAS_DOMAIN}/courses/{COURSE_ID}/assignments/{id}`

---

## Mode 3: Regenerate Assignment

Triggered when the user wants to replace an assignment's description with a different difficulty or fresh content.

**How this differs from Mode 2 (Edit Metadata / Edit Description):**
- Mode 2 metadata edits (points, dates, groups) are direct PUT — no staging, no content regeneration
- Mode 2 description edits modify the existing HTML — fetch current, apply changes, stage, push
- **Mode 3 replaces the entire assignment description** — generates a new description from scratch with adjusted parameters, stages it alongside the original for comparison, and optionally regenerates the attached rubric

### Step 1: Identify the target assignment

```
GET /api/v1/courses/:course_id/assignments?search_term=<query>&per_page=20
```

Fetch current description: `GET /api/v1/courses/:course_id/assignments/:assignment_id` → `description` field.

### Step 2: Determine regeneration type

| 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" / "different approach" | **Different Angle** |

### Step 3: Calculate new parameters

Reference the Regeneration Bloom's Range table and Tier-Aware Defaults:

- **Bump Up**: Increase Bloom's by one level within tier ceiling. Reduce scaffolding (fewer checklist items, less step-by-step guidance). Increase word count default. Add multi-step or comparative requirements.
- **Bump Down**: Decrease Bloom's by one level within tier floor. Add scaffolding (more specific checklist, guiding questions). Reduce word count. Simplify scenario.
- **Different Angle**: Keep same Bloom's level and word count. Switch subtype (e.g., Case Analysis → Comparison/Contrast) or generate a completely new professional scenario. Same objectives.
- **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 `points_possible` and `submission_types` from the original assignment.

### Step 4: Generate replacement description

Write new 6-section HTML following the adjusted parameters. Follow all Required Instruction Sections and Assignment Design Principles, but calibrate scaffolding and complexity to the new Bloom's level.

### Step 5: Stage for comparison

```bash
${ASUCB_PLUGIN_ROOT:-${CODEX_PLUGIN_ROOT:-${CLAUDE_PLUGIN_ROOT}}}/bin/python3 scripts/staging_manager.py --course-id {COURSE_ID} --stage --type assignments --id {assignment_id} --html-file <path>
```

Present a side-by-side summary:
```
CURRENT: Case Analysis (L3 Apply), ~400 words, 6 checklist items
REGENERATED: Case Analysis (L4 Analyze), ~600 words, 4 checklist items
```

Show the full HTML preview of the regenerated description.

### Step 6: User approval gate

- **"Looks good"** → proceed to push
- **"Keep the original"** → clear staging, no changes
- **"Fix section 3 but keep the rest"** → switch to Mode 2 (Edit Description) for targeted changes on the regenerated content

### Step 7: Push

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

Backup automatic via push script. Updates the `description` field only — metadata (points, dates) unchanged unless user requests.

### Step 8: Rubric regeneration

If Bloom's level changed, prompt: "The rubric was calibrated for [old level]. Regenerate the rubric to match?" If yes, invoke rubric-creator with the new Bloom's level and tier.

### Step 9: Verify

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

Run the intra-module alignment check on the regenerated assignment.

---

## Error Handling

| Error | User Message | Recovery |
|---|---|---|
| No course-config.json | "I need course context first. Let me create a config from your course." | Auto-create minimal config |
| Missing module objectives | "Module {N} doesn't have objectives defined yet. Let's add them." | Guide objective creation |
| Push fails | "The push failed but your content is saved in staging/. Let's try again." | Retry |
| Canvas API 401/403 | "Authentication issue — check your Canvas token and permissions." | Guide re-auth |

## Output
The skill produces:
1. Complete assignment with instructions, scenario, and deliverables
2. Matching rubric (via rubric-creator skill)
3. Canvas setup configuration
4. Objective alignment map (using blueprint objective IDs)
5. Grading notes for the instructor
6. Intra-module alignment note explaining how the Artifact complements the KC and Discussion
