wake-alarm/wake_alarm
Krzysztof kuhy Rudnicki 6be5420fcf Stop trusting an alarm the phone published months ago
Belt-and-braces for the publishing race fixed in the previous commit. That bug
is gone, but the shape of the failure is worth closing on this side too: a
publish that never happens is indistinguishable from one that has not changed,
so the last successful publish stayed authoritative forever. One record stamped
2026-08-09 had the PC starting the morning routine at 07:00 for three weeks.

get_alarm now skips any record the phone published longer ago than
PUBLISHED_ALARM_MAX_AGE_SECONDS (14 days) and falls back. That is safe
precisely because FALLBACK_ALARM_HOUR is the phone's own baseline, so a lapsed
record degrades to the right answer rather than to a guess -- and an override
is one-shot anyway, so reverting to the baseline is what the phone would say.

The check is on when the PHONE stamped it, never on when we fetched, and that
distinction is the whole design. Checking the fetch would be trivially
defeated: the cache is rewritten from the same stale record every few minutes,
so `fetched_at` is always fresh no matter how old the record behind it is.
So the winning HLC's instant is now carried out of _alarm_payload, through
_sync_transport, and persisted in the cache as `published_at`. Nothing else
reads that cache any more -- the shutdown wrapper that used to went with the
PC's waking role -- so widening its shape is free.

An undated record is trusted rather than expired. The GitHub mirror reads a
single fixed path with no per-field HLC, so treating "cannot tell how old this
is" as "too old" would break that whole backend, and refusing an alarm we
merely failed to date is a worse failure than honouring it.

test_sync.py and test_sync_backends.py crossed the 250-line cap, so the new
lapse cases and the backend-ordering cases move to test_sync_lapsed.py and
test_sync_dispatch.py.

168 tests at 100% branch coverage. Verified against the real backend: the
cache now carries published_at, and `_sync --show` still resolves 08:00 from
the record the phone stamped minutes earlier.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PcdngP688mW6rJye3LRkSN
2026-08-30 16:37:13 +02:00
..
tests Stop trusting an alarm the phone published months ago 2026-08-30 16:37:13 +02:00
__init__.py Add tests and fix pre-commit issues across all projects 2026-04-12 20:45:24 +02:00
_alarm_payload.py Stop trusting an alarm the phone published months ago 2026-08-30 16:37:13 +02:00
_constants.py Stop trusting an alarm the phone published months ago 2026-08-30 16:37:13 +02:00
_log_dedupe.py Grade against 3.14 too, not just run on it 2026-08-29 11:39:33 +02:00
_log_sink.py Phase 1: structured JSONL logging with cross-process dedupe 2026-08-26 23:00:08 +02:00
_logging_setup.py Phase 1: structured JSONL logging with cross-process dedupe 2026-08-26 23:00:08 +02:00
_state.py Retire the PC's waking role; keep the trigger 2026-08-30 15:24:02 +02:00
_sync_transport.py Stop trusting an alarm the phone published months ago 2026-08-30 16:37:13 +02:00
_sync.py Stop trusting an alarm the phone published months ago 2026-08-30 16:37:13 +02:00
_trigger.py Retire the PC's waking role; keep the trigger 2026-08-30 15:24:02 +02:00