# Project export: Quorum : drop-in validation layer for multi-agent AI Systems

This document was generated by HackStack to give an AI agent context about a hackathon project. Sections are labeled with their provenance; content marked as truncated was cut to keep this document small.

## Project metadata

- Hackathon: UC Berkeley AI Hackathon 2026
- Tagline: Quorum is a validation layer for multi-agent AI systems, running on platforms like Fetch.ai's ASI:One - that prevents upstream hallucinations from cascading into downstream bias and errors.
- Devpost: https://devpost.com/software/quoram
- GitHub: https://github.com/mohiitt/Quorum
- Demo: https://agentverse.ai/agents/details/agent1qtvr2pk4hp4gfh4wh2af33vpjv5zmawz9tj4q6ngt09tandh2jg8smkfak9/profile
- Video: https://www.youtube.com/embed/8BivgXe7MMM?enablejsapi=1&hl=en_US&rel=0&start=&version=3&wmode=transparent
- Result: winner (Best Use of The Agentverse by Fetch AI)
- Team: 1 GitHub contributor(s) — mohiitt (9 commits)

## Devpost submission (written by the team)

### Overview

Find our agent at: https://agentverse.ai/agents/details/agent1qtvr2pk4hp4gfh4wh2af33vpjv5zmawz9tj4q6ngt09tandh2jg8smkfak9/profile Chat with our agent at : https://asi1.ai/chat/1e44922f-85dc-42f3-bfdf-9465fd083c78 (this is a validation agent! ask to check any facts you wish)

### Inspiration

