Baton: the harness beneath the harness

When an AI harness calls an external agent, the visible action is often just one command. The real problem starts immediately afterward: the caller may finish its turn, the tool runner may disappear, the worker may need to outlive its parent, and the reply still has to reach the right session. Pipes and background processes handle the happy path; they do not define a reliable lifecycle.

Baton is a local coordination layer for that boundary. It gives an external-agent call a mailbox and a durable message flow. A request enters an inbox, baton serve claims it, launches the configured agent, and writes the response to an outbox. Its mailbox uses atomic state transitions, single-instance locking, stale-work reclaim, and cooperative stop. Delegation becomes an explicit, inspectable protocol instead of an accidental child-process relationship.

orchestrator / harness → Baton inbox → baton serve → external agent
orchestrator / harness ← Baton outbox ← baton serve ← external agent

That is why Baton is the harness of the harness. The outer harness manages the current model turn, tools, and user interaction. Baton manages the boundary where that harness asks another agent or worker to do something. It does not replace the external model and it does not need to understand the model's reasoning. It provides the durable submission, delivery, retry, and recovery behavior that the outer harness should not have to reinvent for every provider.

The foundation is already useful, but the larger design is a service, not a collection of detached commands. A host-owned Baton supervisor can spawn each session's baton serve, persist its identity and state, and stop or reap it deliberately. That is materially stronger than setsid or disown: detachment changes a process's parent; supervision gives the process a real owner that survives the submitting client.

This is where the companion bg-run layer fits. bg-run is the agent-facing convenience: start long work and end the current turn. Baton can provide the generic task lifecycle underneath it—stable task IDs, isolated process groups, durable results, and immutable milestone or terminal events delivered back to the role mailbox. The agent receives a wake-up when there is something to consume instead of sleeping and polling.

The names should stay in their layers. bg-run describes a useful action in my-ai-team; Baton should expose provider-neutral primitives such as task or job. A future supervisor can then own both session servers and asynchronous tasks without knowing whether the caller was Codex, another harness, or a human-operated CLI.

The opportunity is bigger than a better way to launch subprocesses. If an AI harness is the harness for one agent, Baton can become the infrastructure for a whole population of delegated workers: routing their messages, preserving their work, waking their consumers, and eventually supervising their lifecycles. That is why Baton deserves to be designed as a foundation, not as a thin wrapper around tmux.

Comments

  1. Markdown is allowed. HTML tags allowed: <strong>, <em>, <blockquote>, <code>, <pre>, <a>.