Skip to content

A garden: the flowers piece grows a field, in one wind on one ground - #44

Open
aj-dev-smith wants to merge 89 commits into
mainfrom
flowers-garden
Open

A garden: the flowers piece grows a field, in one wind on one ground#44
aj-dev-smith wants to merge 89 commits into
mainfrom
flowers-garden

Conversation

@aj-dev-smith

@aj-dev-smith aj-dev-smith commented Aug 12, 2026

Copy link
Copy Markdown
Owner

A garden, in the flowers piece

?garden=N (2..12) grows a whole flowering field in flowers.html: N specimens, dealt
without replacement from the eight flowering species, each rotating its own floral form off
its own seed, germinating on a stagger, standing in one wind on one ground, shot by a
five-shot director. The URL still fully decides the field.

flowers.html?garden=7&seed=21
flowers.html?garden=7&seed=21&shot=wide      # pin one shot, for stills

Nothing about a plant's shape is drawn here either. Placement, camera, ground and air are
the environment category the project already allows — "where a plant stands was never a
simulation result"
— and this branch adds no growth code and no organ geometry.

What it cost, measured

before after
minimum spacing 2.5 units, set by eye against one corolla 12, measured over 160 species x form x seed cells
field radius fixed 7 for any N 0.83 s sqrt(N) — constant areal density
capture, garden=7 120.9 ms 38.0 ms (56.0 ms at the establishing distance)
stream floats, garden=7 tri 8.64M / petal 14.63M tri 4.63M / petal 12.94M (veins identical by construction)
pollen hero only — 1 of 7 plants shedding 6 of 7, one population over the field
sky the hero's palette over every species a field blend, chroma-restored, hero leads 0.35

Live, 30 s of real growth at garden=7: gap median 8.7 ms, p95 66.4, worst 117.6, 56.9 fps
measured. Gates: flowers/build.js exits 0, flowers/parity.test.mjs 20/20,
test/smoke.mjs 73/73, test/views.mjs 23/23, both artifacts rebuilt and not stale.

Three findings that outlive the feature

Capture cost was FLORAL, not leaf — and that corrects the shipped app's own diagnosis.
70% of a field capture is floral organs (petal 45.9 ms, sepal 28.2, leaf 25.3, stamen 13.1)
because 20_draw.js pins detL = 1.0 for every floral organ — the microscope permanently
on, so a 0.1-unit filament was built as a 75x75 grid for 70 pixels. flowers/28_lod.js caps
mesh resolution at one quad per pixel: a cap, never a raise, no taste constant in it
(pxHeight is the drawing buffer, fov is the camera's, one quad per pixel is Nyquist).
Do not lower it to buy frames — it is Nyquist, not a dial. ?lod=0 is the pre-LOD page.

Reach is a statement about a SEED, not a species. Ember Creeper columbine measures maxR
7.4 at seed 21 and 65.9 at seed 31697 — same species, same form, 9x apart — and that
specimen is still climbing linearly at step 3200 (11.9 -> 28.8 -> 44.4 -> 70.9): a creeper
whose axes never arrest. A one-seed table got the middle right and the tail 3x wrong, and
the tail is what collides. No fixed spacing can keep a creeper off its neighbours and none
should try — that is organBudget's business, not placement's. So 12 is a stated fraction
(full clearance of two median bodies, 62% of two median arms), not a clearance guarantee.

A plain palette mean is mud, measurably. Blending seven species' atmospheres gives fog
saturation 0.261 against a member mean of 0.598, and keyCol 0.090 against 0.328 — near-grey.
The shipped blend preserves luminance and restores chroma. The hero still leads at 0.35
because a pure field mean gives every garden the same violet sky: mean pairwise fog-hue angle
across 40 fields is 84 deg at lead 1.0, 64 at 0.35, 27 at 0.0.

Also here

  • flowers/45_director.js — wide (establishing, solved from the field's plant bounds and the
    live frame equation), bank (the thicket mid-shot), dolly, close, low. flowerScore() picks a
    subject across the whole field; a drag suspends the director for 25 s in a garden.
  • flowers/25_ground.js — the project's first ground geometry. One shared FL_SKY so the
    ground and the background are the same sky rather than two that resemble each other, plus a
    ground-hugging haze whose optical depth is closed-form. No hard horizon at any camera height
    the director reaches (tools/flowers_horizon.mjs is the check).
  • Harness: tools/flowers_shot.mjs, tools/flowers_perf.mjs, tools/flowers_horizon.mjs,
    test/flowers_capture.mjs (a headless field profiler), test/flowers_pollen.mjs (a census
    that asserts the population balances). The headless profiler caught the shot tool
    double-counting the hero — 998 organs reported for 771.
  • Docs: a GARDEN section in flowers/README.md, the numbers in TUNING, the reasoning and the
    negative results in JOURNAL 2026-08-12, the traps in PITFALLS, a ranked debt list in ROADMAP.

What needs your eye, not mine

  1. Nobody has watched this at framerate. Every judgement here is from stills, which this
    project's own record ranks as its weakest evidence. That is the first thing to do.
  2. The solo page inherits the ground — the Nightglass Parasol's signature shot goes from
    moon-in-black to moon-over-indigo-soil. Taste call. Dials: soil0/soil1 and the melt
    start in 25_ground.js, not the fog.
  3. The mote field barely reaches the screen. Grains drawn larger than 2 px: 0 (wide),
    5 (dolly), 7 (close), 23 (low). The mechanism is right and what a viewer gets is a scatter
    of single pixels. The honest lever is the drawn size — the vein width floor's own
    argument applied to a mote, since a real grain is sub-pixel at every distance.
    ?pol=0.05,12,0.07 is the 3.2x A/B, built and shot but not shipped, because looks on
    this project are decided by watching.
  4. The establishing shot has no visible ground — at 88 units the melt has taken it
    entirely, so the field floats. Correct per the melt's design, and arguably the piece's
    signature void, but it means the frame cannot show you where the floor is.

One bug found and NOT fixed, because it is outside this piece

src/40_plant.js samples the wind at each plant's own this.time, so in a garden a
member germinated at world step 900 bends to the air of 900 steps ago. One field, evaluated
at N different times. The pollen deliberately does not copy it (grains drift on the world
clock). Worth its own branch.

Housekeeping

A phase-1 agent ran ln -s .../node_modules node_modules from the repo root rather than its
worktree, replacing the real directory with a self-referential broken symlink — and committed
it, because .gitignore's node_modules/ matches a directory. Every Playwright tool then
failed with ERR_MODULE_NOT_FOUND. Untracked here, the bare form ignored, incident in
PITFALLS.


Round 4 (2026-08-12/13): the film, and the two artifacts

49 further commits, unattended overnight, seven Opus agents across four staged workflows
plus integration and verification between each. The brief: "make this garden as awesome
and aesthetic and amazing to watch as possible... there's these glitchy flashes on
flowers that seem unintentional."

The glitchy flashes: two defects, one cause, both convicted

The flashes were real, caught on camera by a new probe (tools/flowers_glitch.mjs
snapshots the canvas the exact frame a tile spikes, excluding camera-motion frames), and
they turned out to be the same null geometry reaching the screen two ways. blade()
(src/50_geom.js) emits ~7% zero-area triangles at every leaf base, whose vertices also
carry exactly-zero normals.

The bright gridded square: a zero-area triangle has no barycentric denominator, so
the rasteriser hands its odd fragment varyings outside the hull of its own vertex values
vC*vE*3 measured at 710 against a legitimate ceiling near 3, one HDR texel at 8,863
against a frame median of 2.38 — and the bloom chain's sparse blur renders that delta as
a comb: the "grid" was the blur kernel seen naked. Fixed at two causes: 10_capture.js
drops no-area triangles (scale-free test, counted and reconciled exactly by the parity
gate, extended 20→24 checks
), and the tri/petal shaders enforce the interpolation
contract (|vN| ≤ 1 is a theorem for unit normals under convex interpolation; the spike
held 56.10 of the shaded colour above that test and 0.69 below it).

The one-frame black square (found while gating the fix): normalize(vN) where
|vN| == 0 makes a NaN the bloom smears into a 112 px square — 112 derived from the
blur support, not a GPU tile. The first guard couldn't see it because every comparison
against NaN is false
; rewritten as the negation of the valid band. Headless: 14,485 of
629,364 tri vertices carry an exactly-zero normal, matching the no-area census species
for species, with nothing between 0 and 1−1e-7.

After both: zero events — 0 flash spikes, 0 holes, 0 non-finite texels across all
probe runs at seeds 21, 1337, 4242, 8888 (tens of thousands of frames). Scene-peak p99
369.5 → 5.2. The look is measurably unchanged (close shot mean pixel −0.4%; controlled
same-frame A/B: 0 finite blocks changed). Twelve purpose-built instruments carry the
diagnosis in tools/.

And canalisation.html was measured, not assumed: it has the same unguarded
normalize on 3× the zero normals (7.38%) and does not fire — 133,731 frames, 0
hits — because there the zero-normal edges live only on triangles with identically
zero area, which are never rasterised. Positive controls prove its chain would draw the
square if fed a NaN. src/ untouched; ROADMAP 0g books the deliberate decision:
fix blade() at the source for both pages, or port the (provably no-op) guard.

One air, one clock

Plant sampled windAt at its own life clock, so garden members bent to moments of the
wind up to 2,600 steps apart — a gust could never cross the stand as one event, in
either page's garden. Plant.windPhase (default 0; solo pages and every harness
bit-identical) anchors each member to the scene's wall clock; a regrown hero inherits it
("the weather outlives the specimen"). Gates: smoke 73/73, stem 82/82, wind 27/27.