There is a silent assumption baked into almost every multi-agent AI system built today: that the agents feeding each other information are telling the truth. They are not always. We started thinking about this after watching a demo where a research agent confidently passed a hallucinated statistic downstream - and by the time it reached the final output layer, three more agents had cited it, reasoned from it, and built recommendations on top of it. The hallucination didn't just survive; it compounded. One wrong claim upstream behaves like an avalanche: small at the origin, catastrophic at the base. This isn't a hypothetical edge case. It is the default failure mode of any pipeline where agents trust each other without verification. In financial analysis, healthcare triage, legal research, or automated decision-making - a single undetected error early in the chain can corrupt everything downstream with mathematical certainty. We built Quorum because multi-agent systems are only as trustworthy as their least reliable agent - and nobody was solving that. What It Does Quorum is a drop-in validation layer that intercepts any factual claim before it propagates through a multi-agent pipeline and returns a structured, machine-readable consensus verdict. Every claim runs through three independent validators in parallel: Source Validator : powered by Browserbase The Source Validator doesn't just query an API - it browses the web like a human researcher. Using Browserbase's cloud browser infrastructure, it navigates live pages, extracts real content, and cross-references the claim against DuckDuckGo search results and Wikipedia. This gives us ground-truth web evidence that static APIs simply can't provide. Each source is scored for topic relevance, and the validator gracefully degrades to a benefit-of-the-doubt score when no sources are retrievable - so the pipeline never hard-crashes on network failures. Consistency Validator : powered by Redis The Consistency Validator maintains a live memory of every claim accepted within a workflow session, persisted in Redis. When a new claim arrives, it compares it against all prior accepted claims and surfaces contradictions - even subtle ones across different time periods, metrics, or subsectors. Redis was critical here: it gave us sub-millisecond cross-claim lookups even as workflow histories grew, and let us support concurrent sessions without state bleed. Without a fast, durable store, this validator would be unusable at any real scale. Reasoning Validator : powered by Anthropic Claude The Reasoning Validator asks the hardest question: is this claim internally coherent? Claude evaluates the logical structure of the claim , flagging unsupported conclusions, circular reasoning, category errors, and open-ended questions masquerading as factual assertions. It doesn't just check if something is true; it checks if it's the kind of statement that can be evaluated as true or false in the first place. Consensus Engine The three validators vote independently. Each verdict is weighted by a reliability score and combined into a single consensus score between 0 and 1. Claims above the acceptance threshold pass. Claims below the rejection threshold are blocked. Claims in between are quarantined for human review - not silently dropped, not blindly passed. Fetch.ai Agentverse Integration Quorum was built from the ground up to live in the Fetch.ai ecosystem. The agent is deployed on Agentverse with a mailbox endpoint, fully discoverable, and ships with the Agent Chat Protocol, meaning it can be queried directly from ASI:One as a first-class citizen. Any user building a multi-agent workflow on Fetch.ai can drop our agent address in and get instant validation on every claim their pipeline produces. No integration code. No custom API. Just an agent talking to an agent. A real-time dashboard surfaces live pipeline activity: per-agent verdicts, validator breakdowns, trust scores, quarantine queue, and full provenance trails. How We Built It Backend: Python, FastAPI, uAgents (Fetch.ai), asyncio Validators: Browserbase (live web), Redis (session memory), Anthropic Claude (reasoning) Agentverse: uAgents mailbox deployment, Agent Chat Protocol v0.3.0, Agentverse API registration Frontend: Next.js 15 (App Router), Tailwind CSS, shadcn/ui, WebSocket streaming Infrastructure: Redis Cloud, git-based secrets management, environment-driven validator configuration The architecture is deliberately modular, validators are loaded at startup based on which API keys are available, so the system degrades gracefully in constrained environments rather than failing completely. The consensus engine is decoupled from the validator implementations, so new validators can be added without touching the core pipeline logic. Challenges We Ran Into Redis on a public network. Connecting to a managed Redis instance over a public endpoint introduced latency and occasional connection drops under the async load of parallel validators. We had to implement retry logic, connection pooling, and a FakeStore fallback so the pipeline could continue running even if Redis became temporarily unreachable - critical for a live demo environment. Fetch.ai protocol spec lock. The Agent Chat Protocol spec in the uAgents framework locks the set of allowed replies at registration time. When we tried to add a ChatAcknowledgement handler after the fact, the protocol verification failed because the original spec didn't include it. We had to understand the internals of how ProtocolSpecification works, pass replies=None to bypass the locked reply set, and register both message handlers correctly - a non-obvious fix that took significant debugging. ASI:One discoverability. Getting the agent to actually appear in ASI:One search required more than just deploying it - the agent needed a proper name, description within the 300-character limit, and an active mailbox endpoint registered through the Agentverse API. The registration flow involved a three-step identity challenge-proof-register sequence that had to be triggered correctly at startup. Validator output formatting. Python enum string representations (ValidatorName.REASONING) leaked into frontend output and pipeline rationale text. Fixing it required patching both the backend reply formatter and the frontend rendering layer, and catching a TypeScript s-flag regex incompatibility along the way. Accomplishments That We're Proud Of We built something that works - not just as a demo, but as a production-grade architecture that holds up under adversarial claims, network failures, and concurrent sessions. But the accomplishment we're most proud of isn't technical. Quorum is deployed. Right now. On Agentverse. Anyone building a multi-agent workflow on Fetch.ai can query our agent today. A real agent, at a real address, returning real verdicts. That felt significant to us: not just building something cool, but shipping something usable. We're also proud of the seamless ASI:One integration. The chat protocol means a non-developer can type a claim into the ASI:One interface and get back a structured, human-readable breakdown of what three independent AI systems thought about it. That's a genuinely new capability. And on a personal level: we're proud that we kept the codebase clean, the architecture honest, and the scope disciplined - even when the temptation to add more features was constant. What We Learned Technical: How Fetch.ai's uAgents framework handles protocol registration, identity challenges, and Agentverse mailbox routing - including the parts the documentation doesn't cover How to build a consensus engine that is robust to partial validator failure without sacrificing correctness How Browserbase's async browser sessions work at scale and how to extract structured signals from unstructured live web content How Redis enables stateful session memory in otherwise stateless async pipelines How to manage TypeScript/Next.js App Router constraints when building real-time WebSocket-driven dashboards Human: Building under a tight deadline exposed every assumption we had about how long things take. Features that look simple in a design doc have sharp edges. The things that break are never the things you tested. We learned to timebox ruthlessly, ship the imperfect version that works over the perfect version that doesn't exist yet, and resist the pull of scope creep when momentum feels good. We learned how to work in parallel without stepping on each other - splitting the pipeline backend from the frontend from the Agentverse integration, then stitching them together cleanly at the end. And we learned, the hard way, that sleep is a performance-enhancing tool, not a luxury. What's Next for Quorum The ideal future for this project isn't a standalone app - it's middleware. The most natural integration point is Fetch.ai's internal orchestration layer. When an AI system decides to spin up a multi-agent workflow - research agents, analysis agents, decision agents - Quorum sits in the middle, validating the signal as it flows between them. Not as an optional plugin. As a standard component. The way a load balancer sits between a client and a server not because anything is broken, but because you don't run production systems without one. We'd want to work with Fetch.ai to embed Quorum into the default scaffolding for multi-agent pipelines on ASI:One - so that any workflow built on the platform has trust and consensus built in from day one, not bolted on after the first incident. Beyond that: expanding the validator set (financial data APIs, scientific literature, live news feeds), adding configurable trust profiles per workflow domain, and building a provenance graph that lets operators trace exactly which upstream claim was the origin of a downstream error. The goal isn't to make AI agents perfect. It's to make their failures visible, bounded and recoverable.

## README (from the GitHub repository)

# Quorum

Chat with our agent at : https://asi1.ai/chat/1e44922f-85dc-42f3-bfdf-9465fd083c78

Live Agent at: https://agentverse.ai/agents/details/agent1qtvr2pk4hp4gfh4wh2af33vpjv5zmawz9tj4q6ngt09tandh2jg8smkfak9/profile

**Trust and consensus layer for Fetch.ai multi-agent systems.**

