---
name: discussion-generator
description: "Create or edit graded discussions — full generation, quick metadata edits (points, dates, post-first), or prompt editing."
---

# Discussion 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 discussions AI-aware using the Discussions 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 discussion operations: generate graded discussion prompts, edit metadata settings, or revise the discussion prompt 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/discussions/{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/discussions/{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 a discussion for Module 3" / "Generate discussion prompt" | **Mode 1: Create** (full generation flow) |
| "Set require_initial_post on Module 2 discussion" / "Change points" | **Mode 2: Edit Settings** (fast-path, no generation) |
| "Set due date on the discussion" / "Move to Discussions group" | **Mode 2: Edit Settings** (fast-path) |
| "Fix the discussion prompt for Module 4" / "Rewrite the prompt" | **Mode 3: Edit Prompt** (staging workflow) |
| "Regenerate the Module 3 discussion" / "Try a different prompt" | **Mode 4: Regenerate** |
| "The discussion is too easy" / "Make it more challenging" / "Different angle" | **Mode 4: Regenerate** |

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

---

## CRITICAL — Discussion Field Boundary

Graded discussions have TWO Canvas objects: a **discussion topic** and a **linked assignment**. Fields live on different objects:

| Field | Lives On | API Target |
|---|---|---|
| Title | Discussion topic | `PUT /discussion_topics/:id` |
| Prompt body (message) | Discussion topic | `PUT /discussion_topics/:id` — field is `message`, NOT `description` |
| Require initial post | Discussion topic | `PUT /discussion_topics/:id` |
| Discussion type (threaded) | Discussion topic | `PUT /discussion_topics/:id` |
| Published | Discussion topic | `PUT /discussion_topics/:id` |
| Pinned / Locked | Discussion topic | `PUT /discussion_topics/:id` |
| **Points** | **Linked assignment** | `PUT /assignments/:assignment_id` |
| **Due date** | **Linked assignment** | `PUT /assignments/:assignment_id` |
| **Available from/until** | **Linked assignment** | `PUT /assignments/:assignment_id` |
| **Assignment group** | **Linked assignment** | `PUT /assignments/:assignment_id` |
| **Rubric** | **Linked assignment** | `POST /rubrics` with association to assignment_id |

**WARNING:** Do NOT PUT dates or points on the discussion topic — they won't work. Always target the linked assignment for grading fields. Get the `assignment_id` from: `GET /discussion_topics/:id` → response includes `"assignment_id": 12345`.

---

## Tier-Aware Defaults

Before generating any discussion, read `course.tier` from `course-config.json`. The tier calibrates discussion type recommendations, word counts, and prompt scaffolding. 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 types** | Type E (Reflective Application), Type A (Debate); late modules may reach Type B | Type B (Comparison), Type C (Prediction); late modules reach Type D | Type D (Integration Challenge), Type C (Prediction/Evaluation); peer critique throughout |
| **Type progression** | E → A → B (gentler escalation) | B → C → D (starts higher, reaches integration) | C/D throughout — seminar-style from module 1 |
| **Initial post word count** | 200-300 words | 300-400 words | 400-500 words |
| **Peer response word count** | 100-200 words | 150-250 words | 200-300 words; substantive critique expected, not affirmation |
| **Prompt design** | Include guiding sub-questions and sentence starters within the prompt ("In your initial post, address these three questions: (1)... (2)... (3)...") | Pose a single open-ended question or scenario; expect students to determine their own analytical structure | Single theoretical or professional question, no sub-questions. Students frame their own analytical lens. |
| **Peer engagement** | Scaffolded prompts ("Respond by either agreeing and adding a new example, or respectfully disagreeing with evidence") | Independent ("Engage substantively with your classmates' reasoning") | Seminar-style critique ("Engage with your colleague's methodological assumptions or theoretical framing") |

Tier sets the baseline; module position adjusts within it.

---

## Mode 1: Create Discussion

### Pre-Generation Questionnaire

Before generating, confirm these parameters:

> **1. Discussion type** — "Which type fits this module?"
>
> | Type | Best For | Bloom's |
> |---|---|---|
> | **Type E: Reflective Application** | Early modules, foundational concepts | Apply |
> | **Type A: Professional Reasoning Debate** | Modules with ambiguous scenarios | Analyze |
> | **Type B: Significance Comparison** | Modules with parallel concepts | Evaluate |
> | **Type C: What Would Happen If** | Modules with predictive/causal content | Evaluate |
> | **Type D: Integration Challenge** | Late modules, cross-module synthesis | Create |
>
> **2. Points** — "25 points is our default. Does this fit?" (Intro discussion = 10 pts)
>
> **3. Word count** — Use tier defaults: Introductory = "Initial post: 200-300 words, peer responses: 100-200 words"; Advanced = "Initial post: 300-400 words, peer responses: 150-250 words"; Graduate = "Initial post: 400-500 words, peer responses: 200-300 words". Present the tier default and let the user adjust.
>
> **4. Peer response count** — "2 peer responses is standard. More or fewer?"
>
> **5. Rubric structure** — "3 criteria (Reasoning 10 / Engagement 10 / Communication 5) is default."

If "discussions for all modules," ask once and apply consistently. Use the tier-specific type progression from the Tier-Aware Defaults table above.

### Recommended Progression (Tier-Aware)

**Introductory (100-299):**
- **Early modules (M1-M2)**: Type E — scaffolded reflective application
- **Middle modules (M3-M5)**: Type A or B — single-module reasoning or comparison
- **Late modules (M6-M8)**: Type B — comparison with stronger evaluative reasoning, still within the Introductory cap

**Advanced (300-499):**
- **Early modules (M1-M2)**: Type B — comparison with evaluative reasoning
- **Middle modules (M3-M5)**: Type B or C — comparison, prediction
- **Late modules (M6-M8)**: Type C or D — prediction, cross-module integration

**Graduate (500+):**
- **All modules**: Type C or D — seminar-style throughout. No escalation arc needed; graduate students engage at integration/evaluation level from the start.
- **Early modules**: Type C if new disciplinary content is being introduced; Type D otherwise
- **Peer responses**: Always substantive critique of classmate's analytical framing, not just agreement or additional examples

If no tier is set, fall back to: E → A/B → C/D.

### Discussion Parameters
- **Points**: 25 per module (adjustable); introductory discussion = 10 pts
- **Structure**: Initial post + 2 peer responses
- **Rubric**: Required — use the rubric-creator skill
- **Timing**: Initial post due mid-module; responses due end of module
- **Canvas setting**: "Students must post before seeing replies" = ENABLED (required)

### Discussion Prompt Design

A great discussion prompt:
1. **Has no single right answer** — requires reasoning, not recall
2. **Invites legitimate disagreement** — students can argue different positions with evidence
3. **Requires course content application** — can't be answered without the module material
4. **Connects to professional reality** — feels relevant to career practice
5. **Is specific enough** to focus responses but **open enough** to generate diverse perspectives
6. **Builds on the lecture video** — extends the anchor content into debatable territory

### Assurance by Design

