- Sick days screen (own name, sick icon, cat-2 fill): tap today or a later
day to mark it sick, tap again to clear; past days inert. Writes the
sickdays wire format (state sick/cleared + actor, one HLC per write) to
sickdays-sync/devices via crdt_sync syncLog.
- Mutual exclusion in both pickers: each syncs the other pool on open and
refuses a date it holds, naming the pool; an unreadable pool refuses all.
- Native SickDays cache (fail closed via DayCache); AlarmReceiver skips the
ring with reason "sick_day" (no markFired, no ring_started); StickCheck
verdict sick_day, streak skips sick days; stakes card says so.
- Pre-alarm pool sync: allow-while-idle alarm at 21:00 and A-30 (request
code 1006) runs a headless engine (poolSyncMain) that pulls both pools
from RTDB and rewrites both native caches, so a PC mark arrives with the
app closed. The ring decision stays a cache read.
- JVM unit tests (JUnit 4.13.2) for DayCache, RingDecision,
PoolSyncSchedule, StickCheck; Dart tests; Dart->Python interop check.
pylint hook skipped: verify.py imports sickdays, not in the hook env until
the sickdays-v0.1.0 tag exists; run by hand in a sickdays venv (10.00/10).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Xfj1sxKH9VBPqpcAni8Jry