feat: ErrorEpisode remediation data model — closes #2 - #23
Merged
Conversation
Implements the redefined remediation data model (#2): a wrong answer is no longer merely stored — it is attributed to a cause, prescribed a cause-specific intervention, probed with a transfer item, and tracked for recurrence. Evidence backbone: - SourceRevision: immutable verbatim rawText snapshot (+sha256, length) per source — every citation offset resolves against persisted text, forever. persistIngestionResult now writes revision 1 atomically and links every StudyUnit to it; the seed does the same. - SourceSpan: half-open [start, end) ranges into a revision. - QuizItemCitation: quiz items cite spans (unique per item+span); citation-less items are to be rejected fail-closed at serve time. Provenance: - GenerationRun (kind/provider/model/promptVersion/inputSha256/tokens/ cost) — every AI output (summary, quiz, cause suggestion, intervention, transfer item) links back to one. Remediation loop: - ErrorEpisode: suggestedCause (model hypothesis, with provenance run) vs confirmedCause (learner decision) kept SEPARATE, with open -> cause_confirmed -> intervened -> resolved / item_faulty lifecycle. faulty_item stops attribution: the item is discarded, not the learner blamed. - Intervention: cause-specific kinds (reexplanation, prerequisite check, condition drill, checklist, discrimination set, timed set, item regeneration). - TransferAttempt: same-concept probe whose result IS the recurrence measurement. - ReviewEvent: append-only raw log — rating (again/hard/good/easy), latency, algorithm version, opaque JSON pre/post scheduler state, so schedules are recomputable when the algorithm changes (FSRS in #5). Richer core entities: - QuizItem: acceptedAnswers[], rubric, choices (QuizChoice), citations - Attempt: latencyMs, confidence, gradingMethod enum Removed: ErrorNotebookEntry and ReviewTask tables (no production data; core TS types kept temporarily for the scheduler stub until #5). Migration generated offline via prisma migrate diff; CI applies it to real Postgres and a new integration test exercises the full loop (cited item -> wrong attempt -> suggested!=confirmed cause -> intervention -> transfer -> review event). Closes #2 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Implements the redefined remediation data model (#2) — the schema core of the product thesis. A wrong answer is no longer merely stored (old
ErrorNotebookEntry, now removed): it becomes an ErrorEpisode that is cause-attributed, intervened on, probed with a transfer item, and measured for recurrence.Closes #2
The model
Evidence backbone —
SourceRevisionstores the verbatim rawText (+sha256) so citation offsets resolve against persisted text forever;SourceSpan= half-open ranges;QuizItemCitationlinks items to their evidence.persistIngestionResultand the seed now write revision 1 atomically.Provenance —
GenerationRun(kind/provider/model/promptVersion/inputSha256/tokens/cost); every AI output links back to one (same shape@study-os/summaryalready emits).The loop —
ErrorEpisode:suggestedCause(model hypothesis, with provenance) is kept separate fromconfirmedCause(learner decision) — the acceptance criterion at the heart of the issue. Lifecycle:open → cause_confirmed → intervened → resolved / item_faulty;faulty_itemstops attribution (discard the item, don't blame the learner).Intervention: cause-specific kinds (재설명 / 선수개념 확인 / 조건 drill / 체크리스트 / 변별 세트 / 시간제한 세트 / 문항 재생성).TransferAttempt: the recurrence measurement.ReviewEvent: append-only raw log — rating, latency, algorithm version, opaque JSON pre/post scheduler state → recomputable when the algorithm changes (FSRS lands in Build daily review queue generation #5).Richer entities —
QuizItem+ acceptedAnswers/rubric/choices/citations;Attempt+ latencyMs/confidence/gradingMethod.Cascade deletes throughout (user deletion removes the entire graph — verified by test cleanup).
Acceptance criteria → done
ReviewEventappend-only with opaque state snapshotsVerified
New CI integration test walks the full loop end to end against real Postgres: cited quiz item → wrong attempt (latency/confidence) → suggested≠confirmed cause → intervention → transfer attempt → review event. Local: lint/typecheck/build/smoke green; migration generated via offline
prisma migrate diff(no local Docker) and proven by CI'smigrate deploy.🤖 Generated with Claude Code