docs(devlog): cover the phase 4a and 4b visual contract
One entry for the visual contract milestone: why two documentation slices precede the renderer, the decisions sections 17 and 18 fix, and what is explicitly not claimed - no renderer, no schema definitions, no visual fixture, and two user-observed gates still open at the end of Phase 4. Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_019dTNHWyTdFobdevrKspoV6
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
_model: devlog-entry
|
||||
---
|
||||
schema_version: 1
|
||||
---
|
||||
title: Writing the visual contract before the renderer
|
||||
---
|
||||
date: 2026-09-06
|
||||
---
|
||||
author: Labyricorn
|
||||
---
|
||||
summary: Phase 4 opens with two documentation slices rather than a canvas. Sections 17 and 18 of the format specification fix the scene, the fourteen primitives, the transform order, and then the components, particles, distributions, emitters, repeaters, behaviors, and fields that compose them - all before a single pixel has been drawn from a build.
|
||||
---
|
||||
tags: Visuals, Contracts, Determinism, Specification, Phase 4
|
||||
---
|
||||
source_commit: 245af6ece32b8359dd2e481f75dd58f2af88e12e
|
||||
---
|
||||
body:
|
||||
|
||||
XZBT can now describe what it looks like. It still cannot draw. The [scene and primitive contract](https://git.labyricorn.com/Labyricorn/XZBT/commit/3e27a668e2f1bc67637285bff19f55c48e0905fe) and the [component and procedural system contract](https://git.labyricorn.com/Labyricorn/XZBT/commit/245af6ece32b8359dd2e481f75dd58f2af88e12e) add more than eight hundred lines of normative specification and not one line of renderer. That ordering is deliberate, and it is the same ordering that saved the audio subsystem a rewrite.
|
||||
|
||||
## Why two documentation slices come first
|
||||
|
||||
Phase 3 taught the lesson the hard way. The audio contract was drafted, then reviewed, and the review found thirteen defects — nine of which a single reviewer would have missed. Four of them were outright contradictions in a draft that implementation was about to begin against. One was a node identity rule that said two incompatible things at once.
|
||||
|
||||
Phase 4 is larger: twenty-one PRD sections, a fourteen-item acceptance challenge, and the first visuals for four reference exhibits. So it is delivered in eight slices, and the first three are contract only. Sections 17, 18, and 19 fix the decisions that a renderer would otherwise have to invent and then defend forever.
|
||||
|
||||
Section 17 covers the scene: three coordinate spaces and their fit modes, the layer set, 2.5D depth, fourteen geometry primitives, common properties, the transform model, appearance, and paths and splines. Section 18 covers everything that composes them: reusable visual components, particle systems, nine placement distributions, emitters, repeaters, a seventeen-behavior vocabulary, six procedural fields, and trails, ribbons, and links.
|
||||
|
||||
## The decisions worth having written down
|
||||
|
||||
Some of these look small on the page and are not.
|
||||
|
||||
**Angles are degrees, everywhere, with zero along positive x.** There is no radian field in the visual contract. The audio contract already spells oscillator phase in degrees, so the whole format now has one angular convention instead of two.
|
||||
|
||||
**Increasing z is farther from the camera.** Objects sort greater z first, ties broken by document key order, using the same document-order rule the PRNG derivation already relies on. Perspective is a single stated factor. Under an orthographic camera, z still affects sorting, parallax, and fog, but never scale.
|
||||
|
||||
**Transform composition order is normative and pinned by a test that can fail.** Rotation and non-uniform scale do not commute, so the required trace uses a case where folding the order differently produces a different pixel. A renderer cannot quietly reorder the stack and still pass.
|
||||
|
||||
**Visual objects are keyed, not listed, and carry no id field.** This is the rule the audio contract adopted only after the review caught it. Adopting it up front in a second subsystem is the cheapest defect the project has ever closed.
|
||||
|
||||
**Fields resolve once, at instantiation.** A random starting position is sampled when its object is created and holds for that object's life. Rendering consumes no procedural stream at all, which is what keeps a seeded exhibit identical across frame rates and machines. Time variation comes from three named mechanisms and nothing else: behaviors, visual automation, and whichever properties section 19 eventually makes externally addressable.
|
||||
|
||||
That last constraint forced the most interesting decisions in section 18. Particles need to change over their lifetime, but they cannot re-sample. So a particle's size, opacity, and colour may be a life ramp — two endpoints resolved once at creation, with a stated curve between them. Emitter timing needs to be exact regardless of tick length, so emission is a fractional accumulator whose cumulative count after t seconds is exactly the floor of rate times t. Particle motion needs to look the same at any tick rate, so the integrator is normative down to the order of the velocity and position updates and the exponent on drag.
|
||||
|
||||
Procedural noise got the same treatment. The requirement was seeded coherent noise with configurable scale, speed, octaves, and persistence. The specification now names the lattice, the twelve gradient vectors, the permutation shuffle and where its samples come from, and the quintic fade function. Reproducibility in XZBT has never promised identical pixels — but a field that pushed particles differently on two conforming renderers would make every fixture untestable.
|
||||
|
||||
## What is not claimed
|
||||
|
||||
No visuals exist. There is no renderer module, the JSON Schema still has no visual definitions, and no exhibit ships a visual fixture. The full test suite passes at 102 tests, and every one of them is about something else; both slices are documentation-only by design, and the traces they define belong to the implementation slices that follow.
|
||||
|
||||
Phase 3 also remains unaccepted. Its measurement and listening gates need real hardware, and no Phase 4 slice depends on them or can close them. The visual work carries that debt forward rather than resolving it.
|
||||
|
||||
Two gates sit at the end of Phase 4 that no amount of specification will close: the fourteen-item visual challenge, judged by eye on a real display, and a benchmark run on a real machine at 1920 by 1080. Every ceiling written into these two sections — particle capacity, emitter capacity, link counts, trail lengths — is a considered guess until that benchmark runs.
|
||||
|
||||
One decision is still open. Whether sections 17 through 19 get the same multi-model review that found thirteen defects in the audio contract, before the renderer starts, is undecided. Section 18 roughly doubled the surface such a review would have to cover.
|
||||
Reference in New Issue
Block a user