# Consensus voting

Use this when a single AI judge isn't enough: the cost of being wrong is
high enough that you want N independent agents to vote, and you only
proceed when K of them agree. Think refund exceptions, content moderation,
code-review approval, anything where a one-shot model call is too
unreliable.

## The workflow

A `consensus` node fans out the same prompt to `agentCount` agents in
parallel and routes to `approved` only when at least `quorum` of them vote
yes. Errored or timed-out agents count as no-votes: they neither approve
nor block, and they don't count toward the quorum at all.

```yaml
name: consensus
version: 1
description: |
  Multi-agent gate where 3 independent reviewers must reach a 2-of-3 quorum
  before the workflow proceeds.
initial: ask
states:
  ask:
    type: consensus
    label: Is this idea worth shipping?
    model: claude-haiku-4-5
    prompt: |
      Evaluate this product proposal:

        "Add a feature where users can attach short voice memos (up to 30s) to
         any item in their task list, transcribed automatically and searchable
         alongside text notes."

      Approve only if all four hold:
        1. it solves a real, common user problem
        2. it can ship in under 4 weeks of engineering
        3. it doesn't add meaningful privacy/compliance burden
        4. it's not better delivered as an integration

      Be skeptical — reject if any single criterion is shaky. Answer with
      the JSON shape requested below.
    agentCount: 3
    quorum: 2
    validator:
      kind: boolean
    maxRetries: 1
    on:
      approved: yes-end
      rejected: no-end

  yes-end:
    type: end
    label: Approved
    outcome: success
    message: Reviewer quorum agreed.

  no-end:
    type: end
    label: Rejected
    outcome: failure
    message: Reviewer quorum did not agree.
```

## Running it

```bash
roscoe run consensus
```

The web UI shows a verdict card with each agent's vote and reasoning. When
agents split, you'll see a "split decision" banner and per-agent reasoning
panels. That's the whole point of the node, so design prompts that genuinely
let models disagree.

Note: `consensus` always calls the LLM directly, even in MCP mode. Unlike
`ai_agent` and `ai_judge`, it does not pause for Claude Code to step through
each agent: doing so would defeat the "atomic quorum" guarantee. Running this
workflow needs either `ANTHROPIC_API_KEY` set or the `claude` CLI on PATH.

## Tuning agentCount and quorum

| `agentCount` | `quorum` | Behaviour                                                                    |
| ------------ | -------- | ---------------------------------------------------------------------------- |
| 3            | 2        | Default. Two-of-three majority. Cheap; tolerant of one outlier.              |
| 3            | 3        | Unanimous. Any dissent rejects. Use when false positives are very expensive. |
| 5            | 3        | Bare majority of five. More signal, ~1.7x the cost of 3-of-3.                |
| 5            | 4        | Strong majority. Tolerant of one outlier; rejects on two.                    |
| 7            | 5        | High-stakes, expensive. Rare in practice.                                    |

`agentCount` is bounded `2..7`. `quorum` must be `≤ agentCount`: the schema
rejects `quorum > agentCount` outright, since such a node could never approve.

If quorum equals agentCount you've made the gate strictly unanimous; one
errored agent is enough to block. If you care more about latency than safety,
prefer odd `agentCount` and `quorum = ceil(agentCount/2)`.

## When to reach for it

For a refund exception, three agents check the request against your refund
policy and approve only if 2 of 3 agree it's a genuine edge case. For content
moderation, five agents check a piece of user content and publish only if
4 of 5 say it's safe. For code review approval, three agents review a diff
against the same rubric and ship only if 2 of 3 approve.

For lower-stakes branching (single-agent fact checks, feature toggles, light
guardrails), `ai_judge` is the right call. `consensus` is several times the
cost.

## Variations

For a strictly unanimous variant, set `quorum: 3` with `agentCount: 3`; any
dissent rejects. To vary the question per run, embed a `{{ field }}`
reference in the prompt (declared under the workflow's `inputs:`) and pass
its value via `roscoe run consensus --var field=value`. To chain into a human
gate, route `approved` to a `human` node titled "Final sign-off" instead of
straight to an `end`; useful when you want AI to filter the obvious cases
but a human to confirm the edge ones.

## See also

- `/docs/nodes/ai-judge` — single-agent equivalent for cheaper checks
- `/docs/nodes/consensus` — full reference for the node type
- `/docs/recipes/multi-step-analysis` — chaining an analyst with a verifier