The film

The director is now a cinematographer rather than a slideshow:

  • Nothing stops moving. Every shot carries a perpetual drift at one screen-referred
    rate (FL_DRIFT = 0.75% frame width/s — by eye, the uRef category); stationary samples
    15.1% → 0.0%.
  • A sixth shot goes through. glide traverses the stand's widest clear lane
    (derived from the drawn points' projection), at 3× the drift rate = ~5 cm/s, rack
    focus resolving flowers as they pass. Its entrance frame is the best picture this
    piece has produced.
  • The frame goes where the field is. The establishing heading comes off the field's
    plan-hull diameter (covariance weighted a seedling like a frond): drawn NDC span
    1.17 → 1.53. The low shot is solved from the skyline with closed-form clearance — its
    old pose had the eye inside an Ember Creeper (clearance −4.1 units) and 54% of its
    ink in the top half; now sky over the bank (0.29).
  • Transitions are paced and clear. Peak speed is the law (FL_DIR_VPEAK = 26 u/s,
    derived — it reproduces both old hand constants to 0.4 s); the eye blends in the
    field's polar coordinates (no chording through the stand); headings freeze per shot
    (a diameter is not continuous in a growing stand — the teleport this killed measured
    239 u/s); and where a path would brush foliage the camera cranes over the canopy,
    amplitude solved closed-form against the drawn surface, engaged only when needed
    (4-5 of 6 moves untouched; worst path clearance 0.07 → 2.54 units; foreground-cover
    frames halved). One pre-existing bug found on film: the polar blend re-derived
    "short way round" per frame, so near-antipodal poses teleported 80 units in one frame
    (434 u/s at seed 1337 → 42).
  • Rack focus: shots enter with the subject soft and resolve onto it, amplitude 1.2
    depths of field off the DOF pass's own uRange.
  • tools/flowers_clip.mjs records the film (webm + a 4 Hz camera track) and
    tools/flowers_trans.mjs measures every transition's clearance — both re-runnable.

The field is legible now

  • Pollen reaches the screen. Every grain sat at the point pass's 1 px clamp
    (p50 = p99 = 1.00 — "a channel drawn at the rasteriser's clamp is invisible in a way
    no screenshot reports", now in PITFALLS). A mote is a glare spot, so its size is an
    angle (minAng = 0.004, by eye off a measured 4-point ladder), fogged at 0.45
    (0.80, the tissue's number, extinguishes — a mix toward a colour is not a fade to
    black). Wide shot: 0 → 320 grains above 2 px.
  • The establishing shot has a floor. Not the melt — the glow pool was a 5-unit pool
    at the origin, 0.6% where a field's plants stand. Its length scale is now the
    clearing's (rim + spacing — the radius the pollen derives independently), applied as
    airlight riding the melt: the flat-albedo version was built, measured, and rejected
    for turning an overhead shot magenta (JOURNAL). The solo page's void is preserved by
    construction (no plan → no rim; measured 0.00–0.28 before and after).
  • Every flower is its own. The bullseye threshold and spot atlas were scene-wide —
    the hero's pigment program worn by all seven members. Now per-member via split draw
    groups (vertex format untouched, parity untouched): 7 distinct thresholds spanning
    all three Todesco modes, 7 distinct atlases, solo page delta 0.0000/255 at two seeds.
  • The URL-parameter catalogue came off the canvas (it overstruck the HUD in every
    frame); the gesture hint stays, the catalogue prints to the console.

Verification on the assembled branch

flowers/build.js exits 0 · parity 24/24 · smoke 73/73 · views 23/23 · stem
82/82 · wind 27/27 · flash probe 0 spikes · hole probe 0 holes, 0 non-finite ·
flowers_ident 7 distinct/0 collisions · perf unchanged: gap median 8.4 ms,
57.5 fps at garden=7 (was 8.7/56.9 before the round). Docs: JOURNAL ×3, PITFALLS ×3,
TUNING (all round-4 constants labelled derived-vs-eye, with ladders), flowers/README
(six shots), ROADMAP (0f items closed, 0g added), CLAUDE.md.

What still needs a human eye (ranked)

  1. Watch the film. open 'flowers.html?garden=7&seed=21' and let it run two
    rotations (~4 min). Everything below is subordinate to this.
  2. The cranes: 22–32-unit rises over a 40-unit stand where a straight path would
    brush foliage. Every number says better; whether it reads as a camera or a drone is
    yours. Dial: ?brush=2 cranes less.
  3. FL_DRIFT (0.0075) and the ~2 s rack-in on shot entry — "too much / still frozen"
    each move one number.
  4. Fireflies vs motes: fogged motes shipped; both ends shootable from one build
    (?pol=… variants in TUNING).
  5. ROADMAP 0g: fix blade()'s null geometry at the source (both pages, deletes the
    vertices instead of discarding fragments) or port the no-op guard to 60_render for
    shader parity. Booked, argued, not taken autonomously.
  6. The remaining blur-wall at seed 21 is the dolly pose standing where an Ember
    Creeper arm reaches — a poses question, measured and left.
  7. The glide costs 81 ms capture vs the dolly's 71 (the LOD doing its job at a near
    camera) — 27% of the film's runtime; a decision, not a discovery.

Phase E: the dolly's wall was the lens, not the plants

The last blur-wall in the film was measured and its cause was NOT clearance — the eye was
13-41 units clear of anything drawn at every sample. It was the lens: the dolly stood
at 46 units focusing with uRange = 0.35·D, so the field's near rim was past full blur by
construction, and no standoff fixes that (pushing out just makes a second wide shot —
measured). The one free variable is where the chord runs: flDirDollySolve searches
headings and chord placements at the cut, scoring a frame raster where every cell is
classified wall / read / soft by its nearest surface against the shipped lens's own two
limits, and maximises read — zero for a wall and zero for an empty frame without either
being named. Wall frames in the dolly's dwell: 30.2% → 0 (seed 21), 47% → 19%
(seed 1337, reconstruction); the shot's standoff, travel, and character unchanged
(before/after stills). Two wrong rulers caught by controls on the way — a point-count
blur metric wrong by an inverse square (its "7x improvement" was 30%→34% on film), and a
wall-only objective that bought an empty frame — both written into tools/flowers_hold.mjs
(new), which also names the glide and low as the film's blurriest shots by this metric
(the glide's shallow lens is by design; the low is worth an eye).

🤖 Generated with Claude Code

aj-dev-smith and others added 30 commits August 11, 2026 20:08
tools/flowers_shot.mjs — screenshots flowers.html (flower_shot.mjs targets
canalisation.html). Waits on window.__fl, drains ff via the HUD (&shotstep=
for a step target), settles until the CAMERA is stable rather than for a
fixed time — the fixed wait shot the columbine from inside its own corolla —
prints stream counts off __fl.B (summed over __fl.garden when that lands),
and decodes its own PNG: the documented swiftshader failure is a black frame
WITH a full triangle count, so counts alone prove nothing. &speed=0 is the
reproducible-still recipe.

tools/flowers_perf.mjs — the garden_hitch lesson: a harness that waits cannot
see a freeze. In-page rAF gap sampler over ~30s of live growth (ff dropped
deliberately); prints median/p95/p99/worst and fps beside the HUD's own.
PRINTS, DOES NOT JUDGE — there is no budget yet; this is the baseline.

test/flowers_capture.mjs — headless capture cost, no browser: parity's loader,
a grown specimen, median of 20 flDrawSpecimen calls, stream float counts.
Asserts only structure (the parity organ-range check). n>1 probes for
flGardenPlan and prints 'garden: not built yet' today.

Baseline (this machine, ANGLE-on-Metal): default page 30s live growth —
gap median 8.5ms p95 25.1 p99 33.4 worst 58.3, 66.2 fps measured / 42 HUD.
Headless capture: Ember 21 @1400 9.76ms; Parasol 7 @2600 3.32ms.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
flowers.html had no ground geometry — plants stood on an implied floor at
y=0 against the void. flowers/25_ground.js adds one: a 140-unit disc at
y=-0.01 with FL_TRI_FS's shading subsetted (hemisphere ambient, key
diffuse at 0.9, the same flFog at 0.80 through the scene's own fog
uniform objects, alpha carrying linear depth so the lens racks over it).
Environment, the same allowed category as the wind — nothing about the
plant is drawn.

Colour is palette mixes only: soil0 = mix(bgBot, stem0, 0.16), soil1 =
mix(ambBot, stem0, 0.40) under a two-octave hash value mottle, a 0.6x
bgGlow pool under the specimen, and a radial melt to mix(bgBot, bgTop,
0.65) so the rim never draws a line. Three of those numbers were
corrected by looking: a darker melt target cut a visible trough between
fogged soil and sky, and one step brighter soil doubled a Parasol
down-shot's field value against the old void.

