From c43af4edb76cc1eb0d248c926ce2e62af7d473e7 Mon Sep 17 00:00:00 2001 From: Krzysztof kuhy Rudnicki Date: Thu, 27 Aug 2026 20:49:55 +0200 Subject: [PATCH] Update the continuation TODO for phases 4-6 Items 6, 2 and 10 move to Done. Remaining is the phone chunk (1/4/3), then gating (8), then curtains (5) and the black screen (13). Adds three traps this session paid for: vm run's exit code fails a gate open, _state.py's UTC key is load-bearing across repos and must not be "fixed", and ruff's autofix will silently gut a function whose only effect is printing. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01EckWmyfetYq3Mi8MAnUudh --- TODO-hardening-continue.md | 54 ++++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/TODO-hardening-continue.md b/TODO-hardening-continue.md index 67621ed..0648b4f 100644 --- a/TODO-hardening-continue.md +++ b/TODO-hardening-continue.md @@ -2,7 +2,7 @@ REMOVE ME AFTER FINISH -Phases 0–3b are committed (`4286fcb`..`b3e8c23`). This file is the entry point +Phases 0–6 are committed (`4286fcb`..`97d32c8`). This file is the entry point for the rest. **Full plan, with every measured finding:** `~/.claude/plans/wake-alarm-still-does-witty-toucan.md` — read it before starting; this file deliberately does not duplicate it. @@ -11,32 +11,21 @@ starting; this file deliberately does not duplicate it. | Item | State | |---|---| -| 6 audio (HDMI silent) | `_reactivate.py` retries card-profile activation. **Not yet wired into `WakeAlarm`** — see below. | +| 6 audio (HDMI silent) | **Done.** `_reactivate` wired into `WakeAlarm`; verified on the host — the HDMI sink appeared and became default. | | 7 speakers | `DOCS-speaker-recommendation.md`. Prose only, done. | | 9 refactor | `_alarm.py` 478→250. 12 new modules; see `DOCS-architecture.md`. | | 11 failsafe | `FAILSAFE_SILENCE_SECONDS=300`, audio only. Escalation re-tuned to fit inside it. | | 12 logging | JSONL + cross-process dedupe + derived correlation id. | -| 14 fans | Gone: code, script, sudoers entry, installed state. | +| 14 fans | Gone: code, script, sudoers entry, installed state. Three stale doc/message references cleaned up in phase 6. | +| 2 power button | **Done.** `_inhibit.py` (logind block, self-terminating, stale cleanup by pid via `/proc`) + `_alarm_session.py` fire-time record, re-fired by `_trigger` outside the catch-up window. | +| 10 vmbox | **Done.** `scripts/vmbox/harness.sh` + `DOCS-vmbox.md`. 8 cases, fails closed. Found 2 live bugs the host could not reach. | ## Remaining, in order -1. **Wire `_reactivate` into `WakeAlarm`** (finishes item 6). It exists, - is tested, and is currently called by nothing. Start it next to - `_activate_all_outputs()` in `__init__`, pass `self._stop_beep` as `stop`. - ~20 lines. Do this first — every other item assumes the alarm is audible. -2. **Item 2, power button.** `systemd-inhibit - --what=handle-power-key:shutdown:idle --mode=block` around the alarm, in a - new `_inhibit.py`, released in `on_close()`. Verified viable: - `PowerKeyIgnoreInhibited=no` is in force, so no `logind.conf` edit is - needed. Then the real defence — a **fire-time** session record - (`wake_state.json` is only written on *dismissal* today, so a hard - power-off leaves no trace), and `_trigger` re-fires on an unfinished - session ignoring the catch-up window. Fix the UTC/local key mismatch in - `_state.py` in the same commit. -3. **Item 10, vmbox harness.** `scripts/vmbox/harness.sh` + `DOCS-vmbox.md`. -4. **Items 4/3/1, phone.** Biggest chunk by far. Own session. -5. **Item 8, mutual gating.** Needs 4 done first. -6. **Item 5 curtains**, then **item 13 black screen** (different repo, +1. **Items 4/3/1, phone.** Biggest chunk by far. Own session. Everything here + is new — the app has zero alarm capability today, only a time picker. +2. **Item 8, mutual gating.** Needs 1 done first. +3. **Item 5 curtains**, then **item 13 black screen** (different repo, host-only). ## Decisions already made — do not re-litigate @@ -61,11 +50,11 @@ starting; this file deliberately does not duplicate it. ## Traps that cost time this session - **The 250-line gate fires on *staged* files.** Touching a file means - splitting it in the same commit. 5 source + several test files are still - over (measured 2026-08-27): `test_sync.py` 386, `_sync.py` 371, - `test_smart_plug.py` 351, `_sinks.py` 341, `_alarm_view.py` 329, - `_escape_flow.py` 317, `test_state.py` 314, `test_trigger.py` 252. - Budget for it. + splitting it in the same commit. Still over (re-measured 2026-08-27, after + phase 6): `test_sync.py` 386, `_sync.py` 371, `test_smart_plug.py` 351, + `_sinks.py` 341, `_alarm_view.py` 329, `_escape_flow.py` 317, + `test_state.py` 314. Budget for it. `test_trigger.py` is now split and + under. - **`morning_routine/_orchestrator.py:39` hardcodes `"wake_alarm._alarm"`** (different repo, `~/testsAndMisc`). Any module-path change updates it in the *same* commit. This exact omission caused a month-long silent outage. Keep @@ -85,11 +74,24 @@ starting; this file deliberately does not duplicate it. of `_beep_soft/_medium/_loud` and waits for it will spin forever on the real audio stack and hang the whole suite instead of failing. Patch all three. - Run tests with `/usr/bin/python3`, not the dev venv (no `gatelock` there). +- **`vm run` does not propagate the guest command's exit code** — it reports + the VM's verdict. A gate built on it fails *open*. See `DOCS-vmbox.md`. +- **`_state.py`'s UTC `_today_str()` must NOT be flipped to local**, despite + what the plan says. `screen_locker/_wake_state.py` mirrors the helper and + reads the same `wake_state.json`; flipping it loses an earned workout skip + for any dismissal between 00:00 and 02:00 local. `_alarm_session.py` shows + the way around it: carry an aware `fired_at`, compare elapsed time, no date + key at all. +- **Ruff's autofix will gut a function** whose results are only printed — + it stripped both the assignments and the `print` from a vmbox check, and + every linter stayed green. Grep the file for its output call after any + autofix. ## Verify ``` -/usr/bin/python3 -m pytest wake_alarm/tests/ -q # 404 pass, 100% cov +/usr/bin/python3 -m pytest wake_alarm/tests/ -q # 455 pass, 100% cov +bash scripts/vmbox/harness.sh # 8/8 cases, exit 0 pre-commit run --files /usr/bin/python3 -m wake_alarm._trigger --dry-run /usr/bin/python3 -m wake_alarm._alarm --demo # real window; ask first