Files
XZBT/docs/evidence/phase4/2026-09-06-phase4b-contract.md
T
LabyricornandClaude Opus 5 245af6ece3 docs(visual): specify the phase 4b component, procedural system, and behavior contract
Format Specification section 18 (PRD 77-84) closes slice 4b: visual
components and their inputs scope, particle systems with a normative
integrator and life ramps, the nine placement distributions, emitters
with exact fractional-accumulator emission timing, repeaters and the
copy-scoped repeat.* namespace, the seventeen-behavior vocabulary and
its channel set, the six procedural fields with a normative coherent
noise function, and trails, ribbons, and links.

Seven diagnostic codes are added to the section 7 table. Section 17 is
amended in four places the new section requires: the visuals.fields
container, the component visual object type beside the closed fourteen
primitives, the now-declared behaviors field, and the widened visual
limit row. Revision 0.5 -> 0.6.

Documentation only; no runtime, schema, fixture, or test file changed.
npm test remains 102 passing.

Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_019dTNHWyTdFobdevrKspoV6
2026-09-06 04:13:36 +00:00

11 KiB

Phase 4b evidence — Visual subsystem contract, part II (Format Specification section 18)

Date: September 6, 2026 Slice: 4b — Contract II (documentation only; no runtime change) Baseline: main at 3e27a66 (Phase 4a, section 17) Specification revision: 0.5 → 0.6 PRD coverage: 77-84

What this slice fixes

Section 18 continues the Visual contract section 17 opened. It covers reusable visual components and their input scope, particle systems and the normative motion integrator, the nine placement distributions, emitters and exact emission timing, repeaters and the copy-scoped repeat.* namespace, the seventeen-behavior vocabulary and the channel set behaviors may write, the six procedural fields and the normative coherent-noise function behind them, and trails, ribbons, and links.

Section 19 (Phase 4c) remains the owner of visual automation, lifecycle and ownership, camera, post-processing, and the centralized ceilings. The forward references to 19.1, 19.2, and 19.5 are the only unresolved numeric references in section 18, and they close when 4c lands.

Decisions taken, so 4e does not relitigate them

  1. component is a visual object type, not a fifteenth primitive. Visual Primitive Set 0.1 stays closed at the fourteen geometry primitives section 17.9 fixed. Section 18.1 adds component beside that set, exactly as 15.11 added a component node beside the audio node set 14.3 opened, so a component instance can be placed inline in any content or children container instead of only being reachable through a repeater of count one.
  2. Visual component parameters admit four types, audio's admit one. number, boolean, string, and color — the shared scalar types of section 2. The audio contract (15.15) permits only number because an audio node field is always numeric; a visual field may be a color, a label, or a visibility flag. min, max, and unit remain number-only.
  3. inputs.* and repeat.* are construct-scoped, not document namespaces. Both follow the rule 15.15 fixed for audio components: legal only inside their construct, ERR_INVALID_REFERENCE anywhere else, absent from the section 1.3 namespace list, and granting no section 8.1 capability.
  4. A component's expansion path, not its ID, is its stable instance key for section 9.3 stream derivation. Two instances of one component therefore sample independently, and reordering unrelated siblings does not perturb either — the same property 14.12 gives audio components.
  5. Particle motion has a normative integrator. Semi-implicit Euler, velocity before position, with drag as (1 - drag)^dt so it is tick-length independent. A renderer that integrates position first, or applies drag once per tick regardless of dt, produces visibly different motion at a different tick rate and does not conform. Traces 5 and 6 pin both halves.
  6. Life ramps interpolate resolved endpoints; they do not re-sample. size, opacity, and color may ramp over normalized age using the same four curves PRD 85 fixes for automation. from and to resolve once at particle creation, so 17.14 and 9.3 hold unchanged: rendering still consumes no procedural stream. This is what gives PRD 78 its age property without breaking reproducibility.
  7. Emission timing is a fractional accumulator, not a per-tick rounding. Cumulative count after t seconds at a constant rate is floor(rate * t) exactly, under any tick length, with no drift and no reset when automation changes the rate later.
  8. Unbounded emission fails validation. A system that declares emission but neither a per-item lifetime nor a total limit is ERR_UNBOUNDED_EMISSION. An initial count with no lifetime stays legal — a fixed starfield that never expires is the common case, not the dangerous one.
  9. Pool exhaustion evicts oldest-first, mirroring the voice eviction of 16.6, and is silent at the system level. The aggregate ceiling across systems and its diagnostic belong to 19.5.
  10. Index-driven placement needs a known count. even modes and the grid type place item i of n, so they are legal in a repeater and in a fixed count or burst population and are ERR_INVALID_DISTRIBUTION on continuous rate emission. Distribution sample-consumption order is normative (x, then y, then z; angle before radius) so fixtures place identically everywhere.
  11. Coherent noise is specified, not left to the renderer. Three-dimensional gradient noise on the integer lattice, twelve edge-midpoint gradients, a 256-entry permutation shuffled from the field's own stream at instantiation, and the quintic fade 6u^5 - 15u^4 + 10u^3. Reproducibility (9.3) promises identical decisions rather than identical pixels, but a field that drove motion differently on two conforming renderers would make a fixture untestable, so the function itself is pinned. curl is the default mode because it is divergence-free and will not pile items into a point.
  12. Ribbons are a trail render mode, not a separate system type. A ribbon is the same history buffer drawn with area instead of a stroke, so trail.mode is line, ribbon, or points. PRD 84 is satisfied without a fourth procedural system.
  13. links is illegal on an emitter. A particles system and a repeater have bounded, known populations; an emitter's changes continuously and its pair search would have to be rebuilt every tick at exactly the cost the ceiling exists to prevent. All three PRD 84 rules — distance, nearest, index — are specified, with distance the required 0.1 minimum.
  14. Behaviors write internal channels; they do not extend section 8.1. The property channel set of 18.6 is a behavior's own permitted write set. External addressability of visual properties remains a section 19.1 decision, and a binding, set, or override naming anything introduced here is still ERR_UNSUPPORTED_TARGET.
  15. The morph rule section 17.13 deferred is now fixed: equal type, equal point count, and equal spline mode, with ERR_MORPH_INCOMPATIBLE on any mismatch. Resampling one shape onto another's point count would change the geometry the author wrote, so it fails validation instead.

