Skip to content

EN Course 11 Runtime Parity

lloydzhou edited this page May 29, 2026 · 1 revision

Runtime Parity

bash-agent has four runtimes:

  • Bash
  • C
  • Go
  • Rust

The Bash runtime is the reference implementation. Other runtimes do not need to copy every implementation detail, but they must match the behavior at the boundary.

What Must Match

Runtime parity covers:

  • system prompt bytes
  • request body semantics
  • OpenAI compatibility conversion
  • event names and payloads
  • events.jsonl ordering
  • display semantics
  • tool schema and tool result shape
  • Bash permission classification
  • compaction decisions
  • stats fields
  • interruption and error semantics

Where Implementations Can Differ

Languages can use different internal structures:

  • C can use explicit queues and structs
  • Go can use channels and goroutines
  • Rust can use enums and typed state
  • Bash can use pipes, AWK, and JSONL files

The layers still correspond:

CLI -> agent loop -> transport -> event parser -> display/store -> tools

Provider-specific logic stays at the transport boundary. Display-specific logic stays in the display layer. Tool execution stays behind dispatch.

Logical Message Boundary

Bash uses RESP-like byte streams because its layers communicate through pipes. C, Go, and Rust can pass typed structs internally, but they keep the same logical message boundary:

text / thinking / tool call / tool result / usage / stop / error

That boundary is what lets replay, stream-json, display queues, and tool execution stay aligned across runtimes even when the internal implementation language changes.

Failure and Interruption Semantics

Runtime parity also covers failure shape:

  • Ctrl+C becomes STOP interrupted
  • HTTP failure emits ERROR and stops the turn
  • truncated responses become an explicit max-token error
  • tool timeouts return a tool result with timeout text and non-zero status
  • provider stream differences are normalized before reaching the agent loop

Course Summary

The runtime starts as a small loop and gains one layer at a time:

input -> prompt -> transport -> events -> display/store -> tools -> loop

The project’s main discipline is keeping those layers explicit enough that four implementations can stay aligned.

Clone this wiki locally