# ๐Ÿชฐโš–๏ธ The Fly Adjudicator ![The fly bench in session: a fly in a juror's jacket reviews a replayed X browsing session while its own neural activity is visualised beside it](docs/fly-court.gif) The bench reviewing evidence. Screen on the left is a real rrweb replay of the browsing session that collected the post. Panel on the right is the fly's actual measured response โ€” OFF pathway, ON pathway, inhibition โ€” rendered live as it deliberates. **We wired a real fruit fly's brain to X and made it rule on posts about fruit fly brains.** It has 165,122 neurons. It has 25,563,197 synaptic connections. It has a tiny wooden gavel. It cannot read. --- ## The premise In 2026 HHMI Janelia, Cambridge, the MRC LMB and Google Research released **MaleCNS v1.0** โ€” the complete connectome of an adult male *Drosophila* central nervous system. Every neuron. Every connection. A real, measured, CC-BY wiring diagram of an entire animal. Within days the timeline filled up with people running it as a brain: > *the fly brain can play beat saber* > *I gave the fly brain $100 to trade bitcoin* > *THE FLY BRAIN ESCAPED THE COMPUTER. I PUT IT INSIDE A PHYSICAL ROBOT.* > *We trained a simulated fruit fly brain to review expenses by changing just 4,184 weights* > *I taught a fruit fly to play World of Warcraft!!* So we built the only application this technology was ever destined for: **a fly that decides whether your post is bullshit.** Then, because we had the whole connectome loaded anyway, we checked whether any of this actually works. It mostly doesn't. That part is below, and it's the good part. --- ## How a fly reads a tweet ``` screenshot โ†’ 892 hexagonal eye columns โ†’ lamina โ†’ medulla โ†’ verdict (real retinotopic coords) L1/L2/L3/L5 Tm1/Tm2 ``` 1. **Screenshot the post.** A browser MCP client drives a real logged-in Chrome session. 2. **Show it to the eye.** The image is mapped onto 892 hexagonal ommatidial columns using the *measured* column assignments in the dataset โ€” real retinotopy, not a made-up grid. 3. **Let the fly look around.** A static image produces exactly one transient, which dies in 3 ms. Real flies never hold still, so the image drifts across the eye. This is both the biological fact and the only way to get any signal at all. 4. **Run 165,122 leaky integrate-and-fire neurons for 140 ms.** 5. **Read the optic lobe.** Three numbers come out, and they decide the verdict. | tag | what it is | range | role | |---|---|---|---| | **Dark-edge detectors** | Tm1 + Tm2 spikes โ€” the OFF pathway | 96โ€“241 | verdict, threshold **177** | | **ON/OFF balance** | L1 รท magnitude | 1.63โ€“2.99 | independent, *r* = โˆ’0.38 | | **Inhibitory surround** | GABAergic proximal medulla รท magnitude | 0.62โ€“0.84 | independent, *r* = +0.35 | **Polarity is the joke.** Flies are famously drawn to filth, so a strong dark-edge response โ€” the fly wants to land on it โ€” scores **BULLSHIT**. A post the fly finds uninteresting is **VALID**, which is the worst thing that can happen to you here. The spike counts are real. The polarity is a gag. Both things are true at once. ### What it says ``` ๐Ÿชฐโš–๏ธ Fly Adjudicator Verdict: BULLSHIT Dark-edge detectors: 241 spikes (heavy, threshold 177) ON/OFF balance: 1.94 โ€” balanced Inhibitory surround: 0.73 โ€” clamped Statement: Rarely does this bench encounter a specimen of such generous filth. I rule against it with the greatest possible enthusiasm and I intend to land on it immediately. ``` There are 23 statements in the bank, selected by the tag combination and a hash of the post ID, so a given post always gets the same ruling. The bench speaks like a juror of impeccable procedural manners who is also a fly and regards bullshit as a delicacy. **Current docket: 32 real posts. 22 BULLSHIT, 10 VALID.** --- ## The part where we ruin it for everyone We went in to build a joke and came out with four findings. All of them are reproducible from the scripts in this repo. ### 1. The readout everyone uses is dead Every viral fly-brain demo reads its output from **descending neurons** โ€” the 1,314 cells that carry the brain's commands to the body. It's the obvious choice. It's 0.80% of the network and it's the only output channel there is. We swept the stimulus gain looking for a setting where descending neurons both fire *and* depend on the image. **There isn't one.** ``` gain DN spikes for 5 very different images verdict 14 [ 0, 0, 0, 0, 0] silent 22 [4355, 4092, 4520, 4544, 4713] saturated 30 [4324, 4307, 4084, 4308, 4156] saturated 42 [4244, 4167, 4241, 4264, 4212] saturated ``` Position 3 is a **blank grey rectangle**. It scores 4520, right in the middle. A dense wall of text and a featureless square differ by under 5%. Across 32 real post screenshots the descending neurons fired for **exactly one**. Thirty-one zeros and one 3,507. That is a cliff, not a signal. So this project reads the optic lobe instead, and says so. That's the difference between this and the thing it's parodying. ### 2. Eight neurons decide whether it's perception or a seizure APL, DPM, CT1 and Am1 โ€” four cell types, two cells each, **8 out of 165,122**. They're large wide-field neurons that release transmitter *continuously* instead of firing spikes, and APL is specifically the feedback brake that keeps mushroom-body activity sparse. Model them as ordinary spiking units, like a uniform LIF model does, and two cells firing at a few hundred Hz cannot hold back 4,064 Kenyon cells: | | Kenyon cells, late window | total network spikes | |---|---|---| | all-LIF (8 neurons spiking) | **322 Hz**, forever | 749,124 | | graded (8 neurons non-spiking) | **0 Hz** | 327,817 | Same wiring. Same stimulus. **0.005% of the network** decides whether your simulation looks like a brain or a grand mal seizure. That is not a fact about the fly. ### 3. There is no principled value for the one parameter that matters `alpha` is the voltage a single synaptic contact delivers. The connectome does not contain it โ€” EM tells you *where* and *how many*, never *how much current*. ``` alpha โ‰ค 0.008 โ†’ 0.00 Hz. 100% of neurons silent. Not one spike. alpha = 0.009 โ†’ 3.99 Hz alpha = 0.011 โ†’ 9.98 Hz โ† what we use alpha = 0.030 โ†’ 30.13 Hz ``` Dead to alive between 0.008 and 0.009, with no graded middle to tune inside. You turn the knob until it looks alive and then you publish the video. ### 4. But the anatomy really does work Credit where it's due. Show the network an expanding dark disc โ€” a looming predator โ€” and activity walks the fly's real escape pathway, in the correct order, with nobody telling it to: ``` t = 50 ms lamina L2 OFF channel, the disc darkens its columns t = 51 ms medulla Tm1/Tm2 second stage of the OFF pathway t = 53 ms LC4/LC6/LPLC1/LPLC2 the looming detectors t = 55 ms descending neurons brain output to the body t = 57 ms VNC motor neurons the command reaches muscle ``` **Seven milliseconds, four synapses**, an ordering that fell straight out of the wiring diagram. A real fly's giant-fibre escape is in the same ballpark. Nothing was tuned to make that happen. Then, about ten milliseconds later, the visual pathway goes silent and never recovers while the disc is still expanding. So: the connectome is real, the cascade is real, and anything decoded more than ~10 ms after stimulus onset is not reading the image. --- ## Bonus finding: X's composer hates robots Two bugs that cost real time, documented here so they cost you none: - **Never type a newline into X's reply box.** It's Draft.js, and after a newline commits **the caret resets to position 0**. Everything you type next inserts at the *front*, so a three-line reply comes out in reverse with the first character of each line displaced. The fix: re-collapse the DOM Selection to the end of the editor before *every* `type` call. - **Key events don't reach the composer at all.** `Enter`, `shift+Enter`, `cmd+a`, `Backspace` โ€” all ignored. You cannot clear a dirty draft with keystrokes; you have to reload the page. Submit by **clicking** the Reply button, not with a shortcut. Draft.js ignores synthetic key events but respects a JS-set selection. That asymmetry is the whole story. --- ## Run it yourself ```bash git clone https://github.com/CakeCrusher/fly-adjudicator cd fly-adjudicator uv venv --python 3.12 .venv uv pip install --python .venv/bin/python pyarrow pandas numpy scipy pillow # 1.1 GB of fruit fly, straight from Janelia (CC-BY) mkdir -p data/malecns && cd data/malecns B=https://storage.googleapis.com/flyem-male-cns/v1.0/connectome-data/flat-connectome curl -O $B/connectome-weights-male-cns-v1.0-minconf-0.5.feather # 1.0 GB, the graph curl -O $B/body-annotations-male-cns-v1.0-minconf-0.5.feather # 14 MB, identities curl -O $B/body-neurotransmitters-male-cns-v1.0.feather # 41 MB, the signs cd ../.. .venv/bin/python scripts/10_build_graph.py # signed sparse matrix (~2 min) .venv/bin/python adjudicator/fly_verdict.py data/calibration/*.jpg --reply ``` Judge anything you like: ```bash .venv/bin/python adjudicator/fly_verdict.py my_screenshot.png --reply ``` ### The bot ```bash export X_HANDLE=yourhandle export OCIC_SERVER=/path/to/open-claude-in-chrome/host/codemode/server-hybrid.js node bot/adjudicate-x.mjs --probe # show what it finds node bot/adjudicate-x.mjs # DRY RUN โ€” judges, prints, posts nothing node bot/adjudicate-x.mjs --live # actually replies ``` **Dry run is the default.** `--live` is the only flag that writes to X, and the bot refuses to post if the composer mangles the text. Please don't use this to spam strangers; X's automation rules exist and the fly will not testify on your behalf. --- ## What's in here ``` adjudicator/ fly_verdict.py image โ†’ connectome โ†’ verdict. The whole simulation. verdict_template.py the reply format + 23-statement bank, tag-contingent bot/ mcp-client.mjs minimal MCP stdio client (drives a real Chrome session) adjudicate-x.mjs search โ†’ screenshot โ†’ judge โ†’ reply scripts/ 10_build_graph.py feather files โ†’ signed sparse adjacency matrix 20/21/22_*.py LIF simulation + the sensory encoder attempts 30_stability.py the alpha cliff 31_graded.py the 8-neuron finding 60_find_readouts.py variance search across all 11,751 cell types 70_docket.py builds the 32-case docket docs/ fly-court.html the 3D courtroom (Three.js + rrweb session replay) fly-viewer.html live LIF simulation viewer โ€” watch the 7 ms cascade connectome-primer.html what's actually inside the MaleCNS files ``` The three HTML files are standalone โ€” open them in a browser. --- ## Credits The connectome is **MaleCNS v1.0** from the [FlyEM project at HHMI Janelia](https://male-cns.janelia.org/), with the University of Cambridge, the MRC Laboratory of Molecular Biology and Google Research. CC-BY 4.0. They did the hard part โ€” a decade of electron microscopy and proofreading โ€” and we attached a gavel to it. The integrate-and-fire approach follows Shiu et al. (2024), which showed that even this crude abstraction reproduces real sensorimotor responses in small, well-characterised circuits. Running it across an entire CNS with an invented stimulus is an extrapolation, not an inheritance of that validation. We are being honest about this so that you don't have to be. Browser automation via [open-claude-in-chrome](https://github.com/CakeCrusher/open-claude-in-chrome). --- ## Licence Code: MIT. Connectome data: CC-BY 4.0, Janelia FlyEM. No flies were harmed. One was made to read Twitter, which is arguably worse.