GhostJury
Multi-model deliberation engine for security code review.
Submit code. GhostJury empanels a jury of 5 independent LLMs, each returns a binary verdict with reasoning, and the aggregated result is hash-chained so votes and appeals bind to the exact analysis that produced them.
┌─────────────┐
│ Submission │
└──────┬──────┘
▼
┌─────────────┐
│ Triage │ Haiku 4.5 — "worth empaneling a jury?"
└──────┬──────┘
▼
┌───────┬───┴───┬────────┬───────┐
▼ ▼ ▼ ▼ ▼
Sonnet Opus GPT-5.2 o4-mini Grok 4
│ │ │ │ │
└───────┴───┬───┴────────┴───────┘
▼
┌─────────────┐
│ Synthesis │ rule-based aggregation
└──────┬──────┘
▼
┌─────────────┐
│ Verdict │ APPROVED │ REVIEW │ REJECTED
└─────────────┘
Cost per audit (verified 2026-04-14)
Per-audit assumptions: ~3,500 input tokens / ~200 output tokens per juror, plus a Haiku triage call. Prompt caching is enabled by default on Claude jurors — the ~800-token system prompt becomes a cache hit after the first call, so subsequent jurors and the triage all read it at a 90% discount.
| Juror | Model | $/M in | $/M out | Per call (cached) |
|---|---|---|---|---|
| 1 | claude-sonnet-4-6 | $3.00 | $15.00 | ~$0.011 |
| 2 | claude-opus-4-6 | $15.00 | $75.00 | ~$0.054 |
| 3 | gpt-5.2 | $5.00* | $20.00* | ~$0.022 |
| 4 | o4-mini | $3.00* | $12.00* | ~$0.022 |
| 5 | grok-4.20-0309-reasoning | $2.00 | $6.00 | ~$0.008 |
| Triage | claude-haiku-4-5 | $0.80 | $4.00 | ~$0.001 |
| Per audit | ~$0.118 | (cached path) |
* Estimate, see pricing.py for confidence tier and source.
At volume, with a Haiku triage that skips ~90% of trivial submissions:
| Audits/day | Cost/day | Cost/month |
|---|---|---|
| 100 | ~$1.20 | ~$36 |
| 1,000 | ~$12 | ~$360 |
| 10,000 | ~$120 | ~$3,600 |
Without the triage gate the numbers are roughly 10× higher — the gate is the primary cost lever.
Voting rule
Each juror returns { malicious: bool, reason: str } on a submission. GhostJury aggregates:
| Yes votes | Tier | Action |
|---|---|---|
| 0 | APPROVED |
auto-approve |
| 1 | REVIEW |
human review queue — dissenting juror's reason is visible |
| 2+ | REJECTED |
auto-reject — appeal allowed |
Fail-closed posture. Any juror flag bumps the submission out of auto-approve.
Hash chain
Every verdict carries a verdict_hash derived from:
sha256(
submission_sha ||
triage_result_json ||
jurors_json || # all 5 juror verdicts, in roster order
synthesis_json ||
roster_json # model versions + juror order
)
This matters because when users sign votes on the public page, their signature binds to the specific analysis, not the submission id. Editing the analysis invalidates every existing signature — which is the point.
Install
pip install ghostjury
Quick start
No network — safe demo path:
ghostjury audit path/to/script.py --mock
Real jury (requires API keys):
export ANTHROPIC_API_KEY=sk-ant-...
export OPENAI_API_KEY=sk-...
export XAI_API_KEY=xai-...
ghostjury audit path/to/suspicious_script.py
The CLI refuses to start a real jury with partial keys — it checks every provider in the default roster first and lists exactly which env vars are missing. No half-juries, no wasted tokens.
Architecture
schema.py— Pydantic models for every artifacthashing.py— content-hash computationprompts.py— triage + juror system promptspricing.py— per-model cost estimates (audit and update before production)router.py— backend abstraction:MockBackendfor tests,HttpxBackendfor real callstriage.py— Haiku 4.5 gatejury.py— juror orchestration (currently sequential; becomes parallel once ghostrouter shipsexecute_parallel)synthesis.py— rule-based verdict aggregationcli.py— command-line entry
License
Apache 2.0.
Release files for ghostjury 0.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| ghostjury-0.3.0.tar.gz | 36.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| ghostjury-0.3.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 66.3 kB
Release files / ghostjury-0.3.0.tar.gz
| Download URL | ghostjury-0.3.0.tar.gz |
|---|---|
| Size | 36.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
357928dd9a7de83ccb93f6a4b9ba610d53f9e74b2d89ebadb92fdabed5272f8a
|
|
BLAKE2b-256 checksum How to use checksums |
840b18909808e555fc50dc78332df55a3ea9ddd3c8c3bc7a95f71ba9165119e2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.10
|
Release files / ghostjury-0.3.0-py3-none-any.whl
| Download URL | ghostjury-0.3.0-py3-none-any.whl |
|---|---|
| Size | 30.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
a0a77350a250cc3ec7a68337859de20d0549fcf05f6ea3c701e8c6baada0cf68
|
|
BLAKE2b-256 checksum How to use checksums |
234eebb860903d99e0df7ab1bdbe08688ad6703fafa9f7b326db2a369b3b88fb
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.10
|