From decc109c1801abeab88493f211fdab2a41a00237 Mon Sep 17 00:00:00 2001 From: Claude Code Bot Date: Mon, 24 Aug 2026 16:54:53 -0700 Subject: [PATCH] test: pin checksum state in ssh-failure test; note ioreg to pmset pivot Fixes #35, fixes #36. #35: the "one of three ssh failures" test set no checksum env var, so the ssh stub answered asiago's and mimolette's shasum call with empty stdout. An empty remote_sha never equals local_sha, so provision_host fell through to the push path and re-pushed lock-guard to both hosts on every run. The test still passed because its assertions only checked log-line content, and both push and steady-state end in ssh_exit=0 -- so it silently exercised the push path while reading as a steady-state fan-out test. Pin both non-failing hosts with STUB_SSH_CHECKSUM_ALL_MATCH, matching the sibling "three clients all succeed" test, and assert no push (CMD=cat >) was attempted for any host. STUB_SSH_FAIL_HOST is evaluated before the checksum stubs in the ssh stub, so tilsit still fails as intended. Falsified: perturbing STUB_SSH_CHECKSUM_ALL_MATCH to a non-matching digest makes the new assertion fail. Before this change the same perturbation was undetectable. #36: the design doc described the mic-active signal as `ioreg -c IOAudioEngine -r -l` stubbed via LOCK_SYNC_IOREG, but the shipped check_mic_active uses `pmset -g assertions` matching coreaudiod.*preventuseridlesleep, stubbed via LOCK_SYNC_PMSET. The code is correct -- IOAudioEngine is Intel/kext-era and publishes no live instances on Apple Silicon, so the planned check would have failed open everywhere. The doc is a dated plan record, so rewriting its code blocks would falsify what was actually planned. Instead: add an "Implementation note" addendum below the header documenting the deviation and rationale, update the Status line, and mark the two prose references (the signal list and the Testability section) as superseded. --- ...2-lock-guard-meeting-suppression-design.md | 35 ++++++++++++++++++- tests/lock-fanout.bats | 15 ++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/docs/plans/2026-08-12-lock-guard-meeting-suppression-design.md b/docs/plans/2026-08-12-lock-guard-meeting-suppression-design.md index e3a674e..0279fda 100644 --- a/docs/plans/2026-08-12-lock-guard-meeting-suppression-design.md +++ b/docs/plans/2026-08-12-lock-guard-meeting-suppression-design.md @@ -1,7 +1,31 @@ # `lock-guard`: suppress lock during meetings Date: 2026-08-12 -Status: approved, ready to implement +Status: implemented, with one deviation (see "Implementation note" below) + +## Implementation note: mic-active check uses `pmset`, not `ioreg` + +This document is the plan as approved on 2026-08-12 and is kept as the +historical record. The shipped implementation deviates from it in one +place: **the microphone-active signal.** + +- **Planned:** `ioreg -c IOAudioEngine -r -l`, matching an audio engine in + `running` state, stubbed in tests via `LOCK_SYNC_IOREG`. +- **Shipped:** `pmset -g assertions`, matching + `coreaudiod.*preventuseridlesleep`, stubbed in tests via + `LOCK_SYNC_PMSET` (the same override already used for the + `pmset displaysleepnow` call, so there is no separate mic stub). + +**Why:** `IOAudioEngine` is a legacy Intel/kext-era class. On Apple Silicon +the audio HAL runs in userspace and publishes no live `IOAudioEngine` +instances, so the planned check never matched — it would have silently +failed open on every current Mac. `pmset -g assertions` reports the power +assertion `coreaudiod` takes while an audio input stream is open, which was +verified against real mic open/close on Apple Silicon. + +Every `ioreg`, `IOAudioEngine`, and `LOCK_SYNC_IOREG` reference below is +part of the superseded plan and does **not** describe the shipped code. +See `check_mic_active` in `bin/lock-guard` for the real implementation. ## Purpose @@ -33,6 +57,8 @@ call `pmset displaysleepnow` or skip it and log why. 2. **Microphone actively in use** — `ioreg -c IOAudioEngine -r -l` shows an audio engine in `running` state. Catches apps not in the process list, and any call where you're actually speaking. + (**Superseded:** shipped as `pmset -g assertions` — see "Implementation + note" above.) 3. **Google Meet tab open in Chrome** — `osascript` asks Chrome for open tab URLs and checks for the Meet in-call URL pattern (`meet.google.com/xxx-yyyy-zzz`, not the bare landing page). This is the @@ -106,6 +132,13 @@ scripts under a `STUB_DIR`, matching `lock-fanout.bats`'s `make_ssh_stub` pattern. `pmset` itself is also stubbed the same way (`LOCK_SYNC_PMSET`), so tests can assert whether it was called or not. +**Superseded:** `LOCK_SYNC_IOREG` was never implemented. Because the mic +check shipped on `pmset -g assertions` (see "Implementation note" above), +the mic-active stub is `LOCK_SYNC_PMSET` — the same override that already +covers the `pmset displaysleepnow` call. `lock-guard` therefore has three +overridable commands, not four: `LOCK_SYNC_PGREP`, `LOCK_SYNC_OSASCRIPT`, +and `LOCK_SYNC_PMSET`. + ## Config file: `~/.config/lock-sync/guard-processes` Same shape as the existing `~/.config/lock-sync/config` (plain text, diff --git a/tests/lock-fanout.bats b/tests/lock-fanout.bats index 7886f6a..6ceb665 100755 --- a/tests/lock-fanout.bats +++ b/tests/lock-fanout.bats @@ -153,6 +153,17 @@ mimolette.local" tilsit.local mimolette.local" export STUB_SSH_FAIL_HOST="tilsit.local" + # Pin the two non-failing clients to the steady state (remote checksum + # already matches local), so this test isolates the one variable it is + # about: a single host's SSH failure. Without this, asiago and mimolette + # answer their shasum call with empty stdout, which never matches + # local_sha, so provision_host pushes lock-guard to both on every run — + # the test would still pass (both paths end in ssh_exit=0) while + # silently exercising the push path instead of the steady-state path. + # STUB_SSH_FAIL_HOST is checked before the checksum stubs in the ssh + # stub, so tilsit still fails as intended. + local_sha=$(shasum -a 256 "$BATS_TEST_DIRNAME/../bin/lock-guard" | awk '{print $1}') + export STUB_SSH_CHECKSUM_ALL_MATCH="$local_sha" make_ssh_stub run "$SCRIPT" @@ -166,6 +177,10 @@ mimolette.local" [[ "${lines[2]}" == *"ssh_exit=255"* ]] [[ "${lines[3]}" == *"client=mimolette.local"* ]] [[ "${lines[3]}" == *"ssh_exit=0"* ]] + # No client should have been pushed to: asiago and mimolette are pinned to + # the steady state, and tilsit fails its checksum check before any push. + run grep -q 'CMD=.*cat >' "$SSH_LOG" + [ "$status" -ne 0 ] } @test "host with config override uses override user in ssh target" {