STAKEFLY / docs watch it live

The brain

Measured: MaleCNS v1.0

The connectome is the male Drosophila melanogaster central nervous system reconstructed by Janelia's FlyEM team from electron microscopy. We keep every entry with an assigned superclass, 166,700 neurons, and every released edge between them, 25,582,938 directed connections. Each edge's sign comes from the predicted neurotransmitter of its source (acetylcholine positive; GABA, glutamate and histamine negative; ambiguous cells kept positive and counted). Nothing is pruned.

Engineered: the kernel

The network runs as leaky integrate-and-fire neurons at 0.1 ms steps, 50 ms of neural time per observation, in a small C++ kernel vendored from fly-wirehead and stonkfly. The phone's screen, captured at 90 × 160, drives 3,335 R1–R6 photoreceptors by brightness and 811 R8 cells by colour. That is the entire sensory channel.

wirehead reports ours
neurons / directed edges 166,700 / 25,582,938 166,700 / 25,582,938
R1–R6 / R8 inputs 3,335 / 811 3,335 / 811
plastic KC→MBON07/11 edges 7,835 7,835
control, 200 ms white: PAM11 spikes 0 0
stimulated (20 mV into 15 PAM11): PAM11 spikes 261 261 (87.0 Hz per cell)
plastic edges changed after the stimulated 200 ms 3,087 3,087
video-linked reward == manual pulse (spike hash) yes yes

Also measured, not in wirehead's report: the control run changed 1,768 plastic edges on its own. The centred rule moves weights whenever KC and DAN rates deviate from baseline, so "edges moved" is not a reward signal by itself; the number to show is the difference against a matched control, which was 3,095 edges here.

timing, Mac M1 Pro
graph prepare (import + compile) 19 s
engine load (graph + circuits + kernel build cached) 2.6 s
one 50 ms observation, median of 20 0.282 s (min 0.271, max 0.303)
real-time factor 0.18×
peak RSS 0.95 GB

So on the Mac the fly lives about 5.6× slower than wall-clock. For the show that is fine: the loop advances 50 ms of neural time per observation and we report simulated time, as wirehead does.

timing, Linux box (AMD Ryzen 7 9800X3D, g++ 13)
graph prepare, including the 1.1 GB download ~60 s
engine load 1.3 s
one 50 ms observation, median of 20 0.1689 s (min 0.0653, max 0.1758)
real-time factor 0.3×
peak RSS 0.96 GB

The kernel is single-threaded CPU code; the GPU is not used. The box is 1.7× faster than the Mac per observation.

Engineered: reward and readout

Reward and aversive cells come from wirehead's circuit.identify: the 15 cells typed PAM11 and the 2 typed PPL101 in MaleCNS v1.0, with the 7,835 KC→MBON07/11 edges as the plastic set. Unchanged.

The Spin readout is ours. Candidates were every descending neuron within two hops of MBON07/MBON11 (549 cells at two hops, only 3 at one hop). Rates under a static frame, 1 s of neural time after a 2 s settle, mean per cell:

type white black reels noise no reward / reward (reels, 1 s)
DNa02 (2) 19.5 10.5 11.0 12.5 10.5 / 13.5
DNa03 (2) 36.0 23.0 17.0 27.5 18.0 / 25.5
DNp32 (2) 154.0 154.5 155.0 156.5 155.0 / 155.0
DNp29 (2) 38.0 38.5 40.0 39.0 40.5 / 40.0
DNp62 (2) 9.0 9.0 10.0 10.5 10.5 / 10.0
MN9 (2) 14.5 24.0 16.0 20.5 21.5 / 15.0
DNa13 (4) 2.0 0 0.5 0.2 2.0 / 0.5
DNp09, DNa15, DNp42 (2 each) 0 0 0 0 0 / 0

DNp32 and DNp29 are pinned regardless of input or reward: no decision in them. DNp09, DNa15 and DNp42 never fire. DNa02 + DNa03 vary with the frame and rise with the reward current, so those four cells are the readout. Their body IDs:

type bodyId index
DNa02 10360 332
DNa03 10975 902
DNa03 519624 130282
DNa02 523769 131957

Reward (PAM11):

type bodyId index
PAM11 114661 86107
PAM11 119763 89566
PAM11 137539 100417
PAM11 138822 101105
PAM11 139706 101542
PAM11 145749 104512
PAM11 147857 105465
PAM11 157016 109038
PAM11 204930 119647
PAM11 215931 121077
PAM11 224500 121901
PAM11 238644 122768
PAM11 273182 123824
PAM11 319321 124499
PAM11 520616 130852

Aversive (PPL101):

type bodyId index
PPL101 11327 1235
PPL101 11900 1774

observe(frame, duration_ms, reward_mv=0, aversive_mv=0) returns wirehead's telemetry plus readout_hz, spin, reward_mv, aversive_mv and memory.l1_drift. Spin fires when the readout's mean rate over the observation is ≥ SPIN_THRESHOLD_HZ (20 Hz) and at least SPIN_REFRACTORY_MS (2,000 ms of neural time) have passed since the last one. Both are engineered starting points; S04 measures the resulting spin rate and adjusts. configuration() returns every engineered number and every cell for the page.

Learned: the plasticity rule

The only weights that change are the 7,835 Kenyon-cell-to-MBON07/11 edges. The rule is a baseline-centred anti-Hebbian eligibility model adapted from Huang, Luo et al. 2024 (doi:10.1038/s41586-024-07819-w) by stonkfly: Kenyon-cell activity leaves an eligibility trace, PAM11 activity gates it, and each edge's efficacy drifts within bounds and decays back over half an hour. The page reports how many edges differ from baseline and the L1 drift, live. Applying this rule to this reconstruction is a hypothesis, not a result.

Measured: the network is bistable

Same graph, same checksums, same 200 ms of white input from the same 1.5 s conditioning:

Mac (clang 16, arm64) Linux (g++ 13, x86_64)
control PAM11 spikes 0 0
stimulated PAM11 spikes 261 270
KC spikes in the stimulated 200 ms 1,823 5
plastic edges changed 3,087 5
total spikes, control 200 ms 252,777 162,921

The reward current does the same thing on both (PAM11 silent without it, 90 Hz with it), but the rest of the network is in a different state. The cause is not the compiler alone: the network is bistable. From a cold start it sits in a low state (23k spikes per 50 ms, Kenyon cells silent); under white light it ignites into a high state (~50k, Kenyon cells at ~4,000 spikes per 500 ms) and stays there afterwards. On the Mac ignition happens within the 1.5 s of conditioning; on the Linux build it happens at about 1.8 s (measured: KC spikes per 500 ms chunk 16, 14, 13, then 3,979), so the assay's 200 ms window lands before it and the plasticity rule, which needs Kenyon-cell eligibility, has nothing to move. Floating-point differences between the two builds (FMA contraction on arm64 by default) shift the trajectory of a chaotic network enough to move that moment.

Consequences, applied in S04: the loop keeps the white light on until the Kenyon cells have ignited rather than for a fixed 1.5 s, and the reward / no-reward / frozen controls are always compared on the same machine and build. Exact spike hashes are reproducible on one machine (the tests check that) and not across machines.