After every attempt, Innova updates a per-student, per-topic mastery probability using closed-form Bayesian Knowledge Tracing (Corbett & Anderson, 1995). BKT treats a student’s knowledge of each topic as a hidden binary state — known or not known — and updates the probability of being in the “known” state based on whether the student answered correctly or incorrectly. The result,Documentation Index
Fetch the complete documentation index at: https://mintlify.com/vruizz22/innova-backend-serverless/llms.txt
Use this file to discover all available pages before exploring further.
pKnown, is a single number in [0, 1] that teachers see in real time as a heat-map and trend line.
The BKT Model
BKT is parameterized by four values stored on eachTopic row in Postgres:
| Parameter | Field | Default | Meaning |
|---|---|---|---|
| pL0 | bktPL0 | 0.30 | Initial probability the student already knows the topic before any attempt |
| pT | bktPTransit | 0.10 | Probability of transitioning from not-known to known after a single attempt |
| pS | bktPSlip | 0.10 | Probability of an incorrect response despite knowing (slip) |
| pG | bktPGuess | 0.20 | Probability of a correct response without knowing (guess) |
Update Formulas
After each observation (correct = 1, incorrect = 0) Innova applies the closed-form update in two steps:pKnown is clamped to [0, 1] before being persisted.
The applyAttempt Implementation
The BKT update lives inMasteryService.applyAttempt. It reads the topic’s BKT parameters from Postgres, loads the student’s current pKnown (defaulting to pL0 on first attempt), applies the formulas above, and upserts the result:
Storage
BKT state is stored in theStudentTopicMastery table in Postgres. The key columns are:
| Column | Type | Description |
|---|---|---|
studentId | String | FK to Student |
topicId | String | FK to Topic |
pKnown | Float | Current mastery probability after the latest attempt |
attemptsCount | Int | Total attempts processed for this (student, topic) pair |
lastAttemptAt | DateTime | Timestamp of the most recent attempt |
Attempt table when needed.
Nightly Recalibration
BKT is only as good as its parameters. A separate service —innova-ai-engine — runs a nightly batch calibrator that analyses the full history of student responses for each topic. It fits new pL0, pT, pS, and pG values using expectation-maximization and writes them back to the Topic table in Postgres. On the next attempt, applyAttempt picks up the updated parameters automatically — no deploy required.
Teacher Visibility
Mastery data is exposed through three read paths:Per-student mastery
GET /mastery/:studentId returns the current pKnown for every topic the student has attempted, ordered by topic code.Course heatmap
GET /mastery/course/:courseId/heatmap returns a student × unit matrix. Each cell is the mean pKnown across the unit’s topics for that student.IRT recommendation
GET /mastery/recommend/:courseId/:studentId uses the BKT pKnown as the input to the IRT Fisher-information item picker — see the IRT Practice page.Teacher alerts
The dashboard surfaces an alert when a student’s
pKnown for a topic drops below a configurable threshold, signalling recent regression.pKnown is always clamped to [0, 1] by the Math.min(1, Math.max(0, ...)) guard in applyAttempt. Unit tests in mastery.service.spec.ts verify this property for all four boundary combinations of correct/incorrect answers and extreme parameter values.