From 5e7c3ad7ed8c287b538de97d4de3a4df87e9a100 Mon Sep 17 00:00:00 2001 From: nsfisis Date: Sun, 8 Feb 2026 21:18:55 +0900 Subject: feat(study): use seeded PRNG for deterministic card shuffle order Shuffle order is now fixed within a study day by seeding mulberry32 with the study day boundary timestamp (3:00 AM rollover). Co-Authored-By: Claude Opus 4.6 --- docs/dev/architecture.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'docs') diff --git a/docs/dev/architecture.md b/docs/dev/architecture.md index cb6e634..7d3bdd4 100644 --- a/docs/dev/architecture.md +++ b/docs/dev/architecture.md @@ -378,6 +378,23 @@ GET /api/sync/pull - Pull server changes 4. Client pulls server changes 5. Mark synced items with `_synced = true` +## Study + +### Date Boundary + +The "study day" rolls over at **3:00 AM local time**, not midnight. A study day spans from 3:00 AM to the next day's 3:00 AM. This boundary is used for: + +- Determining which cards are due (`card.due < endOfStudyDay`) +- Counting today's new card reviews (budget calculation) +- Seeding the card shuffle order (see below) + +### Card Shuffle Order + +Cards fetched for a study session are shuffled client-side using the Fisher-Yates algorithm with a **seeded PRNG** (mulberry32). The seed is derived from `getStartOfStudyDayBoundary().getTime()`, which means: + +- The shuffle order is **deterministic within the same study day** — reopening the study screen produces the same card order. +- The order **changes when the study day rolls over** (at 3:00 AM). + ## Authentication - **Hash**: Argon2 for password hashing -- cgit v1.3-1-g0d28