Skip to content

Latest commit

Β 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸͺ°βš–️ 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

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

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:

.venv/bin/python adjudicator/fly_verdict.py my_screenshot.png --reply

The bot

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, 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.


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.

About

πŸͺ°βš–️ A real fruit fly connectome sits as juror and rules on X posts. 165,122 neurons, 25,563,197 synaptic connections, zero reading comprehension. Also: proof that the descending-neuron readout every viral fly-brain demo uses carries no information at all.

Topics

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages