Revision 0.9 adds section 20, the cadence and event subsystems contract, and carries two corrections the implementation forced. Section 6.1 now states that a duration is the authored literal or a non-negative finite number already in milliseconds, since a DurationSpec may be the resolved output of a ValueSpec or a bounded TimeSpec, with the one documented exception of an automation track's `at`, which 19.1 keeps literal-only so that point ordering stays decidable at import. Section 20.11 documents the rejection of an undeclared input name in an event action's `with` map as ERR_UNKNOWN_FIELD — the section's own convention for that shape of error, replacing an invented code that appeared nowhere in the registry. The review record is committed with the code it describes: the two code triages that found these defects, the reconciliation plan that sequenced the fixes, and a follow-up debt record listing what was deliberately left open — the unchecked JSON Schema artifact, degenerate path arcs, post-effect transient allocation, the window-traffic fixture's per-copy wrap bounds, and the unstated `ownership: "persistent"` value on a sound action. None of the five blocks phase 6; all five are written down rather than dropped. Devlog entries are backfilled for the two milestones that had none: phase 3c slice 2, the audio lifecycle and voice ceilings, and slice 4d, the renderer core. The implementation status summary now reflects the reconciled state rather than the in-flight one. 231 tests pass. tools/verify-spec-contract.py reports 46 declared diagnostic codes with every used code resolving and its two long-standing unresolved cross-references unchanged. Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01ShxxFqFmCUDQnQvFNm4TKy
269 lines
19 KiB
Markdown
269 lines
19 KiB
Markdown
# XZBT 0.1 Application Code Triage — Visual Subsystem Readiness & Impact of §§17–19 Review
|
||
|
||
**Context:** Following the triage of multi-model visual specification reviews in [reviews/01-triage.md](01-triage.md) (covering §§17–19 rev 0.7, 30 repair packages V1–V30, and additional defects A1–A3), this document conducts a comprehensive audit and triage of the **current application codebase** (`src/runtime/*`, `schema/xzbt-0.1.schema.json`, `tools/*`, and `test/*`).
|
||
|
||
**Status of Codebase:**
|
||
- Working tree baseline: commit `527220e` (branch `main`).
|
||
- Test suite: **102 tests passing**, zero failures (`npm test`).
|
||
- Implementation progress: Phase 1 (runtime skeleton), Phase 2 (common grammar), and Phase 3 (audio engine through 3c-4) are implemented and verified.
|
||
- Visual status: Sections 17–19 represent the completed visual contract (slices 4a, 4b, 4c). **No visual renderer or procedural runtime code currently exists in `src/runtime/`**. Slice 4d is the scheduled entry point for visual implementation.
|
||
|
||
---
|
||
|
||
## Executive Scorecard & Code Inventory
|
||
|
||
| Subsystem / Module | Path | Current Implementation Status | Visual Contract & Triage Readiness | Key Touchpoints / Gaps |
|
||
| --- | --- | --- | --- | --- |
|
||
| **Top-Level Constants** | `src/runtime/constants.js` | Implements Phase 3b/3c constants | Stale version string; top-level fields present | `XZBT_RUNTIME_VERSION` is `'0.1.0-phase3b'`. Contains `'visual'` in `RNG_DOMAINS` and `'visuals'`, `'components'` in `ALLOWED_TOP_LEVEL_FIELDS`. |
|
||
| **JSON Schema** | `schema/xzbt-0.1.schema.json` | Validates GC2 and Audio (Phase 3c) | **Severe schema drift / Out of date** | `visuals` definition is a Phase 0 stub (`camera`, `systems`, `passes`). Lacks `scene`, `layers`, `fields`, `effects`, and `automation` (V1). `components.visual` is unconstrained `{ "type": "object" }`. |
|
||
| **Validator** | `src/runtime/validator.js` | Validates Meta, Grammar, Audio | **Permits arbitrary visuals; blocks visual bindings** | Completely lacks `validateVisualSubsystem()`. Rejects all 4 visual binding target families as `ERR_UNSUPPORTED_TARGET` (V2). Lacks `ValueSpec<color>` support (V5). Missing visual authoring limits and diagnostics (V7, V25). |
|
||
| **Resolution Engine** | `src/runtime/resolution.js` | Shared GC3 + Audio resolution pipeline | **No visual target exposure** | `target(path)` only recognizes `parameters.*`, `state.*`, and `audio.buses.*.gain`. Rejects all visual target families, blocking bindings, automation, overrides, and modulation for camera, layers, systems, and effects (V2). |
|
||
| **Actions Executor** | `src/runtime/actions.js` | Implements `set` and `override` | **Missing lifecycle actions** | Throws `ERR_UNSUPPORTED_TARGET` on `spawn` and `remove` actions needed by spawned visual systems (§19.2, V7, V23, A1). |
|
||
| **Automation** | `src/runtime/audio-automation.js` | Implements audio graph tracks | **Audio-coupled; lacks loops** | Implements curves/modes and numeric stages, but enforces audio point bounds (256 vs 2048) and lacks `loop` modes (`repeat`, `ping-pong`) required by §19.1 and V12. |
|
||
| **Performance Shell** | `src/runtime/performance.js` | 60 Hz fixed-step scheduler | **Clock/Signals ready; lacks canvas** | `signals.pointer.*` and `signals.viewport.*` are tracked and updated. No Canvas element lifecycle or rendering loop attachment. |
|
||
| **Type Utilities** | `src/runtime/types.js` | Numeric/String/Color types | **Minimal color support; no geometry** | `color` type is checked only as non-empty string. Lacks color math (fog blending V18), angle conversions, or matrix transforms (V3). |
|
||
| **Diagnostics** | `src/runtime/diagnostics.js` | General diagnostics ring buffer | **Missing visual codes** | Visual diagnostic codes from §§17–19 are not declared or mapped (V24, V27). |
|
||
| **Visual Runtime** | `src/runtime/visual-*.js` | **Nonexistent** | **Pending Slice 4d** | No renderer (`visual-engine.js`), procedural system (`visual-procedural.js`), or visual lifecycle modules exist yet. |
|
||
|
||
---
|
||
|
||
## Detailed Impact Analysis of `01-triage.md` Findings on Application Code
|
||
|
||
### 1. Tier 1 — Contract & Architecture Blockers (Affecting Pre-Renderer and Core Modules)
|
||
|
||
#### V1. `visuals.automation` forbidden by owning table
|
||
- **Application Code Impact:**
|
||
- `schema/xzbt-0.1.schema.json`: Currently has `passes` instead of `effects`, and completely omits `automation`. The schema must add an optional `automation` array under `visuals`.
|
||
- `src/runtime/validator.js`: When visual subsystem validation is implemented, `ALLOWED_VISUAL_FIELDS` must permit `automation` alongside `scene`, `layers`, `systems`, `fields`, `camera`, and `effects`.
|
||
- Scope separation: Code must distinguish exhibit-scope automation (`visuals.automation`, clock zero at performance activation) from system-scope automation (`visuals.systems.<id>.automation`, clock zero at system instantiation/spawn).
|
||
|
||
#### V2. Acceptance trace 17.16.14 contradicts closed visual capability table
|
||
- **Application Code Impact:**
|
||
- `src/runtime/validator.js` (`validateBindings`, line 233):
|
||
Currently restricts binding targets to:
|
||
```javascript
|
||
/^(parameters|state)\.[a-z][a-z0-9_-]*$/.test(binding.target) || /^audio\.buses\.[a-z][a-z0-9_-]*\.gain$/.test(binding.target)
|
||
```
|
||
Must be extended to recognize exactly the four visual target families from Format Specification Table 8.1:
|
||
1. `visuals.camera.<property>` (`x`, `y`, `zoom`, `rotation`, `focalLength`)
|
||
2. `visuals.layers.<layer-id>.opacity`
|
||
3. `visuals.systems.<system-id>.visible`
|
||
4. `visuals.effects[<index>].<param>`
|
||
All other visual properties (such as per-object properties) must continue to emit `ERR_UNSUPPORTED_TARGET`.
|
||
- `src/runtime/resolution.js` (`target(path)`, lines 182–192):
|
||
Currently returns `null` for any visual target. It must be updated to return specification records for camera, layer opacity, system visibility, and post-effect parameters, enabling bindings and overrides to resolve against them.
|
||
|
||
#### V3. Fit, camera, and perspective composition in named spaces
|
||
- **Application Code Impact:**
|
||
- Planned `src/runtime/visual-engine.js`:
|
||
- Must implement the unified scene-to-CSS fit matrix `F` (handling `contain`, `cover`, and `stretch` with offsets).
|
||
- Camera translation must be evaluated in CSS display coordinates: `q = F(cameraCenter)`, translation `q - c`.
|
||
- Perspective scaling factor `focalLength / (focalLength + zEffective)` centered at display center `c`.
|
||
- DPR (device pixel ratio) scaling applied once to the backing store transform.
|
||
- `src/runtime/types.js` or a new math utility module:
|
||
- Needs matrix multiplication / 2D affine transform helpers supporting non-uniform scale, translation, and rotation.
|
||
|
||
#### V4. Primitive geometry definitions & path generation
|
||
- **Application Code Impact:**
|
||
- Planned `src/runtime/visual-engine.js`:
|
||
- Explicit local extents and anchors for all 14 primitives (Visual Primitive Set 0.1).
|
||
- Sweep calculation for arcs (direction, zero sweep, full turn >= 360).
|
||
- Catmull–Rom spline evaluation and closed spline index wrapping.
|
||
- Bezier spline explicit closing segment.
|
||
- Point stroke rendering and open-path fill closure rules.
|
||
|
||
#### V5. Paint ValueSpecs contradict component example
|
||
- **Application Code Impact:**
|
||
- `src/runtime/validator.js` (`validateValueSpec`, line 157):
|
||
- Must recognize that `fill` and `stroke` accept `ValueSpec<color>` (e.g. `{ "ref": "inputs.tint" }`), as well as paint objects and null.
|
||
- Must validate that references inside components resolve to declared component inputs.
|
||
- `src/runtime/values.js` (`ValueResolver`):
|
||
- Must resolve color references and weighted choices of color literals without coercing to numbers.
|
||
|
||
#### V6. System controls vs item initialization resolution boundaries
|
||
- **Application Code Impact:**
|
||
- Planned `src/runtime/visual-procedural.js`:
|
||
- Emitter `count` and `rate` must resolve before allocating particle arrays.
|
||
- ValueSpecs resolved at system instantiation boundary vs per-particle birth draws must draw from separate or strictly ordered PRNG streams.
|
||
- Live automation channels must affect existing vs new particles according to the field ownership table.
|
||
|
||
#### V7. Live automation totals vs import authoring bounds
|
||
- **Application Code Impact:**
|
||
- `src/runtime/validator.js`:
|
||
- Check authored static limits (e.g. template track/point counts).
|
||
- `src/runtime/actions.js` & visual lifecycle manager:
|
||
- Runtime check: when executing a `spawn` action, check whether adding that instance's tracks/points would exceed the live budget (128 tracks, 2048 points).
|
||
- If budget would be exceeded, execute **atomic spawn refusal** (do not partially allocate; raise `WARN_VISUAL_CEILING`).
|
||
|
||
#### V8. Coherent noise reproducible algorithm
|
||
- **Application Code Impact:**
|
||
- `src/runtime/rng.js` or `visual-procedural.js`:
|
||
- Current `SeededRNG` only provides `nextFloat()` and `nextInt()`.
|
||
- Must implement a fully deterministic, portable gradient noise algorithm (fixed hash lattice, permutation table, octaves normalization, and curl math) that produces bit-exact vectors across browsers.
|
||
|
||
#### V9. Sorting units for emitters, repeaters, and mixed-depth geometry
|
||
- **Application Code Impact:**
|
||
- Planned `src/runtime/visual-engine.js`:
|
||
- Procedural systems (particles, repeaters, emitters) must sort as atomic units using a documented representative depth (e.g. lowest live particle depth), with internal ordinal stability.
|
||
|
||
#### V10. Offscreen allocation and compositing
|
||
- **Application Code Impact:**
|
||
- Planned `src/runtime/visual-engine.js`:
|
||
- Maintain a pool of up to 16 offscreen canvas buffers.
|
||
- Layer opacity and blend modes count against this pool.
|
||
- Implement deterministic shedding (farthest objects first) when buffers are exhausted, emitting `WARN_VISUAL_CEILING`.
|
||
- Separate instance release multiplier (initialized to 1) applied during release to avoid resetting authored opacity.
|
||
|
||
---
|
||
|
||
### 2. Tier 2 — Slice-Specific Implementation Requirements
|
||
|
||
#### V11. Repeater automation nonexistent `step`
|
||
- **Application Code Impact:**
|
||
- `src/runtime/validator.js` and visual automation: Ensure `step` is rejected as an unsupported automation target on repeaters.
|
||
|
||
#### V12. Infinite loop legality on visual automation
|
||
- **Application Code Impact:**
|
||
- Automation module (`src/runtime/audio-automation.js` or visual equivalent):
|
||
- Implement `repeat` and `ping-pong` loop evaluation.
|
||
- Reconcile loop legality across exhibit scope, persistent systems, and finite/indefinite spawned systems.
|
||
|
||
#### V13. Placement distributions & PRNG draw consumption
|
||
- **Application Code Impact:**
|
||
- Planned `src/runtime/visual-procedural.js`:
|
||
- Deterministic random sampling for all 9 placement distributions.
|
||
- Fixed draw order (angle before radius; explicit draws for depth and jitter).
|
||
- Grid distribution handling when item count does not match rows × columns.
|
||
|
||
#### V14. Behavior schemas & channel composition
|
||
- **Application Code Impact:**
|
||
- Planned `src/runtime/visual-procedural.js`:
|
||
- Implement all 17 behaviors writing to scalar channels (`x`, `y`, `vx`, `vy`, `speed`, `angle`, etc.).
|
||
- Strict conflict detection: scalar channels cannot be simultaneously driven by conflicting behaviors.
|
||
|
||
#### V15. Morph geometry & target sampling
|
||
- **Application Code Impact:**
|
||
- `visual-engine.js` / `visual-procedural.js`:
|
||
- Restrict morph to point-list primitives with equal point counts. Reject unsupported geometry with `ERR_UNSUPPORTED_TARGET`.
|
||
|
||
#### V16. Distribution path references
|
||
- **Application Code Impact:**
|
||
- `validator.js`: Distribution paths must use inline commands; reject sibling-path references that lack an object container.
|
||
|
||
#### V17. Viewport default fit & explicit-layer omission
|
||
- **Application Code Impact:**
|
||
- `validator.js`: In `viewport` space, an absent `fit` is valid; only explicit non-`stretch` is rejected.
|
||
- If `layers` map is present, system omission of `layer` must raise a named diagnostic rather than silently choosing a layer.
|
||
|
||
#### V18. Fog color math & conic fallback
|
||
- **Application Code Impact:**
|
||
- `visual-engine.js`: Fog interpolation in sRGB/RGBA space; clamp conic gradient fallbacks when the focal point is external or degenerate.
|
||
|
||
#### V19. Post-effect radius conversion
|
||
- **Application Code Impact:**
|
||
- `visual-effects.js`: Convert scene-unit blur/bloom radii to device pixels using display fit and DPR. Map filter names (`saturation`, `hueRotate`) to Canvas filter equivalents.
|
||
|
||
#### V20. Open camera clamp range minimum
|
||
- **Application Code Impact:**
|
||
- `src/runtime/resolution.js`: Camera `focalLength` target must define a positive minimum clamp (e.g. `min: 0.001` or `min: 1`) to prevent division by zero in perspective projection.
|
||
|
||
#### V21. Links style/fade defaults & capacity
|
||
- **Application Code Impact:**
|
||
- `visual-procedural.js`: Distance links must enforce capacity <= 256, resolve missing `maxDistance` when `fadeWithDistance` is true, and implement nearest-neighbor tie-breaking.
|
||
|
||
#### V22. Component-input locations
|
||
- **Application Code Impact:**
|
||
- `validator.js`: Enforce single canonical component-instance input location (`emit.inputs` vs system `inputs`).
|
||
|
||
#### V23. Ownership & release edge semantics
|
||
- **Application Code Impact:**
|
||
- `src/runtime/actions.js`: Support `spawn` and `remove`. Handle `cancelWithScenario`, idempotent duplicate removals, and release factor transitions.
|
||
|
||
#### V24. Resource diagnostics cadence & identity
|
||
- **Application Code Impact:**
|
||
- `src/runtime/diagnostics.js`: Implement throttling / deduplication for `WARN_VISUAL_CEILING` and approximation warnings (e.g. once per second or sustained 120-tick reporting).
|
||
|
||
#### V25. Centralized ceilings completeness
|
||
- **Application Code Impact:**
|
||
- `validator.js`: Enforce static draw load ceilings: path commands (512), burst entries (16), grid dimensions (256), custom partials (64).
|
||
|
||
---
|
||
|
||
### 3. Additional Defects (A1–A3)
|
||
|
||
#### A1. Lifecycle fields collide with particle/emitter/repeater fields
|
||
- **Application Code Impact:**
|
||
- In `schema/xzbt-0.1.schema.json` and `src/runtime/validator.js`:
|
||
System-level `lifetime` (for spawned system duration) collides with item-level `lifetime` (for particle lifespan).
|
||
The codebase must enforce the separated container/field naming (e.g. system lifecycle in a dedicated block or renamed property) before writing procedural validation.
|
||
|
||
#### A2. Missing extension fields
|
||
- **Application Code Impact:**
|
||
- Add `direction` to procedural noise field definitions.
|
||
- Clarify or reject `trail` on particle `render` objects.
|
||
|
||
#### A3. Backing-store limit (4096) & pinned parallax
|
||
- **Application Code Impact:**
|
||
- `visual-engine.js`: When CSS display size × DPR exceeds 4096×4096, downsample the DPR multiplier rather than failing or exceeding the canvas maximum.
|
||
- Parallax 0 pins against camera translation only; zoom and rotation still apply.
|
||
|
||
---
|
||
|
||
## Action Plan & Implementation Sequencing for Application Code
|
||
|
||
The application code changes required by the visual specification and triage findings should be delivered in five coordinated stages aligned with the existing project milestones:
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────────┐
|
||
│ Stage 0: Shared Pre-Renderer Alignment (Pre-4d) │
|
||
│ • Reconcile schema/xzbt-0.1.schema.json (§§17-19, V1, A1) │
|
||
│ • Update validator.js: expose 4 visual target families (V2) │
|
||
│ • Update resolution.js: target() returns visual specs (V2) │
|
||
│ • Update constants.js: version string to phase4 │
|
||
└──────────────────────────────┬──────────────────────────────┘
|
||
│
|
||
▼
|
||
┌─────────────────────────────────────────────────────────────┐
|
||
│ Stage 1: Renderer Core (Slice 4d) │
|
||
│ • Canvas 2D backend, Scene fit & Camera transform (V3, A3) │
|
||
│ • 14 Primitives path generator & appearance (V4, V5) │
|
||
│ • 16-buffer offscreen pool & compositing (V10) │
|
||
│ • Depth sorting & fog blending (V9, V18) │
|
||
└──────────────────────────────┬──────────────────────────────┘
|
||
│
|
||
▼
|
||
┌─────────────────────────────────────────────────────────────┐
|
||
│ Stage 2: Procedural Systems (Slice 4e) │
|
||
│ • Component instantiation & inputs resolution (V5, V22, A1) │
|
||
│ • Particle Euler integrator & emission math (V6, V29) │
|
||
│ • 9 Placement distributions & draw orders (V13) │
|
||
│ • 17 Behaviors & scalar channels (V14) │
|
||
│ • Coherent noise algorithm (V8) │
|
||
│ • Distance links & trails (V21) │
|
||
└──────────────────────────────┬──────────────────────────────┘
|
||
│
|
||
▼
|
||
┌─────────────────────────────────────────────────────────────┐
|
||
│ Stage 3: Automation, Lifecycle & Effects (Slice 4f) │
|
||
│ • Shared automation with repeat/ping-pong loops (V1, V12) │
|
||
│ • System lifecycle actions (spawn/remove) in actions.js(V23)│
|
||
│ • Atomic admission & live ceiling checks (V7, V24, V25) │
|
||
│ • Post-processing filter chain & device conversion (V19) │
|
||
└──────────────────────────────┬──────────────────────────────┘
|
||
│
|
||
▼
|
||
┌─────────────────────────────────────────────────────────────┐
|
||
│ Stage 4: Verification & Acceptance (Slices 4g & 4h) │
|
||
│ • PRD 130 challenge fixtures and Exhibit visuals │
|
||
│ • Hardware benchmark and resource audit │
|
||
└─────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
---
|
||
|
||
## Immediate Next Steps & Safety Invariant
|
||
|
||
1. **Safety Invariant:** All existing 102 tests in `npm test` must continue to pass without regression. Audio and common grammar semantics remain locked.
|
||
2. **Contract Synchronization:** Before implementing the Canvas 2D renderer in Slice 4d, Stage 0 must synchronize the shared validator, JSON schema, and target resolver to prevent drift between Format Specification Rev 0.7 and the runtime foundation.
|
||
3. **Evidence Record:** Maintain this triage alongside `reviews/01-triage.md` and `reviews/04-fix-log.md` to track code closure as Phase 4 slices proceed.
|