> Prevents a single hallucinating agent from corrupting an entire multi-agent workflow.

---

## The Problem

When one agent produces a bad output in a Fetch.ai workflow, the error propagates through every downstream agent:

```
Weather Agent → Wrong Claim → Planner → Budget Agent → Wrong Outcome
```

Quorum intercepts every claim before it becomes canonical workflow state and runs it through three independent validators before allowing it to proceed.

---

## Architecture

```
Agent Claim
    ↓
┌─────────────────────────────────────────────┐
│               Quorum Pipeline               │
│                                             │
│  ┌────────┐  ┌─────────────┐  ┌──────────┐ │
│  │ Source │  │ Consistency │  │ Reasoning│ │
│  │  Val.  │  │    Val.     │  │   Val.   │ │
│  └────────┘  └─────────────┘  └──────────┘ │
│         ↓           ↓              ↓        │
│         └───────────┴──────────────┘        │
│                     ↓                       │
│              Consensus Engine               │
│         reliability × confidence            │
│              × evidence quality             │
│                     ↓                       │
│    ACCEPTED │ NEEDS_REVIEW │ REJECTED        │
│                     ↓                       │
│  State Store │ Quarantine │ Provenance       │
└─────────────────────────────────────────────┘
    ↓               ↓               ↓
Workflow State   Dashboard      Trust Scores
```
<img width="1774" height="887" alt="ChatGPT Image Jun 21, 2026 at 10_45_46 AM" src="https://github.com/user-attachments/assets/e138db18-219b-4967-adca-2620c4fec5b2" />

---

## Components

| Component | Description |
|---|---|
| **Source Validator** | Checks claims against OpenWeatherMap, PubMed, SEC EDGAR, Browserbase |
| **Consistency Validator** | Detects contradictions with prior accepted workflow claims via Anthropic |
| **Reasoning Validator** | Evaluates logical soundness of claims via Anthropic (with optional debate round) |
| **Consensus Engine** | Weighted scoring: `reliability × confidence × evidence_quality` |
| **Quarantine** | Holds NEEDS_REVIEW claims in `quorum:pending_claims` |
| **Provenance Layer** | Immutable audit trail: who said what, who validated it, why it was accepted |
| **Trust Manager** | Per-agent trust scores + per-validator reliability, updated after every consensus |
| **FastAPI + WS** | REST API + real-time WebSocket stream of consensus events |
| **Next.js Dashboard** | 4-page shadcn/ui dashboard: Live Consensus, Provenance, Trust, Quarantine |
| **Fetch.ai uAgents** | Quorum gatekeeper agent + weather demo workflow (Bureau) |

---

## Sponsor Alignment

| Sponsor | Usage |
|---|---|
| **Fetch.ai** | uAgents protocols, Bureau multi-agent orchestration |
| **Redis** | Workflow state, provenance, trust, quarantine, consensus history |
| **Anthropic** | Consistency + reasoning validators (Claude) |
| **Browserbase** | Web verification fallback for open-ended claims |

---

## Quick Start

### Prerequisites

- Python 3.11+
- Node.js 18+
- Docker (for Redis)

### Backend

```bash
# Clone and install
git clone https://github.com/your-org/quorum
cd quorum
python3 -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"

# Configure
cp .env.example .env
# Fill in API keys in .env

# Start Redis
docker-compose up redis -d

# Run tests
pytest

# Start API server
uvicorn quorum.api.main:app --reload
```

### Dashboard

```bash
cd dashboard
npm install
npm run dev
# Open http://localhost:3000
```

### Full stack with Docker Compose

```bash
docker-compose up
# API: http://localhost:8000
# Dashboard: http://localhost:3000
```

### Weather Demo (Fetch.ai Agents)

```bash
source .venv/bin/activate
python -m quorum.agents.demo_workflow
```

This runs the weather scenario:
1. `WeatherAgent` submits "0% chance of rain" (hallucinated)
2. Quorum validates → **REJECTED** (contradicts NOAA + reasoning failure)
3. `FallbackAgent` submits "75% rain based on NOAA" 
4. Quorum validates → **ACCEPTED**
5. `PlannerAgent` and `BudgetAgent` receive the correct forecast

---

## API Reference

See [`docs/api.md`](docs/api.md) for the full REST + WebSocket schema.

Key endpoints:

```
POST /claims/validate          — Submit a claim for validation
GET  /claims/{id}/provenance   — Audit trail for a claim
GET  /workflows/{id}/state     — Current canonical workflow state
GET  /agents/trust             — Agent trust scores
GET  /validators/reliability   — Validator reliability scores
GET  /claims/quarantine        — Quarantined (NEEDS_REVIEW) claims
WS   /stream                   — Real-time consensus event stream
```

---

## Project Structure

