Files
XZBT/docs/evidence/phase5/2026-09-06-phase5-events-cadence.md
T
LabyricornandClaude Opus 5 3db1df058f feat(cadence): implement the phase 5 event and cadence subsystems
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
2026-09-06 21:53:51 +00:00

8.0 KiB
Raw Blame History

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:

  1. Contract & Schema: Complete Section 20 normative contract in the Format Specification and JSON Schema definitions for CadenceConfig, CadenceClockRange, SoundCadence, ActionSpec, and EventDefinition.
  2. Static & Semantic Validation: Implemented in src/runtime/cadence-validation.js, integrated with src/runtime/validator.js and tools/validate-exhibit.mjs. Static cycle detection for events (ERR_CYCLIC_DEPENDENCY), clock range ordering (ERR_INVALID_RANGE_ORDER), and sound cadence metadata validation.
  3. Action Model 0.1: Implemented in src/runtime/actions.js with type: 'event' and type: '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).
  4. Procedural Cadence Engine: Implemented in src/runtime/cadence.js with clock interval management for routine, intermittent, occasional, and rare classes, 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 (cadence domain).
  5. 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.
  6. 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 of XZBT.html produce 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), and minor-disturbance event.
  • Exhibit B (Deep Abstract Field): pad-drone (ambient sine drone), harmonic-resonance (intermittent chord), sub-swell (occasional low swell), and field-shift event.
  • Exhibit C (Natural Environment): wind-atmosphere (ambient pink noise), organic-chimes (occasional resonant bell), wind-gust (rare swept gust), and breeze-surge event.
  • Exhibit D (Instrument Display): radar-pulse (routine telemetry ping), button-click (manual UI click), telemetry-alert (occasional alert chime), and sweep-alert event.

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.