A hive at the top is a pooled particle emitter: it spawns bees from a free-list, and the death plane at the bottom recycles any bee that crosses it straight back into the pool — so the population holds a steady state (≈ emit-rate × fall-time). Same kernel shape as the swarm bench: struct-of-arrays, a pure fixed-1/60 s step(), reproducible from (seed, #steps).
An earlier cut of this bench cheated: it drove each bee with analytic servos — hold radius r→R, hold tangential speed →ω·R, hold descent. Those three are the parametric equation of a helix, so the shape was authored, not emergent. This version throws that out. The bees now run real Reynolds boids — separation, alignment, cohesion — as self-propelled, constant-speed particles. The only things authored are the light pipe's controls.
Boids never spontaneously make a helix. Their emergent states are flocks, mills (a spontaneously rotating ring — a fish bait-ball), and swarms. A helix is a mill + descent. Two ingredients make that reachable here:
L.So the light pipe carries one faint rotational input — Light swirl (the pulses spiral by a small amount) — and boids alignment amplifies it into one coherent, repeatable mill that the descent shears into a helix. The swirl's sign sets the handedness (try Counter-spin). Everything else — the radius, the pitch, the rope thickness — stays emergent. Crank the swirl and the light does more of the work; drop it to 0 and you're back to raw, flaky self-organisation. The selftest measures all of this: with a swirl, sign(L) tracks the swirl on every seed; at 0 it just runs.
Bright rings launch from the hive and travel down at pulseSpeed. A bee within pulseBand of a ring gets a downward kick and an emissive glow (an iBright per-instance shader term), so a bright wave ripples down the column in lockstep with the light.
Kernel + selftest: tjs/beelix/beelix.js, beelix.selftest.mjs (18 node checks — steady-state population & exact pool accounting, determinism, the handedness-follows-swirl control property, tube containment, raw-emergence stability, pulse travel). Bee mesh: tjs/beelix/beemesh.js. Reuses the swarm bench's curl-noise via its _internal export.