Skip to main content

SPEC-0003: Agent Dispatch

Overview

Agent dispatch is the engine that turns a compiled brief (SPEC-0002) into a pull request. It runs a chosen agent harness inside a fresh, isolated local container, against a git worktree of the repository, driven by a declarative workflow resolved from the brief's verbs, and produces a branch, a PR, a streamed transcript, and an authored narration artifact.

This spec realizes ADR-0003 (pluggable container runtime), ADR-0004 (pluggable harness adapter), and ADR-0005 (YAML workflow executor). It consumes the Brief from SPEC-0002 and produces PRs surfaced via SPEC-0001's Forge.

Requirements

Requirement: Container Runtime Abstraction

The application SHALL drive local containers through a ContainerRuntime protocol with at least two first-class backends — Apple container/Containerization and Docker — and no application code outside the backend implementations SHALL reference a specific runtime's types.

Scenario: Backend selection by availability

  • WHEN a dispatch begins and both backends are available
  • THEN the runtime is selected per user preference (defaulting to the native Apple backend on capable hardware), and the dispatch proceeds identically regardless of backend.

Scenario: No runtime available

  • WHEN neither backend is available
  • THEN dispatch fails with a clear, actionable error identifying that no container runtime was found, rather than failing opaquely.

Requirement: Isolated Per-Dispatch Sandbox

Each dispatch SHALL run in a fresh sandbox: a new container/VM, an isolated git worktree of the target repo, and a branch-scoped credential that is revoked on teardown.

Scenario: Fresh sandbox per dispatch

  • WHEN a brief is dispatched
  • THEN a new sandbox is created with its own worktree and a credential scoped to the dispatch's branch; on completion or failure the sandbox is torn down and the credential revoked.

Scenario: Isolation between concurrent dispatches

  • WHEN two dispatches run concurrently
  • THEN they do not share a filesystem, worktree, or credential.

Requirement: Harness Adapter Protocol

The application SHALL invoke coding agents through a Harness protocol with first-class adapters for OpenHands, Crush, and Pi. Each adapter SHALL accept an OpenAI-compatible endpoint (OPENAI_BASE_URL / OPENAI_API_KEY), run inside a ContainerRuntime sandbox, and produce a branch, a PR, a streamed transcript, and a narration artifact.

Scenario: Running a harness

  • WHEN a workflow step invokes the configured harness with a task and the repo worktree
  • THEN the adapter runs that harness in the sandbox against the configured model endpoint and streams a transcript back to the app.

Scenario: Switching harnesses

  • WHEN the user changes the configured harness
  • THEN brief compilation, workflow execution, and PR creation are unchanged; only the adapter differs.

Scenario: Bring your own model

  • WHEN the user sets OPENAI_BASE_URL and OPENAI_API_KEY (cloud or local)
  • THEN the configured harness uses that endpoint for all model calls in the dispatch.

Requirement: Declarative Workflow Execution

The application SHALL resolve each brief verb to a YAML workflow definition and execute it with a lightweight local runner supporting single-step and multi-step workflows, where each step issues a templated instruction to the harness and may be gated on prior step results. Invalid workflow YAML SHALL be rejected with a located error.

Scenario: Single-step workflow

  • WHEN a verb resolves to a one-step workflow (e.g., "explain")
  • THEN the runner executes that step via the harness and collects its result.

Scenario: Multi-step workflow

  • WHEN a verb resolves to a multi-step workflow (e.g., refactor → add tests → update docs)
  • THEN the runner executes the steps in order, passing results forward and honoring any gating conditions.

Scenario: Invalid workflow definition

  • WHEN a workflow YAML fails to parse or validate
  • THEN the runner rejects it with an error identifying the file and the problem, and does not dispatch a malformed workflow.

Requirement: Pull Request Creation with Narration

On successful execution, the dispatch SHALL push the branch and create a pull request via the Forge (SPEC-0001), attaching the authored narration artifact (ordered stops with file+range, why, and risk flag) per ADR-0008.

Scenario: Opening a PR

  • WHEN a workflow completes with committed changes
  • THEN the branch is pushed and a PR is opened on the forge, including a narration artifact consumable by SPEC-0002's Tour rail.

Scenario: Follow-up against an existing PR

  • WHEN the brief targets an existing PR/branch (an iteration from SPEC-0002)
  • THEN the dispatch commits to that branch and updates the existing PR rather than opening a new one.

Requirement: Live Dispatch Transcript

The application SHALL present a readable, streamed view of a running dispatch (a narrated feed, not raw logs) and its lifecycle state (queued, running, opening PR, done, failed), independent of which harness produced the output.

Scenario: Watching a dispatch

  • WHEN a dispatch is running
  • THEN the user sees a live, readable transcript and the current lifecycle state, updating as the harness works.

Requirement: Cost and Model Accounting

The application SHALL surface per-dispatch model usage/cost where the endpoint reports it, so the user can see what a piece of feedback cost.

Scenario: Cost meter

  • WHEN a dispatch uses a model endpoint that reports token usage
  • THEN the app displays the dispatch's usage/cost.