ADR-001: Tokio Async Runtime

Status

Accepted

Context

Swarm orchestrates multiple concurrent agent processes, polls SQLite for messages, manages timers (backoff, checkpoints), and handles OS signals. We need an async runtime to avoid blocking the main thread.

Decision

Use Tokio with full features (rt-multi-thread, macros, process, signal, time, sync, io-util, fs).

Alternatives Considered

AlternativeWhy rejected
async-stdSmaller ecosystem, less mature process/signal support
Threads only (no async)Would require manual thread pools, select-like logic is painful
smolLighter, but we need Tokio's process::Command and signal support

Consequences

  • All I/O-heavy functions are async fn.
  • rusqlite is synchronous — wrap calls in tokio::task::spawn_blocking or accept brief blocking on the runtime (acceptable since DB ops are <1ms with WAL).
  • Process spawning uses tokio::process::Command.
  • The TUI event loop must integrate with Tokio (crossterm polling + tokio::select).

Tradeoffs

  • Tokio is a large dependency but well-maintained.
  • Learning curve for contributors unfamiliar with async Rust.