Second field finding: a user-stopped engine came back when a song load
ran a rig_builder chain plan with startAudio:true - the executor calls
native startAudio directly in the main process, bypassing the IPC latch
check entirely (plan 6.1's second writer).
Decision (strict 8.3): only the device screen's user start resumes.
lease-bridge gains gateNativeAudio(), a proxy over the native accessor
that suppresses startAudio while latched (log-once telemetry line);
audio-bridge hands the executor the gated accessor.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Field finding (fix14 test build): nam_tone's 1.5s keep-alive watchdog
calls raw startAudio whenever the engine is not running, restarting it
seconds after the user pressed Stop - and the shim treated any raw start
as user authority, resuming all suspended demands with it.
Per plan 8.3 (user stop always wins) raw start/stop was supposed to be
device-screen-only; now enforced:
- audio:userStartAudio / audio:userStopAudio: explicit user authority.
Stop sets a latch (+ suspends demands); start clears it (+ resumes).
- raw audio:startAudio is SUPPRESSED while latched (log-once telemetry
'suppressed-by-user-stop') and no longer resumes demands.
- raw audio:stopAudio no longer suspends demands (it is the transient
stop the device-apply flow and unmigrated plugins use).
- fresh capture demands born during the latch start suspended, so the
user start resumes them like pre-existing ones; the demand glue also
refuses to start the engine while latched.
- device screen (src/renderer/screen.js) toggle + apply flows use the
user-authority calls.
Contract snapshots regenerated (2 IPC channels, 2 preload keys).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>