PRD · Resonance Garden (v2)

A working design document, published as written. The Resonance Garden that is live today is v1; everything below is the plan for what replaces it. It is in the open because the reasoning is more reusable than the conclusion. Revised August 2026.

One line

A self-contained 3D field where recursive structures grow from simple rules, where coherence is something you can hear before you can see it, and where the system measures emergence but you name it.

Why build it

The Triple Helix proved one mechanic worth keeping: a slow integrator that climbs only under sustained coherence feels more true than reacting to spikes. But the piece is a guided tour. Fixed structure, pre-named layers, scripted ascent. You tune someone else's model and nothing surprises you.

v2 keeps the gating and throws out the fixed meaning. Structure becomes generative. Coherence gets measured from whatever grew. And the relationship inverts: the system stops telling you what things mean. It reports what it can measure, holds the silence past that, and leaves the naming to you. The first PRD asked how much the system should narrate. The answer is now structural: measurement is the system's job, meaning is the user's. That single rule resolves the open-endedness worry. A sandbox feels like a toy when nothing in it matters. Things matter when they're scarce, earned, and yours. So coherence is hard to sustain, tiers decay when you stop tending them, and the forms you stabilize get pressed into a codex under names you chose.

Principles

Core systems

1. Fractal generator (the substrate)

Unchanged in intent from v1. A recursive structure engine grows forms by iterating a rule in 3D. Rule families, in build order:

  1. Recursive branching (L-system style). Seed segment spawns children at angle and scale ratios, recursing to a depth limit. Trees, ferns, coral, and with the right child count and twist, helices. MVP.
  2. Iterated function system. A handful of affine transforms applied to a point cloud. Strange attractors, fractal flames. Stretch.
  3. Recursive subdivision. Polyhedron subdivided and displaced by rule. Shells, membranes. Stretch.

Each family exposes 4 to 6 parameters: depth, child count, scale ratio, branch angle, twist, jitter. Parameters dial live, structure regrows with a short morph rather than a hard rebuild, so cause and effect stay legible.

Every element (segment, point, face) carries a phase: a scalar angle advanced each frame by the dynamics. Phase is what the dynamics act on, what coherence is measured from, and what the audio listens to. This is the load-bearing addition. It makes the structure a population of oscillators instead of static geometry, and everything downstream reads from it.

2. Coherence field (measured, not set)

This was v1's hardest open question. Proposed answer, concrete enough to spike:

Signal A, phase alignment (per frame, cheap). Kuramoto order parameter over a rotating sample of ~256 elements: R = |mean(e^{iθ})|, computed with two running sums. R near 0 is incoherent, near 1 is locked. One pass, no allocation. This alone is enough for MVP.

Signal B, orientation alignment by depth band. Mean resultant length of segment direction vectors within each recursion depth band. Tells you whether order is local or runs the whole structure.

Signal C, multi-scale self-similarity (slow, amortized). Compare realized statistics (mean and variance of angle and scale, after jitter) between adjacent depth bands. High similarity across bands means the pattern repeats across scales, which is the thing that makes a form fractal rather than merely branched. Updates every ~30 frames, not per frame.

Composite coherence C = weighted blend of A, B, C, smoothed by EMA. The sustained-coherence integrator carries over intact: it climbs only while C holds above threshold, with hysteresis so flicker can't game it, and it bleeds when C drops. The user never touches C directly. They influence it through the dynamics (breath modulation, entrainment, drift, echo pulse, field memory), all carried over from the current build, now acting on element phases instead of three fixed strands.

Three time-scales, stated once and honored everywhere: - Fast: phase dynamics, per frame. - Slow: growth and regrowth, seconds. - Geological: field memory and sediment, minutes. Regions that held high coherence leave faint persistent traces in the field. The space remembers the session. Return to a place you stabilized before and the trace gives a small entrainment assist, like a worn path.

3. Emergent tiers (earned and losable)

The system watches for thresholds of sustained coherence and self-similarity and lights tiers as they're earned: glow body, then observer nodes, then outer field. Same visual vocabulary as the current ε / ζ / η envelopes, triggered by measurement.

Two changes from v1's sketch:

4. Sonification (the new narrator)

Pure WebAudio oscillators, no assets, fits the single-file constraint. The field has a quiet drone built from a few partials. The mapping:

