Study.Scheduler — pure SM-2 implementation with exhaustive tests #23

Open
opened 2026-09-26 13:58:35 +00:00 by belvedere · 0 comments
Collaborator

Objective: The scheduling rule as a pure, dependency-free function. This is the piece most
worth getting right, and the easiest to test if it touches nothing.

Files:

  • Create: lib/first_thousand_words/study/scheduler.ex
  • Create: test/first_thousand_words/study/scheduler_test.exs

Steps:

  1. Scheduler.review(state, grade, now) where grade is :again | :hard | :good | :easy and
    state is a plain struct (interval_days, ease, reps, lapses).
  2. SM-2 behaviour: :again resets the interval and increments lapses; :good/:easy multiply
    the previous interval by the ease factor; ease is adjusted within bounds (floor ~1.3).
  3. No DB, no time source other than the injected now — so tests are deterministic.
  4. Cover: first review, graduating interval, ease floor, lapse reset, long-interval cap,
    and grade ordering (easy ≥ good ≥ hard ≥ again).

Verify: mix test test/first_thousand_words/study/scheduler_test.exs — all pass.

Refs: plan §4 (Scheduling). Record the algorithm choice and its known weaknesses in
docs/decisions/0003-scheduling-algorithm.md, including why FSRS is deferred.

**Objective:** The scheduling rule as a pure, dependency-free function. This is the piece most worth getting right, and the easiest to test if it touches nothing. **Files:** - Create: `lib/first_thousand_words/study/scheduler.ex` - Create: `test/first_thousand_words/study/scheduler_test.exs` **Steps:** 1. `Scheduler.review(state, grade, now)` where `grade` is `:again | :hard | :good | :easy` and `state` is a plain struct (`interval_days`, `ease`, `reps`, `lapses`). 2. SM-2 behaviour: `:again` resets the interval and increments lapses; `:good`/`:easy` multiply the previous interval by the ease factor; ease is adjusted within bounds (floor ~1.3). 3. No DB, no time source other than the injected `now` — so tests are deterministic. 4. Cover: first review, graduating interval, ease floor, lapse reset, long-interval cap, and grade ordering (`easy` ≥ `good` ≥ `hard` ≥ `again`). **Verify:** `mix test test/first_thousand_words/study/scheduler_test.exs` — all pass. **Refs:** plan §4 (Scheduling). Record the algorithm choice and its known weaknesses in `docs/decisions/0003-scheduling-algorithm.md`, including why FSRS is deferred.
Sign in to join this conversation.
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
nickkeers/first-thousand-words#23
No description provided.