```
quorum/
  quorum/
    contracts/      # Shared Pydantic models, interfaces, Redis keys, config
    validators/     # source.py, consistency.py, reasoning.py
    consensus/      # engine.py, scoring.py, quarantine.py
    state/          # redis_store.py, provenance.py, trust.py
    agents/         # Fetch.ai uAgents + demo workflow
    api/            # FastAPI routes, WS, observability, startup
    fakes/          # In-memory fakes for testing
    pipeline.py     # QuorumPipeline (integration wiring)
  tests/            # 177 tests across all components
  dashboard/        # Next.js + shadcn/ui light-mode dashboard
  docs/api.md       # API schema
  docker-compose.yml
```

---

## Test Coverage

```
pytest                 # 177 tests, ~2s
pytest tests/contracts # Shared models + fakes
pytest tests/validators# Source, consistency, reasoning validators
pytest tests/consensus # Engine, scoring, quarantine
pytest tests/state     # Redis store, provenance, trust
pytest tests/agents    # uAgents protocols + quorum agent
pytest tests/api       # FastAPI routes + WebSocket
pytest tests/test_pipeline.py  # End-to-end pipeline integration
```


## Detected evidence (automated analysis)

Indexed codebase: 110 recognized source files, 428 KB.
- Anthropic (technology) — detected in the code
- CSS (language) — detected in the code
- FastAPI (technology) — detected in the code
- Next.js (technology) — detected in the code
- Python (language) — detected in the code
- React (technology) — detected in the code
- Tailwind CSS (technology) — detected in the code
- TypeScript (language) — detected in the code
- Redis (technology) — claimed on Devpost, not found in the code
- AI coding agent: Claude Code — evidence: config files committed to the repository
- AI coding agent: Codex — evidence: config files committed to the repository
- AI coding agent: Cursor — evidence: config files committed to the repository

## Codebase structure (from repository index)

### Files (120 of 124)

```
.claude/rules/rocketride.md
.cursor/rules/rocketride.mdc
.env.example
.gitignore
.quorum_pids
agentverse/README.md
dashboard/.gitignore
dashboard/AGENTS.md
dashboard/CLAUDE.md
dashboard/components.json
dashboard/eslint.config.mjs
dashboard/next.config.ts
dashboard/package.json
dashboard/postcss.config.mjs
dashboard/README.md
dashboard/src/app/consensus/page.tsx
dashboard/src/app/demo/page.tsx
dashboard/src/app/globals.css
dashboard/src/app/layout.tsx
dashboard/src/app/page.tsx
dashboard/src/app/provenance/page.tsx
dashboard/src/app/quarantine/page.tsx
dashboard/src/app/slides/page.tsx
dashboard/src/app/slides/slides.css
dashboard/src/app/trust/page.tsx
dashboard/src/components/consensus/claim-card.tsx
dashboard/src/components/consensus/verdict-badge.tsx
dashboard/src/components/layout/header.tsx
dashboard/src/components/layout/sidebar.tsx
dashboard/src/components/ui/badge.tsx
dashboard/src/components/ui/button.tsx
dashboard/src/components/ui/card.tsx
dashboard/src/components/ui/progress.tsx
dashboard/src/components/ui/scroll-area.tsx
dashboard/src/components/ui/separator.tsx
dashboard/src/components/ui/skeleton.tsx
dashboard/src/components/ui/table.tsx
dashboard/src/components/ui/tabs.tsx
dashboard/src/components/ui/tooltip.tsx
dashboard/src/lib/api.ts
dashboard/src/lib/mock.ts
dashboard/src/lib/types.ts
dashboard/src/lib/utils.ts
dashboard/tsconfig.json
DEVPOST.md
docker-compose.yml
Dockerfile
docs/api.md
Makefile
pyproject.toml
quorum/__init__.py
quorum/agents/__init__.py
quorum/agents/agentverse_agent.py
quorum/agents/demo_workflow.py
quorum/agents/protocols.py
quorum/agents/quorum_agent.py
quorum/agents/worker_agents.py
quorum/api/__init__.py
quorum/api/demo.py
quorum/api/dependencies.py
quorum/api/event_bus.py
quorum/api/main.py
quorum/api/observability.py
quorum/api/routes.py
quorum/api/startup.py
quorum/api/ws.py
quorum/consensus/__init__.py
quorum/consensus/engine.py
quorum/consensus/quarantine.py
quorum/consensus/scoring.py
quorum/contracts/__init__.py
quorum/contracts/config.py
quorum/contracts/errors.py
quorum/contracts/interfaces.py
quorum/contracts/models.py
quorum/contracts/redis_keys.py
quorum/fakes/__init__.py
quorum/fakes/event_bus.py
quorum/fakes/fixtures.py
quorum/fakes/llm.py
quorum/fakes/pipeline.py
quorum/fakes/store.py
quorum/fakes/validators.py
quorum/pipeline.py
quorum/state/__init__.py
quorum/state/provenance.py
quorum/state/redis_store.py
quorum/state/trust.py
quorum/utils.py
quorum/validators/__init__.py
quorum/validators/consistency.py
quorum/validators/reasoning.py
quorum/validators/source.py
README.md
requirements.txt
run_agentverse.py
run.sh
tests/__init__.py
tests/agents/__init__.py
tests/agents/conftest.py
tests/agents/test_protocols.py
tests/agents/test_quorum_agent.py
tests/agents/test_worker_agents.py
tests/api/__init__.py
tests/api/test_routes.py
tests/api/test_ws.py
tests/consensus/__init__.py
tests/consensus/test_engine.py
tests/consensus/test_quarantine.py
tests/consensus/test_scoring.py
tests/contracts/__init__.py
tests/contracts/test_fakes.py
tests/contracts/test_models.py
tests/dashboard_check.sh
tests/smoke.sh
tests/state/__init__.py
tests/state/test_provenance.py
tests/state/test_redis_store.py
tests/state/test_trust.py
tests/test_pipeline.py
[4 more files omitted for size]
```

