Workstream H of the pre-revamp quiz batch (epic #537). Do not start until #544 (F) is merged.
read_misconceptions_for_course filters offering_concept_stats.offering_id using the abstract course id (agents/tools/graph_read.py:412, fed from routes/quiz.py's node["course_id"]), while the stats table is keyed on course_offerings.id. Near-certainly zero rows, always — so use_shared_context has been a no-op.
Verify against the live DB before acting. This is one of two findings in the 2026-08-13 data-inventory audit that are code-verified only. Run the filter both ways against staging/prod and confirm the zero-row result before changing anything.
Then: resolve course → active offering inside the tool path (services/academics.py owns that resolution), and land a test asserting non-zero rows on the rich seed so it can't silently regress to empty again.
Related: the same silent-empty class is what #529 was, and what the F5 helper in #544 is meant to catch generally.
Workstream H of the pre-revamp quiz batch (epic #537). Do not start until #544 (F) is merged.
read_misconceptions_for_coursefiltersoffering_concept_stats.offering_idusing the abstract course id (agents/tools/graph_read.py:412, fed fromroutes/quiz.py'snode["course_id"]), while the stats table is keyed oncourse_offerings.id. Near-certainly zero rows, always — souse_shared_contexthas been a no-op.Verify against the live DB before acting. This is one of two findings in the 2026-08-13 data-inventory audit that are code-verified only. Run the filter both ways against staging/prod and confirm the zero-row result before changing anything.
Then: resolve course → active offering inside the tool path (
services/academics.pyowns that resolution), and land a test asserting non-zero rows on the rich seed so it can't silently regress to empty again.Related: the same silent-empty class is what #529 was, and what the F5 helper in #544 is meant to catch generally.