Two traps hit and written down in the file:
- flowers/*.js sorts 25_ before 30_scene, so a top-level ${FL_FOG}
  template parses clean and dies in the TDZ at load; the shader strings
  are built at construction time instead.
- The framing laws predate the ground and walked the eye to y=-16 on a
  tall specimen — under the new floor that is a screen-filling ceiling
  of soil. The boot now holds the eye just above the plane (40_boot.js),
  which also stops the orbit phasing through it.

node flowers/build.js clean, parity 20/20 before and after. Nothing
under src/ touched.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…_garden.js)

flApplyForm is 40_boot.js's inline homeotic block extracted verbatim; a
reference harness sliced the same lines out of git HEAD, wrapped them, and
held both paths to identity -- form name, S.sp, plant.sp, both palettes, and
every captured stream hashed byte for byte at step 1400, across all four
forms and the URL knobs (81/81). parity 20/20. uploadMany concatenates N
FlowerBuffers; upload(B) delegates to it, so the solo upload is unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…g with sqrt(N)

flowers/35_garden.js only.

FL_GARDEN_SPACING 2.5 -> 12, and the 2.5 was set by eye against a single
corolla. Measured headlessly (8 flowering species x 4 forms, 3000 steps,
horizontal reach off the DRAWN streams): max reach min 3.37 / med 9.49 /
max 22.13, body reach r90 min 1.22 / med 5.76 / max 16.77. 12 is full
clearance of two median bodies and a stated 63% of full clearance of two
median arms -- full arm clearance (19.0 median, 44.3 worst) is too sparse
to read as a field. Stated fraction, not a derived one.

Field radius was a FIXED 7 for any N; now 0.83*s*sqrt(N), from RSA disc
capacity, so areal density is constant. ?radius= still overrides.

Placement is dart throwing over the disc, uniform in area, accepting the
first candidate clearing the spacing, with the BEST failed try as the
fallback rather than the LAST. Over seeds 1..64 and N in 2..12 the
achieved minimum gap is >= 12.0 in every case, 0/64 exhaustions.

Stagger 2400 -> 1200 with a first cohort at step 0 (max(2,min(4,ceil(N/3)))):
garden=7 had 2 of 7 germinated at step 1100; it now has 7 of 7 at 1600.

Species deck now deals without replacement ACROSS the reshuffle boundary
too (n>8 could put two of a kind side by side). Seeds were already
injective; the comment now says why.

parity 20/20, solo page unchanged.
…r the garden

PROFILE FIRST (test/flowers_capture.mjs, rewritten as the profiler). A garden
of 7 at seed 21, world step 3000, grown WITH the germination stagger so it is
the page's field and not a different one — and it reproduces the browser float
for float, which is how the double count in tools/flowers_shot.mjs was found
(it added the hero twice: 998 organs for 771, 10.34M tri floats for 8.64M).

Where the 115ms goes, per organ kind:
  petal   45.9   sepal 28.2   leaf 25.3   stamen 13.1   rest 4.4
70% of it is FLORAL organs, and 58% of every float emitted is the petal
stream. That is 20_draw.js handing every floral organ detL = 1.0 — the
microscope, permanently on — so a petal is built at the leaf's own lattice
(~5,600 verts a petal) whether it fills the frame or covers 16 pixels.

1. NEVER FINER THAN THE RASTER (flowers/28_lod.js). bladeMesh is the piece's
   only LOD with no distance term (CLAUDE.md). It gets one: cap mu,mv at one
   quad per pixel, px/unit = pxHeight / (2 d tan(fov/2)), measured to the
   specimen's near face. A cap, never a raise; floor stays 4x2; ceiling stays
   the leaf's lattice. No taste constant and NO HERO EXEMPTION — the subject
   is large on screen by construction, so at the close-up's own framing the
   cap lands above the lattice and does nothing. ?lod=0 is the pre-LOD page.
   Field capture 115.0 -> 67.7ms headless, 100.2 -> 77.7ms in the browser.

2. PAY IN BATCHES, NOT IN SLICES (40_boot). The pool was spent breadth-first —
   one step to every specimen — so every specimen stepped, and a specimen that
   stepped is recaptured: the frame paid the whole field's rebuild to advance
   garden time one step. Depth-first spends the same budget on fewer plants,
   at the same average rate each. How few is Nyquist, not taste: FL_RECAP_HZ =
   1.78 * 4 (four samples per period of the wind's fastest gust, 15_petal.js's
   ripple guard applied to time), so m = nAct * HZ / fps. The hero is exempt
   and always paid first. ?batch=0 is the pre-batching pool.

Live, grown field (flowers_shot, ff=3000 then speed=1, real browser on Metal):
  before  120.9ms capture (7/7)  10 fps
  after    38.0ms capture (3/7)  21 fps   (and 5 more petals — it grew further)

LOOKED AT: shots/g7_ff3000_lodoff.png vs _lodon.png, identical seed and step.
Nothing is deleted — seven plants, every flower, the same picture.

parity 20/20, build clean.
…a maximum it could not miss

A synthesised close-up eye lands INSIDE the specimen's bounding sphere, so the
near-face distance clamps at 0.1 and the corolla check passes at 100% — the
unreachable-maximum trap test/venation.mjs records, arriving in a harness
written twenty minutes earlier. Replaced with a sweep over near-face distance
(2 / 4.51 / 9 / 20 / 45 / 90 units), gated on the row a real browser actually
measured at ?focus=flower:

    d      px/unit   tri kept   petal kept   vein kept
        2      1036      93.6%        99.0%      100.0%
     4.51       459      81.2%        96.6%      100.0%
       20       104      48.8%        92.4%      100.0%
       90        23      22.0%        27.8%      100.0%

Two gates: the corolla keeps >= 95% of the petal stream at the close-up (0.966
measured, floor written first), and the cap touches NO vein, exactly — this law
is about surfaces and must not reach the channel the engine is visible through.

And it corrects 28_lod.js's own comment, which claimed the close-up was
untouched. It is not: -3.4% petal, -18% tri, and NONE of it is leaves. It is
stamens and carpels, because detL = 1.0 is applied by organ IDENTITY, so a
0.1-unit filament is built at the same 75x75 lattice as a petal filling the
frame. The solo page is no longer byte-identical and the difference is
sub-pixel by construction.
Two defects, both found by looking at a garden of seven (seed 21, step 3000)
and both in the atmosphere rather than the plants.

1. THE HORIZON WAS A HARD STRAIGHT LINE. The disc melted over its own RADIUS
   toward one sampled void colour, but the rim was never what a viewer saw:
   a fully fogged ground is uFog and the sky above it is the bg gradient near
   uBot, and on the shipped palettes those differ 3-5x in luminance (Sun
   Coral: fog L 0.041 against bgBot L 0.005). The seam is wherever the plane
   runs out of screen, which from an eye near ground level is a straight line
   across the middle of the frame.

   The ground now melts into THE ACTUAL SKY IN THAT DIRECTION: FL_SKY is the
   background's own gradient extracted as a function (FL_BG_FS now calls it
   too, so there is one sky, not two that resemble each other), sampled at the
   fragment's screen position through a clip-space varying — perspective
   correct, no resolution uniform. Where the melt completes the ground IS the
   void, bit for bit, so the join cannot be seen. Alpha melts to the void's
   3.0 with it so the defocus finds no edge either.

   What drives the melt is a ground-hugging haze: the closed-form optical
   depth of an exponential-height layer along the eye ray, which is uniform
   when the eye is IN the layer and thins as 1/yEye above it. That is the
   whole trick — a Lambertian plane under a directional light has ZERO shading
   variation, so no distance term alone can fade the near ground an eye-level
   camera is mostly looking at. FL_HAZE = [G 2.0, H 3.0, P 1.5, N 5.0], set by
   looking at two shots that pull opposite ways (a garden from y=0.6 needs the
   near ground to go; a solo flower close-up needs a floor under its subject).
   G alone trades one against the other — 1.5 hides the horizon and empties
   the close-up, 0.6 the reverse — and P (the curve's near half) and N (ground
   nearer than 5 units is floor, not air) are what let both be right. Same
   category as the wind's uRef. ?haze=G,H,P,N sweeps.

2. THE WHOLE FIELD WORE THE HERO'S PALETTE. flFieldPal blends the seven
   atmosphere colours across the species actually present. The obvious mean is
   measurably mud — over the eight flowering species the mean fog's saturation
   is 0.295 against a member mean of 0.607, bgGlow 0.337 against 0.770 —
   because averaging in RGB cancels hue against hue. So the blend keeps the
   weighted mean's luminance and hue direction and rescales its chroma back to
   the members' own mean chroma, clamped so no channel goes negative.

   The hero LEADS at 0.35, and that number came from a measurement, not taste:
   a deck of eight dealt seven ways is nearly the whole deck, so at a pure
   field mean every garden gets the SAME sky — mean pairwise fog-hue angle over
   24 base seeds falls to 20.8 degrees, against 85.6 today. 0.35 keeps 64.4
   degrees of field-to-field variety while still moving the air off one
   species (fog saturation 0.714 hero -> 0.574 field, luminance preserved).
   ?sky= overrides; A/B shots at 1 / 0.35 / 0 are on the branch.

The solo page keeps its own palette BY CONSTRUCTION (no plan, or a plan of
one, returns the palette object unchanged) and gains the melt, which it wanted
too: its close-up had the same visible horizon and now has a floor that fades.

parity 20/20, build clean.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Comment only, plus the rebuilt artifact. Swept the reach measurement over
the five seeds a garden actually deals (8 species x 4 forms x 5 seeds, 160
cells): maxR p10 3.6 / med 9.7 / p75 14.4 / p90 23.2 / max 70.9, r90 p10
2.2 / med 5.0 / p75 7.5 / p90 12.1 / max 20.4.

The one-seed table got the middle right (9.49 vs 9.7) and the tail wrong.
Two findings recorded in the file:

 - reach is a statement about a SEED as much as a species. Ember Creeper
   columbine is maxR 7.4 at seed 21 and 65.9 at seed 31697.
 - reach is not bounded in TIME for that species. Sampled every 200 steps
   at seed 31697: 11.9 (step 1000) -> 28.8 -> 44.4 -> 70.9 (step 3200),
   still climbing linearly. A creeper whose axes never arrest. No fixed
   spacing can keep that off a neighbour and none should be expected to.

FL_GARDEN_SPACING stays 12 -- full clearance of two median bodies, 62% of
two median arms, and the fraction is now stated against the wider sample.

parity 20/20, smoke 73/73.
scratch/g2_placement/ — new paths only, nothing shared touched. Kept
because the whole argument for FL_GARDEN_SPACING is a measurement, and a
measurement you cannot re-take is just a number somebody chose.

  loader.mjs      the flowers bundle in plain Node (copied from
                  test/flowers_capture.mjs, plus 35_garden.js so
                  flApplyForm and flGardenPlan are reachable)
  reach.mjs       what one specimen occupies: maxR / r90 / r50 off the
                  DRAWN streams, per species x form
  seedsweep.mjs   the same over the five seeds a garden deals — the run
                  that found the one-seed table's tail was wrong
  arc.mjs         reach over a whole life, every 200 steps — the run that
                  found Ember Creeper never arrests
  plan.mjs        statistics of flGardenPlan itself over seeds 1..64:
                  achieved min gap, depth spread, dart exhaustions,
                  adjacent species duplicates, seed collisions
  field.mjs       the plan GROWN on the boot loop's clock: pairwise
                  overlap at maturity, and what a viewer sees at
                  step 600 / 1200 / 2400 / 3600
  seedsweep.out   the 160-cell table quoted in 35_garden.js
…t exist

flowers/README.md: the profile table, both laws stated, the before/after
matrix at 5/7/10, and the tail the batching costs (isolated with ?batch=0:
the LOD improves every column, the batching trades p99 for median).

And the negative result, measured rather than assumed: THERE IS NO FROZEN
TISSUE TO CACHE. An Ember Creeper at step 3000 with zero live axes changes
56.4% of its triangle floats on the next step, deltas to 0.41 world units —
and still 56.4% with the wind at uRef 0. The material shape of a mature
lamina is frozen and already baked; where it IS moves every step forever,
because the axes are cantilevers and the petioles hang off them. So the
answer to 'recapture less' is temporal, not memoised.
…mens rebuilt

A harness reading fps can see that the field got faster and not why. stepN and
capN are the pool's own two numbers, and the HUD already prints capN as (k/N).
…ADME

p99 83.4 -> 108.4ms against median 50.0 -> 34.9. It trades the tail for the
median and the next person to write a hitch gate for this page should read
that in the code that does it.
…tor.js)

The shipped framer frames ONE subject; pointed at a garden it framed the
bound of everything at once — measured on ?garden=7&seed=21&ff=3000:
radius 36.1, camera 84.2 units out, six plants in a column, most of the
frame empty.

45_director.js is a shot list instead: wide field / dolly across it /
close-up on the best flower ANYWHERE in the field / low against the sky,
cycling with eased 5 s transitions and holds of 20/24/16/12 s. Framing
distances are derived from the frame equation (2 d tan(fov/2)) against the
field's own median plant height, not from the bound.

?shot=wide|dolly|close|low pins one, for stills.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…laim instead

'the corolla keeps >= 95% of the petal stream' passed at 1600 steps (96.6%) and
FAILED at this harness's own default of 1400 (89.0%) — a younger flower's
organs are smaller and a cap in pixels bites a small organ first. A percentage
of a stream was never the claim 28_lod.js makes. The gate is now the claim,
and it is stage-independent: the LARGEST petal in the close-up is drawn float
for float as it was (110400 == 110400 at both stages). If the biggest thing
the shot is pointed at loses one vertex, 'no hero exemption' is false.
Sampling the director's own state at 4 Hz over a full 92 s cycle: shot
lengths land exactly on the table (dolly 29.0 s, close 21.0, low 16.9,
wide 25.1 = hold + 5 s transition each, so nothing ever cuts mid-move),
but entering the CLOSE-UP peaked at 59-62 units/s against 19 for every
other transition. The close-up is the shipped framer and the shipped
framer is three exponential lerps, which is an ease-OUT — and an ease-out
starts at its fastest. Holding the camera back toward the pose it cut
from, by the same smoothstep the other shots use, takes the peak to
22.7 u/s: 3.9 m/s to 1.4 m/s in WORLD.unitM, a whip to a walk.

Also measured: a drag freezes the shot clock for 25 s (verified: el held
at 23.8 through the whole hold, then restarted at 0 with a full eased
re-entry) and hands autoRotate back to the viewer while it does.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Also drops three fields the director never read.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The sight-line clearance is specimen 0's alone (heroCull), and in a stand
this dense that clearance is the difference between a photographed corolla
and a wall of leaf: 33.9 ms with the flower visible on the hero, 131 ms of
the subject's own blades across the lens for ?focus=flower two plants over.
The constant is labelled for deletion the day the cull follows the subject.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
# Conflicts:
#	flowers.html
#	flowers/35_garden.js
# Conflicts:
#	flowers.html
#	flowers/40_boot.js
flowers/README.md gets a GARDEN section in that file's voice — the placement
law and why the spacing is a stated 62% of measured arm clearance, the
germination cohort and stagger, the four-shot director, the ground and the
field palette, the harness. Every number verified against the code or re-taken
here before it was written down.

The three headlines go where this project keeps numbers:

- TUNING: the flower field's knob table, which two are Nyquist and not dials,
  the 160-cell reach sweep behind FL_GARDEN_SPACING, and FL_SKY_LEAD's
  measurement (mean pairwise fog-hue angle 84/64/27 deg at lead 1.0/0.35/0.0,
  reproduced over 40 fields of seven).
- JOURNAL 2026-08-12: capture cost was FLORAL and not leaf (the microscope
  pinned on by organ identity); reach is a statement about a SEED and is not
  bounded in time, so no spacing should try to contain it; a plain palette mean
  is mud (fog saturation 0.261 against a member mean of 0.598).
- PITFALLS: the node_modules symlink incident, and the fact that a field
  profile is a profile of that field's germination schedule.

Two corrections, both from re-taking the measurement rather than copying it:
the per-kind capture table in 28_lod.js and the README's cost section were
measured under the older stagger (2400, uniform startAts), and on the shipped
plan the petal stream is 46.7% of floats and not 58%, with sepals overtaking
petals. The 70%-floral headline survives at 74%. Noted where both are quoted,
not silently overwritten.

CLAUDE.md had no entry for flowers.html at all; it has one now, with the
load-bearing warnings (the LOD cap is Nyquist, the spacing is a stated
fraction, the hero lead is measured, garden time slows with N) and the honest
headline: nobody has watched this at framerate in a real browser.

ROADMAP 0f ranks the debt, watching it first, and books the solo page
inheriting the ground as a taste call rather than a bug.

Docs only — no .js touched, flowers.html rebuilt to a byte-identical file.
Gates: node flowers/build.js OK, parity 20/20, smoke 73/73.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
18_pollen.js walked the hero's axes only, so in a garden of seven six
flowering plants shed nothing. It walks the boot's `specs` list now — one
population, because a grain is not part of a plant: once shed its only
inputs are the wind field and gravity, both scene-wide, and the cap and the
upload are scene-wide resources too. The alternative (one FlPollen per
specimen) is argued down in the file.

Three things came with it:

- TWO CLOCKS, and they are not the same in a garden. A specimen sheds on
  the plant time IT was paid this frame (`spec.stepped`), because
  dehiscence is a plant process and the step pool is spent depth-first;
  every grain drifts on the WORLD clock, because the air is one field over
  the clearing and windAt's `t` is a wall clock. The shipped call passed
  the hero's age and got the right number by accident — the hero is exempt
  from the pool and paid first out of it, so its age IS the world step.
- A MOTE'S COLOUR IS THE KEY LIGHT'S, and in a field the key light is the
  FIELD's (flFieldPal, 25_ground.js), not the hero's. Unchanged on a solo
  page, where flFieldPal returns the hero's palette itself.
- test/flowers_pollen.mjs, a headless census: anthers, grains, where they
  are, where they die, and what a population step costs. It asserts only
  that the census balances (emit - died - alive == 0), because a swap-with-
  last removal loop is exactly the kind that drops one silently.

MEASURED, garden=7 seed=21, step 3000 (before = HEAD's file, run through
the same harness with `polfile`):

                       before            after
  shedding plants      1 of 7            6 of 7
  anthers drawn on     16 (hero)         59 (field)
  grains alive         348               326
  ...within 12u of a   67                194
  plant                (r_mean 44.3)     (r_mean 21.3)
  population step      0.031 ms          0.051 ms

THE CAP HAS NEVER BOUND AND NEITHER HAS `life`: 0 refusals at 59 anthers,
and 0% of grains die of old age. The population is ADVECTION-limited, not
cap-limited — a grain drifts 0.32 world units per plant-time unit in the
shipped 2.5 m/s air, so it crosses the whole clearing in 0.65 s. Two
numbers that look like they control the population and neither does.
wide was not wide: it distanced off the median FLOWER height (5.9-13.8 on
garden=7 seed=21) while the plants standing there are 4.4-49.2 tall, so it
framed a thicket with five specimens cropped top and bottom. That pose is
kept whole under the name 'bank'; 'wide' is now solved from the field's own
plant bounds.

- flDirField grows Rout (85th pct of dist-from-centre + that specimen's own
  canopy reach) and hHi (85th pct of plant height). p85 not max: one Ember
  Creeper sprawls 46.7 units and takes the outer radius 30.6 -> 62.4.
- flDirPoseEstab solves the standoff from the frame equation off the LIVE
  camera's fov and aspect: width (2*Rout across fW of frame width) and
  height (hHi across fH of frame height), whichever binds. It swaps inside
  the shipped range -- garden=3 height-bound at 58.0 vs 33.6, garden=12
  width-bound at 117.1 vs 76.4, garden=7 height-bound at 81.8 vs 67.1.
- Composition is two more fractions with closed forms: feet at bF up the
  frame fixes the target, horizon at hz fixes the eye height.
- Five shots, holds re-balanced to 96 s (was 92 s for four). wide takes a
  7.5 s transition of its own: every cut flips the heading, so standing at
  81.8 where bank stands at 47.9 would have peaked at ~39 u/s against the
  other four's 26.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
A grain is integrated forward-Euler through a 7-octave gust ladder, so the
step has to resolve the fastest thing in that ladder. Derived from the
shipped field rather than chosen: the shortest mode is 8 world units long
and a grain travels uMeanMag + sigmaW per plant-time unit, so space wants
6.2 pt units and the fastest mode's period wants 6.3 — the same
four-samples margin 15_petal.js's ripple guard and 35_garden.js's recapture
rate already keep.

That is exactly the real-time page's per-frame cap, so nSub is 1 in real
time and this touches ?ff= only: at its 40-step chunk a grain jumped 12.8
units per call, further than the shortest gust is long.

⚠ BE HONEST ABOUT WHAT IT BUYS, WHICH IS NOT MUCH. Measured, garden=7 seed
21 at step 3000, chunk 40 (the ff path) against chunk 6 (the watched page):
302 -> 276 grains alive, 168 -> 140 of them near a plant, against the
watched 326/194. The ff'd population was already within ~15% of the watched
one; what the substep fixes is the trajectory each grain takes through the
gusts, not the census. A first version of this note claimed a 15 -> 38 fix
and that number came from a run with a bug in it (rEdge measured from the
origin with the rim unset) — the corrected measurement is above.

Also ?pol=rate,beyond,size, so the three legibility numbers are a shootable
before/after from one build (?lod=0's argument), and the drawn size is now
per-population rather than read off the table at emit.
The comment repeated the retracted 15 -> 38 claim; it says trajectory, not
census, and quotes 302 -> 276 against a watched 326.
Over a full director cycle at ?garden=7 the field holds 330-390 grains and
the number drawn larger than 2 px is 0 (wide) / 5 (dolly) / 7 (close) / 23
(low), never above 4 px — the camera is never within 10 units of a grain,
because the shots stand outside the crowd and a grain only lives within a
plant's room of a plant. The mechanism is right and it barely reaches the
screen; the lever is the drawn size as a constant ANGULAR size (the vein
width floor's argument applied to a mote), ?pol= shows it at 3.2x, and it
is not shipped because that is a look decision and looks are decided by
watching.
rEdge started at where the outermost plant STANDS, and 35_garden.js already
measured why that is not the same thing: median reach 9.7 units, p90 23.2,
and one Ember Creeper columbine at 70.9 — a creeper whose axes never
arrest. On a solo page the rim is 0, so any anther more than one plant's
room from the origin would have shed grains that died on the step they were
born. It grows monotonically with the furthest emission instead. Solo Ember
seed 21: 38 -> 52 grains alive, the 38 near a plant unchanged.
…at it

Three rungs of ?estab= shot at garden=7 and looked at: fH 0.62 (d 103.0)
is the tree_shot lesson, a small clump in a dark frame; fH 0.78 (d 81.8) is
full but the two nearest spires graze the top edge; fH 0.72 (d 88.7) ships.
Verified at all three garden sizes -- the solver reproduces the derivation
exactly: 62.74 against 62.8 predicted at garden=3 (height-bound), 88.7 at
7 (height-bound), 117.12 against 117.1 at 12 (width-bound).

THE HORIZON: tools/flowers_horizon.mjs run at this pose's own eye and
target at 8.0 / 18.4 / 34.0 units of eye height. NO hard horizon at any of
them -- 25_ground.js's melt holds at 88 units, which is what that tool
exists to catch. There is also no ground: the floor is inferred entirely
from where the stems stop. ?haze=2,3,2.5,5 (raising the near shaping P,
the one knob built to keep floor near the camera without bringing a
horizon back) was shot against the default and is indistinguishable. The
limiter is VALUE, not optical depth -- soil albedo 0.03-0.10 by decision
lands within a hair of the void. Nothing in the ground was changed.

Also: a shot with no subject falls back to 'bank', not 'wide'. A field
with nothing flowering is a field of seedlings, where wide is width-bound
at maximum standoff, and three of five shots would be an empty clearing.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
aj-dev-smith and others added 30 commits August 12, 2026 22:07
… is read

Pinning a shot stops the clock, so the glide's u saturates and the camera parks
at the end of its own travel — which, since the window is placed on the mass, is
inside it. The still is a wall of soft blade; in motion the same blade is a wipe.
And a pinned CLIP cannot show this shot at all: 45 s of ?shot=glide travels 1.1
units and scores 94% stationary, because it had arrived before the recording
started. Both measured, both written where somebody would reach for the tool.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
flowers/README.md is the argument for this piece, so a stale sentence in it is
worse than a stale number in a table: three of them were describing code that no
longer ships. The sixth shot (`glide`) is in the table with the reason a pinned
traverse is not a useful still; the establishing heading is the field's plan
DIAMETER rather than the covariance of its origins, with the 0.584/0.777 fill
that decided it and the four seeds' NDC spans; the low shot solves its standoff
and its pitch out of the skyline; and the five measures the director now keeps
apart (`F.plan`, `F.drawn`, `F.tops`, `F.hull`, `F.discs`) are written down with
what each one is the wrong shape for.

The pollen paragraph said the drawn size "is not taken here" and it has been:
every grain sat at the rasteriser's 1 px clamp with zero variance, which is a
thing no screenshot reports. The ground gains the airlight pool and the flat
pool that was built, measured and rejected for lighting an overhead magenta.

And the second artefact is no longer an open mystery with a GPU tile in it: it
was normalize(0) on the same collapsed blade base, the 112 px is the post
chain's own impulse support, and the guard that could not see it could not see
it because every comparison against a NaN is false. The shipped page's null
geometry is now booked as a source fix rather than left as a footnote.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ecided

Round 4 added a camera language, a floor and a visible plume, and every number
in them was either derived from something already shipped or set by looking.
TUNING is where that distinction is kept, so it now carries all of them with the
label attached: FL_DIR_VPEAK derived (it reproduces the two hand-set transition
times it replaced, 5.02 against 5.0 and 7.85 against 7.5), FL_DRIFT and
FL_LOW_SKY and minAng by eye with the ladders they were taken off, FL_GLIDE_K
stated as a ceiling, and the pool's length scale not a constant here at all but
the clearing's own radius.

Two of them carry a warning rather than a range. The drift's first write-up
quoted a "0.00" baseline that nobody measured — the instrument was written after
the baseline run — and the re-run corrects it and shows the close-up was never
the offender. And the establishing heading is a diameter, which is not
continuous in a growing stand: 336 u/s of eye against a 26 u/s peak, so every
per-shot decision is taken on the cut and held.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…n the fix

A person watching said "glitchy flashes", and ten probes later the flash and the
black square found while gating it are the same collapsed blade base reaching the
screen two ways: a triangle with no barycentric denominator handing a fragment
finite-over-nothing varyings, and a vertex normal of exactly zero making
normalize() write a NaN. Both are magnified by the same bloom chain, whose
rectangular impulse support is where the 112 px came from -- the "~128 px, so a
GPU tile" that shaped the first search was an eyeball.

The entry keeps three things a fix alone would lose. The guard added against
corrupt interpolation could not see the worse corruption, because every
comparison against a NaN is false. Three A/B designs returned confident numbers
that were the probe's own floor, and only a control told them apart. And the
cause is in src/50_geom.js, which both pages call, so this is written down as a
source fix somebody should take deliberately.

A second entry takes the round's other four results: the wind clock that had
been sampling one air at N life clocks since the garden shipped, the establishing
heading that was a covariance of origins where it wanted a diameter (and the
teleport that follows from a diameter not being continuous in a growing stand),
the flat pool of light built and rejected for lighting an overhead magenta, and
a plume-scored close-up that loses to a 33-petal corolla which structurally
cannot shed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Each of these cost real time this session and none of them announces itself.
A comparison guard is not NaN-safe -- the one written against corrupt varyings
was the single thing that could not see the corruption that produced a NaN,
because every comparison against a NaN is false; the fix is to state the band
you accept rather than the failure you imagined. Three A/B probes on a page that
never stops moving each returned a confident number that was the probe's own
floor, and only the control -- the identical build against itself -- told them
apart. And a channel drawn at the rasteriser's clamp is invisible in a way no
screenshot reports: 320 grains of pollen, all at exactly 1.00 px, zero variance,
looking on screen precisely like a channel that works.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…s to both pages

Two of them closed differently from how the list expected, which is the reason to
write the answer down rather than tick the box. Pollen being the hero's alone was
listed with "the follow-up is cost"; the follow-up was visibility -- every grain
was drawn at the rasteriser's 1 px clamp. And the wide shot's heading was fixed
(covariance of origins -> the field's plan diameter, 0.584 -> 0.777 of the frame)
without answering what the item was actually about, which is recession, so it is
marked improved rather than done.

0f-i is the one that matters and it is only partly discharged: AJ watched and
reported a defect, which is not the same as anybody sitting through the film.

The new item is blade()'s null geometry. flowers.html fixed it downstream and
canalisation.html draws the same 7% of zero-area triangles and 2.30% of zero
normals into the same bloom chain. It is booked as a source decision with the
warning that a guard is what the other page did, and it left the cause in place.

10b also gains the wind clock, fixed on the way past: every garden member was
sampling one air field at its own life clock, so a gust could not cross the stand.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…watching

All three are now false. It is six shots and a 24/24 gate, and a person HAS
watched the page -- what they saw was two rasterisation bugs whose cause is in
src/50_geom.js and is still there, which is the one thing somebody arriving at
this file needs to know before they touch either page.

The list keeps its shape (short, pointing at flowers/README.md for the story)
and gains two entries that are lessons rather than features: the film's one
screen-referred rate with the derived transition pace under it, and the fact
that a channel drawn at the rasteriser's clamp is invisible in a way no
screenshot reports -- which was true of the pollen and, from the other end, of
the pool of light on the ground.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…rson looks

flowers_floor.mjs and flowers_motes.mjs produced the load-bearing numbers behind
the ground pool and the pollen's angular size, and neither was in tools/README.md
-- which for this project means they would have been rewritten from scratch by
whoever asked the same question next. Both entries carry the trap that bit while
writing them: floor's dMax is the defocus moving at organ silhouettes rather than
floor, and motes reports device AND css pixels because at dpr 2 the two readings
support opposite conclusions.

test/flowers_pollen.mjs was missing from CLAUDE.md's harness list too; run to
confirm before adding it (emit 971, edge 919, residual 0).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The probe count in the JOURNAL entry was ten and it is twelve, six per artefact,
and naming them is more useful than the total. The garden section's heading
promised four stated numbers and round 4 added five more. And a "parity 20/20"
from the round-3 ABC work now reads as a claim about the current gate, which is
24/24 -- the sort of sentence that is true of the code it was written against
and false of the code shipping.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… say the band

45_director.js works the glide at 0.91 u/s off Rout and its landing commit
quotes 0.73 off the solved aim distance; both are arithmetic on the same law and
neither is measured. Quoting one as if it were the answer is exactly the kind of
number this project gets caught on later, so the docs give the band and point at
the screen rate, which is the thing tools/flowers_clip.mjs actually measured.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
flDirBlendEye stopped the eye CHORDING across the middle of the stand; what
was left is that the blended path's height and radius are still a line through
whatever canopy stands between two poses. Caught on film (shots/film/fr06.png:
one out-of-focus near blade, no subject, four seconds into a move) and now
measured — tools/flowers_trans.mjs walks every transition in a rotation with
the real poses and the real blend, against the drawn VERTICES rather than a
model of them. Before, on garden=7&seed=21: two of six transitions pass within
0.7 units of tissue and one puts foreground across 46% of the frame. Seed 1337:
0.07 units and 63%.

So a transition cranes. `eye.y += A * 4w(1-w)` — zero at both ends because the
poses are solved and must not move, and zero in VELOCITY there too since w is
already a smoothstep. A is the smallest amplitude for which nothing drawn is
within FL_DIR_BRUSH of any sample of the path, which has a closed form: it is
flDirClearance's derivation turned on its side, asking how far UP rather than
how far ALONG. Solved on the cut and held, like the establishing end, the low
shot's gap and the traverse's lane.

Three things the measurement decided rather than confirmed:

- THE AIM RISES WITH THE EYE. Lifting the eye alone pitches the lens down onto
  the canopy it just cleared, which is the same wall from above: cover 20% ->
  27%, worse. A crane is a translation, not a swing.
- F.solid, and an organ in it is a chain of spheres. `drawn` is a plan
  projection and samples an organ along its own AXIS, so the first version found
  nothing to clear on a path 0.46 units from a blade.
- 6.0 units, swept: 4 leaves the traverse's exit inside a plant, 8 buys nothing
  and starts craning the two moves that were already clear.

And the close-up's entrance was the one straight line left in the film — it is
the shipped framer, held back by a world-space lerp. It goes through the same
blend now, with the framer's own eye as the far end and the crane as an offset
that is taken back off before the framer reads its own state.

seed 21, worst interior clearance 0.07 -> 0.27 (and below the lens rather than
across it), 2/6 transitions inside 3 units -> 1/6, the traverse's exit 0.70 ->
4.49 with cover 46% -> 24%, four of six transitions untouched. A lifted path is
a longer path, so it is re-priced off the polyline it will fly (FL_DIR_VPEAK is
unchanged); the rotation goes 126.2 -> 129.7 s.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
`src/60_render.js`'s MESH_FS does `normalize(vN)` with no guard of any kind, on
the geometry `blade()` emits, through a comp shader character-for-character the
one flowers transliterated. Every ingredient of flowers.html's one-frame black
square, and nobody had ever probed it. `tools/nan_check.mjs` is that probe.

The ingredient is there and there is MORE of it: the main page's tri stream
carries 41,775 zero normals in 565,932 vertices (7.38%) against the flowers
stream's 1.70%, with no non-unit normals at all.

Measured, over 133,731 frames on ANGLE-on-Metal, headed — solo hero, a garden of
seven at seed 1337, three named species including a fully grown Ashfall Spire,
4x the fragment samples at DPR=2, and 18,000 frames parked on a blade base
filling the frame: ZERO non-finite texels and zero one-frame holes. So the guard
was not ported, and `src/` is untouched.

The reason is structural and `node tools/nan_check.mjs geom` reproduces it. At
u = 0 a blade's half-width is zero, so all MV+1 grid vertices of that row are
the same point, `Pv - P` is the zero vector, and `v3norm` returns an exactly-zero
normal. Per quad in that row you get one triangle with TWO zero normals — area
identically zero, because two corners coincide — and one with ONE, which is
drawn. 13,924 of 13,925 two-zero triangles have area exactly 0 (the last, one
needle, has 1.05e-6). So the only locus where the interpolant is exactly zero
and a fragment could land on it is a single VERTEX; the edge that would divide
by zero over a whole span is collapsed to a point. flowers.html wins that
coincidence rarely too — 69 frames of 4,921 at seed 1337, none at seeds 21 or
4242 — and `flowers_zeron.mjs` shows the drawable population is the same
triangles species for species, so the difference is framing and rasterisation
rather than geometry.

MARK=1 is the A/B and it is better than any picture, because the wind never
stops and a screenshot differ has a floor far above the artefact: it paints the
fragments the guard WOULD discard instead of discarding them. 29,381 frames,
including the conifer and the macro blade base, marked zero blocks. Porting the
guard would be free and would buy nothing today.

Two things worth not relearning, both in the header. The first positive control
wrote `normalize(vec3(0.0))`, which is a compile-time constant — ANGLE folded it
away and the control came back clean, which would have been read as "the probe
works and the page is fine"; it builds the zero vector from a uniform that is
never written. And the exit code flips under CONTROL and MARK, because a
shipped-shader run is bad if it finds something and a control run is bad if it
finds nothing. With the control patched in, canalisation.html draws the black
square perfectly, which is the proof that the chain is identical here and only
the trigger is missing.

node build.js exits 0 and leaves canalisation.html byte-identical; smoke 73/73,
views 23/23.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A result nobody can find is not a result. The 2026-08-12 JOURNAL entry has the
frame counts, the geometry table that explains them, the two alternatives that
were ruled out mechanically rather than by eye, and the two instrument lessons —
including the positive control that could not fire because ANGLE folded a
compile-time constant away, which would have been read as a clean page.

Also corrects one claim in the probe's own header: the two comp shaders are not
character-for-character identical, they differ in exactly one token
(`max(c, 0.0)` against `max(c, vec3(0.0))`, a GLSL ES 1.0 requirement). That is
now a check anyone can re-run rather than something read off two screens.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
# Conflicts:
#	docs/JOURNAL.md
… half-rise

Three corrections, all from measurement, and each one is a thing the first
version got wrong for a reason worth writing down.

THE MODEL WAS A PROXY AND THE PROXY WAS WRONG BOTH WAYS. `drawn` samples an
organ along its own AXIS, so it could not see a blade the lens was inside;
inflating each sample to a sphere of a guessed half-width then over-stated as
often as it under-stated — on seed 1337 it asked for a 36-unit crane where the
true geometry wanted none. Every specimen's FlowerBuffers holds the vertices
that went to the GPU, so `F.solid` is the drawn SURFACE now, subsampled to 8000
points a scan. Same argument as framing a close-up from the drawn reach.

THE WINDOW HAS A FLAT TOP. A crane rises, holds and comes down; `4w(1-w)` is at
full height for an instant, and dividing a required excess by a window that
small blows the amplitude past any ceiling. Two smoothsteps: 24.4 units asked
against 21.9 for the same path.

AND THE AIM RISES ONLY HALF WAY. Sweeping it on the move that cranes 21.9 units
(foreground cover / least ink): no crane 21%/45%, aim 0 20%/44%, aim 0.5
11%/38%, aim 1 10%/25%. At 0 the lens pitches into the canopy it just cleared
and the crane buys nothing; at 1 the top of the arc is empty sky, which is three
blank frames on film. `ink` is new in the harness and is what caught that — a
transition can be a bad two seconds by being empty as well as by being a wall.

The ceiling is `hHi + m` (clearing a point AT the skyline means standing a margin
above it; a bare `hHi` killed a move on seed 1337 by 5%) and it is a KILL
CRITERION: if the crane cannot clear, the director keeps the move it had.
Clamping instead flew the eye through the crown of the plant it could not get
over — clearance 6.41 -> 1.67, cover 8% -> 18%, worse than the straight path.

seed 21, against the same rotation with the crane disabled: bank -> glide cover
21% -> 11%, glide -> dolly 47% -> 25% with clearance 0.23 -> 1.10. seed 1337:
glide -> dolly 63% -> 22% and 0.07 -> 2.54, dolly -> close 47% -> 27% and
0.10 -> 9.20 (that one is the arc alone, no crane). Four of six moves untouched
on seed 21, three of six on 1337.

⚠ And a knob bug worth the line it cost: `+null` is 0 and 0 is a legal margin,
so every unswept run of the page was flying at margin zero while every swept one
used the URL. The ladder was right and the default was a different program.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ry frame

Caught on film, and it predates the crane — it is in both builds. "The short way
round" is not a continuous function of two poses: at a half-turn it is a coin
flip, and `wantEye` is rebuilt every frame by the orbit, the dolly's travel and
the 500 ms field re-measure. `low` and `wide` are very nearly antipodal — one
kneeling outside the stand, one ninety units off the far side — so they sit
exactly on that flip.

tools/flowers_clip.mjs on garden=7&seed=1337 reports `low -> wide` peaking at
191 u/s in the old build and 434 in the new one, against FL_DIR_VPEAK's 26, one
4 Hz sample wide and in the middle of the blend. The track says what it is: the
eye's azimuth runs 221 -> 216 -> 204 -> 186 degrees and then jumps to 238 and
climbs, and the eye moves eighty units between two frames. The blend reversed
its direction of travel mid-move.

The difference is still read from the live want every frame — it has to be, the
want moves — but on the branch the move STARTED on, so it drifts continuously
and can never jump by a turn. Same argument as the frozen heading, the frozen
establishing end, the frozen gap and the frozen lane: nothing about a move in
progress should be a function of what the plants did while it was being flown.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…'s hold went

Two small things, both of which were assumptions until they were written down.

THE SOLVE COULD THREAD ITS OWN SAMPLES. Twenty-one samples on a hundred-unit
path is five units apart against a three-unit margin, so a canopy could sit
between two of them and be declared cleared by a crane that flies straight
through it. The count comes off the path's own length now, at half the margin,
measured first with a pass that touches no geometry and capped at 81 because a
solve is one pass over F.solid per sample.

AND THE LOW SHOT'S DWELL WAS NEVER BEING EATEN. It has been read the other way,
so it is worth a note where someone would look: flDirClock ADDS the transition to
the hold rather than taking it out, and tools/flowers_clip.mjs measures `low` at
12.3 s of which the move is 3.3, in the build before this work and in the build
after it. The only part of the hold the move costs is 40_boot's 0.12-a-frame
damping, about 0.15 s. Neither repair someone might reach for is needed, and
lengthening the hold would push a rotation the crane has already taken from
126 to 130 s further out still.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ses under

The requirement was "the eye must be above everything within the margin in
PLAN", which asks a move that passes comfortably BENEATH a canopy to get over
it. Measured on garden=7&seed=1337, `close -> low` has 6.41 units of clearance
to anything drawn and the solve still wanted a 21-unit crane — which took the
clearance to 2.95 and the foreground cover from 7% to 20%. It made a clean move
worse to satisfy a requirement that move never violated. Passing under a plant
is a perfectly good shot.

A point pushes the eye only when the eye is INSIDE its sphere now, and then only
to the top of it; climbing out of one sphere can put the eye inside a higher one,
so the walk repeats. And the amplitude solve is iterated for the same reason one
level up: the requirement is evaluated at the height the eye will actually fly,
which depends on the amplitude being solved for, so a single pass answers the
question the OLD path asked. Without that, seed 1337's traverse exit lifted 18
units and finished with a leaf 0.4 units above the lens.

seed 1337, against the same rotation with the crane off: `close -> low` back to
6.41 / 7% / 62% (clearance / foreground cover / least ink) from the 2.95 / 20% /
28% the plan rule gave it, and `glide -> dolly` 0.32 -> 2.54 with cover 39% ->
24%. seed 21: `bank -> glide` 0.92 -> 0.50 with cover 21% -> 11%, `glide ->
dolly` 0.23 -> 1.37 with cover 47% -> 23%. Four of six moves untouched on seed
21, five of six on 1337. The rotation goes 126.2 -> 129.9 s.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…s own solve

A transition can be a bad two seconds in two ways and this file only measured
one of them. `ink` is the fraction of the frame with any drawn vertex in it at
any range, so a crane that rises into blank sky scores near zero on both `cov`
and `ink` and reads as a hole rather than as a wall — which is how the aim
fraction got measured instead of tasted.

Also: the per-sample MODEL column now calls flDirRise rather than the plan rule
it replaced, so the harness and the director are asking the same question.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…w is stale

The 3 and 4 rows were measured before the solve stopped craning over canopies
the path passes under, so they were describing a different mechanism. Re-taken:
3 lifts 22.0 and 10.2 units for cover 11% and 23%, 4 lifts 23.5 and 9.8 for 10%
and 22% — a unit and a half of extra crane for nothing a number can see. The 6
row is left as an upper bound and flagged as such rather than quietly kept.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…e invariant instead

The comment computed 0.91 u/s off F.Rout while commit b178e2d computed 0.73
off the solved aim distance — same law, different distance, and both are
arithmetic rather than measurements. The docs pass caught it. The number that
does not move with that choice is the measured screen rate, 2.1-2.2 %frame/s
against FL_DRIFT's 0.75, so the comment now quotes the band and anchors on
the invariant.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…t is shot on

`tools/flowers_hold.mjs` is the instrument the director did not have. Every other
harness here measures a POSE (flowers_frame) or a MOVE (flowers_trans); the dolly
is neither — it travels 45-57 units during its own hold, and only one point of
that chord was ever solved against anything. This walks the dwell of every shot
with the shipped pose functions and the shot clock's own per-cut state.

Two traps it fell into first, both now written into it as controls:

- ONE ROTATION IS ONE BEARING. The heading jitter walks by the golden angle, so
  the dolly stands somewhere new every pass. One rotation called it clean at
  seed 21 (12.9 units of clearance, 12% cover) while the film of the same build
  was a wall. Both true. It walks eight rotations and reports a distribution.
- A VERTEX SAMPLER CANNOT MEASURE COVERAGE. The metric read 14% at a 15k-point
  cloud, 23% at 60k and was still climbing at 240k — a number about its own
  budget. It rasterises triangles by their screen bbox now: 23% at stride 16,
  26% at stride 2. FLSKIP= sweeps it.

And the threshold is the SHIPPED LENS rather than a fraction. flowers_trans calls
a cell foreground when something lands nearer than half the eye-to-subject
distance and says the half is by eye; on the dolly that reports 12% for
unreadable mush, because the focal distance is ~40 units and the plants that fill
it stand 21 to 28 away. uFocus is the eye-to-target distance, uRange is
max(min, k*fd), the defocus pass blurs by |z-uFocus|/uRange — so `fd - rng` is
where full blur begins, and a cell whose NEAREST drawn surface is inside that
band is a cell a viewer can neither read nor see past.

THE MEASUREMENT SAYS THE DEFECT IS NOT CLEARANCE, which is what this branch went
looking for. The dolly's eye is 13.0 to 41.0 units from anything drawn at every
sample of its chord, on both seeds and at three stages of growth; FL_DIR_BRUSH is
3, so a standoff solved by flDirClearance would not have moved it at all. What
fills the frame is the lens, and it has a closed form: the near rim of the field
is unreadable whenever D < Rout/k = 2.86 Rout, and this shot stands at 46 against
2.86*30.6 = 87. The near third is at full blur BY CONSTRUCTION. Confirmed from
the other end: at seed 1337 ff5000 hTop grows enough that the existing floor puts
the dolly at 69.4 on its own and the wall does fall, 47% -> 26% — because it has
stopped being a near-field lateral track. That is the failure mode, not the fix,
and the standoff is left exactly as it was.

So the free variable is WHERE THE CHORD RUNS, and flDirDollySolve solves it:
nine headings across +-0.9 rad and three placements of the chord, scored by
flDirBlurLoad — how much of F.solid sits in the blur frustum, over four positions
of the travel. Bounded at +-0.9 because the flip and the +-0.5 rad jitter are what
stop a six-shot loop reading as a loop, the same bargain flDirGap strikes.
Decided on the cut and held, like the establishing end, the low shot's gap and
the traverse's lane. Ties go to the pose the shot would have taken, or an empty
field would park every dolly at a0 - 0.9.

flDirGrowth is the growth allowance and it is read, not stated: F.Rout against
the director's own clock, 2 s interval, slow EMA, rate floored at zero and the
allowance capped at R/4 (Rout is a p85 and a percentile is not continuous in a
growing stand). Measured, Rout goes 30.6 at step 3000 to 57.2 at 5000 at ~11.5
steps/s, so ~0.15 u/s and ~3.5 units over one dolly, against a cap of ~7. It
returns zero under a harness by construction — a reconstruction of one instant
has no elapsed time in it — so the allowance is a claim about a film.

BLUR WALL over the dolly's dwell, mean over the dwell, median over 8 bearings
(tools/flowers_hold.mjs, stride 4):

    seed 21  ff3000     25% -> (see next commit's films)
    seed 21  ff4000     36% ->  5%   peak 45% -> 33%
    seed 1337 ff3000    47% -> 19%   peak 66% -> 22%,  35/104 wall samples -> 0

Clearance and travel are unchanged (14.3-16.5 units, 36-51 units of track).
40_boot reads FL_DIR_DOLLY_DOF rather than keeping its own k and min: a shot
framed against its own depth of field must not read that number out of a copy.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…as wrong by an inverse square

The first version of flDirBlurLoad returned the NUMBER OF F.solid POINTS inside
the lens's full-blur band. It is the obvious thing to write and it is wrong: a
blade seven units from the lens fills eighty percent of the picture with the same
few hundred sampled points that a blade twenty-five units away spends on three
percent of it. Occupancy of the field is not coverage of the frame.

Nothing about that was visible from inside the solve. It agreed with itself, and
tools/flowers_hold.mjs's RECONSTRUCTION agreed with it too — 36% -> 5% at seed 21,
47% -> 19% at seed 1337 — because both were reading the same frozen field from the
same eight bearings. What did not agree was the FILM: live, the dolly's wall was
30.2% of its dwell before the change and 34.2% after it. A 7x improvement that the
thing it was for could not see.

The control that caught it is one line in the harness: print the DIRECTOR'S OWN
SCORE beside the rasterised answer, at the pose the director actually chose. At
el 21 s of a dolly at ?garden=7&seed=21 the raster read 83% of the frame
unreadable and the point count read 1.9%. The solve was never picking the wrong
bearing — it was measuring the wrong quantity.

So the band's contents are BINNED into a coarse frame instead of counted. The
perpendicular offsets divided by the depth are exactly a screen coordinate, so
this is a projection and costs nothing extra, and what comes back is the fraction
of CELLS holding anything — the same quantity the harness rasterises, computed
from the points the director already has. 16 x 10 rather than the harness's
32 x 20, because F.solid is ~11k points over a whole field and a finer grid would
be measuring the subsample rather than the field.

ON THE FILM, ?garden=7&seed=21&ff=3000, the dolly's own dwell (tools/flowers_hold
live mode, camera and lens read out of the running page):

    wall samples (blur >= 50% of frame)   35/116  ->  0/56
    median blur                              31%  ->  21%
    peak blur                                82%  ->  47%
    clearance, min / median              2.3/11.6 -> 2.1/15.6

and the director's own score now tracks the raster within a few points (28%
against 33% at the worst sample) instead of by a factor of forty.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…E, not empty frame

Caught by eye, on the film, and by nothing else. The bearing search from the last
two commits minimises how much of the picture is inside the lens's full-blur band
— and that objective has its optimum pointing OUT of the stand. It found one:
shots/after21/f160.png is fog, the HUD and nothing else, several seconds into the
second dolly of the rotation, against shots/before21/f160.png at the same frame
number and the same step, which is a readable frame with a corolla in the near
foreground. The old shot was a wall; the first repair made a hole.
tools/flowers_trans.mjs already carries this warning about the crane ("IS THERE
ANYTHING IN THE PICTURE AT ALL — the other way a transition can be a bad two
seconds, and the one a crane invents") and it applies here word for word.

flDirBlurLoad is flDirFrameLoad now and returns both halves: `ink` is frame cells
holding any drawn surface at any depth, `blur` is the subset inside the band, and
`read` is the difference. The solve maximises `read` summed over the chord. No
weight is needed between the two terms because they are the same unit — thirds of
a picture — and their difference is the quantity the shot is actually for.

tools/flowers_hold.mjs counts HOLES beside WALLS now (ink under 15% of the frame;
15% is by eye and is a reporting threshold, the same category as the 50% that
calls a frame a wall), so the trade cannot be made again without it showing.

ON THE FILM, ?garden=7&seed=21&ff=3000, 200 s, live mode:

                          shipped     minimise blur     maximise read
    dolly wall samples    35/116          5/108             5/113
    dolly holes                -        (f160, by eye)      0/113
    dolly median blur        31%            16%               16%
    dolly min ink              -              -               19%
    whole film wall        27.3%          17.8%             14.5%
    whole film holes           -              -             0/399

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…rame

The previous commit's objective was `ink - blur`, ink being anything in front of
the lens at any depth. It did not close the hole. shots/after21b/f160.png is the
same empty frame at the same step, while tools/flowers_hold.mjs cheerfully
reported 19% ink for it — because a stand thirty units past the focal plane is
ink to a projection and fog to a viewer. Both the solve and the harness were
counting content nobody can see.

The lens has two limits and only one of them was being used. |z - uFocus|/uRange
is at full blur BEYOND uFocus + uRange as well as inside uFocus - uRange, and
this page then hazes what is out there (25_ground's melt). So a cell is
classified by its NEAREST surface — the only one a viewer meets — into exactly
three states: WALL nearer than the band, READ inside it, SOFT beyond it or empty.
The solve maximises READ over the chord, and that is zero for a wall and zero for
a hole without either having to be named or weighted: a bearing pointing out of
the stand scores nothing, because there is nothing at the distance this lens is
focused on. The harness classifies the same three ways, so neither failure can
hide from it again.

ON THE FILM, ?garden=7&seed=21&ff=3000, 200 s, live mode, the dolly's own dwell:

                       shipped   minimise blur   ink - blur   MAXIMISE READ
    wall (blur>=50%)   35/116        5/108          5/113         0/107
    hole (read<10%)         -    f160, by eye   f160, by eye        3/107
    median blur           31%          16%            16%            20%
    median in-focus         -            -              -            32%
    whole film wall     27.3%        17.8%          14.5%          18.3%

and by eye over the dolly dwells, sampled every ~6 frames of the 1 fps films:
5 walls of 8 sampled frames before (shots/before21 f025, f030, f036, f042, f168),
0 walls and 0 holes of 8 after (shots/final). shots/final/f043.png and f172.png
are what the shot is for — something passing the lens with the field readable
behind it — and f160.png, the frame that was empty in both earlier attempts, is
a corolla at focal range.

⚠ The `glide` reads 59/87 holes in that table and it is NOT one: its lens is the
shallowest in the film by design (k = 0.22), so almost nothing is ever inside its
depth of field. The hole threshold is calibrated on shots that have a subject.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Documentation and the two thresholds, no behaviour change. The hold harness's
header still described the metric it started with (foreground cover at half the
focal distance, a vertex-sampled cloud) rather than the one it ships with, and
FL_DOLLY_OFFS was a bare array with the A/B that justifies it living only in a
terminal.

    heading search only        seed 21  10%   seed 1337  21%, 3/104 wall
    heading + chord offset     seed 21   5%   seed 1337  19%, 0/104 wall

The offset is what removes the last literal walls on 1337 and takes that seed's
peak from 41% to 33%; it is also the one term that changes the track's geometry
(the eye's distance from the middle runs 41.5 -> 57.4 rather than 46.8 -> 49.0),
which is why it was measured both ways rather than shipped on the strength of the
idea. FL_DOLLY_OFFS = [0] restores heading-only exactly.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
27 candidates x 4 positions of the travel x 11,638 points of F.solid is 5.10 ms,
once per dolly cut — ten times flDirArc's 0.51 ms and about a fifteenth of what
a grown stand of seven already spends capturing one frame. It lands every ~127 s
on a frame that is already the most expensive in the rotation, because that frame
is also solving the crane. Recorded so the number exists before anyone widens the
candidate grid.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant