13 min

Structured Agent Handoffs: Contracts, State Machines, and Acceptance Gates

AI Agents Delegation MCP Reliability

A delegation message is not a handoff protocol. A reliable handoff binds an objective to scope, permissions, inputs, budgets, acceptance checks, lifecycle state, and evidence. The coding model is replaceable; that contract is the durable system boundary.

I learned this by routing implementation work from an OpenClaw orchestrator to Qwen Code. The early design looked clean on a diagram. The operating history exposed the missing parts.

What the original three-message story missed

The first version described proposal, response, and approval. That reduced ambiguity, but it did not guarantee integration. Main-machine learning records later captured three concrete failures:

Observed failureWhy the handoff allowed itContract repair
A package compiled but was not wired into the MCP server; the note estimated this occurred in roughly one in five tasks“Build the package” was treated as completionRequire tool registration, handler, composition-root wiring, and an end-to-end call
Registering an MCP server in OpenClaw did not make it available inside Qwen's separate processCapability availability was assumed across process boundariesPreflight the assignee's actual tool list and runtime identity
Fourteen scheduled jobs were duplicated onto a Qwen/ACP route without needing a coding agentRouting policy and task intent were conflatedMake assignee selection explicit and reject unsupported scheduled routes

These are operational notes, not a controlled benchmark. They are still more useful than a flawless anecdote because they identify where the protocol boundary failed.

Separate contract, transport, and executor

These layers solve different problems:

LayerQuestionExamples
Handoff contractWhat is authorised, complete, and provable?JSON document, schema, acceptance evidence
TransportHow does the request move?Local queue, SSH, HTTP, MCP tool call
ExecutorWho performs the work?Qwen Code, Codex, another coding agent, a human

MCP's official architecture likewise separates its JSON-RPC data layer from transport. MCP can expose tools and progress, but it does not define your product's delegation semantics, acceptance policy, or authority model.

The contract envelope

{
  contractVersion,
  handoffId,
  idempotencyKey,
  createdAt,
  issuer: {id, role},
  assignee: {id, role},
  objective,
  scope: {include, exclude},
  inputs: [{name, uri, digest?}],
  constraints: [],
  acceptance: [{
    id,
    assertion,
    verificationCommand?,
    evidenceRequired
  }],
  permissions: {read, write, network, secrets},
  budget: {wallClockSeconds, maxAttempts},
  escalation: {on, route},
  state,
  attempt,
  result?
}

The downloadable JSON Schema validates this structure. The companion EntityScope example is a reference contract reconstructed from the system's lessons; it is not presented as a verbatim historical message.

Treat lifecycle as a state machine

proposed ──accept──▶ accepted ──start──▶ running
    │                   │                   │
    └──cancel───────────┴──cancel──────────┤
                                            ├──blocked──▶ running
                                            │              │
                                            ├──verify──────▶ verifying
                                            │                 ├──succeeded
                                            │                 └──failed
                                            └──failed

Every transition needs an actor, timestamp, reason, and attempt number. Terminal states are immutable. A retry creates a new attempt under the same idempotency key; it does not erase the failed evidence.

“Done” is not a state. succeeded means the verifier executed every required acceptance check against the integrated system and retained the evidence.

Preflight before spending tokens

  1. Resolve the assignee. Confirm the intended agent exists and is appropriate for the task type.
  2. Negotiate capabilities. Inspect the tools visible inside that exact process, not another agent's configuration.
  3. Verify inputs. Resolve repository paths and immutable revisions; reject missing or stale briefs.
  4. Authorize scope. Grant only the required read, write, network, and secret access.
  5. Validate acceptance. Ensure checks exercise the composition root, not only isolated packages.
  6. Reserve budget. Set wall time and maximum attempts before execution begins.

If preflight fails, keep the handoff in proposed or move it to blocked. Do not let the coding agent improvise missing infrastructure.

Acceptance must cross the integration boundary

The Qwen integration gap produced code that compiled in isolation but was unreachable in the running MCP server. The corrective checklist has eight points:

  1. package import;
  2. application struct field;
  3. constructor parameter;
  4. constructor assignment;
  5. tool registration;
  6. request handler;
  7. composition-root wiring;
  8. tests updated at the public boundary.

This generalises beyond MCP. A new class is not a feature. A passing unit test is not an integrated capability. Acceptance should invoke the same public path the consuming agent will use.

Retries need idempotency and classification

Failure classRetry?Action
Transient transport interruptionYes, boundedResume or retry with the same idempotency key
Missing capability or dependencyNo automatic retryBlock and repair preflight
Acceptance failureYes, if budget remainsReturn exact failing evidence to the assignee
Scope or architecture conflictNoEscalate to the issuer or human owner
Unknown external effectNo blind retryReconcile the effect first

The idempotency key should represent the intended effect, not the delivery attempt. That prevents a transport retry from creating a duplicate branch, deployment, message, or scheduled job.

Permissions belong in the handoff

Machine separation is useful only when authority is actually constrained. “The coding agent runs elsewhere” does not prove it lacks workstation access, internet access, or inherited secrets. Bind permissions explicitly:

  • readable and writable repository paths;
  • allowed network destinations;
  • named secrets, preferably short-lived;
  • permitted tools and destructive operations;
  • branch, deployment, and messaging authority.

For remote MCP servers that handle sensitive actions, use the protocol's documented authorization flow; do not treat network reachability as permission.

Evidence returned by the specialist

A useful result contains more than prose:

  • changed artifact list and revision;
  • acceptance command, exit status, and relevant output;
  • unresolved risks and deliberately excluded work;
  • external effect receipts;
  • links to logs, test reports, and reviewable diffs.

The orchestrator should independently rerun high-value checks. The executor's claim that tests passed is evidence to inspect, not a substitute for verification.

Download the reference contract

Download the handoff JSON Schema