chore(quiz): delete the dead effective_explanations read (#572) - #587

Merged
AndresL230 merged 2 commits into
mainfrom
chore/572-drop-effective-explanations-read
Aug 26, 2026
Merged

chore(quiz): delete the dead effective_explanations read (#572)#587
AndresL230 merged 2 commits into
mainfrom
chore/572-drop-effective-explanations-read

Conversation

@AndresL230

@AndresL230AndresL230 commented Aug 23, 2026

Copy link
Copy Markdown
Collaborator

Summary

services/course_context_service.py::_parse_quiz_context_to_arrays read
quiz_context.context_json's effective_explanations key alongside its two
legitimate siblings (common_mistakes, weak_areas) — but no writer
anywhere in the codebase (agents/quiz_context.py::QuizContext writes only
weak_areas/common_mistakes/questions_seen_summary/
recommended_difficulty/notes) ever produces that key. The read has been
silently dead since the column existed, meaning
offering_concept_stats.effective_explanations has persisted an
always-empty array for every offering — indistinguishable from "this class
produced no effective explanations" (the #548/#529 failure class, found by
the code review that specifically went looking for it, #554 H2).

Per the issue's own decision framing, this takes option 2: delete the
read
(option 1, making the field real, needs #558-style consent framing
before it can widen what class-derived text the tutor surfaces — out of
scope for a cleanup task).

  • Removed the effective_explanations accumulation from
    _parse_quiz_context_to_arrays (now returns a 2-tuple) and its write into
    the offering_concept_stats upsert.
  • Dropped the matching "effective_explanations": [] from
    db/seed_local_rich.py's seed — noise now that nothing reads it; the
    column's own DB default ('{}', unchanged in 0022_analytics.sql)
    produces the identical value.
  • No migration: the column stays, per the brief.

Grep verification

/usr/bin/grep -rn effective_explanations across backend/, frontend/src,
frontend/e2e, docs/ — every hit accounted for (full table in
task-8-report.md): 2 immutable migrations (kept, column stays), 2 docs
(kept, doc-historical/still-accurate), 5 code sites in
course_context_service.py + 1 in seed_local_rich.py (all deleted), zero
frontend or admin-analytics consumers.

Test plan

  • New regression test
    TestUpdateCourseContext::test_effective_explanations_never_emitted_even_when_source_has_it
    — plants the key in source data, asserts it's absent from the upsert
    payload. RED confirmed against pre-fix code, GREEN after.
  • venv/bin/ruff check . — All checks passed
  • Full backend suite: 2224 passed, 79 skipped

Closes#572

Lane runs (overnight 2026-08-23, local stack under the flock, function mode)

Merge-gate review (2026-08-26)

/code-review (medium) on this PR: the core deletion reviewed clean (5 angles). It also
surfaced 5 in-PR polish nits and 6 pre-existing debts in the touched function.

  • In-PR polish applied (commit 4b38b13): a structural tripwire assertion
    (assertNotIn("effective_explanations", QuizContext.model_fields)) so the regression test
    enforces its premise in code, not just prose; tightened two comments (the DB-default claim only
    holds on a fresh INSERT, not on the upsert's merge-duplicates UPDATE path; every stored
    context_json row also carries a server-stamped schema_version); deduplicated the quiz: offering_concept_stats.effective_explanations is a dead read — no agent writes that key #572 story to
    one canonical telling with two one-line pointers; extended the test's _table_factory helper and
    deleted a dead _make_table_mock. Full suite re-verified green (2224 passed / 79 skipped), ruff
    clean.
  • Pre-existing findings in update_course_context (not fixed here — out of scope for this cleanup):
    filed as course_context rollup: opt-out purge gap, silent-empty overwrite, unguarded legacy shapes, N+1 reads/writes #595 (opt-out purge gap on two early exits, a silent-empty catch whose overwrite can wipe
    previously-good aggregates on a transient failure, missing legacy-shape guards in the parse loop,
    and N+1 reads/writes in the per-concept loop).

Summary by CodeRabbit

  • Bug Fixes

    • Improved course-context aggregation by consistently relying on default explanation values.
    • Preserved common misconceptions and prerequisite gaps while preventing redundant explanation data from being stored.
  • Tests

    • Added regression coverage to verify correct course-context processing and database updates.

`_parse_quiz_context_to_arrays` read quiz_context.context_json's
effective_explanations key, but no writer (agents/quiz_context.py::
QuizContext writes weak_areas/common_mistakes/questions_seen_summary/
recommended_difficulty/notes only) ever produces it -- the read has
been silently dead since offering_concept_stats.effective_explanations
existed, always persisting []. Delete the read and its now-noise seed
write in seed_local_rich.py; the column stays on its DB default per
the issue's own decision framing (no migration).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitaiBot commented Aug 23, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 28571d7b-4f4e-4961-a782-ac35fc3b540f

📥 Commits

Reviewing files that changed from the base of the PR and between 9f34454 and 2ad7002.

📒 Files selected for processing (3)
  • backend/db/seed_local_rich.py
  • backend/services/course_context_service.py
  • backend/tests/test_shared_course_context.py

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

The quiz-context aggregation now handles only common misconceptions and prerequisite gaps. Concept-statistics upserts and local seed rows omit effective_explanations. A regression test verifies the behavior.

Changes

Course context aggregation cleanup

Layer / File(s)Summary
Remove effective explanations handling
backend/services/course_context_service.py, backend/tests/test_shared_course_context.py, backend/db/seed_local_rich.py
The parser and upsert omit effective_explanations. The regression test verifies that the remaining fields are preserved. Local seed rows rely on the database default.

Estimated code review effort: 2 (Simple) | ~10 minutes

Merge Risk:⚪ Minimal · up to 2ad70

This localized cleanup stops emitting an unused empty field while preserving the database column and its default behavior; no actionable merge-blocking risk remains after normal checks and review.

Suggested reviewers:darkest-teddy, jose-gael-cruz-lopez

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check nameStatusExplanation
Linked Issues check✅ PassedThe changes implement issue #572 option 2 by removing the dead read and seed value while retaining the database column and default.
Out of Scope Changes check✅ PassedAll code changes support the linked issue and stated objective; no unrelated implementation changes are present.
Docstring Coverage✅ PassedDocstring check was indeterminate for this PR — some files could not be analyzed in time. Not blocking.
Description check✅ PassedThe description clearly explains the dead read, lists the code and seed changes, identifies issue #572, documents regression and suite testing, and includes reviewer notes. It uses equivalent headings…
Title check✅ PassedThe title clearly and concisely describes the main change: removing the unused effective_explanations read from quiz processing.
Full details: Description check

Explanation

The description clearly explains the dead read, lists the code and seed changes, identifies issue #572, documents regression and suite testing, and includes reviewer notes. It uses equivalent headings instead of the exact template headings, but the required information is present.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/572-drop-effective-explanations-read

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@cloudflare-workers-and-pages

cloudflare-workers-and-pagesBot commented Aug 23, 2026

Copy link
Copy Markdown

Deploying with Cloudflare Workers Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

StatusNameLatest CommitPreview URLUpdated (UTC)
✅ Deployment successful!
View logs
frontend-staging4b38b13Commit Preview URL

Branch Preview URL
Aug 26 2026, 05:27 AM

@supabase

supabaseBot commented Aug 23, 2026

Copy link
Copy Markdown

This pull request has been ignored for the connected project ybgqdonkoqftwrmweuyv because there are no changes detected in supabase directory. You can change this behaviour in Project Integrations Settings ↗︎.


Preview Branches by Supabase.
Learn more about Supabase Branching ↗︎.

/code-review on PR #587 (the effective_explanations dead-read deletion, #572)
reviewed the core deletion clean and turned up five in-PR nits + six
pre-existing debts. This lands the in-PR nits; the pre-existing debts are
filed as #595.
- F5 (tripwire): test_effective_explanations_never_emitted_even_when_source_has_it
pinned its premise (QuizContext never emits effective_explanations) only in
prose. Add the structural assertion (assertNotIn on QuizContext.model_fields)
so a future field-without-rollup regression goes red instead of just
documenting the drop as correct.
- F6/F7 (comment precision): the canonical #572 comment in
_parse_quiz_context_to_arrays overstated the DB default's coverage (only
true on a fresh INSERT — the on_conflict merge-duplicates UPDATE path never
touches the column, so an out-of-band value would persist) and omitted that
every stored context_json row also carries a server-stamped schema_version.
- F9 (prose dedup): the #572 story was told in full three times (the
service comment, the test docstring, db/seed_local_rich.py). Keep one
canonical telling at the deletion site; the other two are now one-line
pointers at it.
- F8/F10 (test-helper dedup): extended TestUpdateCourseContext._table_factory
with an optional quiz_rows param and converted all four ad hoc `_table`
dispatch closures (three pre-existing + the new tripwire test) to use it;
deleted the dead module-level _make_table_mock (zero call sites).
Refs #572. Follow-up: #595.
@AndresL230
AndresL230 merged commit f6ed004 into mainAug 26, 2026
8 checks passed
AndresL230 added a commit that referenced this pull request Aug 26, 2026
Brings in the include_answer_key default flip (#590), the dead
effective_explanations deletion (#587) and the CI port preflight (#588).
Clean auto-merge: main's routes/quiz.py hunks are in the generate
handler's response projection, this branch's are in the shared
gather/hoist above it.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

quiz: offering_concept_stats.effective_explanations is a dead read — no agent writes that key

1 participant

@AndresL230
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

chore(quiz): delete the dead effective_explanations read (#572) - #587

Merged
AndresL230 merged 2 commits into
mainfrom
chore/572-drop-effective-explanations-read
Aug 26, 2026
Merged

chore(quiz): delete the dead effective_explanations read (#572)#587
AndresL230 merged 2 commits into
mainfrom
chore/572-drop-effective-explanations-read

Conversation

@AndresL230

@AndresL230AndresL230 commented Aug 23, 2026

Copy link
Copy Markdown
Collaborator

Summary

services/course_context_service.py::_parse_quiz_context_to_arrays read
quiz_context.context_json's effective_explanations key alongside its two
legitimate siblings (common_mistakes, weak_areas) — but no writer
anywhere in the codebase (agents/quiz_context.py::QuizContext writes only
weak_areas/common_mistakes/questions_seen_summary/
recommended_difficulty/notes) ever produces that key. The read has been
silently dead since the column existed, meaning
offering_concept_stats.effective_explanations has persisted an
always-empty array for every offering — indistinguishable from "this class
produced no effective explanations" (the #548/#529 failure class, found by
the code review that specifically went looking for it, #554 H2).

Per the issue's own decision framing, this takes option 2: delete the
read
(option 1, making the field real, needs #558-style consent framing
before it can widen what class-derived text the tutor surfaces — out of
scope for a cleanup task).

  • Removed the effective_explanations accumulation from
    _parse_quiz_context_to_arrays (now returns a 2-tuple) and its write into
    the offering_concept_stats upsert.
  • Dropped the matching "effective_explanations": [] from
    db/seed_local_rich.py's seed — noise now that nothing reads it; the
    column's own DB default ('{}', unchanged in 0022_analytics.sql)
    produces the identical value.
  • No migration: the column stays, per the brief.

Grep verification

/usr/bin/grep -rn effective_explanations across backend/, frontend/src,
frontend/e2e, docs/ — every hit accounted for (full table in
task-8-report.md): 2 immutable migrations (kept, column stays), 2 docs
(kept, doc-historical/still-accurate), 5 code sites in
course_context_service.py + 1 in seed_local_rich.py (all deleted), zero
frontend or admin-analytics consumers.

Test plan

  • New regression test
    TestUpdateCourseContext::test_effective_explanations_never_emitted_even_when_source_has_it
    — plants the key in source data, asserts it's absent from the upsert
    payload. RED confirmed against pre-fix code, GREEN after.
  • venv/bin/ruff check . — All checks passed
  • Full backend suite: 2224 passed, 79 skipped

Closes#572

Lane runs (overnight 2026-08-23, local stack under the flock, function mode)

Merge-gate review (2026-08-26)

/code-review (medium) on this PR: the core deletion reviewed clean (5 angles). It also
surfaced 5 in-PR polish nits and 6 pre-existing debts in the touched function.

  • In-PR polish applied (commit 4b38b13): a structural tripwire assertion
    (assertNotIn("effective_explanations", QuizContext.model_fields)) so the regression test
    enforces its premise in code, not just prose; tightened two comments (the DB-default claim only
    holds on a fresh INSERT, not on the upsert's merge-duplicates UPDATE path; every stored
    context_json row also carries a server-stamped schema_version); deduplicated the quiz: offering_concept_stats.effective_explanations is a dead read — no agent writes that key #572 story to
    one canonical telling with two one-line pointers; extended the test's _table_factory helper and
    deleted a dead _make_table_mock. Full suite re-verified green (2224 passed / 79 skipped), ruff
    clean.
  • Pre-existing findings in update_course_context (not fixed here — out of scope for this cleanup):
    filed as course_context rollup: opt-out purge gap, silent-empty overwrite, unguarded legacy shapes, N+1 reads/writes #595 (opt-out purge gap on two early exits, a silent-empty catch whose overwrite can wipe
    previously-good aggregates on a transient failure, missing legacy-shape guards in the parse loop,
    and N+1 reads/writes in the per-concept loop).

Summary by CodeRabbit

  • Bug Fixes

    • Improved course-context aggregation by consistently relying on default explanation values.
    • Preserved common misconceptions and prerequisite gaps while preventing redundant explanation data from being stored.
  • Tests

    • Added regression coverage to verify correct course-context processing and database updates.

`_parse_quiz_context_to_arrays` read quiz_context.context_json's
effective_explanations key, but no writer (agents/quiz_context.py::
QuizContext writes weak_areas/common_mistakes/questions_seen_summary/
recommended_difficulty/notes only) ever produces it -- the read has
been silently dead since offering_concept_stats.effective_explanations
existed, always persisting []. Delete the read and its now-noise seed
write in seed_local_rich.py; the column stays on its DB default per
the issue's own decision framing (no migration).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitaiBot commented Aug 23, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 28571d7b-4f4e-4961-a782-ac35fc3b540f

📥 Commits

Reviewing files that changed from the base of the PR and between 9f34454 and 2ad7002.

📒 Files selected for processing (3)
  • backend/db/seed_local_rich.py
  • backend/services/course_context_service.py
  • backend/tests/test_shared_course_context.py

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

The quiz-context aggregation now handles only common misconceptions and prerequisite gaps. Concept-statistics upserts and local seed rows omit effective_explanations. A regression test verifies the behavior.

Changes

Course context aggregation cleanup

Layer / File(s)Summary
Remove effective explanations handling
backend/services/course_context_service.py, backend/tests/test_shared_course_context.py, backend/db/seed_local_rich.py
The parser and upsert omit effective_explanations. The regression test verifies that the remaining fields are preserved. Local seed rows rely on the database default.

Estimated code review effort: 2 (Simple) | ~10 minutes

Merge Risk:⚪ Minimal · up to 2ad70

This localized cleanup stops emitting an unused empty field while preserving the database column and its default behavior; no actionable merge-blocking risk remains after normal checks and review.

Suggested reviewers:darkest-teddy, jose-gael-cruz-lopez

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check nameStatusExplanation
Linked Issues check✅ PassedThe changes implement issue #572 option 2 by removing the dead read and seed value while retaining the database column and default.
Out of Scope Changes check✅ PassedAll code changes support the linked issue and stated objective; no unrelated implementation changes are present.
Docstring Coverage✅ PassedDocstring check was indeterminate for this PR — some files could not be analyzed in time. Not blocking.
Description check✅ PassedThe description clearly explains the dead read, lists the code and seed changes, identifies issue #572, documents regression and suite testing, and includes reviewer notes. It uses equivalent headings…
Title check✅ PassedThe title clearly and concisely describes the main change: removing the unused effective_explanations read from quiz processing.
Full details: Description check

Explanation

The description clearly explains the dead read, lists the code and seed changes, identifies issue #572, documents regression and suite testing, and includes reviewer notes. It uses equivalent headings instead of the exact template headings, but the required information is present.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/572-drop-effective-explanations-read

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@cloudflare-workers-and-pages

cloudflare-workers-and-pagesBot commented Aug 23, 2026

Copy link
Copy Markdown

Deploying with Cloudflare Workers Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

StatusNameLatest CommitPreview URLUpdated (UTC)
✅ Deployment successful!
View logs
frontend-staging4b38b13Commit Preview URL

Branch Preview URL
Aug 26 2026, 05:27 AM

@supabase

supabaseBot commented Aug 23, 2026

Copy link
Copy Markdown

This pull request has been ignored for the connected project ybgqdonkoqftwrmweuyv because there are no changes detected in supabase directory. You can change this behaviour in Project Integrations Settings ↗︎.


Preview Branches by Supabase.
Learn more about Supabase Branching ↗︎.

/code-review on PR #587 (the effective_explanations dead-read deletion, #572)
reviewed the core deletion clean and turned up five in-PR nits + six
pre-existing debts. This lands the in-PR nits; the pre-existing debts are
filed as #595.
- F5 (tripwire): test_effective_explanations_never_emitted_even_when_source_has_it
pinned its premise (QuizContext never emits effective_explanations) only in
prose. Add the structural assertion (assertNotIn on QuizContext.model_fields)
so a future field-without-rollup regression goes red instead of just
documenting the drop as correct.
- F6/F7 (comment precision): the canonical #572 comment in
_parse_quiz_context_to_arrays overstated the DB default's coverage (only
true on a fresh INSERT — the on_conflict merge-duplicates UPDATE path never
touches the column, so an out-of-band value would persist) and omitted that
every stored context_json row also carries a server-stamped schema_version.
- F9 (prose dedup): the #572 story was told in full three times (the
service comment, the test docstring, db/seed_local_rich.py). Keep one
canonical telling at the deletion site; the other two are now one-line
pointers at it.
- F8/F10 (test-helper dedup): extended TestUpdateCourseContext._table_factory
with an optional quiz_rows param and converted all four ad hoc `_table`
dispatch closures (three pre-existing + the new tripwire test) to use it;
deleted the dead module-level _make_table_mock (zero call sites).
Refs #572. Follow-up: #595.
@AndresL230
AndresL230 merged commit f6ed004 into mainAug 26, 2026
8 checks passed
AndresL230 added a commit that referenced this pull request Aug 26, 2026
Brings in the include_answer_key default flip (#590), the dead
effective_explanations deletion (#587) and the CI port preflight (#588).
Clean auto-merge: main's routes/quiz.py hunks are in the generate
handler's response projection, this branch's are in the shared
gather/hoist above it.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

quiz: offering_concept_stats.effective_explanations is a dead read — no agent writes that key

1 participant

@AndresL230
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

chore(quiz): delete the dead effective_explanations read (#572) - #587

Merged
AndresL230 merged 2 commits into
mainfrom
chore/572-drop-effective-explanations-read
Aug 26, 2026
Merged

chore(quiz): delete the dead effective_explanations read (#572)#587
AndresL230 merged 2 commits into
mainfrom
chore/572-drop-effective-explanations-read

Conversation

@AndresL230

@AndresL230AndresL230 commented Aug 23, 2026

Copy link
Copy Markdown
Collaborator

Summary

services/course_context_service.py::_parse_quiz_context_to_arrays read
quiz_context.context_json's effective_explanations key alongside its two
legitimate siblings (common_mistakes, weak_areas) — but no writer
anywhere in the codebase (agents/quiz_context.py::QuizContext writes only
weak_areas/common_mistakes/questions_seen_summary/
recommended_difficulty/notes) ever produces that key. The read has been
silently dead since the column existed, meaning
offering_concept_stats.effective_explanations has persisted an
always-empty array for every offering — indistinguishable from "this class
produced no effective explanations" (the #548/#529 failure class, found by
the code review that specifically went looking for it, #554 H2).

Per the issue's own decision framing, this takes option 2: delete the
read
(option 1, making the field real, needs #558-style consent framing
before it can widen what class-derived text the tutor surfaces — out of
scope for a cleanup task).

  • Removed the effective_explanations accumulation from
    _parse_quiz_context_to_arrays (now returns a 2-tuple) and its write into
    the offering_concept_stats upsert.
  • Dropped the matching "effective_explanations": [] from
    db/seed_local_rich.py's seed — noise now that nothing reads it; the
    column's own DB default ('{}', unchanged in 0022_analytics.sql)
    produces the identical value.
  • No migration: the column stays, per the brief.

Grep verification

/usr/bin/grep -rn effective_explanations across backend/, frontend/src,
frontend/e2e, docs/ — every hit accounted for (full table in
task-8-report.md): 2 immutable migrations (kept, column stays), 2 docs
(kept, doc-historical/still-accurate), 5 code sites in
course_context_service.py + 1 in seed_local_rich.py (all deleted), zero
frontend or admin-analytics consumers.

Test plan

  • New regression test
    TestUpdateCourseContext::test_effective_explanations_never_emitted_even_when_source_has_it
    — plants the key in source data, asserts it's absent from the upsert
    payload. RED confirmed against pre-fix code, GREEN after.
  • venv/bin/ruff check . — All checks passed
  • Full backend suite: 2224 passed, 79 skipped

Closes#572

Lane runs (overnight 2026-08-23, local stack under the flock, function mode)

Merge-gate review (2026-08-26)

/code-review (medium) on this PR: the core deletion reviewed clean (5 angles). It also
surfaced 5 in-PR polish nits and 6 pre-existing debts in the touched function.

  • In-PR polish applied (commit 4b38b13): a structural tripwire assertion
    (assertNotIn("effective_explanations", QuizContext.model_fields)) so the regression test
    enforces its premise in code, not just prose; tightened two comments (the DB-default claim only
    holds on a fresh INSERT, not on the upsert's merge-duplicates UPDATE path; every stored
    context_json row also carries a server-stamped schema_version); deduplicated the quiz: offering_concept_stats.effective_explanations is a dead read — no agent writes that key #572 story to
    one canonical telling with two one-line pointers; extended the test's _table_factory helper and
    deleted a dead _make_table_mock. Full suite re-verified green (2224 passed / 79 skipped), ruff
    clean.
  • Pre-existing findings in update_course_context (not fixed here — out of scope for this cleanup):
    filed as course_context rollup: opt-out purge gap, silent-empty overwrite, unguarded legacy shapes, N+1 reads/writes #595 (opt-out purge gap on two early exits, a silent-empty catch whose overwrite can wipe
    previously-good aggregates on a transient failure, missing legacy-shape guards in the parse loop,
    and N+1 reads/writes in the per-concept loop).

Summary by CodeRabbit

  • Bug Fixes

    • Improved course-context aggregation by consistently relying on default explanation values.
    • Preserved common misconceptions and prerequisite gaps while preventing redundant explanation data from being stored.
  • Tests

    • Added regression coverage to verify correct course-context processing and database updates.

`_parse_quiz_context_to_arrays` read quiz_context.context_json's
effective_explanations key, but no writer (agents/quiz_context.py::
QuizContext writes weak_areas/common_mistakes/questions_seen_summary/
recommended_difficulty/notes only) ever produces it -- the read has
been silently dead since offering_concept_stats.effective_explanations
existed, always persisting []. Delete the read and its now-noise seed
write in seed_local_rich.py; the column stays on its DB default per
the issue's own decision framing (no migration).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitaiBot commented Aug 23, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 28571d7b-4f4e-4961-a782-ac35fc3b540f

📥 Commits

Reviewing files that changed from the base of the PR and between 9f34454 and 2ad7002.

📒 Files selected for processing (3)
  • backend/db/seed_local_rich.py
  • backend/services/course_context_service.py
  • backend/tests/test_shared_course_context.py

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

The quiz-context aggregation now handles only common misconceptions and prerequisite gaps. Concept-statistics upserts and local seed rows omit effective_explanations. A regression test verifies the behavior.

Changes

Course context aggregation cleanup

Layer / File(s)Summary
Remove effective explanations handling
backend/services/course_context_service.py, backend/tests/test_shared_course_context.py, backend/db/seed_local_rich.py
The parser and upsert omit effective_explanations. The regression test verifies that the remaining fields are preserved. Local seed rows rely on the database default.

Estimated code review effort: 2 (Simple) | ~10 minutes

Merge Risk:⚪ Minimal · up to 2ad70

This localized cleanup stops emitting an unused empty field while preserving the database column and its default behavior; no actionable merge-blocking risk remains after normal checks and review.

Suggested reviewers:darkest-teddy, jose-gael-cruz-lopez

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check nameStatusExplanation
Linked Issues check✅ PassedThe changes implement issue #572 option 2 by removing the dead read and seed value while retaining the database column and default.
Out of Scope Changes check✅ PassedAll code changes support the linked issue and stated objective; no unrelated implementation changes are present.
Docstring Coverage✅ PassedDocstring check was indeterminate for this PR — some files could not be analyzed in time. Not blocking.
Description check✅ PassedThe description clearly explains the dead read, lists the code and seed changes, identifies issue #572, documents regression and suite testing, and includes reviewer notes. It uses equivalent headings…
Title check✅ PassedThe title clearly and concisely describes the main change: removing the unused effective_explanations read from quiz processing.
Full details: Description check

Explanation

The description clearly explains the dead read, lists the code and seed changes, identifies issue #572, documents regression and suite testing, and includes reviewer notes. It uses equivalent headings instead of the exact template headings, but the required information is present.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/572-drop-effective-explanations-read

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@cloudflare-workers-and-pages

cloudflare-workers-and-pagesBot commented Aug 23, 2026

Copy link
Copy Markdown

Deploying with Cloudflare Workers Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

StatusNameLatest CommitPreview URLUpdated (UTC)
✅ Deployment successful!
View logs
frontend-staging4b38b13Commit Preview URL

Branch Preview URL
Aug 26 2026, 05:27 AM

@supabase

supabaseBot commented Aug 23, 2026

Copy link
Copy Markdown

This pull request has been ignored for the connected project ybgqdonkoqftwrmweuyv because there are no changes detected in supabase directory. You can change this behaviour in Project Integrations Settings ↗︎.


Preview Branches by Supabase.
Learn more about Supabase Branching ↗︎.

/code-review on PR #587 (the effective_explanations dead-read deletion, #572)
reviewed the core deletion clean and turned up five in-PR nits + six
pre-existing debts. This lands the in-PR nits; the pre-existing debts are
filed as #595.
- F5 (tripwire): test_effective_explanations_never_emitted_even_when_source_has_it
pinned its premise (QuizContext never emits effective_explanations) only in
prose. Add the structural assertion (assertNotIn on QuizContext.model_fields)
so a future field-without-rollup regression goes red instead of just
documenting the drop as correct.
- F6/F7 (comment precision): the canonical #572 comment in
_parse_quiz_context_to_arrays overstated the DB default's coverage (only
true on a fresh INSERT — the on_conflict merge-duplicates UPDATE path never
touches the column, so an out-of-band value would persist) and omitted that
every stored context_json row also carries a server-stamped schema_version.
- F9 (prose dedup): the #572 story was told in full three times (the
service comment, the test docstring, db/seed_local_rich.py). Keep one
canonical telling at the deletion site; the other two are now one-line
pointers at it.
- F8/F10 (test-helper dedup): extended TestUpdateCourseContext._table_factory
with an optional quiz_rows param and converted all four ad hoc `_table`
dispatch closures (three pre-existing + the new tripwire test) to use it;
deleted the dead module-level _make_table_mock (zero call sites).
Refs #572. Follow-up: #595.
@AndresL230
AndresL230 merged commit f6ed004 into mainAug 26, 2026
8 checks passed
AndresL230 added a commit that referenced this pull request Aug 26, 2026
Brings in the include_answer_key default flip (#590), the dead
effective_explanations deletion (#587) and the CI port preflight (#588).
Clean auto-merge: main's routes/quiz.py hunks are in the generate
handler's response projection, this branch's are in the shared
gather/hoist above it.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

quiz: offering_concept_stats.effective_explanations is a dead read — no agent writes that key

1 participant

@AndresL230
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

chore(quiz): delete the dead effective_explanations read (#572) - #587

Merged
AndresL230 merged 2 commits into
mainfrom
chore/572-drop-effective-explanations-read
Aug 26, 2026
Merged

chore(quiz): delete the dead effective_explanations read (#572)#587
AndresL230 merged 2 commits into
mainfrom
chore/572-drop-effective-explanations-read

Conversation

@AndresL230

@AndresL230AndresL230 commented Aug 23, 2026

Copy link
Copy Markdown
Collaborator

Summary

services/course_context_service.py::_parse_quiz_context_to_arrays read
quiz_context.context_json's effective_explanations key alongside its two
legitimate siblings (common_mistakes, weak_areas) — but no writer
anywhere in the codebase (agents/quiz_context.py::QuizContext writes only
weak_areas/common_mistakes/questions_seen_summary/
recommended_difficulty/notes) ever produces that key. The read has been
silently dead since the column existed, meaning
offering_concept_stats.effective_explanations has persisted an
always-empty array for every offering — indistinguishable from "this class
produced no effective explanations" (the #548/#529 failure class, found by
the code review that specifically went looking for it, #554 H2).

Per the issue's own decision framing, this takes option 2: delete the
read
(option 1, making the field real, needs #558-style consent framing
before it can widen what class-derived text the tutor surfaces — out of
scope for a cleanup task).

  • Removed the effective_explanations accumulation from
    _parse_quiz_context_to_arrays (now returns a 2-tuple) and its write into
    the offering_concept_stats upsert.
  • Dropped the matching "effective_explanations": [] from
    db/seed_local_rich.py's seed — noise now that nothing reads it; the
    column's own DB default ('{}', unchanged in 0022_analytics.sql)
    produces the identical value.
  • No migration: the column stays, per the brief.

Grep verification

/usr/bin/grep -rn effective_explanations across backend/, frontend/src,
frontend/e2e, docs/ — every hit accounted for (full table in
task-8-report.md): 2 immutable migrations (kept, column stays), 2 docs
(kept, doc-historical/still-accurate), 5 code sites in
course_context_service.py + 1 in seed_local_rich.py (all deleted), zero
frontend or admin-analytics consumers.

Test plan

  • New regression test
    TestUpdateCourseContext::test_effective_explanations_never_emitted_even_when_source_has_it
    — plants the key in source data, asserts it's absent from the upsert
    payload. RED confirmed against pre-fix code, GREEN after.
  • venv/bin/ruff check . — All checks passed
  • Full backend suite: 2224 passed, 79 skipped

Closes#572

Lane runs (overnight 2026-08-23, local stack under the flock, function mode)

Merge-gate review (2026-08-26)

/code-review (medium) on this PR: the core deletion reviewed clean (5 angles). It also
surfaced 5 in-PR polish nits and 6 pre-existing debts in the touched function.

  • In-PR polish applied (commit 4b38b13): a structural tripwire assertion
    (assertNotIn("effective_explanations", QuizContext.model_fields)) so the regression test
    enforces its premise in code, not just prose; tightened two comments (the DB-default claim only
    holds on a fresh INSERT, not on the upsert's merge-duplicates UPDATE path; every stored
    context_json row also carries a server-stamped schema_version); deduplicated the quiz: offering_concept_stats.effective_explanations is a dead read — no agent writes that key #572 story to
    one canonical telling with two one-line pointers; extended the test's _table_factory helper and
    deleted a dead _make_table_mock. Full suite re-verified green (2224 passed / 79 skipped), ruff
    clean.
  • Pre-existing findings in update_course_context (not fixed here — out of scope for this cleanup):
    filed as course_context rollup: opt-out purge gap, silent-empty overwrite, unguarded legacy shapes, N+1 reads/writes #595 (opt-out purge gap on two early exits, a silent-empty catch whose overwrite can wipe
    previously-good aggregates on a transient failure, missing legacy-shape guards in the parse loop,
    and N+1 reads/writes in the per-concept loop).

Summary by CodeRabbit

  • Bug Fixes

    • Improved course-context aggregation by consistently relying on default explanation values.
    • Preserved common misconceptions and prerequisite gaps while preventing redundant explanation data from being stored.
  • Tests

    • Added regression coverage to verify correct course-context processing and database updates.

`_parse_quiz_context_to_arrays` read quiz_context.context_json's
effective_explanations key, but no writer (agents/quiz_context.py::
QuizContext writes weak_areas/common_mistakes/questions_seen_summary/
recommended_difficulty/notes only) ever produces it -- the read has
been silently dead since offering_concept_stats.effective_explanations
existed, always persisting []. Delete the read and its now-noise seed
write in seed_local_rich.py; the column stays on its DB default per
the issue's own decision framing (no migration).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitaiBot commented Aug 23, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 28571d7b-4f4e-4961-a782-ac35fc3b540f

📥 Commits

Reviewing files that changed from the base of the PR and between 9f34454 and 2ad7002.

📒 Files selected for processing (3)
  • backend/db/seed_local_rich.py
  • backend/services/course_context_service.py
  • backend/tests/test_shared_course_context.py

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

The quiz-context aggregation now handles only common misconceptions and prerequisite gaps. Concept-statistics upserts and local seed rows omit effective_explanations. A regression test verifies the behavior.

Changes

Course context aggregation cleanup

Layer / File(s)Summary
Remove effective explanations handling
backend/services/course_context_service.py, backend/tests/test_shared_course_context.py, backend/db/seed_local_rich.py
The parser and upsert omit effective_explanations. The regression test verifies that the remaining fields are preserved. Local seed rows rely on the database default.

Estimated code review effort: 2 (Simple) | ~10 minutes

Merge Risk:⚪ Minimal · up to 2ad70

This localized cleanup stops emitting an unused empty field while preserving the database column and its default behavior; no actionable merge-blocking risk remains after normal checks and review.

Suggested reviewers:darkest-teddy, jose-gael-cruz-lopez

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check nameStatusExplanation
Linked Issues check✅ PassedThe changes implement issue #572 option 2 by removing the dead read and seed value while retaining the database column and default.
Out of Scope Changes check✅ PassedAll code changes support the linked issue and stated objective; no unrelated implementation changes are present.
Docstring Coverage✅ PassedDocstring check was indeterminate for this PR — some files could not be analyzed in time. Not blocking.
Description check✅ PassedThe description clearly explains the dead read, lists the code and seed changes, identifies issue #572, documents regression and suite testing, and includes reviewer notes. It uses equivalent headings…
Title check✅ PassedThe title clearly and concisely describes the main change: removing the unused effective_explanations read from quiz processing.
Full details: Description check

Explanation

The description clearly explains the dead read, lists the code and seed changes, identifies issue #572, documents regression and suite testing, and includes reviewer notes. It uses equivalent headings instead of the exact template headings, but the required information is present.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/572-drop-effective-explanations-read

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@cloudflare-workers-and-pages

cloudflare-workers-and-pagesBot commented Aug 23, 2026

Copy link
Copy Markdown

Deploying with Cloudflare Workers Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

StatusNameLatest CommitPreview URLUpdated (UTC)
✅ Deployment successful!
View logs
frontend-staging4b38b13Commit Preview URL

Branch Preview URL
Aug 26 2026, 05:27 AM

@supabase

supabaseBot commented Aug 23, 2026

Copy link
Copy Markdown

This pull request has been ignored for the connected project ybgqdonkoqftwrmweuyv because there are no changes detected in supabase directory. You can change this behaviour in Project Integrations Settings ↗︎.


Preview Branches by Supabase.
Learn more about Supabase Branching ↗︎.

/code-review on PR #587 (the effective_explanations dead-read deletion, #572)
reviewed the core deletion clean and turned up five in-PR nits + six
pre-existing debts. This lands the in-PR nits; the pre-existing debts are
filed as #595.
- F5 (tripwire): test_effective_explanations_never_emitted_even_when_source_has_it
pinned its premise (QuizContext never emits effective_explanations) only in
prose. Add the structural assertion (assertNotIn on QuizContext.model_fields)
so a future field-without-rollup regression goes red instead of just
documenting the drop as correct.
- F6/F7 (comment precision): the canonical #572 comment in
_parse_quiz_context_to_arrays overstated the DB default's coverage (only
true on a fresh INSERT — the on_conflict merge-duplicates UPDATE path never
touches the column, so an out-of-band value would persist) and omitted that
every stored context_json row also carries a server-stamped schema_version.
- F9 (prose dedup): the #572 story was told in full three times (the
service comment, the test docstring, db/seed_local_rich.py). Keep one
canonical telling at the deletion site; the other two are now one-line
pointers at it.
- F8/F10 (test-helper dedup): extended TestUpdateCourseContext._table_factory
with an optional quiz_rows param and converted all four ad hoc `_table`
dispatch closures (three pre-existing + the new tripwire test) to use it;
deleted the dead module-level _make_table_mock (zero call sites).
Refs #572. Follow-up: #595.
@AndresL230
AndresL230 merged commit f6ed004 into mainAug 26, 2026
8 checks passed
AndresL230 added a commit that referenced this pull request Aug 26, 2026
Brings in the include_answer_key default flip (#590), the dead
effective_explanations deletion (#587) and the CI port preflight (#588).
Clean auto-merge: main's routes/quiz.py hunks are in the generate
handler's response projection, this branch's are in the shared
gather/hoist above it.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

quiz: offering_concept_stats.effective_explanations is a dead read — no agent writes that key

1 participant

@AndresL230
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

chore(quiz): delete the dead effective_explanations read (#572) - #587

Merged
AndresL230 merged 2 commits into
mainfrom
chore/572-drop-effective-explanations-read
Aug 26, 2026
Merged

chore(quiz): delete the dead effective_explanations read (#572)#587
AndresL230 merged 2 commits into
mainfrom
chore/572-drop-effective-explanations-read

Conversation

@AndresL230

@AndresL230AndresL230 commented Aug 23, 2026

Copy link
Copy Markdown
Collaborator

Summary

services/course_context_service.py::_parse_quiz_context_to_arrays read
quiz_context.context_json's effective_explanations key alongside its two
legitimate siblings (common_mistakes, weak_areas) — but no writer
anywhere in the codebase (agents/quiz_context.py::QuizContext writes only
weak_areas/common_mistakes/questions_seen_summary/
recommended_difficulty/notes) ever produces that key. The read has been
silently dead since the column existed, meaning
offering_concept_stats.effective_explanations has persisted an
always-empty array for every offering — indistinguishable from "this class
produced no effective explanations" (the #548/#529 failure class, found by
the code review that specifically went looking for it, #554 H2).

Per the issue's own decision framing, this takes option 2: delete the
read
(option 1, making the field real, needs #558-style consent framing
before it can widen what class-derived text the tutor surfaces — out of
scope for a cleanup task).

  • Removed the effective_explanations accumulation from
    _parse_quiz_context_to_arrays (now returns a 2-tuple) and its write into
    the offering_concept_stats upsert.
  • Dropped the matching "effective_explanations": [] from
    db/seed_local_rich.py's seed — noise now that nothing reads it; the
    column's own DB default ('{}', unchanged in 0022_analytics.sql)
    produces the identical value.
  • No migration: the column stays, per the brief.

Grep verification

/usr/bin/grep -rn effective_explanations across backend/, frontend/src,
frontend/e2e, docs/ — every hit accounted for (full table in
task-8-report.md): 2 immutable migrations (kept, column stays), 2 docs
(kept, doc-historical/still-accurate), 5 code sites in
course_context_service.py + 1 in seed_local_rich.py (all deleted), zero
frontend or admin-analytics consumers.

Test plan

  • New regression test
    TestUpdateCourseContext::test_effective_explanations_never_emitted_even_when_source_has_it
    — plants the key in source data, asserts it's absent from the upsert
    payload. RED confirmed against pre-fix code, GREEN after.
  • venv/bin/ruff check . — All checks passed
  • Full backend suite: 2224 passed, 79 skipped

Closes#572

Lane runs (overnight 2026-08-23, local stack under the flock, function mode)

Merge-gate review (2026-08-26)

/code-review (medium) on this PR: the core deletion reviewed clean (5 angles). It also
surfaced 5 in-PR polish nits and 6 pre-existing debts in the touched function.

  • In-PR polish applied (commit 4b38b13): a structural tripwire assertion
    (assertNotIn("effective_explanations", QuizContext.model_fields)) so the regression test
    enforces its premise in code, not just prose; tightened two comments (the DB-default claim only
    holds on a fresh INSERT, not on the upsert's merge-duplicates UPDATE path; every stored
    context_json row also carries a server-stamped schema_version); deduplicated the quiz: offering_concept_stats.effective_explanations is a dead read — no agent writes that key #572 story to
    one canonical telling with two one-line pointers; extended the test's _table_factory helper and
    deleted a dead _make_table_mock. Full suite re-verified green (2224 passed / 79 skipped), ruff
    clean.
  • Pre-existing findings in update_course_context (not fixed here — out of scope for this cleanup):
    filed as course_context rollup: opt-out purge gap, silent-empty overwrite, unguarded legacy shapes, N+1 reads/writes #595 (opt-out purge gap on two early exits, a silent-empty catch whose overwrite can wipe
    previously-good aggregates on a transient failure, missing legacy-shape guards in the parse loop,
    and N+1 reads/writes in the per-concept loop).

Summary by CodeRabbit

  • Bug Fixes

    • Improved course-context aggregation by consistently relying on default explanation values.
    • Preserved common misconceptions and prerequisite gaps while preventing redundant explanation data from being stored.
  • Tests

    • Added regression coverage to verify correct course-context processing and database updates.

`_parse_quiz_context_to_arrays` read quiz_context.context_json's
effective_explanations key, but no writer (agents/quiz_context.py::
QuizContext writes weak_areas/common_mistakes/questions_seen_summary/
recommended_difficulty/notes only) ever produces it -- the read has
been silently dead since offering_concept_stats.effective_explanations
existed, always persisting []. Delete the read and its now-noise seed
write in seed_local_rich.py; the column stays on its DB default per
the issue's own decision framing (no migration).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitaiBot commented Aug 23, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 28571d7b-4f4e-4961-a782-ac35fc3b540f

📥 Commits

Reviewing files that changed from the base of the PR and between 9f34454 and 2ad7002.

📒 Files selected for processing (3)
  • backend/db/seed_local_rich.py
  • backend/services/course_context_service.py
  • backend/tests/test_shared_course_context.py

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

The quiz-context aggregation now handles only common misconceptions and prerequisite gaps. Concept-statistics upserts and local seed rows omit effective_explanations. A regression test verifies the behavior.

Changes

Course context aggregation cleanup

Layer / File(s)Summary
Remove effective explanations handling
backend/services/course_context_service.py, backend/tests/test_shared_course_context.py, backend/db/seed_local_rich.py
The parser and upsert omit effective_explanations. The regression test verifies that the remaining fields are preserved. Local seed rows rely on the database default.

Estimated code review effort: 2 (Simple) | ~10 minutes

Merge Risk:⚪ Minimal · up to 2ad70

This localized cleanup stops emitting an unused empty field while preserving the database column and its default behavior; no actionable merge-blocking risk remains after normal checks and review.

Suggested reviewers:darkest-teddy, jose-gael-cruz-lopez

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check nameStatusExplanation
Linked Issues check✅ PassedThe changes implement issue #572 option 2 by removing the dead read and seed value while retaining the database column and default.
Out of Scope Changes check✅ PassedAll code changes support the linked issue and stated objective; no unrelated implementation changes are present.
Docstring Coverage✅ PassedDocstring check was indeterminate for this PR — some files could not be analyzed in time. Not blocking.
Description check✅ PassedThe description clearly explains the dead read, lists the code and seed changes, identifies issue #572, documents regression and suite testing, and includes reviewer notes. It uses equivalent headings…
Title check✅ PassedThe title clearly and concisely describes the main change: removing the unused effective_explanations read from quiz processing.
Full details: Description check

Explanation

The description clearly explains the dead read, lists the code and seed changes, identifies issue #572, documents regression and suite testing, and includes reviewer notes. It uses equivalent headings instead of the exact template headings, but the required information is present.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/572-drop-effective-explanations-read

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@cloudflare-workers-and-pages

cloudflare-workers-and-pagesBot commented Aug 23, 2026

Copy link
Copy Markdown

Deploying with Cloudflare Workers Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

StatusNameLatest CommitPreview URLUpdated (UTC)
✅ Deployment successful!
View logs
frontend-staging4b38b13Commit Preview URL

Branch Preview URL
Aug 26 2026, 05:27 AM

@supabase

supabaseBot commented Aug 23, 2026

Copy link
Copy Markdown

This pull request has been ignored for the connected project ybgqdonkoqftwrmweuyv because there are no changes detected in supabase directory. You can change this behaviour in Project Integrations Settings ↗︎.


Preview Branches by Supabase.
Learn more about Supabase Branching ↗︎.

/code-review on PR #587 (the effective_explanations dead-read deletion, #572)
reviewed the core deletion clean and turned up five in-PR nits + six
pre-existing debts. This lands the in-PR nits; the pre-existing debts are
filed as #595.
- F5 (tripwire): test_effective_explanations_never_emitted_even_when_source_has_it
pinned its premise (QuizContext never emits effective_explanations) only in
prose. Add the structural assertion (assertNotIn on QuizContext.model_fields)
so a future field-without-rollup regression goes red instead of just
documenting the drop as correct.
- F6/F7 (comment precision): the canonical #572 comment in
_parse_quiz_context_to_arrays overstated the DB default's coverage (only
true on a fresh INSERT — the on_conflict merge-duplicates UPDATE path never
touches the column, so an out-of-band value would persist) and omitted that
every stored context_json row also carries a server-stamped schema_version.
- F9 (prose dedup): the #572 story was told in full three times (the
service comment, the test docstring, db/seed_local_rich.py). Keep one
canonical telling at the deletion site; the other two are now one-line
pointers at it.
- F8/F10 (test-helper dedup): extended TestUpdateCourseContext._table_factory
with an optional quiz_rows param and converted all four ad hoc `_table`
dispatch closures (three pre-existing + the new tripwire test) to use it;
deleted the dead module-level _make_table_mock (zero call sites).
Refs #572. Follow-up: #595.
@AndresL230
AndresL230 merged commit f6ed004 into mainAug 26, 2026
8 checks passed
AndresL230 added a commit that referenced this pull request Aug 26, 2026
Brings in the include_answer_key default flip (#590), the dead
effective_explanations deletion (#587) and the CI port preflight (#588).
Clean auto-merge: main's routes/quiz.py hunks are in the generate
handler's response projection, this branch's are in the shared
gather/hoist above it.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

quiz: offering_concept_stats.effective_explanations is a dead read — no agent writes that key

1 participant

@AndresL230
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

chore(quiz): delete the dead effective_explanations read (#572) - #587

Merged
AndresL230 merged 2 commits into
mainfrom
chore/572-drop-effective-explanations-read
Aug 26, 2026
Merged

chore(quiz): delete the dead effective_explanations read (#572)#587
AndresL230 merged 2 commits into
mainfrom
chore/572-drop-effective-explanations-read

Conversation

@AndresL230

@AndresL230AndresL230 commented Aug 23, 2026

Copy link
Copy Markdown
Collaborator

Summary

services/course_context_service.py::_parse_quiz_context_to_arrays read
quiz_context.context_json's effective_explanations key alongside its two
legitimate siblings (common_mistakes, weak_areas) — but no writer
anywhere in the codebase (agents/quiz_context.py::QuizContext writes only
weak_areas/common_mistakes/questions_seen_summary/
recommended_difficulty/notes) ever produces that key. The read has been
silently dead since the column existed, meaning
offering_concept_stats.effective_explanations has persisted an
always-empty array for every offering — indistinguishable from "this class
produced no effective explanations" (the #548/#529 failure class, found by
the code review that specifically went looking for it, #554 H2).

Per the issue's own decision framing, this takes option 2: delete the
read
(option 1, making the field real, needs #558-style consent framing
before it can widen what class-derived text the tutor surfaces — out of
scope for a cleanup task).

  • Removed the effective_explanations accumulation from
    _parse_quiz_context_to_arrays (now returns a 2-tuple) and its write into
    the offering_concept_stats upsert.
  • Dropped the matching "effective_explanations": [] from
    db/seed_local_rich.py's seed — noise now that nothing reads it; the
    column's own DB default ('{}', unchanged in 0022_analytics.sql)
    produces the identical value.
  • No migration: the column stays, per the brief.

Grep verification

/usr/bin/grep -rn effective_explanations across backend/, frontend/src,
frontend/e2e, docs/ — every hit accounted for (full table in
task-8-report.md): 2 immutable migrations (kept, column stays), 2 docs
(kept, doc-historical/still-accurate), 5 code sites in
course_context_service.py + 1 in seed_local_rich.py (all deleted), zero
frontend or admin-analytics consumers.

Test plan

  • New regression test
    TestUpdateCourseContext::test_effective_explanations_never_emitted_even_when_source_has_it
    — plants the key in source data, asserts it's absent from the upsert
    payload. RED confirmed against pre-fix code, GREEN after.
  • venv/bin/ruff check . — All checks passed
  • Full backend suite: 2224 passed, 79 skipped

Closes#572

Lane runs (overnight 2026-08-23, local stack under the flock, function mode)

Merge-gate review (2026-08-26)

/code-review (medium) on this PR: the core deletion reviewed clean (5 angles). It also
surfaced 5 in-PR polish nits and 6 pre-existing debts in the touched function.

  • In-PR polish applied (commit 4b38b13): a structural tripwire assertion
    (assertNotIn("effective_explanations", QuizContext.model_fields)) so the regression test
    enforces its premise in code, not just prose; tightened two comments (the DB-default claim only
    holds on a fresh INSERT, not on the upsert's merge-duplicates UPDATE path; every stored
    context_json row also carries a server-stamped schema_version); deduplicated the quiz: offering_concept_stats.effective_explanations is a dead read — no agent writes that key #572 story to
    one canonical telling with two one-line pointers; extended the test's _table_factory helper and
    deleted a dead _make_table_mock. Full suite re-verified green (2224 passed / 79 skipped), ruff
    clean.
  • Pre-existing findings in update_course_context (not fixed here — out of scope for this cleanup):
    filed as course_context rollup: opt-out purge gap, silent-empty overwrite, unguarded legacy shapes, N+1 reads/writes #595 (opt-out purge gap on two early exits, a silent-empty catch whose overwrite can wipe
    previously-good aggregates on a transient failure, missing legacy-shape guards in the parse loop,
    and N+1 reads/writes in the per-concept loop).

Summary by CodeRabbit

  • Bug Fixes

    • Improved course-context aggregation by consistently relying on default explanation values.
    • Preserved common misconceptions and prerequisite gaps while preventing redundant explanation data from being stored.
  • Tests

    • Added regression coverage to verify correct course-context processing and database updates.

`_parse_quiz_context_to_arrays` read quiz_context.context_json's
effective_explanations key, but no writer (agents/quiz_context.py::
QuizContext writes weak_areas/common_mistakes/questions_seen_summary/
recommended_difficulty/notes only) ever produces it -- the read has
been silently dead since offering_concept_stats.effective_explanations
existed, always persisting []. Delete the read and its now-noise seed
write in seed_local_rich.py; the column stays on its DB default per
the issue's own decision framing (no migration).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitaiBot commented Aug 23, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 28571d7b-4f4e-4961-a782-ac35fc3b540f

📥 Commits

Reviewing files that changed from the base of the PR and between 9f34454 and 2ad7002.

📒 Files selected for processing (3)
  • backend/db/seed_local_rich.py
  • backend/services/course_context_service.py
  • backend/tests/test_shared_course_context.py

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

The quiz-context aggregation now handles only common misconceptions and prerequisite gaps. Concept-statistics upserts and local seed rows omit effective_explanations. A regression test verifies the behavior.

Changes

Course context aggregation cleanup

Layer / File(s)Summary
Remove effective explanations handling
backend/services/course_context_service.py, backend/tests/test_shared_course_context.py, backend/db/seed_local_rich.py
The parser and upsert omit effective_explanations. The regression test verifies that the remaining fields are preserved. Local seed rows rely on the database default.

Estimated code review effort: 2 (Simple) | ~10 minutes

Merge Risk:⚪ Minimal · up to 2ad70

This localized cleanup stops emitting an unused empty field while preserving the database column and its default behavior; no actionable merge-blocking risk remains after normal checks and review.

Suggested reviewers:darkest-teddy, jose-gael-cruz-lopez

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check nameStatusExplanation
Linked Issues check✅ PassedThe changes implement issue #572 option 2 by removing the dead read and seed value while retaining the database column and default.
Out of Scope Changes check✅ PassedAll code changes support the linked issue and stated objective; no unrelated implementation changes are present.
Docstring Coverage✅ PassedDocstring check was indeterminate for this PR — some files could not be analyzed in time. Not blocking.
Description check✅ PassedThe description clearly explains the dead read, lists the code and seed changes, identifies issue #572, documents regression and suite testing, and includes reviewer notes. It uses equivalent headings…
Title check✅ PassedThe title clearly and concisely describes the main change: removing the unused effective_explanations read from quiz processing.
Full details: Description check

Explanation

The description clearly explains the dead read, lists the code and seed changes, identifies issue #572, documents regression and suite testing, and includes reviewer notes. It uses equivalent headings instead of the exact template headings, but the required information is present.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/572-drop-effective-explanations-read

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@cloudflare-workers-and-pages

cloudflare-workers-and-pagesBot commented Aug 23, 2026

Copy link
Copy Markdown

Deploying with Cloudflare Workers Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

StatusNameLatest CommitPreview URLUpdated (UTC)
✅ Deployment successful!
View logs
frontend-staging4b38b13Commit Preview URL

Branch Preview URL
Aug 26 2026, 05:27 AM

@supabase

supabaseBot commented Aug 23, 2026

Copy link
Copy Markdown

This pull request has been ignored for the connected project ybgqdonkoqftwrmweuyv because there are no changes detected in supabase directory. You can change this behaviour in Project Integrations Settings ↗︎.


Preview Branches by Supabase.
Learn more about Supabase Branching ↗︎.

/code-review on PR #587 (the effective_explanations dead-read deletion, #572)
reviewed the core deletion clean and turned up five in-PR nits + six
pre-existing debts. This lands the in-PR nits; the pre-existing debts are
filed as #595.
- F5 (tripwire): test_effective_explanations_never_emitted_even_when_source_has_it
pinned its premise (QuizContext never emits effective_explanations) only in
prose. Add the structural assertion (assertNotIn on QuizContext.model_fields)
so a future field-without-rollup regression goes red instead of just
documenting the drop as correct.
- F6/F7 (comment precision): the canonical #572 comment in
_parse_quiz_context_to_arrays overstated the DB default's coverage (only
true on a fresh INSERT — the on_conflict merge-duplicates UPDATE path never
touches the column, so an out-of-band value would persist) and omitted that
every stored context_json row also carries a server-stamped schema_version.
- F9 (prose dedup): the #572 story was told in full three times (the
service comment, the test docstring, db/seed_local_rich.py). Keep one
canonical telling at the deletion site; the other two are now one-line
pointers at it.
- F8/F10 (test-helper dedup): extended TestUpdateCourseContext._table_factory
with an optional quiz_rows param and converted all four ad hoc `_table`
dispatch closures (three pre-existing + the new tripwire test) to use it;
deleted the dead module-level _make_table_mock (zero call sites).
Refs #572. Follow-up: #595.
@AndresL230
AndresL230 merged commit f6ed004 into mainAug 26, 2026
8 checks passed
AndresL230 added a commit that referenced this pull request Aug 26, 2026
Brings in the include_answer_key default flip (#590), the dead
effective_explanations deletion (#587) and the CI port preflight (#588).
Clean auto-merge: main's routes/quiz.py hunks are in the generate
handler's response projection, this branch's are in the shared
gather/hoist above it.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

quiz: offering_concept_stats.effective_explanations is a dead read — no agent writes that key

1 participant

@AndresL230
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

chore(quiz): delete the dead effective_explanations read (#572) - #587

Merged
AndresL230 merged 2 commits into
mainfrom
chore/572-drop-effective-explanations-read
Aug 26, 2026
Merged

chore(quiz): delete the dead effective_explanations read (#572)#587
AndresL230 merged 2 commits into
mainfrom
chore/572-drop-effective-explanations-read

Conversation

@AndresL230

@AndresL230AndresL230 commented Aug 23, 2026

Copy link
Copy Markdown
Collaborator

Summary

services/course_context_service.py::_parse_quiz_context_to_arrays read
quiz_context.context_json's effective_explanations key alongside its two
legitimate siblings (common_mistakes, weak_areas) — but no writer
anywhere in the codebase (agents/quiz_context.py::QuizContext writes only
weak_areas/common_mistakes/questions_seen_summary/
recommended_difficulty/notes) ever produces that key. The read has been
silently dead since the column existed, meaning
offering_concept_stats.effective_explanations has persisted an
always-empty array for every offering — indistinguishable from "this class
produced no effective explanations" (the #548/#529 failure class, found by
the code review that specifically went looking for it, #554 H2).

Per the issue's own decision framing, this takes option 2: delete the
read
(option 1, making the field real, needs #558-style consent framing
before it can widen what class-derived text the tutor surfaces — out of
scope for a cleanup task).

  • Removed the effective_explanations accumulation from
    _parse_quiz_context_to_arrays (now returns a 2-tuple) and its write into
    the offering_concept_stats upsert.
  • Dropped the matching "effective_explanations": [] from
    db/seed_local_rich.py's seed — noise now that nothing reads it; the
    column's own DB default ('{}', unchanged in 0022_analytics.sql)
    produces the identical value.
  • No migration: the column stays, per the brief.

Grep verification

/usr/bin/grep -rn effective_explanations across backend/, frontend/src,
frontend/e2e, docs/ — every hit accounted for (full table in
task-8-report.md): 2 immutable migrations (kept, column stays), 2 docs
(kept, doc-historical/still-accurate), 5 code sites in
course_context_service.py + 1 in seed_local_rich.py (all deleted), zero
frontend or admin-analytics consumers.

Test plan

  • New regression test
    TestUpdateCourseContext::test_effective_explanations_never_emitted_even_when_source_has_it
    — plants the key in source data, asserts it's absent from the upsert
    payload. RED confirmed against pre-fix code, GREEN after.
  • venv/bin/ruff check . — All checks passed
  • Full backend suite: 2224 passed, 79 skipped

Closes#572

Lane runs (overnight 2026-08-23, local stack under the flock, function mode)

Merge-gate review (2026-08-26)

/code-review (medium) on this PR: the core deletion reviewed clean (5 angles). It also
surfaced 5 in-PR polish nits and 6 pre-existing debts in the touched function.

  • In-PR polish applied (commit 4b38b13): a structural tripwire assertion
    (assertNotIn("effective_explanations", QuizContext.model_fields)) so the regression test
    enforces its premise in code, not just prose; tightened two comments (the DB-default claim only
    holds on a fresh INSERT, not on the upsert's merge-duplicates UPDATE path; every stored
    context_json row also carries a server-stamped schema_version); deduplicated the quiz: offering_concept_stats.effective_explanations is a dead read — no agent writes that key #572 story to
    one canonical telling with two one-line pointers; extended the test's _table_factory helper and
    deleted a dead _make_table_mock. Full suite re-verified green (2224 passed / 79 skipped), ruff
    clean.
  • Pre-existing findings in update_course_context (not fixed here — out of scope for this cleanup):
    filed as course_context rollup: opt-out purge gap, silent-empty overwrite, unguarded legacy shapes, N+1 reads/writes #595 (opt-out purge gap on two early exits, a silent-empty catch whose overwrite can wipe
    previously-good aggregates on a transient failure, missing legacy-shape guards in the parse loop,
    and N+1 reads/writes in the per-concept loop).

Summary by CodeRabbit

  • Bug Fixes

    • Improved course-context aggregation by consistently relying on default explanation values.
    • Preserved common misconceptions and prerequisite gaps while preventing redundant explanation data from being stored.
  • Tests

    • Added regression coverage to verify correct course-context processing and database updates.

`_parse_quiz_context_to_arrays` read quiz_context.context_json's
effective_explanations key, but no writer (agents/quiz_context.py::
QuizContext writes weak_areas/common_mistakes/questions_seen_summary/
recommended_difficulty/notes only) ever produces it -- the read has
been silently dead since offering_concept_stats.effective_explanations
existed, always persisting []. Delete the read and its now-noise seed
write in seed_local_rich.py; the column stays on its DB default per
the issue's own decision framing (no migration).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitaiBot commented Aug 23, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 28571d7b-4f4e-4961-a782-ac35fc3b540f

📥 Commits

Reviewing files that changed from the base of the PR and between 9f34454 and 2ad7002.

📒 Files selected for processing (3)
  • backend/db/seed_local_rich.py
  • backend/services/course_context_service.py
  • backend/tests/test_shared_course_context.py

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

The quiz-context aggregation now handles only common misconceptions and prerequisite gaps. Concept-statistics upserts and local seed rows omit effective_explanations. A regression test verifies the behavior.

Changes

Course context aggregation cleanup

Layer / File(s)Summary
Remove effective explanations handling
backend/services/course_context_service.py, backend/tests/test_shared_course_context.py, backend/db/seed_local_rich.py
The parser and upsert omit effective_explanations. The regression test verifies that the remaining fields are preserved. Local seed rows rely on the database default.

Estimated code review effort: 2 (Simple) | ~10 minutes

Merge Risk:⚪ Minimal · up to 2ad70

This localized cleanup stops emitting an unused empty field while preserving the database column and its default behavior; no actionable merge-blocking risk remains after normal checks and review.

Suggested reviewers:darkest-teddy, jose-gael-cruz-lopez

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check nameStatusExplanation
Linked Issues check✅ PassedThe changes implement issue #572 option 2 by removing the dead read and seed value while retaining the database column and default.
Out of Scope Changes check✅ PassedAll code changes support the linked issue and stated objective; no unrelated implementation changes are present.
Docstring Coverage✅ PassedDocstring check was indeterminate for this PR — some files could not be analyzed in time. Not blocking.
Description check✅ PassedThe description clearly explains the dead read, lists the code and seed changes, identifies issue #572, documents regression and suite testing, and includes reviewer notes. It uses equivalent headings…
Title check✅ PassedThe title clearly and concisely describes the main change: removing the unused effective_explanations read from quiz processing.
Full details: Description check

Explanation

The description clearly explains the dead read, lists the code and seed changes, identifies issue #572, documents regression and suite testing, and includes reviewer notes. It uses equivalent headings instead of the exact template headings, but the required information is present.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/572-drop-effective-explanations-read

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@cloudflare-workers-and-pages

cloudflare-workers-and-pagesBot commented Aug 23, 2026

Copy link
Copy Markdown

Deploying with Cloudflare Workers Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

StatusNameLatest CommitPreview URLUpdated (UTC)
✅ Deployment successful!
View logs
frontend-staging4b38b13Commit Preview URL

Branch Preview URL
Aug 26 2026, 05:27 AM

@supabase

supabaseBot commented Aug 23, 2026

Copy link
Copy Markdown

This pull request has been ignored for the connected project ybgqdonkoqftwrmweuyv because there are no changes detected in supabase directory. You can change this behaviour in Project Integrations Settings ↗︎.


Preview Branches by Supabase.
Learn more about Supabase Branching ↗︎.

/code-review on PR #587 (the effective_explanations dead-read deletion, #572)
reviewed the core deletion clean and turned up five in-PR nits + six
pre-existing debts. This lands the in-PR nits; the pre-existing debts are
filed as #595.
- F5 (tripwire): test_effective_explanations_never_emitted_even_when_source_has_it
pinned its premise (QuizContext never emits effective_explanations) only in
prose. Add the structural assertion (assertNotIn on QuizContext.model_fields)
so a future field-without-rollup regression goes red instead of just
documenting the drop as correct.
- F6/F7 (comment precision): the canonical #572 comment in
_parse_quiz_context_to_arrays overstated the DB default's coverage (only
true on a fresh INSERT — the on_conflict merge-duplicates UPDATE path never
touches the column, so an out-of-band value would persist) and omitted that
every stored context_json row also carries a server-stamped schema_version.
- F9 (prose dedup): the #572 story was told in full three times (the
service comment, the test docstring, db/seed_local_rich.py). Keep one
canonical telling at the deletion site; the other two are now one-line
pointers at it.
- F8/F10 (test-helper dedup): extended TestUpdateCourseContext._table_factory
with an optional quiz_rows param and converted all four ad hoc `_table`
dispatch closures (three pre-existing + the new tripwire test) to use it;
deleted the dead module-level _make_table_mock (zero call sites).
Refs #572. Follow-up: #595.
@AndresL230
AndresL230 merged commit f6ed004 into mainAug 26, 2026
8 checks passed
AndresL230 added a commit that referenced this pull request Aug 26, 2026
Brings in the include_answer_key default flip (#590), the dead
effective_explanations deletion (#587) and the CI port preflight (#588).
Clean auto-merge: main's routes/quiz.py hunks are in the generate
handler's response projection, this branch's are in the shared
gather/hoist above it.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

quiz: offering_concept_stats.effective_explanations is a dead read — no agent writes that key

1 participant

@AndresL230
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

chore(quiz): delete the dead effective_explanations read (#572) - #587

Merged
AndresL230 merged 2 commits into
mainfrom
chore/572-drop-effective-explanations-read
Aug 26, 2026
Merged

chore(quiz): delete the dead effective_explanations read (#572)#587
AndresL230 merged 2 commits into
mainfrom
chore/572-drop-effective-explanations-read

Conversation

@AndresL230

@AndresL230AndresL230 commented Aug 23, 2026

Copy link
Copy Markdown
Collaborator

Summary

services/course_context_service.py::_parse_quiz_context_to_arrays read
quiz_context.context_json's effective_explanations key alongside its two
legitimate siblings (common_mistakes, weak_areas) — but no writer
anywhere in the codebase (agents/quiz_context.py::QuizContext writes only
weak_areas/common_mistakes/questions_seen_summary/
recommended_difficulty/notes) ever produces that key. The read has been
silently dead since the column existed, meaning
offering_concept_stats.effective_explanations has persisted an
always-empty array for every offering — indistinguishable from "this class
produced no effective explanations" (the #548/#529 failure class, found by
the code review that specifically went looking for it, #554 H2).

Per the issue's own decision framing, this takes option 2: delete the
read
(option 1, making the field real, needs #558-style consent framing
before it can widen what class-derived text the tutor surfaces — out of
scope for a cleanup task).

  • Removed the effective_explanations accumulation from
    _parse_quiz_context_to_arrays (now returns a 2-tuple) and its write into
    the offering_concept_stats upsert.
  • Dropped the matching "effective_explanations": [] from
    db/seed_local_rich.py's seed — noise now that nothing reads it; the
    column's own DB default ('{}', unchanged in 0022_analytics.sql)
    produces the identical value.
  • No migration: the column stays, per the brief.

Grep verification

/usr/bin/grep -rn effective_explanations across backend/, frontend/src,
frontend/e2e, docs/ — every hit accounted for (full table in
task-8-report.md): 2 immutable migrations (kept, column stays), 2 docs
(kept, doc-historical/still-accurate), 5 code sites in
course_context_service.py + 1 in seed_local_rich.py (all deleted), zero
frontend or admin-analytics consumers.

Test plan

  • New regression test
    TestUpdateCourseContext::test_effective_explanations_never_emitted_even_when_source_has_it
    — plants the key in source data, asserts it's absent from the upsert
    payload. RED confirmed against pre-fix code, GREEN after.
  • venv/bin/ruff check . — All checks passed
  • Full backend suite: 2224 passed, 79 skipped

Closes#572

Lane runs (overnight 2026-08-23, local stack under the flock, function mode)

Merge-gate review (2026-08-26)

/code-review (medium) on this PR: the core deletion reviewed clean (5 angles). It also
surfaced 5 in-PR polish nits and 6 pre-existing debts in the touched function.

  • In-PR polish applied (commit 4b38b13): a structural tripwire assertion
    (assertNotIn("effective_explanations", QuizContext.model_fields)) so the regression test
    enforces its premise in code, not just prose; tightened two comments (the DB-default claim only
    holds on a fresh INSERT, not on the upsert's merge-duplicates UPDATE path; every stored
    context_json row also carries a server-stamped schema_version); deduplicated the quiz: offering_concept_stats.effective_explanations is a dead read — no agent writes that key #572 story to
    one canonical telling with two one-line pointers; extended the test's _table_factory helper and
    deleted a dead _make_table_mock. Full suite re-verified green (2224 passed / 79 skipped), ruff
    clean.
  • Pre-existing findings in update_course_context (not fixed here — out of scope for this cleanup):
    filed as course_context rollup: opt-out purge gap, silent-empty overwrite, unguarded legacy shapes, N+1 reads/writes #595 (opt-out purge gap on two early exits, a silent-empty catch whose overwrite can wipe
    previously-good aggregates on a transient failure, missing legacy-shape guards in the parse loop,
    and N+1 reads/writes in the per-concept loop).

Summary by CodeRabbit

  • Bug Fixes

    • Improved course-context aggregation by consistently relying on default explanation values.
    • Preserved common misconceptions and prerequisite gaps while preventing redundant explanation data from being stored.
  • Tests

    • Added regression coverage to verify correct course-context processing and database updates.

`_parse_quiz_context_to_arrays` read quiz_context.context_json's
effective_explanations key, but no writer (agents/quiz_context.py::
QuizContext writes weak_areas/common_mistakes/questions_seen_summary/
recommended_difficulty/notes only) ever produces it -- the read has
been silently dead since offering_concept_stats.effective_explanations
existed, always persisting []. Delete the read and its now-noise seed
write in seed_local_rich.py; the column stays on its DB default per
the issue's own decision framing (no migration).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitaiBot commented Aug 23, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 28571d7b-4f4e-4961-a782-ac35fc3b540f

📥 Commits

Reviewing files that changed from the base of the PR and between 9f34454 and 2ad7002.

📒 Files selected for processing (3)
  • backend/db/seed_local_rich.py
  • backend/services/course_context_service.py
  • backend/tests/test_shared_course_context.py

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

The quiz-context aggregation now handles only common misconceptions and prerequisite gaps. Concept-statistics upserts and local seed rows omit effective_explanations. A regression test verifies the behavior.

Changes

Course context aggregation cleanup

Layer / File(s)Summary
Remove effective explanations handling
backend/services/course_context_service.py, backend/tests/test_shared_course_context.py, backend/db/seed_local_rich.py
The parser and upsert omit effective_explanations. The regression test verifies that the remaining fields are preserved. Local seed rows rely on the database default.

Estimated code review effort: 2 (Simple) | ~10 minutes

Merge Risk:⚪ Minimal · up to 2ad70

This localized cleanup stops emitting an unused empty field while preserving the database column and its default behavior; no actionable merge-blocking risk remains after normal checks and review.

Suggested reviewers:darkest-teddy, jose-gael-cruz-lopez

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check nameStatusExplanation
Linked Issues check✅ PassedThe changes implement issue #572 option 2 by removing the dead read and seed value while retaining the database column and default.
Out of Scope Changes check✅ PassedAll code changes support the linked issue and stated objective; no unrelated implementation changes are present.
Docstring Coverage✅ PassedDocstring check was indeterminate for this PR — some files could not be analyzed in time. Not blocking.
Description check✅ PassedThe description clearly explains the dead read, lists the code and seed changes, identifies issue #572, documents regression and suite testing, and includes reviewer notes. It uses equivalent headings…
Title check✅ PassedThe title clearly and concisely describes the main change: removing the unused effective_explanations read from quiz processing.
Full details: Description check

Explanation

The description clearly explains the dead read, lists the code and seed changes, identifies issue #572, documents regression and suite testing, and includes reviewer notes. It uses equivalent headings instead of the exact template headings, but the required information is present.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/572-drop-effective-explanations-read

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@cloudflare-workers-and-pages

cloudflare-workers-and-pagesBot commented Aug 23, 2026

Copy link
Copy Markdown

Deploying with Cloudflare Workers Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

StatusNameLatest CommitPreview URLUpdated (UTC)
✅ Deployment successful!
View logs
frontend-staging4b38b13Commit Preview URL

Branch Preview URL
Aug 26 2026, 05:27 AM

@supabase

supabaseBot commented Aug 23, 2026

Copy link
Copy Markdown

This pull request has been ignored for the connected project ybgqdonkoqftwrmweuyv because there are no changes detected in supabase directory. You can change this behaviour in Project Integrations Settings ↗︎.


Preview Branches by Supabase.
Learn more about Supabase Branching ↗︎.

/code-review on PR #587 (the effective_explanations dead-read deletion, #572)
reviewed the core deletion clean and turned up five in-PR nits + six
pre-existing debts. This lands the in-PR nits; the pre-existing debts are
filed as #595.
- F5 (tripwire): test_effective_explanations_never_emitted_even_when_source_has_it
pinned its premise (QuizContext never emits effective_explanations) only in
prose. Add the structural assertion (assertNotIn on QuizContext.model_fields)
so a future field-without-rollup regression goes red instead of just
documenting the drop as correct.
- F6/F7 (comment precision): the canonical #572 comment in
_parse_quiz_context_to_arrays overstated the DB default's coverage (only
true on a fresh INSERT — the on_conflict merge-duplicates UPDATE path never
touches the column, so an out-of-band value would persist) and omitted that
every stored context_json row also carries a server-stamped schema_version.
- F9 (prose dedup): the #572 story was told in full three times (the
service comment, the test docstring, db/seed_local_rich.py). Keep one
canonical telling at the deletion site; the other two are now one-line
pointers at it.
- F8/F10 (test-helper dedup): extended TestUpdateCourseContext._table_factory
with an optional quiz_rows param and converted all four ad hoc `_table`
dispatch closures (three pre-existing + the new tripwire test) to use it;
deleted the dead module-level _make_table_mock (zero call sites).
Refs #572. Follow-up: #595.
@AndresL230
AndresL230 merged commit f6ed004 into mainAug 26, 2026
8 checks passed
AndresL230 added a commit that referenced this pull request Aug 26, 2026
Brings in the include_answer_key default flip (#590), the dead
effective_explanations deletion (#587) and the CI port preflight (#588).
Clean auto-merge: main's routes/quiz.py hunks are in the generate
handler's response projection, this branch's are in the shared
gather/hoist above it.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

quiz: offering_concept_stats.effective_explanations is a dead read — no agent writes that key

1 participant

@AndresL230