Add it to a workflow
View as markdownThe agent exists;
now give it a status to own. Wiring a new agent into a workflow is two
files: the status identity is declared once in statuses.yaml, and the
workflow file references it by id, adds an owner, and points it at the
agent. Keep that split correct: repeating name: or category: in the
workflow file fails the load.
1. Declare the status identity
Add the status to the project-wide catalog in
workflows/statuses.yaml, placed where you
want its column to sit, between in-progress and review:
# workflows/statuses.yaml
statuses:
- { id: backlog, name: Backlog, category: backlog }
- { id: todo, name: Todo, category: ready }
- { id: in-progress, name: In Progress, category: active }
- { id: adversarial-review, name: Adversarial Review, category: active }
- { id: review, name: Review, category: handoff }
- { id: done, name: Done, category: done }category comes from the
closed vocabulary:
backlog, ready, active, handoff, done, archived. Because an
agent is actively working the review while a task sits here, it's
active, not handoff: handoff means "one owner finished, another's
input is required next," which is what the human review status already
is. Declaration order here is the left-to-right column order in the TUI.
2. Reference it from the workflow
In the workflow file, reference the status
by id between in-progress and review. Make it agent-owned and point
it at the agent you authored:
# workflows/default.yaml
statuses:
- { id: backlog, owner: user, agent: orchestrator }
- { id: todo, owner: agent, agent: orchestrator }
- { id: in-progress, owner: agent, agent: developer }
- { id: adversarial-review, owner: agent, agent: adversarial-review }
- { id: review, owner: user, agent: orchestrator }
- { id: done, owner: user }owner: agent makes the status the orchestrator's to act on, so tasks
that land here are auto-dispatched; the
agent: adversarial-review field names which agent runs it. No name:
or category: appears here. Those live in statuses.yaml, and repeating
them fails the load.
3. Rewire the transitions
Transitions declare the
hub-side side-effects that fire on an edge. For the moves a human makes on
the board, an unlisted edge is just a pure status change. For an
agent-initiated move (the reviewer's bounce), the block does double
duty as an allowlist: once a transitions: block exists, an agent may only
take edges it declares, so the bounce edge has to be listed or the poller
rejects it. Route the developer's branch into adversarial review, then on
to human review, with a bounce-back for when the skeptic finds problems,
and keep merge on the single final edge into done:
transitions:
- { from: in-progress, to: adversarial-review, actions: [push_branch, open_pr] }
- { from: adversarial-review, to: review, actions: [] }
- { from: adversarial-review, to: in-progress, actions: [] }
- { from: review, to: done, actions: [merge, delete_branch] }What each edge does:
in-progress → adversarial-reviewrunspush_branchandopen_pr, so the branch is on the remote with a PR open before the reviewer starts. The reviewer works against a real diff, and its findings have somewhere to land.adversarial-review → reviewhas no actions: the branch is already pushed and PR'd, so promoting a clean pass to human review is a pure status change.adversarial-review → in-progressis the bounce-back. When the skeptic files blockers and writes the transition marker, the task drops to the developer with no git side-effects: same branch, same PR, another pass. This edge is what makes that bounce legal; drop it and the poller refuses the reviewer's send-back.review → doneis the only edge carryingmerge(anddelete_branch). That's deliberate.
The action primitives in play are
push_branch (push the task branch to origin), open_pr (open its PR),
merge (merge the branch into its target), and delete_branch (delete the
local and remote branch).
Keep merge on the final edge
merge trips Zen Mode's high-confidence bar.
Keeping it on the single review → done edge, and nowhere earlier, means
the automated reviewer never lands code. It surfaces findings; the human
still owns the accept.
What you see now
The board grows an Adversarial Review column between In Progress and
Review. Tasks the developer marks ready flow into it, get auto-dispatched
to the adversarial-review agent, and either bounce back with blockers or
advance to human review with the skeptic's findings already waiting on the
PR.
See also
- Workflow config — the field-by-field
reference for
statuses,transitions, and their actions. - Statuses — the
statuses.yamlcatalog and the closed category vocabulary. - Orchestrator — how agent-owned statuses get auto-dispatched and handed off.