docs(audio): close three defects in the phase 3c contract

Re-read section 16 before handing the implementation slice onward. Three
defects, all of the same classes the Phase 3a review turned up.

The 16.5 ending-bound table gave a contribution for every node type
except the one that contains other nodes, so a one-shot whose tail lived
inside a component had no defined bound. Components now contribute the
bound of their own graph by the same rule, terminating on the existing
nesting cap.

The 16.3 state machine offered no exit from CREATED for a stop arriving
before scheduling except FAILED, which would have reported an ordinary
cancellation as a fault. Permit CREATED -> FINISHED, and say why it
differs from SCHEDULED -> RELEASING: a created instance is connected to
nothing, so there is no signal to ramp down.

Automation point ordering was a stage conflation. Points had to be in
strictly increasing `at` order while `at` was a DurationSpec, which
section 6.2 permits to be a procedural TimeSpec resolved at
instantiation — so the ordering rule could not have been enforced at the
semantic stage where it was filed. This is structurally the same defect
as the audioMaxFrequency one closed in Phase 3a. Fix `at` as a duration
literal; point values remain full ValueSpecs.

Still contract only. No runtime change, and no sound has been heard from
any build.

Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_011FWPdCqKaaDnP9NC3JAwh6
This commit is contained in:
2026-09-05 23:29:23 +00:00
co-authored by Claude Opus 5
parent 42e4b32fd6
commit 50fb72c0e8
2 changed files with 16 additions and 5 deletions
@@ -19,6 +19,14 @@ Phase 3c is delivered in four slices, recorded in the implementation plan. This
- **Unlock reports once per batch.** A long pre-unlock interval raises a single counted `INFO_AUDIO_UNLOCK_SKIP` rather than flooding the panel with one entry per skipped one-shot.
- **Master protection is specified in shape, provisional in value.** Finite-sample handling is normative now because a `NaN` in the output buffer is never acceptable at any ceiling. The peak ceiling, numerical tolerance, and release behavior carry provisional values and are confirmed by GC6 measurement.
## Post-review corrections
Section 16 was re-read before handing the implementation slice onward. Three defects were found in it and fixed in a follow-up commit. All three are the same classes the Phase 3a review turned up, which is why the review step exists rather than being a formality:
1. **The 16.5 ending-bound table omitted `component`.** Every node type had a contribution except the one that contains other nodes, so a one-shot whose tail lived inside a component had no defined bound. Components now contribute the bound of their own graph, computed by the same rule; the recursion terminates on the 15.14 nesting cap.
2. **The 16.3 state machine had no exit from `CREATED` for a stop arriving before scheduling** — only `FAILED`, which would have misreported an ordinary cancellation as a fault. `CREATED -> FINISHED` is now permitted, and the text says why it differs from `SCHEDULED -> RELEASING`: a created instance is connected to nothing, so there is no signal to ramp down.
3. **Automation point ordering was a stage conflation.** Points had to be in strictly increasing `at` order while `at` was a DurationSpec, which section 6.2 permits to be a procedural `TimeSpec` resolved at instantiation — so the ordering rule could not have been enforced at the semantic stage where it was filed. This is structurally the same defect as the `audioMaxFrequency` one closed in Phase 3a. `at` is now a duration literal only; point *values* remain full ValueSpecs.
## Verification
This slice changes documentation only. The full suite still runs 62 tests with zero failures and all three exhibit fixtures still validate, confirming no regression, not that section 16 is implemented. Section cross-references resolve with no dangling targets, and every diagnostic code section 16 uses appears in the single section 7 table.