Mid-session camera TCC revoke not observed — wrong notification + becameAuthorized has no production caller #3

Closed
opened 2026-05-12 18:57:40 +00:00 by KofTwentyTwo · 0 comments
KofTwentyTwo commented 2026-05-12 18:57:40 +00:00 (Migrated from github.com)

Summary

Two related defects in the mid-session TCC lifecycle:

  1. Wrong notification observed. The watcher listens for AVCaptureSessionRuntimeError instead of AVCaptureSessionWasInterrupted. When the user toggles camera access off mid-session, WasInterrupted fires (not RuntimeError), so the revoke event is missed silently — the camera session keeps thinking it's healthy.

  2. becameAuthorized() has no production callsite. The re-grant path exists in code but never fires in production, so a user who denies + later grants access mid-session never recovers.

Evidence

  • Audit .planning/audit-2026-05-12/vision-audit.md (2026-05-12) — exact file:line pending, agent flagged the pair.

Recommended fix

  1. Switch the watcher to observe AVCaptureSessionWasInterrupted. Check the interruption reason; surface .cameraRevoked banner on .videoDeviceNotAvailableInBackground / authorization-related reasons.
  2. Wire becameAuthorized() to fire on AVCaptureDevice.requestAccess(for: .video) completion when status flips from .denied to .authorized. Hook the TCC change observer too (macOS doesn't publish a direct authorization-change notification — likely needs to be polled from the audio-graph mic-regrant pattern that's already proven).

Source

Audit .planning/audit-2026-05-12/vision-audit.md (2026-05-12)

## Summary Two related defects in the mid-session TCC lifecycle: 1. **Wrong notification observed.** The watcher listens for `AVCaptureSessionRuntimeError` instead of `AVCaptureSessionWasInterrupted`. When the user toggles camera access off mid-session, `WasInterrupted` fires (not `RuntimeError`), so the revoke event is missed silently — the camera session keeps thinking it's healthy. 2. **`becameAuthorized()` has no production callsite.** The re-grant path exists in code but never fires in production, so a user who denies + later grants access mid-session never recovers. ## Evidence - Audit `.planning/audit-2026-05-12/vision-audit.md` (2026-05-12) — exact file:line pending, agent flagged the pair. ## Recommended fix 1. Switch the watcher to observe `AVCaptureSessionWasInterrupted`. Check the interruption reason; surface `.cameraRevoked` banner on `.videoDeviceNotAvailableInBackground` / authorization-related reasons. 2. Wire `becameAuthorized()` to fire on `AVCaptureDevice.requestAccess(for: .video)` completion when status flips from `.denied` to `.authorized`. Hook the TCC change observer too (macOS doesn't publish a direct authorization-change notification — likely needs to be polled from the audio-graph mic-regrant pattern that's already proven). ## Source Audit `.planning/audit-2026-05-12/vision-audit.md` (2026-05-12)
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: KofTwentyTwo/Jarvis#3