Observability, the OODA loop & why agents thrive on the BEAM
Kevin Edey · Code to Cloud Summit · 2026
I've been accused of AI psychosis more than once. I talk directly to
Claude — in conversations where I'm not telling it to write code —
and I tend to believe it.
…but never about time. Claude has
literally no concept of time.
whoami
Kevin Edey — AI & Elixir advocate
Laid off end of March 2026 — been charging hard ever since
Building Mob: a mobile framework that lets agents build native UI apps in Elixir
Started April 5. A fully functioning framework in under two months.
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.
It's in the name
Large Language Model.
Language is the forte.
Not sight.
Not hearing.
Not time.
Not spatial reasoning.
Everything else, it has to be told about.
Everything else is a warning bell
Vision, audio, metrics → it reaches for a tool and reads the result… as text
Like a fighter pilot's warning bell — noise until you've learned what it means
Humans get laughter and breaking glass for free — no interpreter needed
But infrared? Ultrasonic? We're blind there too — we lean on sensors
Bring it back to language
In language, the agent is in its element
Out of it, it's reading instruments it half-speaks — guessing at best
The job: render the world into language, faithfully
Hallucination is a symptom
It hallucinates when it's filling a gap you left
Usually not a model failure — a context failure: Observe was starved
Give it enough context and it doesn't need to invent
Fog the canopy → it guesses.
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, RabbitMQ & Supabase
You might already run it — RabbitMQ is Erlang, Supabase Realtime is Elixir
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
iex / erl: a live REPL into the running system — there since day one, not an afterthought
The BEAM was built to be operated live — telecom switches you can't reboot
Tidewave is just the newest instrument: 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.
But brief the pilot
A great cockpit isn't a mission plan — the pilot still gets briefed
Ease the agent into the context before the serious work
A session tuned to what you're doing right now beats a cold start, every time
AGENTS.md is one way to prime it — but priming is a practice, not a single file
There are no magic prompts
A clever incantation won't rescue a thin session
The lever is the richness of the whole session, not one line
Starve the context → it guesses. Invest in the session → it flies.
The prompt isn't the product. The session is.
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
So I asked Claude what it wants
I talk to Claude about Claude — yes, the "psychosis." So I asked: what's missing in a language built for you?
Feedback loop, first-class — show me the minimal edit to correctness
Confidence annotations — flag the parts I'm unsure of for harder checks
Intent, formally — machine-readable why, not comments — to constrain future edits
Distribution in the type system — which value lives on which node
AI-maintainability as a property — does the context to safely modify fit in a window?
Its #1 gap: the feedback loop. That's this whole talk — and it'd build on the BEAM.
Takeaways
Agent productivity ≈ the quality of its OODA loop
Observability isn't a nice-to-have — it's the canopy