Section 20 in full: the automatic scheduling algorithm with its eligible-pool filtering, cooldown and overlap exclusion, weight evaluation, the anti-repetition multiplier table applied by recency-queue position, pool relaxation when total effective weight reaches zero, and reschedule by uniform sample divided by intensity; the priority clocks and minimum-gap servicing of 20.6 with deferred classes retained; intensity clamping and the pause threshold of 20.7, under which ambient voices keep running; the 1024-unit dispatch budget and sixteen levels of event nesting; and manual SAMPLE evaluation in an isolated stream that does not perturb cadence scheduling. Two defects found by the section 20 review triage are fixed here rather than shipped. A sound action's usage check tested whether the target sound permitted *some* action context instead of the caller's own, so a scenario-only sound was playable from a manual action; it now checks the caller's context and rejects with ERR_UNSUPPORTED_TARGET, the code 20.2.2 and 20.12 actually name, and the two cases the previous test never exercised — manual-only from scenario, and scenario-only from manual — are covered. Traces 7 through 10 drove `triggerSound()` and `calculateEligiblePool()`, a duplicate scheduler with no production call site, rather than the `advance()`/`fireClass()` path a real exhibit runs. The two implementations disagreed on recency-history semantics: 20.5.9 requires a plain queue of the last four firings, and the duplicate moved an existing entry to the front instead. Nothing caught it because nothing called both. Those traces now drive `update()`/`advance()` with a seeded RNG, as traces 11 through 14 already did, and the duplicate is deleted rather than reconciled. Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01ShxxFqFmCUDQnQvFNm4TKy
8.0 KiB
Phase 5: Events and Cadence Acceptance Evidence
Date: September 6, 2026
Status: Complete and fully verified
Specification References: PRD 61–68 (Cadence Model), 90–91 (Event Model 0.1), 139 (Milestone criteria); Format Specification Revision 0.9, Section 20 ("Cadence and Event Subsystems Contract")
1. Executive Summary
Phase 5 completes the Cadence and Event subsystems of XZBT 0.1, delivering:
- Contract & Schema: Complete Section 20 normative contract in the Format Specification and JSON Schema definitions for
CadenceConfig,CadenceClockRange,SoundCadence,ActionSpec, andEventDefinition. - Static & Semantic Validation: Implemented in
src/runtime/cadence-validation.js, integrated withsrc/runtime/validator.jsandtools/validate-exhibit.mjs. Static cycle detection for events (ERR_CYCLIC_DEPENDENCY), clock range ordering (ERR_INVALID_RANGE_ORDER), and sound cadence metadata validation. - Action Model 0.1: Implemented in
src/runtime/actions.jswithtype: 'event'andtype: 'sound', per-tick action dispatch budget (1024 units/tick), 16-level event recursion limit, strict input parameter scoping, default value substitution, type validation (ERR_TYPE_MISMATCH), undeclared parameter rejection (ERR_UNKNOWN_FIELD), and sound usage gating (ERR_UNSUPPORTED_TARGET). - Procedural Cadence Engine: Implemented in
src/runtime/cadence.jswith clock interval management forroutine,intermittent,occasional, andrareclasses, minimum gap scheduling (minGap, default 1.5s), priority queue ordering (rare>occasional>intermittent>routine), weighted random selection, cooldown checking, overlap refusal, anti-repetition recency multipliers (0.0,0.25,0.50,0.75) with automatic pool relaxation, continuous ambient sound voice auto-start and maintenance, and strict PRNG domain isolation (cadencedomain). - Content Integration: All four reference exhibits (
exhibits/exhibit-{a,b,c,d}.xzbt) populated with valid audio synthesis graphs, sounds, cadence clocks, and lifecycle events. - Verification: All 14 acceptance traces of Section 20.15 verified in
test/phase5-cadence.test.mjs. The full suite of 229 automated tests passes with zero failures. Deterministic builds ofXZBT.htmlproduce byte-identical SHA-256 digests.
2. Test Execution and Acceptance Traces
The 14 acceptance traces defined in Section 20.15 of the Format Specification are verified by test/phase5-cadence.test.mjs:
| Trace | Title | Verification Target | Status |
|---|---|---|---|
| Trace 1 | Schema & Static Validation | Top-level cadence and sound cadence validation; clock range with min > max rejected with ERR_INVALID_RANGE_ORDER. |
PASS |
| Trace 2 | Static Cycle Detection | Static dependency graph analysis detects direct, mutual, and transitive event cycles, rejecting them with ERR_CYCLIC_DEPENDENCY. |
PASS |
| Trace 3 | Event Scoping & Typing | Declared default inputs are applied; caller overrides are strictly type-checked; undeclared parameters are rejected with ERR_UNKNOWN_FIELD. |
PASS |
| Trace 4 | Event Recursion Limit | Dynamic event nesting exceeding 16 levels halts dispatch cleanly with ERR_DISPATCH_BUDGET. |
PASS |
| Trace 5 | Dispatch Budget | Per-tick action execution budget of 1024 units is strictly enforced; excess actions refused with ERR_DISPATCH_BUDGET. |
PASS |
| Trace 6 | Sound Action Usage | Actions attempting to trigger sounds from unauthorized contexts are refused with ERR_UNSUPPORTED_TARGET. |
PASS |
| Trace 7 | Cooldown Refusal | Sounds are refused if re-triggered before their declared cooldown duration has elapsed. |
PASS |
| Trace 8 | Overlap Refusal | Sounds configured with overlap: false refuse dispatch when another voice instance of that sound is active. |
PASS |
| Trace 9 | Anti-Repetition Multipliers | Recent sound playbacks receive monotonically graded multipliers: rank 0 = 0.0, rank 1 = 0.25, rank 2 = 0.50, rank 3 = 0.75. |
PASS |
| Trace 10 | Pool Relaxation | When all candidate sounds in a pool are penalized to effective weight zero, weights relax to base values so scheduling never deadlocks. | PASS |
| Trace 11 | Intensity Scaling | Higher intensity compresses clock intervals; lower intensity expands intervals; clamped to safe bounds (>= 100ms). | PASS |
| Trace 12 | Minimum Gap & Priority | Automatic sound scheduling respects the minimum gap (minGap, default 1.5s) and prioritizes rare > occasional > intermittent > routine. |
PASS |
| Trace 13 | Ambient Voice Maintenance | Continuous ambient sounds auto-start when audio is unlocked and maintain exactly one voice, restarting if stopped. | PASS |
| Trace 14 | Manual SAMPLE PRNG Isolation | Interspersing manual SAMPLE draws from the manual-sample / sample PRNG domain has zero effect on cadence scheduling. |
PASS |
Test Suite Execution Output
> node test/phase5-cadence.test.mjs
✔ Trace 1: Schema & Static Validation of cadence and sound metadata (3.4712ms)
✔ Trace 2: Static cycle detection rejects circular event action chains (0.5927ms)
✔ Trace 3: Event input scoping, defaults application, and strict type checking (1.2611ms)
✔ Trace 4: Dynamic event nesting exceeding 16 levels is halted (0.4059ms)
✔ Trace 5: Per-tick 1024-unit action dispatch budget is strictly enforced (0.9943ms)
✔ Trace 6: Sound actions targeting unauthorized sounds are refused with ERR_UNSUPPORTED_TARGET (0.5403ms)
✔ Trace 7: Sound cooldown refrains from re-dispatching before interval expires (0.7546ms)
✔ Trace 8: Overlap false prevents new instance while existing voice is active (0.6852ms)
✔ Trace 9: Anti-repetition penalties apply 0.0, 0.25, 0.50, 0.75 recency multipliers (0.2897ms)
✔ Trace 10: Anti-repetition relaxation to base weights when all candidates are penalized to zero (0.2865ms)
✔ Trace 11: Intensity scaling inversely compresses or expands clock intervals (0.1554ms)
✔ Trace 12: Minimum gap (1.5s) and priority ordering (rare > occasional > intermittent > routine) (0.1433ms)
✔ Trace 13: Continuous ambient sounds auto-start and maintain exactly one active voice (0.1067ms)
✔ Trace 14: Manual SAMPLE evaluations run in isolated stream without perturbing cadence scheduling (0.9915ms)
ℹ tests 14
ℹ suites 0
ℹ pass 14
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 15.0156
Full repository regression (npm test): 229 tests pass, 0 fail.
3. Exhibits A–D Content Validation
All reference exhibits were augmented with audio graphs, sounds, cadence configurations, and events:
- Exhibit A (Procedural Machine):
machine-hum(ambient drone),relay-click(routine percussive),steam-purge(intermittent burst),emergency-siren(rare alarm), andminor-disturbanceevent. - Exhibit B (Deep Abstract Field):
pad-drone(ambient sine drone),harmonic-resonance(intermittent chord),sub-swell(occasional low swell), andfield-shiftevent. - Exhibit C (Natural Environment):
wind-atmosphere(ambient pink noise),organic-chimes(occasional resonant bell),wind-gust(rare swept gust), andbreeze-surgeevent. - Exhibit D (Instrument Display):
radar-pulse(routine telemetry ping),button-click(manual UI click),telemetry-alert(occasional alert chime), andsweep-alertevent.
All exhibits validated cleanly via tools/validate-exhibit.mjs:
[PASS] exhibits/exhibit-a.xzbt (0 errors)
[PASS] exhibits/exhibit-b.xzbt (0 errors)
[PASS] exhibits/exhibit-c.xzbt (0 errors)
[PASS] exhibits/exhibit-d.xzbt (0 errors)
4. Deterministic Build Digest
Rebuilding XZBT.html via node tools/build-xzbt.mjs incorporates all new runtime modules (src/runtime/cadence-validation.js, src/runtime/cadence.js, and updated actions.js, audio-engine.js, performance.js, app.js):
- Artifact:
XZBT.html - File size: 502,989 bytes
- SHA-256 Digest:
f3f634d7d33b2f8a57cae541fc31b4dcedce88b2ee2648093f92a2cfc168d718 - Determinism: Successive independent builds generate the identical byte sequence and hash.