a905eb8c67
The defend page fabricated taskId = `task-${competencyId}`, but variant
task_ids are `task-<seed[:16]>` (D-029) — so in the real browser flow the
defense ran against an empty trace (no digest grounding) and Grade My Work
always returned UNGRADABLE_EMPTY_TRACE. The E2E test masked this by passing
the real task_id directly.
Fix: DefenseSession resolves the learner's stored variant by competency
via GET /v1/variants?learner_id (new listVariants client), defends + grades
under the variant's real task_id, and shows an honest empty state when no
build session exists for the competency yet.
---ci---
phase: 6
milestone: v0.3
status: verify
requirements:
covered: [REQ-3-008]
partial: []
lessons:
- A green E2E test can still mask a broken UI wiring when the test hand-picks
the join key the UI is supposed to derive; verify browser flows against the
ids the pages actually construct, not the engine contract alone.
---/ci---