diff --git a/AGENTS.md b/AGENTS.md index 277cc9e9..bab1045e 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -78,6 +78,22 @@ were name-only across ALL libraries. Fixed; do not regress. returned zero books until 0a7fbd6). Only real system query types (continue-reading etc.) route there; `query_type='filter'` is the schema DEFAULT on every user row, not a query type. +4. **End-of-day arithmetic**: anchor the END bound to the START of the + day, never to NOW(). `now.AddDate(0,0,1) − 1ns` carries this + instant's clock time into tomorrow — a range "ending today" + resolves tomorrow's calendar date and today's rows land in + yesterday's bucket (found twice now: analytics 1601548 and stats + 2026-10-14). Same trap, two deaths. +5. **Test binaries run against the LIVE dev DB**: hand-probes made in + psql during debugging (seed rows, fake sessions) will silently + pollute the next integration run — DELETE them when done (this + burned the first stats suite run: a stray 30-min probe row shipped + a phantom "185 minutes" failure). +6. **SaveProgressRequest.DeviceID is NOT always a device**: the + web/app progress paths have historically stuffed the USER id into + it (it only fed a broadcast label before stats). Anything that + dereferences it (reading_history device_id FK, device joins) must + probe DeviceExistsForUser first — stats capture does. ## Conventions (absorbed from the retired PROJECT_GUIDELINES.md — ## only the rules that still matched reality)