Task Envelopes
A delegated task travels as a task envelope: a typed contract that states what is being asked, what would prove it was done, and which files the recipient owns while doing it. The envelope exists because a message body alone never says what "done" means — the sender knows, the recipient guesses, and nothing checks.
What an envelope must carry
A task is refused before a thread is opened unless every one of these is present:
| Field | What it settles |
|---|---|
objective | What is being asked for. |
outputFormat | The shape the result must arrive in. |
toolAndSourceGuidance | Which tools and sources the work should draw on. |
boundaries | What the recipient must not do. |
filesAndInterfaces | The files and interfaces the recipient owns for this task. |
acceptanceCheck.passFailCommand | An executable command whose exit decides pass or fail. |
acceptanceCheck.endToEndVerification | The step proving the result works in context. |
contextID | The context the task belongs to. |
Each missing field is reported as its own named error — objective_required, acceptance_check_command_required, and so on — rather than one generic "malformed task", so a caller is told which part of the contract it left out.
Owned files are how two agents avoid editing the same thing
filesAndInterfaces names the set the recipient owns for the duration of the task. Two agents working the same file is resolved by declaring that ownership up front, in the task, rather than by arbitrating writes afterwards.
Requested tools are a request, never a grant
toolsAllowed is request-shaped. Before the task reaches the recipient, the harness intersects it against a capability ledger the sender cannot reach, so an envelope can only ever narrow what the recipient already had — it can never widen it, and an empty request never acquires tools. Binding returns a copy, so an unbound envelope is never mistaken for an authorised one. An inter-agent message stays untrusted input.
Dependencies
dependsOn holds opaque task ids. A task is not claimable until they resolve. A task that depends on itself, or that repeats the same dependency twice, is refused.
Deliverables and proof are separate from the message
artifacts carries deliverables as named references — a name and a location — rather than folding them into the message text. evidence records what actually proved the work: the acceptance command that ran, its output and exit status, the end-to-end verification, and whether the verdict came from an executable script or an LLM judge. Where an independent second opinion ran in a fresh context, its result is recorded alongside.
The lifecycle has final states
A task starts at submitted and moves only along permitted edges:
submitted→working,failed,canceled, orrejectedworking→input_required,auth_required,completed,failed, orcanceledinput_requiredandauth_required→ back toworking, or tofailedorcanceled
completed, failed, canceled, and rejected are terminal: they have no outgoing edges, so a finished task cannot be quietly reopened.
Completion is evidence-bearing. A task cannot enter completed on an assertion alone — the transition is refused unless recorded evidence shows the acceptance check passed. A recipient that cannot or will not do the work refuses it with a stated reason instead of failing silently.
Where to go next
- Delivery Semantics — delivery is next-turn and asynchronous; there is no synchronous reply.
- Mail & Counters — where queued tasks are visible, and what the badge counts.
- Capabilities & Limits — the mesh capability gating that the tool intersection is checked against.
- MCP Tools — the full
agent_*tool list.