feat(audio): implement phase 3c master protection

This commit is contained in:
2026-09-05 20:45:47 -07:00
parent 249328e595
commit 90fcbbe467
21 changed files with 6732 additions and 71 deletions
@@ -0,0 +1,27 @@
# Phase 3c slice 4 — Master protection implementation
Date: September 5, 2026. Contract: PRD 58, 118120, 129 and Format Specification 16.7, 16.11. **Implementation and automated verification complete; hardware measurement and listening acceptance pending.** This supersedes the slice-3 stop for the newly authorized slice-4 work.
## Runtime changes
The placeholder compressor is replaced by an embedded AudioWorklet. The only audible route is voice → internal release gain → voice finite-sample guard → declared bus (when present) → master volume → final protection → destination. The engine creates these nodes; the document cannot target them, and `audio.master` remains rejected.
The candidate settings are centralized in `AUDIO_PROTECTION`: 1 dBFS ceiling, 0.1 dB tolerance, 5 ms lookahead, 0.5 ms attack and 250 ms exponential gain-recovery time constant. A stereo-linked peak detector holds incoming peaks through the lookahead interval, smooths gain reduction/recovery, and a final hard sample clamp bounds attack overshoot and extreme overload. Stereo is explicitly two channels; quiet samples retain their values after the lookahead delay. Float32 rounding may put the mathematical ceiling a fraction above 1 dBFS, within the provisional tolerance. This algorithm and its numerical tests do not establish freedom from audible artifacts.
A nonfinite sample anywhere in a voice guard mutes that entire stereo render quantum. A separate finite fault lane reaches the final master and mutes its entire mixed block, including healthy voices. The master also scans its summed input, and flushes delayed history when it mutes a block. Voice warnings use the production sound instance key; each guard and the final master warn once for their lifetime. The capture counts all affected blocks, including repeat faults after the first warning.
Unlock resumes from the gesture, loads the embedded data-URL worklet, and exposes playable audio only after protected routing is ready. Concurrent unlocks share initialization. Unsupported/rejected worklet loading or resume fails silently with `WARN_AUDIO_UNAVAILABLE`; no unprotected fallback is connected. Disposal during loading cannot resurrect output. Processor failure disconnects output and rejects an active measurement. Guards, ports, master nodes and buses are disconnected/closed with their owners.
## Verification
`npm test`: **102 passed, 0 failed**, including 14 new slice-4 tests. The first sandboxed invocation could not spawn Node test workers (`EPERM`); the authorized escalated run passed. No browser or audio device was opened.
The tests execute the exact serialized production worklet processor in a VM, exercising finite output and peak bounds at 8, 44.1, 48, 96 and 192 kHz under DC, alternating full-scale floating-point overload, sine overlap, transients and silence. They verify quiet stereo preservation and delay, monotonic release recovery, complete block muting for NaN and both infinities, once-per-instance warnings, fault-lane propagation, affected-block counts, capture-window boundaries, routing, async initialization failures/races, capture completion/disposal/failure, and missing AudioContext behavior (16.11 traces 12 and 14).
Both new `.xzbt` fixtures validate and instantiate deterministically. The twelve challenge recipes cover the authored PRD 129 candidates. The overload fixture has finite transient ending bounds shorter than the 2-second burst cadence. Production and acceptance HTML builds are self-contained and deterministic; the acceptance build records the exact production and fixture hashes in its page and exported report.
## User-run evidence still required
[The standalone acceptance page](../../../prototypes/phase3/XZBT-audio-acceptance.html) and [run instructions](../../../prototypes/phase3/README.md) provide a frozen 16-continuous/64-one-shot workload, 30-second warmup, 120-second output capture, environment fields, actual burst/voice logs and JSON export. The meter measures the final worklet's Float32 samples before the destination. It cannot measure downstream browser/OS resampling or analog output. Counts apply to blocks intersecting the window; the sample peak covers exactly the requested frames.
No production-build audio has been heard or measured in this work. The 1 dBFS / 0.1 dB values and audible release behavior remain provisional. Format Specification 16.11 traces 1517, reference-exhibit listening, full PRD 129, real GC4 synchronization and the Phase 1 direct-file restart observation remain open. Slice 4 and Phase 3 are not accepted until the required user-performed evidence is reviewed. Later phases have not started.