MiG: poor visibility + a manual stick that fatigued the pilot, slowing his loop
Better observation + faster cycle beat the better airframe.
Now fog the canopy
Take away a chunk of what the pilot can see.
The plane didn't get worse. The loop did.
They're flying blind.
This is what we do to agents
An agent runs an OODA loop too: read → model → decide → edit.
Hand it a stack with no introspection and we've fogged its canopy.
Then we're surprised when it flails.
The thesis
Agent productivity is bounded by the quality of its OODA loop.
Elixir / the BEAM gives it a clear canopy and a hydraulic stick.
A degraded loop, in a typical stack
Observe: scrape stdout / grep logs (low signal)
Orient: guess at hidden, mutable state (corrupted model)
Decide: pick a fix on a hunch
Act: rebuild → restart → state wiped (slow + blind again)
Every lap is expensive and the agent sees almost nothing.
60-second BEAM primer
Elixir runs on the BEAM — the runtime behind WhatsApp, Discord, Pinterest
A live system you can talk to, not a binary you restart
You don't reboot it to change it — you reach in
① A clear canopy Observe
Attach to a running node. RPC any function. Read real state.
One round-trip, real state
# Connect to the live system and just... ask
iex> :sys.get_state(MyApp.Sequencer)
%MyApp.Sequencer{bpm: 120, playing: true, step: 14}
iex> MyApp.Catalog.get_user!(42) # call the real code path
%User{id: 42, plan: :pro, ...}
No rebuild. No restart. No log-grep. Just look.
② Instruments inside the app Observe
Tidewave: an MCP server that runs code in the running Phoenix app
Evaluate, inspect Ecto queries, hit the real DB — from where the truth lives
③ Trustworthy readings Observe
Compiler warnings catch whole classes of "the agent guessed wrong"
The agent ties into the runtime itself — evaluate live in IEx, get ground-truth feedback
"Let it crash": only the code running right now dies — the BEAM carries blissfully on, so the agent sees the real fault and just tries again
④ Honest Orient Orient
Immutability + pattern matching: what the agent reads is what runs
No implicit state — the code is what it says it is: no hidden pointers, no shared mutable objects acting at a distance
The agent's model of the code can't silently drift from reality
⑤ A hydraulic stick Act → Observe
Speed of iteration is the loop — Boyd: cycle faster, get inside theirs
Hot code reload: change behavior without losing live state
Faster Act→Observe transitions = more laps per minute
No rebuild-the-world wall
typical: save → compile/bundle → relink → restart proc → re-warm → reconnect
beam: save → recompile *one module* → hot-swap into the live VM
iex> recompile()
Compiling 1 file (.ex)
:ok
# new code is live — same VM, same state, no restart
Elixir compiles — but the loop has no restart wall. Basically immediate.
Demo
Watch the loop close in real time.
Two loops
fogged: scrape logs → guess at hidden state → rebuild → restart
clear: read live state → model matches reality → reload → confirm
Same agent. Different cockpit.
Where the canopy doesn't help
Smaller ecosystem — fewer libraries, less training data for the model
ML lib maturity vs. Python; team familiarity / hiring
TODO any other honest caveats
Takeaways
Agent productivity ≈ the quality of its OODA loop
Observability isn't a nice-to-have — it's the canopy