# Plan: Deep-pass cognitive demand (read prompts + rubrics, not inherited objectives)

## Why
The assurance audit grounded each assessment's Bloom level in its module's objectives
(MLO inheritance) plus conservative caps. On COM 100 / 151110 this misclassified the
seven discussions: the deterministic engine capped them at Understand, but reading the
actual prompts shows Evaluate ("do you agree? why?", "are these ethical?", "which
viewpoint makes most sense? why?", "should X count as mass media? compare"). The engine
under-claimed cognitive demand by two levels. The fix: read each assessment's real
prompt and rubric and classify the Bloom level the task REQUIRES. This is the standard
depth for the audit going forward.

Architecture stays as-is: deterministic scripts FETCH + ATTACH content; Claude classifies
inline (the existing `needs_ai_review` path). No LLM client in the scripts. The deep-read
distribution is a within-course diagnostic (never feeds the cross-course tier/coverage).

## A. Inventory — attach full content for every weighted assessment (`assurance_inventory.py`)
For each assessment with grade_weight_pct > 0, attach:
1. `content_excerpt` — assignment `description`, discussion `message` (the prompt, fetched
   via the discussion topic), or quiz question stems where the API returns them. HTML-stripped, capped.
2. `rubric_excerpt` — NEW: the assessment's rubric criteria (`description` + `long_description`
   per criterion), HTML-stripped, capped. Rubrics are the strongest cognitive-demand signal.
3. `bloom_content_available` — bool: True when prompt or rubric text was obtained; False when
   the item is an objective quiz/exam whose items come from a question bank the API does not
   expose (mark these for format inference, not content read).
Keep the existing deterministic Bloom (title verb → MLO inheritance → caps → objective_floor)
as the baseline/fallback.

Acceptance: on 151110, the 10 short papers carry `rubric_excerpt`; the 7 discussions carry the
prompt as `content_excerpt`; Exam 1/2 and chapter quizzes carry `bloom_content_available=False`.

## B. Audit — emit a deep-bloom review item for every weighted assessment (`assurance_audit.py`)
When the deep pass is active (default on), emit a `bloom_content` `needs_ai_review` item for
EVERY weighted assessment (not only Unknown), carrying `content_excerpt` + `rubric_excerpt` +
`bloom_content_available`. Dedup structurally-identical items (the 10 short papers share one
template → one representative). Items with `bloom_content_available=False` are tagged
`basis="format"` so Claude classifies them by instrument format, not content.

## C. Report — display the deep-read distribution (`assurance_report_html.py`)
The "What the Course Measures" section displays the narrative's `cognitive_demand` object when
present (Claude's deep-read distribution + per-cluster basis), labeled "Read from each
assessment's prompt and rubric (deep pass)". Falls back to the deterministic distribution
otherwise. Show, per cluster: the level, the weight, and the basis (rubric / prompt / format).
Where any weight is format-inferred (bank-locked items), state it in the section, not only a caveat.

Narrative shape (`cognitive_demand`):
```
{"distribution": {"Understand": 88.6, "Evaluate": 10.9, "Remember": 0.6},
 "clusters": [{"label":"Short papers","weight":57.1,"level":"Understand","basis":"rubric: summarize/define/explain/link"}, ...],
 "format_inferred_weight_pct": 30.8}
```

## D. Skill — make the deep pass the documented standard (`skills/assurance-audit/SKILL.md`)
Document the deep pass in the cognitive-demand step: Claude reads each weighted assessment's
attached prompt + rubric and classifies the Bloom level the task REQUIRES (not inherited from
module objectives), folds the result into `cognitive_demand` for the renderer, and labels
format-inferred items (objective items whose bank-locked stems the API does not expose).
State plainly that higher Bloom does not improve assurance (an Evaluate-level async post is as
AI-substitutable as an Understand-level one); the deep pass refines Dimension C only, never the tier.

## Out of scope
- No change to tier / coverage / lane math. Cognitive demand is diagnostic only.
- No LLM client or embeddings in scripts. No new dependency.

## Verify
- Full `pytest tests/ -q` green on a clean checkout.
- 151110: rubric_excerpt on papers, prompt on discussions, format flag on exams/quizzes; the
  rendered "What the Course Measures" shows the deep-read distribution (Understand ~88.6%,
  Evaluate ~10.9%, Remember ~0.6%) labeled as read from prompts/rubrics, with the ~31%
  format-inferred weight stated.
- Read the diff by hand before merge. Coder ≠ reviewer.