Amendments to section 17

Four, all consequences of this slice rather than corrections:

  • 17.3 gains a fields row for the visuals.fields container. Without it the strict unknown-field policy would make every declared field ERR_UNKNOWN_FIELD.
  • 17.9 records that Visual Primitive Set 0.1 is closed at fourteen and that 18.1 adds the component object type beside it.
  • 17.10's behaviors row no longer reads "Rejected as ERR_UNKNOWN_FIELD until section 18 declares them"; it now carries the 0 to 8 bound.
  • 17.15's local ERR_VISUAL_LIMIT_EXCEEDED row names the procedural-system ceilings this section adds.

No decision recorded in section 17 was reversed.

New diagnostic codes

Seven were added to the section 7 table, which remains the single authoritative list: ERR_INVALID_DISTRIBUTION_TYPE, ERR_INVALID_DISTRIBUTION, ERR_INVALID_BEHAVIOR_TYPE, ERR_INVALID_BEHAVIOR_TARGET, ERR_INVALID_FIELD_TYPE, ERR_MORPH_INCOMPATIBLE, and ERR_UNBOUNDED_EMISSION. Section 18.9 repeats them for locality, exactly as 15.18, 16.10, and 17.15 do.

ERR_COMPONENT_RECURSION is reused for visual component recursion and over-nesting rather than duplicated under a visual name, along with ERR_VISUAL_LIMIT_EXCEEDED, ERR_INVALID_REFERENCE, ERR_INVALID_RANGE_ORDER, ERR_OUT_OF_BOUNDS, ERR_TYPE_MISMATCH, ERR_UNKNOWN_FIELD, ERR_SCHEMA_VALIDATION, and WARN_AUTOMATION_FALLBACK.

Authoring limits fixed in this slice

Limit Bound Diagnostic
Visual component nesting depth 8 (matches audio, 15.14) ERR_COMPONENT_RECURSION
Particle capacity per system 4096 ERR_VISUAL_LIMIT_EXCEEDED
Emitter capacity per system 512 ERR_VISUAL_LIMIT_EXCEEDED
Repeater count 1024 ERR_VISUAL_LIMIT_EXCEEDED
burst entries per system 16 ERR_SCHEMA_VALIDATION
Behaviors per object 8 ERR_VISUAL_LIMIT_EXCEEDED
Declared fields per exhibit 8 ERR_VISUAL_LIMIT_EXCEEDED
Fields referenced per system or behavior 4 ERR_VISUAL_LIMIT_EXCEEDED
Noise octaves 4 ERR_OUT_OF_BOUNDS
Grid columns / rows 256 each ERR_VISUAL_LIMIT_EXCEEDED
Trail length 128 samples ERR_VISUAL_LIMIT_EXCEEDED
Links per system per tick (maxLinks) 1024 ERR_VISUAL_LIMIT_EXCEEDED
Statically known population under a pairwise link rule 256 ERR_VISUAL_LIMIT_EXCEEDED
Nearest-neighbour links per item (count) 8 ERR_SCHEMA_VALIDATION

These are authoring bounds a document must satisfy at validation. The aggregate runtime ceilings — total active particles, total spawned systems, total links, total field evaluations, and the per-tick budget they share (PRD 89, 120) — remain slice 4c and are not set here. Slice 4h is what determines whether these bounds are the right ones.

Verification performed

This slice changes documentation only. No runtime source, schema, fixture, or test file was touched.

  • Every diagnostic code used in section 18 (19 distinct codes) resolves to a row in the section 7 table; zero unresolved, checked programmatically.
  • Every numeric cross-reference in section 18 resolves to an existing heading, except the intended forward references to 19.1, 19.2, and 19.5.
  • All code fences in section 18 are balanced and every table row is well formed.
  • npm test passes 102 tests with zero failures, confirming the existing suite is unaffected.
  • The section 11 contract register's Visuals row now reads In progress (Rev 0.6 / Phase 4a-4b) and names what remains for 4c.

Test boundary

Traces 1-19 of section 18.10 are automated and belong to slice 4e, where the procedural systems exist to run them. Traces 20 and 21 — the PRD 130 visual challenge judged on a real display, and the early combined GC6 benchmark at 1920 x 1080 — are user-observed and close slice 4h. Trace 20 is the same gate as trace 15 of 17.16, restated for locality rather than added as a second gate.

State at this checkpoint

Sections 17 and 18 are contract only. No visual runtime code exists: src/runtime has no renderer module, the JSON Schema has no visual definitions, exhibits/ has no visual fixture, and nothing has been drawn from any build. Phase 3 also remains unaccepted while its own user-observed gates (traces 15-17 of section 16.11) and the Phase 1 direct-file restart observation are open; no Phase 4 slice depends on them, and no Phase 4 slice can close them.

Whether sections 17-19 pass a multi-model review before slice 4d begins — the pass that found thirteen defects in sections 14-16, nine of which any single reviewer would have missed — remains an open decision, and section 18 has now roughly doubled the surface that review would cover.