Commit Graph

5 Commits

Author SHA1 Message Date
Dejvino
e6f5a2f0d5 Epic 2.5.2: make the framing actually reach the image
Revisiting the framing layer turned up that it was not reaching four of the
forty-two scenes, and that none of its gates could have told us.

Those gates check the PLAN — cue sizes, the distribution of shot sizes across
a population, headroom, seek determinism — and a plan that never reaches the
image passes every one of them. Rendered at wide, normal and close, Scan
Tear, Pylon Grid, Pitch Shatter and the 3D Particle Field came back
byte-identical at every size.

The cause was a category error in the first implementation. Framing was
applied inside sigCamera, which is gated on the `camera` personality trait —
so a scene that declined the track's drift and sway silently declined the
shot size as well. That gating is right for a TRAIT and wrong for framing,
which is not one: framing is where the camera is standing for this shot, and
no scene should be exempt from it because of an unrelated art-direction
decision.

- Framing now lives in the shader epilogue, applied to the coordinate every
  fragment scene is handed, so honouring it is not optional. uv is left
  unframed on purpose: it is screen space, and prev() and sigGrain belong to
  the output image rather than to the scene being filmed.
- Scan Tear and Pitch Shatter build their image from uv deliberately — a
  signal artefact happens to the signal, not to the world behind it. They now
  slice on raw uv and build the field they displace from a new framedUv(p),
  so the tear stays locked to the frame while the imagery behind it is filmed
  wide or close.
- Particle Field receives framing in update() and honours it as a camera
  dolly, which is what framing literally is when a layer has a real camera.
  Distance divided by scale, matching the fragment path where the coordinate
  is divided by it.

New gate renders instead of inspecting: 42 of 42 scenes now respond to
framing, weakest Ridge Terrain at 0.22 of its own brightness, against a 0.05
floor. Also drops a stale comment on Layer.setFraming that still claimed
sigCamera applied it.

105/105 checks pass including the slow set.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-06 20:18:08 +02:00
Dejvino
8f5ff3a239 Side quest 2: give three churning scenes something to develop
Curl Flow, Signal Decay and Circuit Bloom had no parameter that changed their
structure. Each was one process at one scale, statistically identical
everywhere and at every moment — which is the technical statement of "it
looks the same for five minutes". Every pixel moving, the image never
changing.

Each got the large-scale structure it was missing, and the slow axis now has
something real to walk:

- Curl Flow gains a CURRENT: one broad band carries the filaments and the
  rest runs bare. The axis is the band's strength rather than its position,
  and that choice was measured — moving the band preserves the frame's total
  energy, so a ten-second average of it is nearly the same image wherever it
  sits (0.0028 across a full sweep). Opening and closing it changes how much
  of the frame is lit at all. The current gates the final image rather than
  only the vein term, because the feedback trail and the flow tint each fill
  the frame on their own.
- Signal Decay gains a DAMAGE FRONT: lock falls away on one side of a moving
  boundary, so the stack has a shape instead of every lane being an
  independent coin flip. Hiss had to be gated by it too — hiss rises as lock
  falls, so without that a damaged lane simply traded signal for noise and
  carried the same energy, and the front cancelled itself out.
- Circuit Bloom now actually BLOOMS. `reach` was a fixed vignette, so the
  packets ran, the pads blinked and the board never changed. Its range stops
  at 1.6 because the frame's far corner is ~1.4 units out and travel spent
  past that changes nothing — the first attempt wasted most of the axis up
  there.

The gate itself was wrong, and this is the more important half of the commit.
It compared the scene at thirty seconds against the scene at two and a half
minutes and divided by what it did between those points with frozen
parameters. Those are two different places in the song, so the denominator
was full of audio reactivity: it was really asking "does the axis move this
scene MORE than the music does", which no scene should have to pass. Circuit
Bloom failed at 0.92x while its mean luminance moved 5.6x across the axis — a
large structural change scored as nothing.

The experiment now holds time constant and varies only the axis, against a
control that is the same parameters over the next window — the residual churn
the ten-second average failed to cancel, which is the noise floor it has to
beat. With the axis disabled the two parameter sets are identical and the
ratio is 0.00 by construction, so the companion check is a real discriminator
rather than a formality. It reads 0.00x on all six scenes.

Moiré Grid 28.7x · Gate Corridor 14.3x · Truchet Fold 3.3x · Signal Decay
1.9x · Curl Flow 1.7x · Circuit Bloom 1.4x, against a 1.25x bar.

104/104 checks pass including the slow set. Closes SIDE-QUESTS.md §2 and the
open half of EPIC-2.md §3.4.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-06 19:51:51 +02:00
Dejvino
19bfff8651 Epic 2.5.1: basis for framing layer 2026-08-06 10:29:32 +02:00
Dejvino
189328587d Epic 2.4: a slow axis, and an honest account of what it fixes
Eleven scenes changed as much in half a second as in two minutes. The cause
was that everything moving in them was cyclic: ArcDriver's drift is a 20-70
second LFO, and an LFO returns, so ten cycles of it over five minutes is not
five minutes of anything. The eye adapts in about two seconds and then there
is nothing left to find — violently animated, and reads as static.

ArcDriver._slowAxisFor adds the missing timescale: a param that travels ONE
WAY across the whole track, keyed on the module so a scene returning in the
last section arrives further along rather than resetting. Rate params are
excluded for the reason schema.js already gives.

Two things were learned by getting them wrong first, and both are recorded
where the next person will hit them.

The first version chose the param at random from everything eligible and
measured as doing NOTHING — identical structural change with the axis applied
and with it disabled. Which param you move decides everything: sweeping Moiré
Grid's `width` moves its time-averaged structure by 0.110 and its `offset` by
0.002, and a random draw finds the second kind almost every time. So the axis
is now DECLARED, `slowAxis: true`, validated by the schema (and rejected on
rate params, where walking one would jump the animation phase).

The second is that single-frame distance cannot measure this at all. A
churning scene's consecutive frames are already ~0.6 apart, so every pair of
its frames scores the same whether the structure moved or not — the metric is
saturated by the churn it exists to see through, and the first gate passed
while the mechanism was provably inert. The gate now compares TEN-SECOND
time-averaged frames. The window was measured rather than guessed: at one
second Moiré Grid's frozen control still reads 0.024, at ten it reads 0.0095
while the signal holds at 0.037.

Per EPIC-2.md §4, the metric is verified by breaking what it should catch:
a second check runs the identical measurement with the axis disabled and
requires it to read ~1.0. It reads exactly 1.00x on all three scenes.

The honest scope, measured across ten candidates and written into EPIC-2.md
§3.4: the axis works on Moiré Grid (3.93x), Gate Corridor (2.88x) and Truchet
Fold (1.40x). Curl Flow, Signal Decay and Circuit Bloom have NO parameter that
changes their structure and still need shader work — parameter automation
cannot substitute for structure a scene does not have. Four more already
develop on their own and were never the problem. The flag is set only where it
is proven, so it means something.

69/70 on phases 3,4,7-11 slow; the one failure is the known load-dependent
Horizon Lines flake recorded in d14d473.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-06 07:54:35 +02:00
Dejvino
b69eaa799d Epic 2: plan for holding five minutes
Written after watching the output rather than after building it. Records what
was measured — the cut metronome, the frozen palette, the 39% of the library
that either churns without developing or barely moves, the constant
kind-to-family table, five or six distinct images per track — and turns it
into five workstreams with gates and a sequence.

Also records what NOT to touch: the production-design layer measures as
strong as parameter variation, so the unifying mechanism is working and is
explicitly out of scope.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-06 07:23:57 +02:00