Apply the Discussions moves from `standards/assessment-assurance-design.md`: bind the prompt to cohort-specific named evidence (a case, a classmate's post, a shared artifact), keep post-before-see-peers enabled, and offer an optional audio/video identity variant. Offer a critique-an-AI-answer variant where students name what an AI response missed. Run the by-design self-check before returning the prompt.

### Prompt Types

**Type A: Professional/Clinical Reasoning Debate**
- "A [scenario] occurs with [observations]. Two explanations are proposed: [A] and [B]. Which do you think is more likely, and why?"

**Type B: Mechanism Comparison & Significance**
- "We've studied [X] and [Y]. Which has greater [practical/clinical/theoretical] significance, and why?"

**Type C: "What Would Happen If" Prediction**
- "Imagine [intervention]. Predict the consequences at [multiple levels]. What unintended effects would you anticipate?"

**Type D: Integration Challenge**
- "Choose a single [case/scenario] and explain it using concepts from at least [2-3] modules. How do these concepts interact?"

**Type E: Reflective Application**
- "Consider this [scenario]. (1) Identify which module concept(s) are most relevant. (2) Explain how you'd apply one. (3) Reflect on how this connects to your experience."

### Discussion Prompt Template

```
## Discussion [#]: [Title]

### The Scenario
[2-3 paragraphs presenting the scenario, question, or challenge.]

### Your Initial Post (due [date])
In your initial post (300-400 words), address:
1. [Primary question — requires applying module concepts]
2. [Secondary question — requires reasoning about mechanism or significance]
3. Support with specific concepts from this module.

### Peer Responses (2 responses due [date])
Respond to at least TWO classmates (150-250 words each):
- Engage substantively with their reasoning
- Add a new perspective, ask a probing question, or respectfully challenge
- Reference specific course concepts

### What Makes a Great Post
- Uses precise discipline-specific terminology
- Traces reasoning through multiple levels of analysis
- Acknowledges complexity and uncertainty
- References specific course resources

### Grading
This discussion is worth 25 points. See the attached rubric.
```

### Module 0: Introduction Discussion

**Type**: Community building + baseline assessment
**Points**: 10 (lower stakes)
**Rubric**: Simplified 2-criterion (Engagement 5 pts, Completeness 5 pts)

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

#### Step 1: Stage the discussion prompt

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

Staged to: `courses/{COURSE_ID}/staging/discussions/m{N}-discussion.html`

Show the user a preview. Wait for approval.

#### Step 2: Create the discussion on Canvas (after approval)

```
POST /api/v1/courses/:course_id/discussion_topics
Body: {
  "title": "Discussion N: [Title]",
  "message": "<p>staged HTML content</p>",
  "discussion_type": "threaded",
  "require_initial_post": true,
  "published": false,
  "assignment": {
    "name": "Discussion N: [Title]",
    "points_possible": 25,
    "due_at": "2026-03-15T23:59:00-07:00",
    "assignment_group_id": <id>,
    "submission_types": ["discussion_topic"]
  }
}
```

**Important:** The nested `assignment` object creates a graded discussion. Dates, points, and assignment group go HERE.

#### Step 3: Attach rubric

Get `assignment_id` from the created topic: `GET /discussion_topics/:id` → `"assignment_id"`.
Invoke rubric-creator with the `assignment_id`.

#### Step 4: Verify

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

#### Step 5: Clear staging

```bash
${ASUCB_PLUGIN_ROOT:-${CODEX_PLUGIN_ROOT:-${CLAUDE_PLUGIN_ROOT}}}/bin/python3 scripts/staging_manager.py --course-id {COURSE_ID} --clear --type discussions --id m{N}-discussion
```

## Rubric Integration
Standard discussion rubric (25 pts):
- Scientific/Professional Reasoning (10 pts)
- Peer Engagement (10 pts)
- Evidence & Communication (5 pts)

D0 rubric (10 pts):
- Engagement & Thoughtfulness (5 pts)
- Completeness & Peer Interaction (5 pts)

## Intra-Module Alignment Check

1. **Reference the syllabus** for objectives and alignment matrix
2. **Review KC and Artifact**: Discussion should extend into different territory — open-ended reasoning, peer debate, or cross-module integration
3. **Verify Bloom's level**: Discussion = Evaluate/Create — above KC (Apply/Analyze), complementary to Artifact (Analyze/Evaluate)
4. **Document alignment** in the output

---

## Mode 2: Edit Discussion Settings (Fast-Path)

**Skip the generation questionnaire.**

### Step 1: Identify the discussion

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

### Step 2: Display combined settings

Fetch the topic AND its linked assignment (if graded):

```
GET /api/v1/courses/:course_id/discussion_topics/:topic_id
```
If `assignment_id` exists:
```
GET /api/v1/courses/:course_id/assignments/:assignment_id
```

Show combined table:

| Field | Current Value | Lives On |
|---|---|---|
| Title | Discussion 3: Debate | Topic |
| Discussion type | threaded | Topic |
| Require initial post | true | Topic |
| Published | true | Topic |
| Points | 25 | Assignment |
| Due date | 2026-03-15 | Assignment |
| Assignment group | Discussions | Assignment |
| Rubric | Yes (3 criteria) | Assignment |

### Step 3: Apply edits

**Topic-level settings** — PUT on the discussion topic:
```
PUT /api/v1/courses/:course_id/discussion_topics/:topic_id
Body: { <only changed fields> }
```

| Field | API Parameter |
|---|---|
| Title | `title` |
| Require initial post | `require_initial_post` |
| Discussion type | `discussion_type` (threaded / side_comment) |
| Published | `published` |
| Pinned | `pinned` |
| Locked | `locked` |

**Grading settings** — PUT on the linked assignment:
```
PUT /api/v1/courses/:course_id/assignments/:assignment_id
Body: { "assignment": { <only changed fields> } }
```

| Field | API Parameter |
|---|---|
| Points | `assignment[points_possible]` |
| Due date | `assignment[due_at]` (ISO 8601, -07:00 for AZ) |
| Available from | `assignment[unlock_at]` |
| Available until | `assignment[lock_at]` |
| Assignment group | `assignment[assignment_group_id]` |

Confirm with the user before pushing.

### Step 4: Verify

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

---

## Mode 3: Edit Discussion Prompt (Body)

For rewriting or fixing the discussion prompt text. Uses the staging workflow.

### Step 1: Fetch current prompt

```
GET /api/v1/courses/:course_id/discussion_topics/:topic_id
```
The body is in the **`message`** field (NOT `description`).

### Step 2: Edit and stage

1. Apply the user's requested changes to the HTML
2. Stage: `${ASUCB_PLUGIN_ROOT:-${CODEX_PLUGIN_ROOT:-${CLAUDE_PLUGIN_ROOT}}}/bin/python3 scripts/staging_manager.py --course-id {COURSE_ID} --stage --type discussions --id {topic_id} --html-file <path>`
3. Preview the staged content for user approval

### Step 3: Push

```bash
${ASUCB_PLUGIN_ROOT:-${CODEX_PLUGIN_ROOT:-${CLAUDE_PLUGIN_ROOT}}}/bin/python3 scripts/push_to_canvas.py --type discussion --id {topic_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 discussion --id {topic_id} --course-id {COURSE_ID}
```

---

## Mode 4: Regenerate Discussion

Triggered when the user wants to replace a discussion prompt with a different difficulty or fresh content.

**How this differs from Mode 2 (Edit Settings) and Mode 3 (Edit Prompt):**
- Mode 2 edits metadata — topic-level fields (title, require_initial_post) via PUT on discussion topic; grading fields (points, dates) via PUT on linked assignment
- Mode 3 edits the prompt HTML in place — fetches `message` field from discussion topic, applies modifications, stages, pushes
- **Mode 4 replaces the entire discussion prompt** — generates a new scenario and prompt structure (potentially a different discussion type), stages it alongside the original for comparison

**Critical field boundary reminder**: The prompt body lives in the `message` field on the **discussion topic** (NOT `description`). Points, dates, assignment group live on the **linked assignment**. Regeneration only touches the `message` field unless the user also wants metadata changes.

### Step 1: Identify the target discussion

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

Fetch current prompt: `GET /api/v1/courses/:course_id/discussion_topics/:topic_id` → `message` field. Also get `assignment_id` for rubric handling.

### Step 2: Determine regeneration type

| User says... | Type |
|---|---|
| "too easy" / "make it harder" / "students aren't engaging" | **Bump Up** |
| "too hard" / "simpler" / "students are confused" | **Bump Down** |
| "different angle" / "try again" / "new scenario" | **Different Angle** |

### Step 3: Calculate new parameters

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

- **Bump Up**: Move to the next-higher discussion type within the tier's range (e.g., Type E → Type A, or Type B → Type C). Reduce guiding sub-questions. Increase expected word count.
- **Bump Down**: Move to the next-lower discussion type within the tier's range. Add more guiding sub-questions and sentence starters. Reduce word count.
- **Different Angle**: Keep the same discussion type and word count. Generate a completely new scenario, different professional context, and fresh guiding questions targeting the same objectives.
- **At ceiling/floor**: Tell the user: "This is already at the [highest/lowest] discussion type within the [tier] range. To go further, you'd need to change the course tier."

Preserve `points_possible` and peer response count from the original.

### Step 4: Generate replacement prompt

Write a new discussion prompt HTML following the adjusted type template and all Discussion Prompt Design principles.

### 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 discussions --id {topic_id} --html-file <path>
```

Present a side-by-side summary:
```
CURRENT: Type A (Professional Debate), 300 words initial, 3 guiding questions
REGENERATED: Type B (Significance Comparison), 350 words initial, 2 guiding questions
```

Show the full HTML preview of the regenerated prompt.

### Step 6: User approval gate

- **"Looks good"** → proceed to push
- **"Keep the original"** → clear staging, no changes
- **"Fix the scenario but keep the questions"** → switch to Mode 3 (Edit Prompt) 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 discussion --id {topic_id} --course-id {COURSE_ID}
```

Updates the `message` field on the discussion topic. Backup automatic. Linked assignment metadata (points, dates) unchanged.

### Step 8: Rubric regeneration

If discussion type changed, prompt: "The rubric was calibrated for [old type]. Regenerate to match?" If yes, invoke rubric-creator targeting the linked assignment (`assignment_id` from the discussion topic).

### Step 9: Verify

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

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

---

## Discussion Facilitation Guide (for Instructor)
1. **Model exemplary reasoning** — Post a faculty response to the first 1-2 discussions
2. **Redirect off-topic threads** — Steer conversations back to course concepts
3. **Prompt quieter students** — Ask follow-up questions to students who don't receive responses
4. **Highlight strong reasoning** — Call out posts that demonstrate excellent analytical thinking

## Error Handling

| Error | User Message | Recovery |
|---|---|---|
| No course-config.json | "I need course context first." | Auto-create minimal config |
| Missing module objectives | "Module {N} needs objectives first." | Guide objective creation |
| Push fails | "Push failed but content is in staging/." | Retry |
| Canvas API 401/403 | "Authentication issue." | Guide re-auth |

## Output
1. Complete discussion prompt with scenario, requirements, and rubric reference
2. Canvas setup configuration (points, due dates, post-first settings)
3. Objective alignment map
4. Suggested grading notes for instructor
5. 2-3 example "strong response" descriptions
