• v0.1.8 ec6fcc64bc

    cloudinit-bot released this 2026-08-04 11:43:39 +00:00 | -2 commits to main since this release

    v0.1.8 — v0.4 Phase 2: Cohort Dashboard + Aggregation

    Milestone: v0.4 (Operator tier — cohort dashboard, auth, Postgres)
    Phase: 2 (cohort dashboard + aggregation — feature)
    Previous: v0.1.7 (phase 1 — operator foundation)

    What's in this release

    Cohort aggregation pipeline + auth-gated operator API + React cohort dashboard with 3 k-anonymized views.

    Requirements Covered (4)

    REQ-ID Requirement
    REQ-DASH-01 Cohort dashboard — 3 views (practice/mastery/failure-patterns), React, k-anon ≥10
    REQ-NFR-DASH-01 k-anonymity ≥ 10 enforced (write-time suppression, display, e2e test)
    REQ-NFR-DASH-02 Freshness ≤ 24h (nightly reconcile + on-session-end hook)
    REQ-MT-02 Cohort aggregation pipeline (hook + nightly + k-anon suppression)

    Key features

    • Aggregation pipeline: async fire-and-forget on-session-end hook (non-blocking, C-8) + nightly reconciliation at 03:00 CT; k-anonymity ≥ 10 write-time suppression (cell_suppressed=TRUE, value=NULL for cells < 10); idempotent upsert; no raw PII in Postgres
    • 4 operator API endpoints (auth-gated): GET /api/operator/cohort (practice volume), /mastery (progression), /failure-patterns, GET+POST /credentials (VC management)
    • React cohort dashboard: BrowserRouter for /operator/*, login form, dashboard shell with auth gate (GET /api/operator/me on mount), 3 k-anonymized view components, inline SVG sparklines (zero-dep), suppressed-cell display ("— (<10 learners)"), freshness indicator
    • SPA fallback: SpaStaticFiles custom subclass (G-041 binding) — NOT a catch-all route; serves index.html for client-side routes; API routes + StaticFiles assets unaffected; voice UI at / unchanged
    • G-038 differencing-attack test: 10 learners in window A, 9 in B → B suppressed, dropped learner not recoverable via subtraction (unit + API e2e)

    Tests

    317 passed, 36 skipped (Postgres-requiring), 0 failed (Python)
    17/17 vitest passed (Dashboard auth gate, login, sparkline, suppressedLabel, formatFreshness, no-PII)
    npm build + typecheck clean

    Grill MUSTs honored (2/2 P2-applicable)

    • G-038: differencing-attack test (unit + API e2e)
    • G-041: SPA fallback via custom StaticFiles subclass (not catch-all route)

    P1+ flagged for P3 review (4)

    • Credential revocation audit log (operator_id of revoker)
    • Nightly scheduler timezone (UTC-5 vs true DST)
    • Aggregation in-memory cache lost on restart
    • set_credential_status f-string interpolation (code smell)

    Next

    v0.1.9 (P3 — final review + audit + milestone ship to main = v0.4 milestone release)

    Downloads