This is how the instrument narrates without words. The whole question of "how much should the system say" mostly dissolves: it hums. Master mute, default volume low, audio starts only on first user gesture (mobile autoplay rules require this anyway).

5. Sandbox interaction

6. Seed codes (sharing without a server)

Any state serializes to a compact string: rule family, parameters, RNG seed, dynamics snapshot, packed and base64'd. Maybe 60 characters. Copy it, paste it anywhere, paste one back in and the exact form regrows. Discovery becomes shareable with zero persistence and zero backend, which keeps the single-file constraint pure. This is cheap to build and might be the highest-value feature per line of code in the document.

7. The codex (pressing flowers)

When a structure holds tier ζ or above for a dwell time, the system offers to press it: a snapshot thumbnail, the seed code, and the measured signature (tier reached, hold duration, fold symmetry, coherence trace) go into an in-session codex. The user names the entry. The system never suggests names. A session's codex is a record of what you found and what you called it. Stretch: export the codex as a single image strip.

8. Garden mode (evolution under coherence selection)

The "let it run" idea, sharpened into a mechanic. Parameters take slow random walks. The sustained-coherence integrator acts as fitness: mutations that raise sustained coherence persist, mutations that collapse it revert toward the last stable point. Walk speed anneals as coherence climbs, so a stable form settles and a stuck form keeps searching. The field gardens itself, drifting toward attractors nobody specified. The user can watch, or perturb mid-evolution and see the search resume. This is the feature that makes the system able to surprise its own author, which is the bar v1 set in its first principle.

9. Interference (post-MVP, second structure first)

Multiple structures couple through the shared field. Each broadcasts its mean phase, others entrain toward it weighted by inverse distance. Expected behaviors, all emergent from one coupling rule: beat patterns between mismatched forms, mutual capture when frequencies are close, one structure destabilizing another, and the interesting case, two individually unstable structures stabilizing each other. Don't special-case any of these. If the coupling rule is right they fall out.

Honest state

When measured coherence has been flat and low for ~20 seconds, one quiet line: "field static, coherence 0.12, deepest band incoherent." When a tier collapses: "ζ lost at 02:31." No advice, no encouragement. The instrument reports. The user decides what to do about it.

What changes from v1 of this PRD

v1 said v2 says
Coherence measured "somehow," needs a spike Concrete three-signal metric, order parameter first, spike defined
Four tiers detected, mechanism vague Hysteresis, dwell times, and decay; tiers are losable
Narration: "less than current, more than zero" Sonification narrates state; text reduced to measurement reports; user names everything in the codex
Open question: does open-endedness dilute the payload Resolved by scarcity and ownership: earned tiers, decay, sediment, named codex entries
"Let it run" as a stretch curiosity Garden mode: mutation under coherence selection, annealed
Save/recall in memory Seed codes: full states as short shareable strings
Multiple structures "coexist and interfere" One coupling rule (distance-weighted phase entrainment), behaviors emergent

What stays from the current build: the sustained integrator, the dynamics panel, the FUI restraint from the last cleanup pass, ACES tone mapping, bloom behind a plain-render fallback, the refined palette.

MVP scope

  1. Recursive branching family with live regrowth and morphing.
  2. Element phases plus Signal A (order parameter) driving the integrator. Signals B and C land in a fast follow.
  3. Tier detection with hysteresis and decay.
  4. Sonification core: drone, harmonic locking, tier partials. (Small surface area, large payoff, belongs in MVP.)
  5. Perturbation grammar: tap, hold, drag.
  6. Triple helix recoverable as a branching preset. This is the acceptance test that the general engine subsumes the old piece.
  7. Seed codes for save, recall, and sharing.
  8. Carried-over dynamics panel and post-processing with fallback.

Stretch

Technical constraints

Spikes, in order

  1. Order parameter over instanced phases. Build a 5k-element branching structure with per-element phase, compute R per frame, confirm 60fps on a mid-range phone. This de-risks the whole coherence system and most of the perf budget in one go.
  2. Live regrowth. Parameter change to morphed regrowth without hitching. Decides whether morphing is interpolation of node targets or fade-out/fade-in.
  3. Harmonic locking audio. Map R to partial detune, confirm the locking moment is audible and not annoying at low volume.
  4. Seed code round-trip. Pack, unpack, regrow, verify identical.

Spike 1 gates everything. If the metric can't run cheap, the fallback is computing R over depth-band means instead of raw elements, which is coarser but nearly free.

Remaining open questions