### Dependencies

- dashboard/package.json: @base-ui/react@^1.6.0, @tailwindcss/postcss@^4, @types/node@^20, @types/react@^19, @types/react-dom@^19, class-variance-authority@^0.7.1, clsx@^2.1.1, eslint@^9, eslint-config-next@16.2.9, lucide-react@^1.21.0, next@16.2.9, react@19.2.4, react-dom@19.2.4, shadcn@^4.11.0, tailwind-merge@^3.6.0, tailwindcss@^4, tw-animate-css@^1.4.0, typescript@^5
- pyproject.toml: anthropic@>=0.28.0, anyio[trio]@>=4.4.0, arize@>=7.24.0, fakeredis[aioredis]@>=2.23.0, fastapi@>=0.111.0, httpx@>=0.27.0, playwright@>=1.44.0, pydantic@>=2.7.0, pydantic-settings@>=2.3.0, pytest@>=8.2.0, pytest-asyncio@>=0.23.0, pytest-httpx@>=0.30.0, redis[asyncio]@>=5.0.0, respx@>=0.21.0, ruff@>=0.4.0, sentry-sdk@>=2.5.0, uagents@>=0.14.0, uvicorn[standard]@>=0.30.0, websockets@>=12.0
- requirements.txt: anthropic@>=0.28.0, anyio[trio]@>=4.4.0, arize@>=7.24.0, fakeredis[aioredis]@>=2.23.0, fastapi@>=0.111.0, httpx@>=0.27.0, pydantic@>=2.7.0, pydantic-settings@>=2.3.0, pytest@>=8.2.0, pytest-asyncio@>=0.23.0, pytest-httpx@>=0.30.0, redis[asyncio]@>=5.0.0, respx@>=0.21.0, ruff@>=0.4.0, sentry-sdk@>=2.5.0, uagents@>=0.14.0, uvicorn[standard]@>=0.30.0, websockets@>=12.0

### Recent commits (newest first)

- Merge pull request #1 from mansiguptacs/patch-1
- fix(slides): demo CTA uses plain anchor for reliable navigation to /demo
- fix(slides): hero gradient text - hex colors + color:transparent, drop oklch in gradient
- fix(slides): hero gradient text - inline span fixes background-clip:text
- feat(dashboard): cinematic scroll slide deck at /slides
- Update README with agent chat and profile links
- fix(agentverse): cap rationale at 140 chars with word-boundary trim to prevent ASI:One truncation
- Update components list in README
- docs: add Devpost submission writeup
- feat(dashboard): add landing page at root /
- fix(dashboard): increase font sizes for important terms in agent card
- fix(dashboard): clean demo card — highlight % with verdict color, fix casing, strip rationale dump
- fix(agentverse): clean validator names and redesign chat reply format
- chore: add .gitignore, untrack .env
- chore: add example API key and fix event loop initialization
- feat(agentverse): add Agent Chat Protocol for ASI:One chat UI
- feat(agentverse): auto-register on Agentverse via /connect on startup
- feat(agentverse): publishable Quorum validator uAgent

## Key source files (fetched from GitHub, selected and truncated for size)

### DEVPOST.md

