Your AI agents, deliberating on the record. MCP-grounded multi-agent consensus with recorded dissent and an auditable decision log.
Project description
Caucus
Your AI agents, deliberating on the record.
MCP-grounded multi-agent consensus with recorded dissent and an auditable, tamper-evident decision log.
Convene agents. Reach consensus. Keep the receipts.
Why
Multi-agent debate is a proven pattern — but every existing implementation deliberates over text and throws the deliberation away. Caucus is built on two convictions:
- Agents should argue over evidence, not vibes. Every analyst agent grounds itself in live state pulled through MCP servers — your broker, your issue tracker, your observability stack — before it opens its mouth.
- The record is the product. Each run produces a hash-chained decision record: every agent's position, the dissent that was overruled, the confidence of the final consensus, and the evidence it rested on. You can defend a Caucus decision in an audit. You cannot defend a chat transcript.
Caucus is a decision layer, not another agent framework. It orchestrates deliberation and guarantees the record; bring your own agents, tools, and domain.
Quickstart
Requires uv and Claude Code.
git clone https://github.com/srinath-jukanti/caucus.git && cd caucus
uv sync
uv run caucus version
Or let your AI agent set it up for you — paste the prompt in AGENT_SETUP.md into Claude Code, Codex, or Cursor and it will install, configure, and verify Caucus end to end.
Architecture
| Layer | What it does | Storage |
|---|---|---|
| Deliberation engine | N analyst agents in parallel → synthesis → adversarial review → consensus with confidence | — |
| Evidence layer | MCP servers declared in config; agents ground every claim in live tool state | — |
| Decision record | Append-only, hash-chained log of positions, dissent, and evidence | JSONL |
| Intents | Slow-moving goals the engine works toward across runs | SQLite |
| Memory | Layered notes with decay half-lives; reflection scores past decisions against outcomes | Markdown |
Everything is inspectable with cat and sqlite3. No vector database, no hosted service, no telemetry.
Deliberate
uv run caucus deliberate "Adopt library X for feature Y?" --evidence evidence.json
Three analysts — an advocate, a skeptic, and an assessor — argue over your evidence in parallel. A chair weighs the arguments — votes are not counted — and the verdict, every position, and the overruled dissent land in the hash-chained log:
DECISION (75% confidence): Adopt it, with guardrails.
DISSENT [skeptic]: hidden costs in the integration surface
On the record: decisions.jsonl (hash 3f9c2a81d0b4…)
Provider-agnostic by construction: a backend is anything with complete(prompt) -> str. The default is the locally authenticated Claude Code CLI (zero API keys); --backend openai --model <m> --base-url <url> reaches any OpenAI-compatible provider — OpenAI, Ollama, vLLM, Groq, Together, OpenRouter — via the optional caucus[openai] extra:
uv run caucus deliberate "Adopt library X?" --backend openai --model llama3.1 --base-url http://localhost:11434/v1
The subject, the evidence, and the panel's own positions are all fenced behind unforgeable random-token delimiters and framed as data, never instructions — prompt-injection resistance is a design rule, not an afterthought.
Persistent setup lives in one file — copy config.example.yaml to config.yaml (picked up automatically) to choose the log path, the backend, and your own panel of analysts. With the Claude backend, mcp_config + allowed_tools turn on the MCP evidence layer: analysts ground their positions in live tool state — your broker, your issue tracker, your observability stack — during deliberation.
The decision record
The record format is a versioned, open specification — see SPEC.md. Each record embeds its predecessor's SHA-256, so editing a record invalidates its own hash and deleting one breaks its successor's link:
from caucus.record import DecisionLog, DecisionRecord
log = DecisionLog("decisions.jsonl")
log.append(DecisionRecord(
subject="Trim QQQ this week?",
decision="yes — one weekly tranche",
confidence=0.8,
positions=[{"agent": "macro", "stance": "yes", "summary": "overweight vs target", "confidence": 0.9}],
dissent=[{"agent": "momentum", "stance": "no", "summary": "trend still intact", "confidence": 0.6}],
evidence=[{"source": "quotes", "ref": "QQQ@725.60"}],
))
$ uv run caucus verify decisions.jsonl
OK — 1 records, chain intact
Change any recorded value — a decision, a dissent, a confidence, the presence or order of records — and verify fails, naming the record and the reason. (Hashes cover each record's canonical form, so semantically equivalent re-serializations are normalized rather than flagged.) Both properties are enforced by tests, not by promises.
Example
examples/trading-robinhood/ is the reference example — a sanitized distillation of the private system Caucus was extracted from, which has deliberated real portfolio decisions headless, twice a day, on the author's own money since June 2026. It includes a fictional-evidence dry run that needs no brokerage and no API keys, and a live configuration that grounds a macro/momentum/risk panel in read-only Robinhood MCP tools. It deliberates and records; it never trades.
Status
The v1 core is complete: the hash-chained decision record (SPEC.md), the deliberation engine, provider-agnostic backends, configuration, and the MCP evidence layer — extracted vertical slice by vertical slice from the reference system, every PR adversarially reviewed in public.
License
MIT. The trading example is a demonstration of the framework, not investment advice — see DISCLAIMER.md.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file caucus-0.2.4.tar.gz.
File metadata
- Download URL: caucus-0.2.4.tar.gz
- Upload date:
- Size: 89.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
420e8e14aa194f1ee5cfd3cdaf90a64ccf758ff75711da04076bb0b9aebd3309
|
|
| MD5 |
b3683c97d9daf9de8dd72615c604123b
|
|
| BLAKE2b-256 |
94562f74e50c14c444206d0a9f083a056f447b11853b427b8a904674b24daa5e
|
Provenance
The following attestation bundles were made for caucus-0.2.4.tar.gz:
Publisher:
release.yml on srinath-jukanti/caucus
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
caucus-0.2.4.tar.gz -
Subject digest:
420e8e14aa194f1ee5cfd3cdaf90a64ccf758ff75711da04076bb0b9aebd3309 - Sigstore transparency entry: 2165365896
- Sigstore integration time:
-
Permalink:
srinath-jukanti/caucus@43c1d7b4c0b74316351160ed132553e4be418f01 -
Branch / Tag:
refs/tags/v0.2.4 - Owner: https://github.com/srinath-jukanti
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@43c1d7b4c0b74316351160ed132553e4be418f01 -
Trigger Event:
push
-
Statement type:
File details
Details for the file caucus-0.2.4-py3-none-any.whl.
File metadata
- Download URL: caucus-0.2.4-py3-none-any.whl
- Upload date:
- Size: 27.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4fd1eb5dd35f53db80f109aef1f649dfd26bcb02913e0b497006f60d94127683
|
|
| MD5 |
37a4dd62e4826769e9e921865ac05e7b
|
|
| BLAKE2b-256 |
8b0a742e404b7e684671706ec8a2b3e11959f78c81bf1d9e9e506906e9f460d0
|
Provenance
The following attestation bundles were made for caucus-0.2.4-py3-none-any.whl:
Publisher:
release.yml on srinath-jukanti/caucus
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
caucus-0.2.4-py3-none-any.whl -
Subject digest:
4fd1eb5dd35f53db80f109aef1f649dfd26bcb02913e0b497006f60d94127683 - Sigstore transparency entry: 2165365904
- Sigstore integration time:
-
Permalink:
srinath-jukanti/caucus@43c1d7b4c0b74316351160ed132553e4be418f01 -
Branch / Tag:
refs/tags/v0.2.4 - Owner: https://github.com/srinath-jukanti
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@43c1d7b4c0b74316351160ed132553e4be418f01 -
Trigger Event:
push
-
Statement type: