Offline multi-agent document council on
@qvac/sdk. Zero cloud β verifiable.
- βΆ Watch the 3-min demo (network off on camera): https://youtu.be/tnVqrbXNMco
- Run it locally (first launch downloads models ~2 GB):
npm install npm run start # backend :3001 + web app :5173 (keep running) make seed # 2nd terminal β ingest the dossier (curl -X POST :3001/api/seed) # open http://localhost:5173 β status pill reads "LIVE Β· QVAC"
- Ask the demo query: βWho authorized the Entity X payment and was it legitimate?β β watch the Researcher β Skeptic β Synthesizer debate stream in. The Skeptic catches the planted contradiction (VP Chen "authorized" a payment while on PTO); the Synthesizer returns a cited, disputed verdict with lowered confidence.
- Verify the claims:
- π No remote APIs β zero cloud calls:
docs/REMOTE_APIS.md - π Structured audit log β model loads/unloads + per-inference TTFT / tokens / tokens-per-sec:
docs/AUDIT_LOG.mdβ real run indocs/audit-log.jsonl python3 scripts/verify_offline.pyβ 0 outbound (disconnect network first) Β· 18/18 checksnpm run benchβ real on-device latency + contradiction recall βdata/bench_results.json(p50 β 2.1 s, peak RAM β 180 MB, citation coverage 1.0)npm run ciβ 163 unit tests, 100% core coverage + lint + typecheck
- π No remote APIs β zero cloud calls:
- Why only QVAC / no remote APIs (
docs/REMOTE_APIS.md): all inference is local (Llama 3.2 1B + GTE-Large via@qvac/sdk). See Why ONLY QVAC? β remove QVAC and you'd need a cloud LLM + hosted vector DB, and the confidentiality premise is gone.
Offline multi-agent document council β 3 AI agents debate your documents to a cited answer. The visible disagreement IS the trust mechanism.
When analyzing confidential documents β legal dossiers, financial audits, HR records β you can't upload them to cloud AI. But a single LLM will just parrot the first document it reads, missing contradictions.
Quorum solves this with a 3-agent council that cross-examines your corpus entirely offline:
Key Features:
- π Researcher β Retrieves relevant documents, proposes initial answer with citations
- β‘ Skeptic β Counter-retrieves to challenge claims, finds planted contradictions
- π§© Synthesizer β Reconciles viewpoints, assigns HIGH/MEDIUM/LOW confidence
- π Every claim cited β Source chunk mapped to exact document
- π΄ Contradiction detection β Skeptic catches what a single LLM would miss
Real local inference β the network is off the entire time (note the β LIVE Β· QVAC pill).
The contradiction catch. Ask "Who authorized the Entity X payment and was it legitimate?" β a naive RAG repeats the memo ("VP Chen, March 12"), but Quorum's Skeptic re-queries and surfaces the conflicting HR access logs and board minutes, so the Synthesizer returns a cited, disputed verdict with lowered confidence:
![]() |
![]() |
| π Every claim maps to an exact source chunk | βοΈ A second debate β governance Β§4.2 compliance |
flowchart LR
Q["π£οΈ User Query"] --> R["π Researcher"]
R --> S["β‘ Skeptic"]
S --> Y["π§© Synthesizer"]
Y --> A["π Cited Answer"]
R -.- R1["RAG retrieve\n+ propose"]
S -.- S1["Counter-retrieve\n+ challenge"]
Y -.- Y1["Reconcile\n+ confidence"]
style Q fill:#1e293b,stroke:#06b6d4,color:#f1f5f9
style R fill:#0e2a30,stroke:#06b6d4,color:#06b6d4
style S fill:#2a1f0e,stroke:#f59e0b,color:#f59e0b
style Y fill:#0e2a14,stroke:#22c55e,color:#22c55e
style A fill:#1e293b,stroke:#06b6d4,color:#f1f5f9
style R1 fill:none,stroke:#06b6d4,color:#94a3b8,stroke-dasharray:4
style S1 fill:none,stroke:#f59e0b,color:#94a3b8,stroke-dasharray:4
style Y1 fill:none,stroke:#22c55e,color:#94a3b8,stroke-dasharray:4
| Layer | Technology |
|---|---|
| Frontend | Vite 8, React 19, TypeScript |
| AI Engine | @qvac/sdk (completion, RAG) |
| Embeddings | GTE-Large-FP16 via @qvac/sdk |
| LLM | Llama 3.2 1B (local) |
| QVAC SDK Method | Quorum Usage | Cloud Alternative You'd Need |
|---|---|---|
loadModel() + completion() |
Runs all 3 agents (Researcher, Skeptic, Synthesizer) | OpenAI API ($0.03/query Γ 3 agents) |
ragIngest() + ragSearch() |
Embeds & searches private dossier locally | Pinecone + OpenAI Embeddings API |
loadModel(GTE_LARGE_FP16) |
1024-dim embeddings for citation matching | Cohere Embed API |
unloadModel() |
Memory lifecycle β load once, 3 agents, unload | N/A (cloud doesn't care) |
Take QVAC out and you'd need 3 separate cloud services (OpenAI + Pinecone + Cohere), a network connection, and your confidential documents would leave your machine.
The demo includes a 5-document Northwind dossier with deliberate contradictions:
| Document | Claims | Contradiction |
|---|---|---|
memo_ref_4821.txt |
VP Chen authorized $2.4M payment March 12 | Chen was on PTO |
board_minutes_march.txt |
Chen PTO March 11-15, no Entity X discussion | Memo claims March 12 |
q1_financial_report.txt |
Audit flags: no SOW, no deliverables | Payment processed |
hr_access_logs.txt |
No badge/VPN access March 12 | Memo timestamped March 12 |
governance_charter.txt |
>$1M needs board resolution | No board approval |
git clone https://github.com/edycutjong/quorum.git
cd quorum
npm install
npm run start # backend (:3001) + web app (:5173) β keep this running (make start)
# then, in a SECOND terminal, ingest the dossier into the running backend:
curl -X POST http://localhost:3001/api/seed # or: make seed
# open http://localhost:5173 β status pill should read "LIVE Β· QVAC"First launch downloads the local models. The status pill reads DEMO Β· OFFLINE until the backend is reachable; once it's up and seeded it switches to LIVE Β· QVAC.
Devastating Demo Query: "Who authorized the Entity X payment and was it legitimate?"
Run npm run bench to reproduce. This runs the real 3-agent council over the
dossier via @qvac/sdk and writes data/bench_results.json (latency, contradiction
recall, citation coverage). Use npm run bench -- --assert to fail on budget regressions.
Representative run on an Apple M1 Max (32 GB) β reproduce with npm run bench:
| Metric | Measured | Budget |
|---|---|---|
| Full Council Round (p50 / p95) | ~2.5s / ~2.7s | <15,000ms |
| Model Load (cold) | ~1.2s | <10,000ms |
| Corpus Ingest (5 docs β 9 chunks) | ~1.8s | β |
| Citation coverage | 1.0 | β₯0.95 |
| Contradiction recall (planted set) | 0.67β1.0ΒΉ | 1.0 |
| Peak RAM | ~196 MB | <4,096MB |
ΒΉ Recall varies run-to-run: the Skeptic reliably retrieves the conflicting documents, but Llama-3.2-1B is non-deterministic and doesn't always phrase an explicit objection β an honest limitation of a 1B model on-device.
npm run benchrecords real measurements from your hardware intodata/bench_results.json. (The legacyscripts/bench.pyis a deterministic simulation kept only as a CI smoke test.)
171 tests Β· 100% core coverage: 163 unit tests (Vitest) covering RAG citation mapping & chunking, agent orchestration, contradiction-driven confidence, the audit log, and the offline SDK wrappers, plus 8 E2E specs (Playwright) β backed by 18 offline-verification checks (verify_offline.py).
Everything the judges' verification asks for, as concrete artifacts:
| Gate | Where | How to reproduce |
|---|---|---|
| No remote APIs β zero cloud calls | docs/REMOTE_APIS.md |
python3 scripts/verify_offline.py (scans for banned cloud SDKs; 18/18) |
| Structured audit log β model loads/unloads + inference perf (prompt, tokens, TTFT, tokens/sec) | docs/AUDIT_LOG.md β docs/audit-log.jsonl |
on by default; npm run start + a query writes it |
| Offline proof β 0 outbound connections | scripts/verify_offline.py |
disconnect network, then run |
| Real on-device benchmarks β latency, recall, RAM | data/bench_results.json |
npm run bench |
7-stage pipeline: Quality β Security β Build β E2E β Performance β Offline β Deploy
# ββ Code Quality ββββββββββββββββββββββββββββ
npm run lint # ESLint
npm run typecheck # TypeScript check
npm run ci # Full quality gate
# ββ E2E & Performance ββββββββββββββββββββββ
npm run e2e # Playwright E2E (3 suites)
npm run lighthouse # Lighthouse CI audit
# ββ Evidence Bundle βββββββββββββββββββββββββ
python3 scripts/verify_offline.py # airgapped run β disconnect network first
npm run bench # real council latency + contradiction recall
python3 scripts/check_submission_readiness.py| Layer | Tool | Status |
|---|---|---|
| Code Quality | ESLint + TypeScript | β |
| E2E Testing | Playwright (3 suites) | β |
| Security (SAST) | CodeQL | β |
| Security (SCA) | Dependabot + npm audit | β |
| Secret Scanning | TruffleHog | β |
| Performance | Lighthouse CI | β |
| Offline Verification | verify_offline.py (18/18) | β |
quorum/
βββ docs/ # README assets
βββ data/fixtures/
β βββ northwind_dossier/ # 5 docs with planted contradictions
βββ e2e/ # Playwright E2E tests
βββ scripts/ # seed, bench, verify, readiness
βββ src/
β βββ core/
β β βββ qvac.ts # @qvac/sdk wrapper
β β βββ rag.ts # Corpus RAG pipeline
β β βββ council.ts # 3-agent council orchestration
β βββ App.tsx # Debate transcript viewer
β βββ App.css # Dark mode theme
βββ .github/ # CI/CD + CodeQL + Dependabot
βββ playwright.config.ts
βββ lighthouserc.json
βββ README.md
- Small model β limited reasoning depth vs cloud LLMs
- Sequential agents β no true parallel debate
- English only
- Fixed dossier β no live document upload yet
- Mock inference in demo mode
MIT Β© 2026 Edy Cu
Built for QVAC Hackathon I β Unleash Edge AI (DoraHacks). Thank you to the QVAC team for making multi-agent AI possible on the edge.



