MCP Task Orchestrator · Field guidePlate 6 of 9
A phase is often several jobs: plan, build, test, record. Seats name those jobs in config. The orchestrator learns which agent to send, the gate reports missing notes by owner, and the server can check that the tests and the code were written by different actors.
This project's own bug-fix schema with its default traits. Select a seat to see what the server serves for it.
work_item_schemas:
bug-fix:
default_traits: [delegated, needs-test-author]
seats:
- { name: planner, phase: queue }
- { name: implementer, phase: work, enters: true }
- { name: orchestrator, phase: work, after: [implementer] }
- { name: reviewer, phase: review }
notes:
- { key: implementation-notes, role: work,
required: true, seat: implementer }
traits:
needs-test-author:
seats:
- { name: test-author, phase: work,
after: [implementer],
reads_exclude: [implementation-notes] }
notes:
- { key: test-manifest, role: work, required: true,
seat: test-author,
independent_of: [implementer] }
delegated:
dispatch:
work:
agent: task-orchestrator:implementer
seats:
implementer: { model: sonnet }
test-author: { agent: null, model: sonnet }
| Field | Meaning | Server's part |
|---|---|---|
name, phase | A named role in queue, work or review. The name means nothing to the server. | Validates and serves |
enters | This seat makes the transition into the phase. | Allows one per phase |
after | Seats whose work this one follows. | Serves as a hint |
reads_exclude | Note keys this seat should not read. Keeps a test author blind to the implementation. | Serves as a hint |
note seat | The seat that owns a note. | Groups missing notes by owner |
note independent_of | Seats whose author must differ from this note's author. | Checks at the gate |
dispatch.<phase>.seats | Agent, model and effort for one seat. null clears a field inherited from the phase. | Resolves and serves |
The YAML is abridged from this project's config, and its independent_of line follows the reference example in the config documentation. A config with no seats anywhere is unaffected: every seat field is left out of every response.
"missingNotes": [
{ "key": "implementation-notes", … },
{ "key": "test-manifest", … },
{ "key": "session-tracking", … }
]
A flat list. The orchestrator has to know, from somewhere outside the config, whose job each note is.
"missingNotes": [ … ],
"missingBySeat": {
"implementer": ["implementation-notes"],
"test-author": ["test-manifest"],
"orchestrator": ["session-tracking"]
}
The same failure, routed. A required note that no seat owns is listed under unowned, last.
When a note declares independent_of, the gate compares the actor who wrote it with the actors who wrote the named seat's notes. Here the implementer's note was written by impl-agent-1, and test-manifest declares independent_of: [implementer].
The actor is whatever string the caller sent. Pair the check with actor authentication and require_verified: true to compare proven identities.
Re-upserting a note replaces its actor. No history is kept, so the plugin's orchestrator never rewrites a note a seat owns.
Whoever writes the note can add the waiver line. Treat reject as a discipline aid for cooperating agents. It is not a security control.
How the Claude Code plugin's four agent definitions (planner, implementer, test author, reviewer) and the main session take these seats.
diagnosis and test-plan. The expected results for the tests are fixed before any code exists.advance_item(start). The queue gate checks the planner's notes. Then it writes the fix and its note.test-manifest.session-tracking and advances the item. The work gate checks all three seats' notes.review-checklist and test-independence-audit.Only the entry seat calls advance_item. Every other seat fills its own notes and returns, and the orchestrator owns each later transition. For several items at once, the run-wave skill builds these stages from each item's seats.
A trait seat whose name already exists on the schema is dropped with a warning. Across traits, the first to declare a name keeps it.
For a seat's agent, model and effort, per-item traits are read before default traits. That is how one item can raise its implementer to a stronger model, as the trait toggles above show.
If merging traits at resolve time yields two entry seats in one phase, the first keeps the role and the later one is served with enters: false.
| In one config document | Result |
|---|---|
Two seats with enters: true in the same phase | The load fails. A global config stops server startup. A per-project push is rejected and nothing is stored. |
| Two seats with the same name | |
A seat named unowned | |
A cycle in after | |
| A required note with no seat, in a schema that has seats | A warning. The note is served under unowned. |
| A malformed seat entry or dispatch override | A warning. That entry is skipped. |