Files
praxis/server
Praxis CI c396ded395 feat(P02): SLICE-07 cohort aggregation pipeline — k-anon, hook, nightly
TASK-07-01: server/cohort/aggregator.py — aggregate_session with k-anon
  write-time suppression (D-034, K_ANON_THRESHOLD=10), idempotent upsert,
  7-day rolling window, multiple metrics (sessions_count, active_learners,
  gate_open_rate, median_mastery_score, rubric_criterion_means,
  failure_mode_frequency, branch distribution). No PII in aggregates (D-031).
TASK-07-02: server/cohort/hook.py — on_session_end fire-and-forget (D-054),
  no-op when no Postgres, failures log + nightly reconciles.
TASK-07-03: server/cohort/nightly.py — NightlyScheduler in-process asyncio
  loop, 03:00 CT (America/Winnipeg approx), reconcile from mastery_gate_events,
  R-DASH-04 failure handling.
TASK-07-04: session_recorder.py — chain aggregation hook after mastery flow
  via asyncio.create_task (parallel, off voice path, D-054).
TASK-07-05: tests/test_cohort_aggregation.py — k-anon threshold (9/10/11),
  idempotent, 7-day window, metrics, no PII.
TASK-07-06: tests/test_cohort_nightly.py — scheduler timing, reconciliation,
  hook-failure+nightly recovery, R-DASH-04.
G-038 (binding): differencing-attack test — 10 learners window A, 9 in B,
  verify dropped learner cannot be isolated (B suppressed, value=NULL).

---ci---
project: praxis
phase: 2
milestone: v0.4
status: execute
persona: backend-engineer
task: 07-01..07-06
requirements:
  covered: [REQ-MT-02, REQ-NFR-DASH-02, REQ-NFR-DASH-01]
---/ci---
2026-08-04 02:01:06 +00:00
..