maestro-graph
Use when a task is a pre-known path with several agent steps: a review gate, a research sweep, a judge panel, a fix loop. The path is one markdown graph file; maestro holds the run, executes the deterministic nodes itself and hands you only the agent and human nodes to spawn. maestro never starts a model (Hub d78), so the loop below is yours on every harness. Design, diagnosis and the SLP seat protocol stay outside graphs.
Pick or write the graph
maestro graph listshows every graph across the repo (<repo>/.maestro/graphs), the room (~/maestro/graphs) and the shipped set; a nearer file shadows a farther one by name.maestro graph show <name>prints one.- A shipped preset fits: run it by name.
review-gatetakesrange=<git range>andtier=light|full;fix-looptakesscope=<what to fix>andcheck=<command that must pass>and drives a writing fixer for at most three rounds;counciltakesbrief=<neutral brief>andtier=lens|debate|debate-with-proof|high-riskand runs the maestro-council protocol with you (the Lead) answering the draft and verdict nodes. - Nothing fits: write a graph for the task from
references/authoring.md and run it with
--file <path>. Keep a good one by copying the file into a graphs directory (Hub d100; there is no save verb).
The pull loop (executor subagent)
maestro graph run <name>|--file <path> [key=value ...] [--limit k=v] --json
loop:
envelope = the JSON just returned (or maestro graph next <run> --json)
if envelope.done: stop; the verdict, LIMIT stop or failed node is in it
for each node in envelope.nodes (all at once, they are independent):
kind human -> stop and ask the user the prompt; feed the answer back
kind agent -> spawn a sub-agent with the node's profile and brief
for each returned sub-agent:
maestro graph result <run> <ref> --file <path>|--text "<result>"
maestro graph next <run> --json
runreturns the first envelope, so the firstnextis implicit.- Every node in
nodesis ready now; spawn them in parallel. Nodes that depend on one of them appear on a laternext, as soon as their own inputs are in: only ajoinwaits for a whole fan-out (Hub d82). refis the node id, ornode@keyfor one instance of a foreach.- A node with a
schemamust return JSON of that shape. Write the sub-agent's answer to a file and pass--file; maestro extracts the first JSON block from prose or a fence.PARSE_FAILEDwithretry: truemeans re-ask that sub-agent for JSON matching the schema carried in the error (two retries); the third failure marks the node failed and the run ends withfailed. stopped: "LIMIT"ends the run at a structural limit (nodes,loops,fanout, Hub d84) withpartialstate; rerun with--limit <k>=<N>when the cap, not the graph, was wrong.GRAPH_UNTRUSTEDon a repo graph's function node: review the file the error names, then run themaestro graph trustcommand it gives andgraph nextagain. Home and shipped graphs never ask.maestro trace <run>is the journal: every node transition and round.
Spawning an agent node
The profile is a definition maestro install rendered for both harnesses
(Hub d83): ~/.claude/agents/maestro-<profile>.md and
~/.codex/agents/maestro-<profile>.toml.
- Claude Code: the
Agenttool withsubagent_type: "maestro-<profile>",model: "opus", and the node'sbriefverbatim as the task. A profile whoseharnessis codex (challenger, verifier, auditor) opens as a Codex pane with--profile maestro-<profile>instead; the Agent tool rejects its model. - Codex:
spawn_agentwith agent typemaestro-<profile>and the node'sbriefverbatim.
Send the brief, never the bare prompt: the brief is the prompt plus, when
a schema is declared, one sentence naming the required keys and any optional
keys, then the schema as a JSON block (Hub d843), so the agent answers in the declared
shape instead of its harness habit. It already
carries the run state the graph author placed in it. Add only what the harness needs to return
the answer (for example, "write your JSON answer to <path>"). Never merge
two nodes into one spawn and never run a function node's command yourself;
maestro already did.
Executor team
graph run reports executor in every envelope (Hub d88): subagent
from a plain session, claude -p, codex exec or a desktop app; team
when the driver is a role pane of a running SLP team. Under team the
Lead is the driver and each agent node is one Peer work item (Hub d89);
the Lead is never a node and maestro still spawns nothing.
Team Supervisor: maestro work add "run graph <name> <key=value ...>" \
--acceptance "the run's verdict"
Lead: maestro work take <item>
maestro graph run <name> [key=value ...] --json
loop:
envelope = the JSON just returned (or maestro graph next <run> --json)
if envelope.done: maestro work return <item> "<verdict JSON>"; stop
for each node in envelope.nodes without a work field:
kind human -> answer it yourself: maestro graph result <run> <ref> --text "<answer>"
kind agent -> maestro work add "<node.brief>" --to peer-<node.profile> \
--acceptance "one JSON object matching the schema in the brief" --json
maestro graph result <run> <ref> --work <new item id>
for each node with a retry field (its item's body failed the schema):
open a fresh item with node.brief and rebind exactly as above; two
retries, the third failure fails the node
for each node with a work field whose workState is RETURNED:
read it (maestro status <item>), then maestro work accept <item>
(or maestro work note <item> "<gap>" --rework for one retake)
maestro graph next <run> --json
Team Supervisor: maestro work accept <item>
- One pane per profile:
--to peer-<profile>opens the Peer lazily on the first item and sends later nodes of that profile to the same pane; eachwork addwakes the pane with[from lead][<id> OPEN], so no hand prompt. - A bound node stays in
nodeswithworkandworkStateuntil its item is DONE;nextthen parses the item's returned body like any result (schema and all) and issues what depended on it. A body that fails the schema unbinds the node and lists it withretry: {error, schema, work}, twice at most (d843); a cancelled item fails the node. - Bound nodes count toward
limits.fanout; keep the fan-out under the number of Peers you are willing to open. - Prompts to a Peer must open with a lowercase plain sentence; a brief that opens "You are ..." is swallowed as a slash command. The node prompts in the shipped presets already do.
- The graph runtime writes no SLP state: every
work add,acceptandreturnabove is yours (A7).
Hand-off
The verdict is the run's evidence on its work item (maestro work show <run>); quote it in the return that asked for the gate. A graph that
misbehaved is a finding for the handback, not a card.