Training (LMS)
Annual compliance training is not just ineffective. In high-stakes domains, it is actively dangerous.
>
Ebbinghaus published the forgetting curve in 1885. Humans forget approximately 70% of new information within a week without reinforcement. Annual training is designed around the assumption that this curve doesn't exist.
The Training module replaces annual compliance training with daily 60-second micro-assessment, EMA-scored, with the teaching moment surfaced immediately on every wrong answer. Compliance is a knowledge state, measured daily — not a training event measured annually.
The entities
Six, mirroring agicore-examples/accelerando/lms/accelerando_lms.agi:
- ComplianceDomain — registry of regulatory topics with passing + critical score thresholds (HIPAA Privacy, OSHA, Cybersecurity Awareness, etc.)
- Question — scenario-based MCQ with the teaching-moment
explanationfield - LearnerProfile — per-learner streak, points, overall_compliance, department, role
- ComplianceScore — per-learner per-domain knowledge score (the real metric)
- DailyAssessment — the daily-3 event with status / streak / points
- AssessmentResponse — per-question audit row (immutable)
Deferred: TrainingModule (refresher content), RefresherAssignment (triggered remediation), ComplianceBadge (gamification), DepartmentCompliance (rollup). All extend the spine without redesigning it.
The math — src/lms.ts
// EMA score update: 0.85 prior + 0.15 result × 100
new_score = (current_score × 0.85) + (correct ? 100 : 0) × 0.15
A single wrong answer doesn't crater the score — the system is statistically robust against bad days. But consistent failure on a topic reliably drives the score below threshold, because it should.
Status ladder:
score ≥ passing → "current" (compliant)
score ≥ passing − 5 → "at_risk"
score < passing → "non_compliant"
score < critical → "critical"
Question picker preferences: weak subtopic (last failed) > previously-missed > unseen > previously-correct. Domain rotation so the daily-3 spreads coverage.
The Today flow
- Operator picks a learner from the dropdown (production would auth-bind; demo uses the picker)
start_daily_assessmentcreates a DailyAssessment record for today (or resumes one if open) + selects 3 questions- Each question renders with the prompt + 4 choices
- On submit:
- Server marks the AssessmentResponse (immutable) - Updates ComplianceScore via EMA - Stamps consecutive_correct + computes points (10 + min(5, streak/2) for correct, 0 for wrong) - Returns {is_correct, explanation, correct_answer, new_score, status}
- The UI highlights the picked choice + correct one, reveals the explanation card with the new score + status pill, then Next/Finish
complete_daily_assessmentstamps the streak (+1 if yesterday's was also complete, else reset to 1), updates learner.assessments_completed + total_points, recomputes overall_compliance as the mean across domains
The Compliance Dashboard
Two stacked sections:
Department rollup — for each department × domain pair, counts in the ladder buckets (current / at_risk / non_compliant / critical) + the mean score across that department's learners. Non-compliant + critical columns carry the aging-bad red emphasis when > 0.
Score over time per learner — pick a domain + a window (7d / 30d / 90d / 365d), get one row per learner with a compliance sparkline drawn against the domain's passing + critical thresholds (green-dashed and red-dashed horizontal lines). Current score + Δ-from-start of window + status pill. Δ flagged with ⚠ when the learner is >10 points below where they started — the SPC drift signal applied to knowledge state.
That last chart is the demo headline: a manager opens it Monday morning and sees who's drifting, *right now*, three weeks before the next audit.
Why the loop matters
The regulatory intent behind compliance training is *knowledge retention*, not course completion. Annual training proves attendance; this system proves knowledge. The audit export the regulator gets:
- Current knowledge score per learner per domain
- All assessment responses for the period (question, answer, correct/incorrect, timestamp)
- Score trend over the period
- Score-below-threshold incidents with refresher status
- Immutable audit log with hash chain (every commit is a real git commit)
That is provably stronger evidence of compliance than a completion date. Regulators who understand adult learning theory know it.
The cross-link to Quality
LearnerProfile.email matches CorrectiveAction.owner_actor, Defect.source_actor / assignee_id, and audit_log.actor. The Operator Scorecard in the Quality module blends all four lanes for that actor — including the learner's overall_compliance from the LMS — into one composite score per person. The LMS isn't a silo; it's the third lane of the unified quality framework.