1
0

4 Commits

Author SHA1 Message Date
46f7f55633 Phase 6: participation grading, gradebook passback, opt-out integrity
Ports the timing-neutral foregone-participation grading scheme from
participation_grades.R: answer quality (per-course level points) minus
a deduction for participation foregone through unavailability,
estimated by Monte Carlo simulation of the actual weighted draw and
averaged over when absences fall, plus a small form-filing incentive
for drawn-while-absent-without-opt-out days. Reason-blind and
luck-protected; zero-answer students floor to 0. Parameters
(allowance in SD units, passing line, form penalty, simulation
size/seed) are course settings. Verified against the R engine's
rendered 2026q2 reports via the new import-legacy command: quality and
availability match exactly, finals within Monte Carlo noise; dropped
students import as inactive enrollments and are excluded identically.

Grades are computed on demand into stored GradeRun snapshots and
reviewed on a grades page with CSV export and per-student reports
(also served to students via a publish toggle). Display scales map
points to UW 4.0, a threshold table (one-click import of the Canvas
course grading scheme), or raw points. Gradebook passback via AGS
sits behind a settings toggle with a review-then-push flow.

Opt-out withdrawals are now soft-deletes with a withdrawn_at audit
trail, and close when class begins (class days gained optional start
times), so availability records cannot be rewritten after the fact.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-31 18:38:22 -07:00
7ec1be5dc6 Phase 5: reporting, exports, pronouns, and roster freshness
Instructor participation report: per-student histograms, outcome mix
by class day, and a sortable table including the fairness ratio
(answered calls over questions present for, with opt-out days out of
the denominator), plus CSV exports of students, calls, and opt-outs.

Assessment scales are now per-course data: ordered levels with labels
and points out of 100 (defaults carry the old R grading values), with
calls referencing levels by id so renames follow through to history.
Renaming, re-pointing, reordering, and adding levels are always
allowed; deleting a level in use by recorded calls is blocked.

Pronouns and course term dates come from Canvas custom variable
substitutions, at launch and roster-wide via rlid-scoped NRPS; the
student page notes that names/pronouns are Canvas-sourced. Rosters
can also be refreshed outside launches: a "Sync roster now" button
and a sync-rosters CLI command for an hourly cron job, skipping ended
courses. Alembic now runs SQLite-compatible batch migrations with a
constraint naming convention.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-31 17:05:34 -07:00
7845167ec5 Phase 4: student views, opt-outs, and class schedule
Student page with a standing summary, a class-comparison histogram
(zero-dependency HTML/CSS) with a plain-language fewer/same/more
sentence, opt-out management with withdrawal of future dates, and a
call history that respects the per-course assessment-visibility
setting and never shows pending or skipped calls. Opt-outs validate
against a new per-course class-day schedule (range generator plus
individual add/remove for holidays), since Canvas has no structured
meeting-day data; courses without a schedule fall back to a free date
picker. Dev mode seeds a Tue/Thu pattern.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-31 16:44:49 -07:00
8d8a463f81 Phase 1: scaffold, data models, selection logic, tests
Flask application skeleton with SQLAlchemy models for courses (including
per-course settings), students, enrollments, opt-outs, and calls; the
weighted and cycle selection logic ported from the manual coldcall
scripts; alembic migrations; and a pytest suite covering selection
behavior and the model query helpers.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-31 16:27:09 -07:00