Status: Accepted · Date: 2026-05 (Sprint E; closes #59)
Full design doc: ../completion-authority.md
Completion state lived in three places (in-memory SolveState,
solve_sessions, puzzle_completions) with undocumented ownership and a few
divergence windows.
Adopt the hybrid model with named authorities (Option C of the design doc):
SolveState owns the live solve; only SolveNotifier
writes it.puzzle_completions (append-only) is the authority for completion
history — stats, streaks, personal bests.solve_sessions is the resumable session cache (Archive + resume),
not historical truth.SolveRepositoryImpl._statusFromDb and
SolveNotifier._deriveCompletionType must remain inverses
(locked by a round-trip test).Alternatives rejected: notifier-as-authority (ephemeral, can’t serve Archive/Stats) and DB-as-authority (keystroke-latency regression).