```markdown
# Quorum — Devpost Submission

---

## Inspiration

There is a silent assumption baked into almost every multi-agent AI system built today: that the agents feeding each other information are telling the truth.

They are not always.

We started thinking about this after watching a demo where a research agent confidently passed a hallucinated statistic downstream — and by the time it reached the final output layer, three more agents had cited it, reasoned from it, and built recommendations on top of it. The hallucination didn't just survive; it compounded. One wrong claim upstream behaves like an avalanche: small at the origin, catastrophic at the base.

This isn't a hypothetical edge case. It is the *default* failure mode of any pipeline where agents trust each other without verification. In financial analysis, healthcare triage, legal research, or automated decision-making — a single undetected error early in the chain can corrupt everything downstream with mathematical certainty.

We built Quorum because **multi-agent systems are only as trustworthy as their least reliable agent** — and nobody was solving that.

---

## What It Does

Quorum is a drop-in validation layer that intercepts any factual claim before it propagates through a multi-agent pipeline and returns a structured, machine-readable consensus verdict.

Every claim runs through three independent validators in parallel:

### 🌐 Source Validator — *powered by Browserbase*
The Source Validator doesn't just query an API — it *browses the web like a human researcher*. Using Browserbase's cloud browser infrastructure, it navigates live pages, extracts real content, and cross-references the claim against DuckDuckGo search results and Wikipedia. This gives us ground-truth web evidence that static APIs simply can't provide. Each source is scored for topic relevance, and the validator gracefully degrades to a benefit-of-the-doubt score when no sources are retrievable — so the pipeline never hard-crashes on network failures.

### 🔁 Consistency Validator — *powered by Redis*
The Consistency Validator maintains a live memory of every claim accepted within a workflow session, persisted in Redis. When a new claim arrives, it compares it against all prior accepted claims and surfaces contradictions — even subtle ones across different time periods, metrics, or subsectors. Redis was critical here: it gave us sub-millisecond cross-claim lookups even as workflow histories grew, and let us support concurrent sessions without state bleed. Without a fast, durable store, this validator would be unusable at any real scale.

### 🧠 Reasoning Validator — *powered by Anthropic Claude*
The Reasoning Validator asks the hardest question: *is this claim internally coherent?* Claude evaluates the logical structure of the claim — flagging unsupported conclusions, circular reasoning, category errors, and open-ended questions masquerading as factual assertions. It doesn't just check if something is *true*; it checks 
[truncated — 7794 more characters]
```

### dashboard/CLAUDE.md

```markdown
@AGENTS.md

```

### Dockerfile

```
FROM python:3.11-slim

WORKDIR /app

COPY pyproject.toml requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt

COPY quorum/ ./quorum/

CMD ["uvicorn", "quorum.api.main:app", "--host", "0.0.0.0", "--port", "8000"]

```

### requirements.txt

```
# Core
pydantic>=2.7.0
pydantic-settings>=2.3.0
redis[asyncio]>=5.0.0
httpx>=0.27.0
anthropic>=0.28.0
uagents>=0.14.0
fastapi>=0.111.0
uvicorn[standard]>=0.30.0
websockets>=12.0
sentry-sdk>=2.5.0
arize>=7.24.0

# Dev / Test
fakeredis[aioredis]>=2.23.0
pytest>=8.2.0
pytest-asyncio>=0.23.0
pytest-httpx>=0.30.0
respx>=0.21.0
anyio[trio]>=4.4.0
ruff>=0.4.0

```

### docker-compose.yml

```yaml
version: "3.9"

services:
  redis:
    image: redis:7-alpine
    ports:
      - "6379:6379"
    volumes:
      - redis_data:/data
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 5s
      timeout: 3s
      retries: 5

  api:
    build: .
    command: uvicorn quorum.api.main:app --host 0.0.0.0 --port 8000 --reload
    ports:
      - "8000:8000"
    env_file: .env
    depends_on:
      redis:
        condition: service_healthy
    volumes:
      - .:/app

  dashboard:
    build: ./dashboard
    ports:
      - "3000:3000"
    environment:
      - NEXT_PUBLIC_API_URL=http://localhost:8000
      - NEXT_PUBLIC_WS_URL=ws://localhost:8000/stream
    depends_on:
      - api

volumes:
  redis_data:

```

### pyproject.toml

```
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[project]
name = "quorum"
version = "0.1.0"
description = "Trust and consensus layer for Fetch.ai multi-agent systems"
readme = "README.md"
requires-python = ">=3.11"
dependencies = [
    "pydantic>=2.7.0",
    "pydantic-settings>=2.3.0",
    "redis[asyncio]>=5.0.0",
    "httpx>=0.27.0",
    "anthropic>=0.28.0",
    "uagents>=0.14.0",
    "fastapi>=0.111.0",
    "uvicorn[standard]>=0.30.0",
    "websockets>=12.0",
    "sentry-sdk>=2.5.0",
    "arize>=7.24.0",
    "fakeredis[aioredis]>=2.23.0",
    "playwright>=1.44.0",
]

[project.optional-dependencies]
dev = [
    "pytest>=8.2.0",
    "pytest-asyncio>=0.23.0",
    "pytest-httpx>=0.30.0",
    "respx>=0.21.0",
    "anyio[trio]>=4.4.0",
    "ruff>=0.4.0",
]

[tool.hatch.build.targets.wheel]
packages = ["quorum"]

[tool.pytest.ini_options]
asyncio_mode = "auto"
testpaths = ["tests"]

[tool.ruff]
line-length = 100
target-version = "py311"

[tool.ruff.lint]
select = ["E", "F", "I", "UP"]

```

### dashboard/package.json

