Skip to content

Fix bugs from the repo audit: event order, stale data after untrack, reset/export gaps - #98

Merged
Maharsh17 merged 2 commits into
mainfrom
audit-fixes
Sep 25, 2026
Merged

Maharsh17 merged 2 commits into
mainfrom
audit-fixes

Conversation

@Maharsh17

Copy link
Copy Markdown
Member

Fixes from a full audit of the repo (backend, pipeline, frontend, prod data).

High

  • Live events were processed newest-first. Prod's page_by_time is newest-first (like page_student), and drain persisted and routed in page order. In prod, 303 of 503 consecutive vex_log rows go back in time. So a tick with several events fed the worker backwards: a playgroundData outcome could attach to the wrong run, runs in one tick were numbered newest-first, and episodes scrambled. Drain now collects its pages and sorts oldest-first before persisting and routing.
  • Untracking left stale goal evidence. Purging a student from the last board deleted vex_log, state and triggers but not goal_profile or switch_event, so a re-add mixed old goal runs into the rebuilt ones.

Medium

  • Goal profiles are written after student_state, with no change signal of their own, so an open sheet could refetch before the newest run's evidence landed. goal_profile now bumps the states channel.
  • Reset (from Stable run numbers across backfills and restarts; Reset clears the whole student tile #97) hid alerts that are still open; the feed now keeps open ones.
  • The CSV export (and the reset backup) left out goal_profile.
  • Resuming a paused board while another board was live left a permanent gap for its students (the shared cursor moved on). Resume now re-backfills that board's students.

Low

  • A transient failure blanked notes, trigger history or the student sheet; now the last good data stays (switching students still clears).

Every backend fix has a regression test in tests/test_audit_fixes.py that failed before the fix. Backend 262 passed, ruff clean; frontend 49 passed; build OK.

Not changed (design questions): dismissing an identity switch is global rather than per board, and the trigger on/off config is global.

🤖 Generated with Claude Code

- Drain sorts prod's newest-first pages oldest-first before persisting and
  routing, so workers see events in order (outcomes landed on the wrong run,
  runs in one tick were numbered backwards, episodes scrambled).
- Untracking a student from the last board also purges their goal profiles and
  switches, so a re-add no longer mixes in stale goal runs.
- Goal profile writes signal the states channel, so an open sheet stops showing
  the previous evidence for the newest run.
- Reset keeps alerts that are still open (current state, not history).
- The CSV export, and so the reset backup, includes goal evidence.
- Resuming a paused board re-backfills its students to fill the pause gap.
- A failed notes/history/detail fetch keeps the last good data instead of
  blanking; switching students still clears.
@Maharsh17
Maharsh17 merged commit ee1060b into main Sep 25, 2026
2 checks passed
Sign up for free to 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.

1 participant