mirror of
https://github.com/kuhyx/wake-alarm.git
synced 2026-11-10 19:27:02 +01:00
Adds the diagnostic substrate the rest of the hardening work builds on. A 6am failure should be reconstructable afterwards instead of re-debugged. Two sinks, deliberately. stderr -> journal is unchanged. Alongside it, one JSON object per line in ~/.local/state/wake_alarm/events.jsonl, so a morning can be replayed with jq. The hard constraint is that _trigger is a fresh process every 60 seconds, so an in-memory rate limiter would reset on every tick and suppress nothing. _log_dedupe therefore persists the last emitted fingerprint to disk and flushes a suppressed_repeats count onto the next distinct record. Verified across separate processes: 4 invocations logging the same routine event produce 1 record plus an accurate count of 3. That is what satisfies the standing "do not raise the level of _sync's degraded-read paths" rule by construction, rather than by keeping levels artificially low and losing the signal. The correlation id is derived, never generated: both halves compute wake-YYYYMMDD-HHMM from the resolved alarm instant, so the PC and the phone agree with no handshake and no uuid exchange -- which matters precisely when sync is down. Logging never raises. An unwritable sink degrades to journal-only. _alarm.py and _sync.py keep the default component= for now; tagging them means splitting them for the 250-line gate, which belongs in the phases that actually restructure those files. 389 tests pass, 100% branch coverage held. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EckWmyfetYq3Mi8MAnUudh |
||
|---|---|---|
| .. | ||
| tests | ||
| __init__.py | ||
| _alarm_display.py | ||
| _alarm_payload.py | ||
| _alarm_view.py | ||
| _alarm.py | ||
| _audio.py | ||
| _challenges.py | ||
| _constants.py | ||
| _correlation.py | ||
| _escape_flow.py | ||
| _log_dedupe.py | ||
| _log_sink.py | ||
| _logging_setup.py | ||
| _sinks.py | ||
| _smart_plug.py | ||
| _state.py | ||
| _sync.py | ||
| _trigger.py | ||