```
{
  "name": "dashboard",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "eslint"
  },
  "dependencies": {
    "@base-ui/react": "^1.6.0",
    "class-variance-authority": "^0.7.1",
    "clsx": "^2.1.1",
    "lucide-react": "^1.21.0",
    "next": "16.2.9",
    "react": "19.2.4",
    "react-dom": "19.2.4",
    "shadcn": "^4.11.0",
    "tailwind-merge": "^3.6.0",
    "tw-animate-css": "^1.4.0"
  },
  "devDependencies": {
    "@tailwindcss/postcss": "^4",
    "@types/node": "^20",
    "@types/react": "^19",
    "@types/react-dom": "^19",
    "eslint": "^9",
    "eslint-config-next": "16.2.9",
    "tailwindcss": "^4",
    "typescript": "^5"
  }
}

```

### quorum/api/main.py

```python
"""FastAPI application entry point."""

from __future__ import annotations

from contextlib import asynccontextmanager
from typing import AsyncIterator

from fastapi import Depends, FastAPI, WebSocket
from fastapi.middleware.cors import CORSMiddleware

from quorum.api.dependencies import get_event_bus
from quorum.api.observability import init_sentry
from quorum.api.demo import demo_router
from quorum.api.routes import router
from quorum.api.ws import ws_endpoint
from quorum.contracts.interfaces import EventBus


@asynccontextmanager
async def lifespan(app: FastAPI) -> AsyncIterator[None]:
    import logging
    logging.basicConfig(
        level=logging.INFO,
        format="%(asctime)s [%(name)s] %(levelname)s %(message)s",
        datefmt="%H:%M:%S",
    )
    from quorum.contracts.config import get_settings
    settings = get_settings()
    init_sentry(settings.sentry_dsn)
    try:
        from quorum.api.startup import initialize_pipeline
        await initialize_pipeline()
    except Exception as exc:
        import logging
        logging.getLogger(__name__).warning("Pipeline init skipped: %s", exc)
    yield


app = FastAPI(
    title="Quorum API",
    description="Trust and consensus layer for Fetch.ai multi-agent systems",
    version="0.1.0",
    lifespan=lifespan,
)

app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

app.include_router(router)
app.include_router(demo_router)


@app.websocket("/stream")
async def websocket_stream(
    websocket: WebSocket,
    event_bus: EventBus = Depends(get_event_bus),
) -> None:
    await ws_endpoint(websocket, event_bus)

```

### dashboard/src/app/layout.tsx

```typescript
import type { Metadata } from "next";
import { Geist, Geist_Mono } from "next/font/google";
import "./globals.css";
import { Sidebar } from "@/components/layout/sidebar";
import { TooltipProvider } from "@/components/ui/tooltip";

const geistSans = Geist({
  variable: "--font-geist-sans",
  subsets: ["latin"],
});

const geistMono = Geist_Mono({
  variable: "--font-geist-mono",
  subsets: ["latin"],
});

export const metadata: Metadata = {
  title: "Quorum — Trust & Consensus Dashboard",
  description:
    "Real-time visibility into claim validation, consensus, provenance, and agent trust.",
};

export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  return (
    <html
      lang="en"
      className={`${geistSans.variable} ${geistMono.variable} h-full antialiased dark`}
    >
      <body className="flex h-full bg-zinc-950">
        <TooltipProvider>
          <Sidebar />
          <main className="flex flex-1 flex-col overflow-y-auto">{children}</main>
        </TooltipProvider>
      </body>
    </html>
  );
}

```

### dashboard/src/app/page.tsx

