Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 34 additions & 1 deletion docs/plans/2026-08-12-lock-guard-meeting-suppression-design.md
Original file line number Diff line number Diff line change
@@ -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

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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,
Expand Down
15 changes: 15 additions & 0 deletions tests/lock-fanout.bats
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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" {
Expand Down
Loading