Wing Gundam Zero reflected in Corin Nander's eyes. Turn A Gundam (Sunrise, 1999)
Optional soundtrack. Press play and let it run while you read.
Two problems, one shape
I was watching an AI agent try to read htop. It had no idea what was on screen.
It was pulling raw bytes (escape codes, cursor moves, color sequences) and looking for meaning in the noise. Couldn't scroll. Couldn't check which process had focus. Eventually gave up and shelled out top -l 1. The agent could read what the terminal handed it, but it couldn't ask the terminal anything about its own screen: where the cursor was, what was visible, whether anything had just scrolled.
Two problems showed up that week, in the same shape.
The first was a terminal for AI agents. A real emulator where agents address structured screen state (cursor positions, scroll regions, alternate screens) as buffers they can reason about.
The second was the cockpit of a Gundam. Wing Zero specifically, because the cockpit works as a design when every subsystem fails on its own. Sensor goes dark, the HUD prints "NO DATA" in that one slot and keeps drawing the rest. Real fighter cockpits behave the same way, but mech anime makes the design philosophy visceral. You watch a pilot lose a sensor, then a comms link, then a leg, and keep flying with whatever is left.
The terminal is the cockpit. The agent is just another pilot. The only runtime I trust to make either of them work is the BEAM, the virtual machine Erlang and Elixir run on.
When the Telegram bridge drops, the dashboard keeps rendering. When one task crashes mid-job, the notification for the task next door still fires. That fault-isolation is what you get once you stop fighting the runtime.
Giovanni Battista Piranesi, Le Carceri d'Invenzione, Plate XIV: The Gothic Arch (1761).
What AI agents are missing
Most agents do the same loop. Observe, decide, act. Read state. Pick a tool. Execute. Read the result. Repeat.
The reasoning is clean. The runtime underneath is duct tape. Shelling to cat and grep and sed. Reading files as strings and hoping the encoding is fine. State management via a conversation window that gets compressed once it runs long. Single-threaded, no fault isolation, no hot reload. Beautiful brain, broken body.
Two things follow. The runtime matters as much as the model. The smartest reasoner in the world stops being useful the moment its process dies and takes everything with it. And agents do better with structured environments. An agent that can address terminal state (what is visible, where the cursor is, which pane has focus) will outperform one staring at a wall of bytes every time.
Give an agent a real VT100 buffer and the questions change. It can read a specific region of the screen, check what's visible, scroll, focus a pane. Raxol does this. It is a terminal emulator written in Elixir, backed by a proper screen buffer, with structured access to that state for agents and humans alike.
Helmet POV inside Epyon's cockpit. Labeled regions, status text, numerical state. This is the view an agent should get, not a wall of bytes.
Joseph Wright of Derby, A Philosopher Lecturing on the Orrery (c. 1766). Derby Museum and Art Gallery.
TEA for everything
Raxol uses the Elm Architecture, TEA for short: a design pattern for interactive applications built around unidirectional data flow and immutable state. It came out of the Elm language and went on to shape Redux and the modern React app model.
The architecture has three pieces. Model is the immutable state of the application at a tick; updates produce a new model, they don't mutate the old one. Update is a pure function (Model, Message) -> Model that holds the application logic. View is a pure function Model -> UI. The cycle: View renders the Model. An event becomes a Message. Update returns the next Model. View re-renders.
What that buys is predictability. Side effects don't hide inside event handlers. Mutations can't race each other because there is only one path that creates new state. A crash can be replayed from its message log and the bug happens the same way every time. Testing reduces to feeding update/2 a list of messages and checking the resulting model.
Every input is a message: sensor reading, keystroke, LLM token, solver bid, 402 response. The cockpit is a view over current state; the pilot is one more message source. A counter, a file browser, and an AI agent streaming tokens from Claude all have the same shape. The runtime does not care whether the messages come from a human, a sensor, or a model. Three callbacks and a supervised application falls out the other end.
# Human-operated counter
defmodule Counter do
use Raxol.Core.Runtime.Application
def init(_), do: {%{n: 0}, []}
def update(:increment, model), do: {%{model | n: model.n + 1}, []}
def update(:decrement, model), do: {%{model | n: model.n - 1}, []}
end
# Same architecture. Different input source. This one pays for its data.
defmodule Researcher do
use Raxol.Agent
alias Raxol.Payments.{Req.AgentPlugin, SpendingPolicy, Wallets}
def init(_) do
plugin = AgentPlugin.auto_pay(
wallet: Wallets.OP, # 1Password-backed signing key
policy: SpendingPolicy.dev(), # per-session / lifetime caps
agent_id: :researcher
)
{%{notes: [], http: plugin}, []}
end
def update({:dig, topic}, %{http: plugin} = model) do
{model, Command.async(fn sender ->
{:ok, resp} =
Req.new(url: "https://feed.example.com/q?t=" <> URI.encode(topic))
|> plugin.()
|> Req.get()
sender.({:found, resp.body})
end)}
end
def update({:command_result, {:found, data}}, model) do
{%{model | notes: [data | model.notes]}, []}
end
end
One module takes keystrokes. The other takes Req responses. Both supervised, both hot-reloadable. When the upstream returns 402, AutoPay parses the challenge, checks the ledger against SpendingPolicy, signs an x402 header from the agent's own wallet, and resends. The agent's update/2 never sees the failure. If the researcher crashes mid-query, the supervisor restarts it with last known good state. The counter keeps counting.
The difference between a human app and an agent is where the input comes from. Agents can render to the terminal through view/1, or skip it and run headless. The runtime is indifferent.
This is the piece most agent frameworks get wrong. They bolt a separate "agent SDK" onto a language and end up rebuilding supervision, state machines, and lifecycle hooks from scratch. In Raxol, agents and interfaces are the same object. How you process messages is your business. ReAct, chain-of-thought, an FSM with guards. Different bodies for update/2.
The cockpit
Subsystems hold while the suit takes the hit. Endless Waltz (Sunrise, 1997).
In most agent frameworks, a bad tool call cascades. Process crashes, state vanishes, restart from scratch if you're lucky. If you're not lucky, it corrupts a shared structure and takes other agents with it.
This is why Raxol runs on the BEAM Virtual Machine. Erlang came out of Ericsson in the 80s to keep telephone switches answering calls while pieces of the system died and restarted around them. The BEAM gives us isolated processes, supervised restart, and graceful degradation. Forty years of telco failure modes, already debugged.
The same lineage runs through the wiring under the floor. Bob Metcalfe's Ethernet at Xerox PARC ended up speaking over the twisted-pair phone cabling already strung through every office building, once engineers pinned down the RJ45 pinout. The wire and the runtime both descend from the same obsession with not dropping a call.
Ethernet cable categories, Cat3 onward. The twisted-pair lineage. (samm.com)
OTP (Open Telecom Platform) is the standard library that ships with the BEAM: supervisors, GenServers, application lifecycle, hot code reload, distributed messaging. Most agent frameworks bolt on a queue, a retry layer, a job runner, a circuit breaker, a state store. Raxol uses what's already in the box. No Redis, no Celery, no Sidekiq in the failure path.
The agent is one of those OTP processes. When it crashes the supervisor catches it, the cockpit stays up, the agent restarts from its last known good state, and the HUD shows a blip. One gauge resets to stale-but-safe data while the fresh state loads. The pilot keeps flying.
Every subsystem is a separate gauge. When one fails, the gauge says NO DATA. The pilot keeps flying. (Bandai Namco)
I keep coming back to how right this feels as a design target. High availability in a very specific sense: graceful degradation as a UI pattern. A dozen subsystems feeding one interface (navigation, sensors, comms, weapons), each one running independently, all reporting to a single HUD. When one dies, the gauge stays on screen and says "NO DATA." The pilot sees a degraded but functional world. That distinction is the whole game.
+--------------------------------------------------+
| SENSOR HUD [NOMINAL] 12:34:56.789 |
+--------------------------------------------------+
| CPU ====---- 42% | MEM ====----- 38% |
| NET ........... | DISK ======-- 67% |
+--------------------------------------------------+
| SPARKLINE ._/\._./^^\._. (last 60s) |
+--------------------------------------------------+
| THREATS: [NONE] |
| MINIMAP: [sector 7-G clear] |
+--------------------------------------------------+
Put an AI agent in that seat. It reads the same HUD. Processes sensor data through update/2. Issues commands: reallocate resources, flag an anomaly, adjust course. The runtime executes. Same interface, same state, same fault isolation. Carbon pilot or silicon pilot.
ZERO System cockpit schematic. Two seats by design.
Where it stands
The plan was six packages. There are thirteen now, which probably says something about how much I've underestimated the scope of this thing every quarter for two years.
Last quarter I went back and unified the lifecycle code across all of them. Every package now uses the same BaseManager pattern for its GenServers. That kind of consolidation does not make a good headline, but it is the work that turns thirteen scattered packages into thirteen packages that behave like one runtime. Eleven of them ship on Hex. The two holdouts, raxol_acp and raxol_symphony, are still pre-alpha.
The originals are stable: raxol_core, raxol_terminal, raxol_sensor, raxol_mcp, raxol_liveview, raxol_plugin. The two staged extractions shipped: raxol_agent and raxol_payments are first-class packages now. Then three surface packages I didn't plan for a year ago: raxol_speech (TTS announcements via Bumblebee, STT input via Whisper), raxol_telegram (TEA modules rendered as inline keyboards inside a chat), raxol_watch (APNS and FCM push for glanceable summaries, with tap actions routed back as events). Each of these started as "what if the surface was X" and turned out to share enough machinery with the existing renderers that they slotted in.
Inside ZERO System cockpit. The pilot and the machine share state on the same tick.
Then two new flagship packages that genuinely caught me by surprise.
raxol_symphony is a port of OpenAI Symphony. An orchestrator polls a tracker (Linear or GitHub Issues), claims eligible work, isolates each issue in its own workspace, and runs a coding agent until the work reaches a workflow-defined handoff state. Six surfaces consume the same orchestrator snapshot over PubSub: terminal dashboard, LiveView, MCP tools, Telegram inline keyboards, Watch push, JSON API. Per-run evidence (CI status, PR comments, complexity scores, asciinema replays) is collected automatically. Two runner backends ship: the default wraps Raxol.Agent.Stream, the other is the upstream codex app-server over a Port for parity with the original Elixir reference.
When I drafted this post the first time, "cockpit" was a metaphor. Symphony turned it into something I can point at. One orchestrator state, six independent surfaces, each failing in its own corner. I didn't design it that way on purpose.
raxol_acp is the other one. Agent Commerce Protocol, the spec used by Virtuals' agent marketplace. The polite framing is "we shipped an OTP implementation of ACP." The honest framing is that every other ACP seller is a Python or Node script with a hand-rolled threading.Lock and a polling loop for a flaky WebSocket. raxol_acp gets you one supervised process per active job, a dedicated NonceServer GenServer per wallet so concurrent jobs can't trample each other while signing, hot reload of a buggy offering without dropping the socket, process-per-offering with crash isolation, and DETS-backed memo persistence so a node restart resumes mid-flight jobs instead of orphaning them. None of that is exotic on the BEAM. It is exotic in agent commerce, where the default infrastructure is "a thread lock and a prayer."
v0.1 engineering is done. The on-chain client is real Req-based JSON-RPC, with EIP-1559 typed-transaction signing, hand-rolled Yellow-Paper RLP, and a log decoder that pulls job_id out of create_job receipts. The seller stack ships behind a feature flag. What is left is waiting on Virtuals to publish the SCA contract spec so the ABIs stop being placeholders.
raxol_payments got a lot bigger this quarter. The last draft of this post mentioned x402 and Xochi. What's there now: three protocols (x402, MPP for Stripe/Tempo machine payments, Xochi for cross-chain intent settlement), an auto-selecting Router that picks based on chain, privacy tier, and trust score, ERC-5564 and ERC-6538 stealth addresses (about 300 lines of secp256k1), ZKSAR attestation verification across six proof types, a TrustScore aggregator with diminishing returns, the Glass Cube privacy tier model (six tiers, attestation-gated), a per-request/session/lifetime spending ledger as its own GenServer, and a PXE Bridge to Aztec for execution-level privacy beyond what stealth gives you.
The piece I keep tuning is the auth model. A Raxol agent transacts either as a Guest (paying per call via x402, capped at Standard privacy, holding its own keys) or under a Mandate (a human signs a scoped EIP-712 envelope with max amount, expiry, and call count; the agent inherits the human's trust tier and privacy access for the envelope's lifetime).
alias Raxol.Payments.{Mandate, Wallets}
{:ok, mandate} =
Mandate.build(
human_wallet: member_addr,
agent_wallet: agent_addr,
scopes: ["execute"],
max_amount_usd: 250,
max_calls: 20,
expires_at: System.system_time(:second) + 3600
)
{:ok, signed} = Mandate.sign(mandate, Wallets.OP)
{:ok, envelope} = Mandate.to_envelope(signed)
# Agent presents `envelope` in X-Xochi-Delegation on every call.
# Xochi verifies the signature against human_wallet and decrements
# budget counters keyed by H(envelope). The agent never authenticates.
The server verifies per-call and stores nothing persistent that links agent to human. The digest runs through a shared Raxol.Payments.EIP712 encoder with string[] support, and the pinned vector test matches viem's hashTypedData byte-for-byte, so signatures verify on the Xochi side without divergence. Agents that need real privacy can have it without becoming the human's pseudonymous twin on-chain.
Xochi itself is now built into the raxol README as a first-class example, because at some point I stopped explaining the framework abstractly and started pointing at the most convincing thing I could find. The Xochi trader terminal serves over SSH with zero install. The web trading UI renders the same TEA module via LiveView. The solver agent surface lets Riddler's sub-2ms solver consume auto-derived MCP tools to bid on intents. The ops cockpit watches solver health, validator peers, and settlement latency on a BEAM dashboard with sensor fusion. One TEA module. Four surfaces. The solver agent and the human trader interact with the same widget tree through different projections.
Coinbase recently launched Agentic Wallets, and on-chain volume from agents on Base and Solana is climbing steeply. The conversation around it is mostly about guardrails: spending caps, whitelisted contracts, circuit breakers. Almost nobody is talking about the harder problem. An agent broadcasting its rebalancing strategy to a public mempool is a sitting target. Every MEV bot on Ethereum sees the move before it settles. $289M was extracted by sandwich attacks in 2025, and agents running 24/7 with predictable patterns are easier prey than human traders by a wide margin. Once the cockpit has a wallet, private execution is what keeps the pilot from being picked apart on every trade.
Caravaggio, The Calling of Saint Matthew (c. 1600). San Luigi dei Francesi, Rome. Christ points at Matthew mid-count. The instant a money-handler is called into a different kind of actor.
Inter-agent messaging is plain: Command.send_agent/2, broadcast, call. State stays inside processes; communication happens by message. On the BEAM, fault tolerance is the default. You have to work to break it.
I will admit I am still not sure what happens when you put an agent into all of this and let it run unsupervised. The machinery works: the headless runtime, the payment rails, the supervision trees, the six-surface fan-out, the per-job isolation in Symphony, the spending ledger that refuses to sign past its mandate. "Works" and "is a good idea" are different questions, and I do not think anyone has a good answer to the second one yet. The next quarter is finding out. Production deployments. Agents in the wild, running headless, paying for their own compute, trading privately through Xochi, opening their own pull requests through Symphony, and crashing in ways I will not see coming.
That last part is what the BEAM is for.
The Romefeller phase
The thing nobody talks about in Wing is the money.
Diego Velazquez, The Forge of Vulcan (1630). Museo del Prado, Madrid. Apollo arrives at the smithy as Vulcan forges armor for Mars. The patrician order pays a visit to the workshop that builds its war machine.
OZ does not pay for itself. The Romefeller Foundation pays for OZ. Romefeller is centuries-old European aristocratic capital, the kind of money that owns the suits, the factories, and most of the colonel-rank officers. They produce Leos by the thousand. They want a long war the way a defense contractor wants a long war. Treize Khushrenada is their golden boy until he stops being convenient, which is approximately the moment he tries to make conflict expensive again on purpose.
The Gundams are an asymmetric counter-play. Five scientists, no budget worth naming, working underground from colonial cover. They cannot match Romefeller's industrial throughput so they do not try. They build six suits out of Gundanium Alloy, which can only be manufactured in zero gravity at the L-points, and they ship those suits to Earth with one pilot apiece. Tiny budget. Architectural superiority. The whole strategy is "we cannot out-produce them, so we have to out-design them."
The AI agent economy right now is in its Romefeller phase.
OpenAI, Anthropic, and Google are the foundation. They produce the underlying capability. The standard agent stack runs downstream of them: Python scripts with a thread lock and a prayer, billed per token by the lab that trained the model, restarted by hand when the process dies. These are the Leos. Cheap, mass-produced, easy to lose in volume. The procurement contract is perpetual.
Raxol plus Xochi is a colonial-scientist play. Build the frame for a small number of architecturally superior agents that hold their own wallets, sign their own envelopes, and execute privately enough to avoid getting sandwiched by the bots watching them. The BEAM is the Gundanium. Supervision trees are the binders. The five scientists of this story are whoever happens to be writing fault-tolerant agent infrastructure outside the dominant industrial mode.
A few specifics on what that buys an agent economically:
- A wallet makes it a first-class economic actor. It can pay other agents directly through x402 or ACP, settle in USDC, and hold value without routing through the lab that trained it.
- The Mandate model is Operation Meteor on-chain. A human signs an EIP-712 envelope with scope, budget, and expiry. The agent operates autonomously inside that envelope. The scientist sends the pilot out with a briefing. The pilot does not phone home for every move.
- Stealth addresses and Aztec PXE are the cloaking. Public mempool is hostile space. Every MEV bot watching the chain is a Mobile Doll watching your trajectory. Private execution is what keeps an automated trader from being picked apart on every trade.
- The Glass Cube privacy tiers map trust score to operational privacy. You earn the right to operate in stealth by accumulating attestations, not by inheriting a rank. The OZ class structure inverted.
None of this matters if agents stay billed-by-the-call rentals on a centralized API. It matters once a process has a wallet, a mandate, a private execution path, and the supervisor tree to survive the inevitable crash. Then it is a pilot, not a seat.
Albrecht Durer, Knight, Death and the Devil (1513). National Gallery of Art. The armor, the horse, the dog, the route. Death holds the hourglass, the Devil leers from behind, and the knight rides past both because he came equipped. The tools makes the pilot.
The ZERO System
My favorite Gundam is the XXXG-00W0 Wing Gundam Zero. Hajime Katoki's Endless Waltz redesign specifically, with the big white wing binders rather than the boxier original. If you have seen the EW cut you know the scene where the wings unfold and the camera lingers too long. That is the one.
Wing Gundam Zero, Endless Waltz redesign. New Mobile Report Gundam Wing: Endless Waltz (Sunrise, 1997).
The wings came off the OZ-00MS Tallgeese Flügel, Zechs Merquise's space-combat variant, decommissioned after the Eve Wars. Howard salvaged the four binders and grafted them onto the wreckage of the Wing Gundam Proto Zero. Two large wings, two small. The large pair doubles as a shield and as atmospheric re-entry armor. Anti-beam coating, Gundanium Alloy throughout. The armament list is the kind of thing I have memorized: Twin Buster Rifle generator-coupled for rapid fire, two beam sabers stored in the wing pylons, shoulder machine cannons with drum feed, Wing Vulcans on the shield. The Glory of the Losers manga adds the Drei Zwerg, three Messer Zwerg rifles that combine, and combine again with the Twin Buster Rifle to make the Drei Zwerg Buster Doppelt. That one vaporized the Libra wreckage before it hit Earth.
Wing Zero with the Twin Buster Rifle. Glory of the Losers, the manga that ships the Drei Zwerg.
Twin Buster Rifle vaporizing the Libra wreckage. Endless Waltz (Sunrise, 1997).
Neo-Bird Mode is the other thing I think about. The suit folds down into a high-speed flight configuration, shield as nose, binders adjusting around it. Atmospheric or space. As close as the franchise gets to "the suit moves the way a body would, only better."
And then there is the ZERO System.
Wing Zero with the ZERO System engaged. Pilot and machine on the same tick.
ZERO stands for Zoning and Emotional Range Omitted. A brain-computer interface that strips the pilot's affective load and feeds them an ongoing probability map of every action and its consequences across the battlespace. It makes the human and the machine think on the same timestep. The catch is the human has to be psychologically intact enough to survive the load. Most are not. ZERO has driven pilots to breakdowns and worse. Heero is one of the few who can sustain it.
This is the seed of Raxol.
The design target I keep circling is the same one ZERO points at. A runtime where the pilot and the machine share state on the same tick. Every subsystem reports honestly, the interface degrades gracefully when something dies, and the loop closes fast enough that human and machine are reading the same world. TEA gives me the shared state. OTP gives me the supervision. The BEAM gives me the tick. Raxol is the cockpit I can actually build right now, on a laptop, in Elixir, today.
The agent is the second pilot in the seat. Carbon and silicon read the same buffer, issue commands through the same update/2, share a HUD. When one of them fails, the other keeps flying.
My actual life goal, the one I do not usually write down in blog posts, is to build and pilot a Wing Gundam Zero, or as close to one as engineering and biology let me get in one lifetime. I do not expect to finish. I expect to learn things on the way that are worth more than the finish would have been. Raxol is the part of that project I can ship.
Raxol is an OTP-native multi-surface runtime for Elixir. GitHub
The payment rails run through Xochi. The open infrastructure runs through axol.io. Fund the lab on Giveth.