```typescript
import Link from "next/link";
import { Badge } from "@/components/ui/badge";
import { buttonVariants } from "@/components/ui/button";
import { CheckCircle, XCircle, AlertTriangle, Globe, GitBranch, Brain, ArrowRight, Zap, Shield, Bot } from "lucide-react";
import { cn } from "@/lib/utils";

const VALIDATORS = [
  {
    icon: Globe,
    name: "Source",
    color: "emerald",
    description: "Live web evidence via DuckDuckGo, Wikipedia, and Browserbase. Scores real-world support for every claim.",
    badge: "Web Search",
  },
  {
    icon: GitBranch,
    name: "Consistency",
    color: "blue",
    description: "Cross-checks the claim against everything already accepted in the session. Catches contradictions before they propagate.",
    badge: "Memory",
  },
  {
    icon: Brain,
    name: "Reasoning",
    color: "violet",
    description: "Claude evaluates internal coherence. Flags unsupported conclusions, circular logic, and category errors.",
    badge: "LLM",
  },
];

const VERDICTS = [
  { icon: CheckCircle, label: "Accepted", color: "text-emerald-400", bg: "bg-emerald-950/40 border-emerald-800/60" },
  { icon: XCircle,    label: "Rejected",  color: "text-red-400",     bg: "bg-red-950/40 border-red-800/60" },
  { icon: AlertTriangle, label: "Needs Review", color: "text-amber-400", bg: "bg-amber-950/40 border-amber-800/60" },
];

const colorMap: Record<string, { icon: string; card: string; badge: string; border: string }> = {
  emerald: {
    icon: "text-emerald-400",
    card: "bg-emerald-950/20 border-emerald-800/40 hover:border-emerald-700/60",
    badge: "bg-emerald-950/50 text-emerald-300 border-emerald-800",
    border: "border-l-emerald-500",
  },
  blue: {
    icon: "text-blue-400",
    card: "bg-blue-950/20 border-blue-800/40 hover:border-blue-700/60",
    badge: "bg-blue-950/50 text-blue-300 border-blue-800",
    border: "border-l-blue-500",
  },
  violet: {
    icon: "text-violet-400",
    card: "bg-violet-950/20 border-violet-800/40 hover:border-violet-700/60",
    badge: "bg-violet-950/50 text-violet-300 border-violet-800",
    border: "border-l-violet-500",
  },
};

export default function LandingPage() {
  return (
    <div className="min-h-full bg-zinc-950 text-zinc-100">
      {/* ── Hero ── */}
      <section className="relative overflow-hidden border-b border-zinc-800/60 px-8 py-16">
        {/* subtle grid background */}
        <div className="pointer-events-none absolute inset-0 bg-[linear-gradient(to_right,#ffffff08_1px,transparent_1px),linear-gradient(to_bottom,#ffffff08_1px,transparent_1px)] bg-[size:40px_40px]" />
        <div className="relative max-w-3xl">
          <div className="flex items-center gap-2 mb-4">
            <Badge className="bg-zinc-800 text-zinc-300 border-zinc-700 text-xs font-mono">v1.0</Badge>
            <Badge className="bg-violet-950/50 text-violet-300 border-violet-800 text-xs">Agentverse Ready</Badge>
          </div>
          <h1 className="text-5xl font-bold tracking-tight mb-3">
            <span className="bg-gradient-to-r from-zinc-100 via-zinc-300 to-zinc-500 bg-clip-text text-transparent">
              Quorum
            </span>
          </h1>
          <p className="text-xl text-zinc-400 mb-2 font-light">
            Multi-agent trust &amp; consensus for AI pipelines.
          </p>
          <p className="text-sm text-zinc-500 mb-8 max-w-xl">
            Every agent claim runs through three independent validators — Source, Consistency, and Reasoning —
            before reaching consensus. Built on Fetch.ai uAgents, queryable from ASI:One.
          </p>
          <div className="flex flex-wrap gap-3">
            <Link
              href="/demo"
              className={cn(buttonVariants({ size: "lg" }), "bg-zinc-100 text-zinc-900 hover:bg-zinc-200 font-semibold")}
            >
              Try the Demo <ArrowRight className="ml-2 h-4 w-4" />
            </Link>
            <a
              href="https://agentverse.ai"
              target="_blank"
              rel="noreferrer"
              className={cn(buttonVariants({ size: "lg", variant: "outline" }), "border-zinc-700 text-zinc-300 hover:bg-zinc-800 hover:text-zinc-100")}
            >
              <Bot className="mr-2 h-4 w-4" /> Find on Agentverse
            </a>
          </div>
        </div>
      </section>

      {/* ── Stats strip ── */}
      <section className="border-b border-zinc-800/60 px-8 py-5">
        <div className="flex flex-wrap gap-8">
          {[
            { label: "Validators", value: "3" },
            { label: "Consensus score", value: "0 – 1" },
            { label: "Verdicts", value: "3" },
            { label: "Agentverse protocol", value: "Chat + Custom" },
          ].map(({ label, value }) => (
            <div key={label} className="flex items-baseline gap-2">
              <span className="text-2xl font-bold text-zinc-100 tabular-nums">{value}</span>
              <span className="text-xs text-zinc-500 uppercase tracking-wide">{label}</span>
            </div>
          ))}
        </div>
      </section>

      {/* ── Validators ── */}
      <section className="px-8 py-10 border-b border-zinc-800/60">
        <p className="text-[10px] font-semibold text-zinc-500 uppercase tracking-widest mb-5 flex items-center gap-2">
          <Zap className="h-3 w-3" /> Three-Layer Pipeline
        </p>
        <div className="grid gap-4 sm:grid-cols-3">
          {VALIDATORS.map(({ icon: Icon, name, color, description, badge }) => {
            const c = colorMap[color];
            return (
              <div
                key={name}
                className={`rounded-lg border ${c.card} border-l-4 ${c.border} px-5 py-4 space-y-3 transition-colors`}
              >
                <div className="flex items-center justify-between">
                  <div className="flex items-center gap-2">
                    <Icon className={`h-4 w-4 ${c.icon}`} />
                    <span className="font-semibold text-zinc-100">{name}</span>
     
[truncated — 3221 more characters]
```

[95 more indexed source files omitted to keep this export small. The full file list is in the Codebase structure section above.]