02
Anatomy of an AI Coding Agent — Article 2 of 8

The Nervous SystemHow Components Talk

The SQ/EQ protocol: submission queues, event queues, and the async channels that decouple every part of Codex into a living, breathing system.

The Restaurant Kitchen Analogy

Imagine a restaurant. A busy one. On one side, waiters take orders from diners. On the other side, chefs work at stations: prep, grill, plating. In the middle: a ticket system.

The waiter doesn't shout across the kitchen. They don't interrupt the chef mid-flip. Instead, they write an order ticket and place it in the pass. The ticket has everything the chef needs: what to make, when it was ordered, any special requests.

When the dish is ready, the chef rings a bell. The food waits in the window. A runner picks it up and delivers it to the table.

The kitchen doesn't know which diner ordered what. The diner doesn't see the chaos of the kitchen. The ticket system—the nervous system—connects them without coupling them.

Codex works exactly like this. And the protocol that implements it? It's called SQ/EQ: the Submission Queue and the Event Queue.

DINERS (Frontends) TUI / IDE / CLI Submit orders TICKET SYSTEM (SQ/EQ Protocol) Submission Q Event Q KITCHEN (Core Engine) Orchestrator AI + Sandbox

Submissions: The Order Tickets

When you send a command to Codex, you're not directly talking to the core engine. You're writing a Submission.

pub struct Submission {
    pub id: String,              // Unique ID to correlate with responses
    pub op: Op,                  // The operation (the "order")
    pub trace: Option<W3cTraceContext>,  // Distributed tracing
}

Three fields. But they pack a punch. The id is a UUID tying submissions to events. The trace carries W3C trace context for end-to-end observability. And the op field is an enum representing every possible action:

The Op Enum: Orders in the Kitchen

UserTurn
The bread and butter. User prompt with CWD, approval policy, sandbox policy, model, and reasoning settings.
Interrupt
You hit Ctrl+C. Aborts the current turn gracefully without nuking background processes.
ExecApproval
"The chef wants to run rm -rf /—approve?" Respond Approved or Rejected.
Shutdown
Time to close. Codex cleans up, exits the loop. Orderly teardown.
Undo
Revert the last agent action. A git rollback for conversation state.
ThreadRollback
Roll back N turns. Rewind conversation to a prior checkpoint.
Design Insight

The beauty of this enum-based design is extensibility. Need a new operation? Add a variant to Op. The protocol doesn't change at the transport layer. New and old clients coexist.

Events: The Kitchen Responds

While submissions flow in, events flow out. Here's the critical insight: events are not responses to submissions. They're not synchronous. The kitchen emits a stream of events as work progresses.

pub enum EventMsg {
    TurnStarted(TurnStartedEvent),
    AgentMessage(AgentMessageEvent),
    AgentReasoning(AgentReasoningEvent),
    ExecCommandBegin(ExecCommandBeginEvent),
    ExecCommandOutputDelta(...),
    ExecCommandEnd(ExecCommandEndEvent),
    ExecApprovalRequest(ExecApprovalRequestEvent),
    TurnComplete(TurnCompleteEvent),
    // ... dozens more
}

You submit a UserTurn with id abc-123, and within milliseconds you get: TurnStartedAgentMessage (streaming, delta by delta) → ExecCommandBeginExecApprovalRequest → your approval → ExecCommandEnd → more agent output → TurnComplete. All of it streaming in real-time.

See It In Action

Click "Run Simulation" to watch a real SQ/EQ exchange. Left: submissions go in. Right: events come out.

SQ/EQ Protocol Simulator
Submissions (In)
Events (Out)

The Hierarchy: Threads, Turns, Items

Codex introduces a nested structure mirroring how conversations work:

Thread (a conversation)
Turn (a back-and-forth round trip)
Item: UserMessage your prompt
Item: AgentMessage agent response text
Item: Reasoning agent thinking process
Item: WebSearch external lookups
Item: CommandExecution shell commands run
Item: FileChange patches applied

A Thread is a conversation. A Turn is a single round trip. An Item is a discrete piece of work within a turn. Each item has its own ID and lifecycle. This hierarchy lets the UI render conversation in a granular way—stream text character by character, show shell output as it arrives, toggle reasoning collapsed.

The Async Channels: The Real Magic

// Frontend sends submissions here
let (tx_sub, rx_sub) = mpsc::channel::<Submission>();

// Core sends events here
let (tx_event, rx_event) = mpsc::channel::<EventMsg>();

// The core engine loop
tokio::spawn(async move {
    while let Some(submission) = rx_sub.recv().await {
        match submission.op {
            Op::UserTurn { items, cwd, model, ... } => {
                tx_event.send(EventMsg::TurnStarted(...)).await?;
                // Process the turn, call the model, execute commands...
                tx_event.send(EventMsg::TurnComplete(...)).await?;
            }
            Op::Interrupt => {
                tx_event.send(EventMsg::TurnAborted(...)).await?;
            }
            // ... handle other operations
        }
    }
});

The frontend and core are decoupled by channels. The frontend doesn't wait for a response—it sends a submission and listens on the event stream. Multiple frontends can connect to the same core. The web interface, the TUI, a CI/CD pipeline—all listening to the same event stream.

Why This Design Is Brilliant

Decoupling
Swap the frontend without touching the core. Reimplement the core without breaking clients.
Concurrency
Async channels let many operations happen in parallel. Send approvals while the agent thinks.
Streaming
Events are a stream, not a single response. Real-time feedback, character by character.
Testability
Mock the submission channel and inspect events. No full end-to-end setup needed.
Observability
W3C trace context flows through every submission for end-to-end tracing.
Extensibility
New operations and events? Add them to the enum. Old and new coexist.

Key Takeaways

The SQ/EQ protocol decouples frontends from the core using async channels.
Submissions are incoming orders: UUID + Op enum + optional trace context.
Events are outgoing signals: a stream, not a single response, enabling real-time feedback.
Thread → Turn → Item hierarchy mirrors conversation structure for granular rendering.
Multiple frontends can connect to the same core, sharing one event stream.
W3C trace context propagates through the entire system for distributed tracing.
← Prev: The 10,000-Foot View Article 2 of 8 Next: The Brain →