Major additions: - Community Next.js app (port 18187) for browsing claims with API docs - stemedb-chaos crate: Fault injection, chaos testing, CRDT properties - Latent ingestion system: Reddit/FDA ingesters with ADK-Go agents - Disputed claims handling: Manual review workflows and validation - Aphoria security scanner: New extractors (SQL injection, command injection, weak crypto, TLS version), policy-based ignores, UAT reports - Docker infrastructure: Dockerfile, docker-compose.yml for full stack - VulnBank demo: Intentionally vulnerable multi-language test corpus SDK & API enhancements: - Source registry handlers for tracking data provenance - Metrics endpoint - Skeptic filtering improvements Code quality: - Split 14 large files (>500 lines) into focused modules - All files now under 500-line limit per project guidelines Documentation: - Chaos testing guide, circuit breakers, observability docs - Phase 7 UAT documentation updates - Martin Kleppmann technical writer agent Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
13 KiB
Disputed Roadmap
Architecture
┌────────────────────────────────────────────────────────────┐
│ DISPUTED │
├────────────────────────────────────────────────────────────┤
│ │
│ INPUT LAYER │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ System Audio│ │ Mic Input │ │ Text Input │ │
│ │ (loopback) │ │ (live) │ │ (paste/OCR) │ │
│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │
│ │ │ │ │
│ └────────────────┼────────────────┘ │
│ ▼ │
│ TRANSCRIPTION LAYER │
│ ┌─────────────────────────────────────────┐ │
│ │ Whisper (local) / Groq API / Deepgram │ │
│ │ - Streaming transcription │ │
│ │ - Speaker diarization (future) │ │
│ └──────────────────┬──────────────────────┘ │
│ ▼ │
│ EXTRACTION LAYER │
│ ┌─────────────────────────────────────────┐ │
│ │ Claim Extractor (LLM) │ │
│ │ - Identifies factual claims │ │
│ │ - Structures as subject/predicate/obj │ │
│ │ - Assigns confidence from hedging │ │
│ │ - Extracts source metadata │ │
│ └──────────────────┬──────────────────────┘ │
│ ▼ │
│ STORAGE LAYER │
│ ┌─────────────────────────────────────────┐ │
│ │ Episteme (stemedb) │ │
│ │ - Append-only claim storage │ │
│ │ - Conflict detection via Lenses │ │
│ │ - Source provenance tracking │ │
│ │ - Trust tier scoring │ │
│ └──────────────────┬──────────────────────┘ │
│ ▼ │
│ UI LAYER │
│ ┌─────────────────────────────────────────┐ │
│ │ Tauri Desktop App │ │
│ │ - Menubar presence │ │
│ │ - Toast notifications │ │
│ │ - Claim browser / search │ │
│ │ - Conflict explorer │ │
│ └─────────────────────────────────────────┘ │
│ │
└────────────────────────────────────────────────────────────┘
Implementation Progress
Week 1: Foundation & Core Pipeline ✅ COMPLETE
Goal: Clean, professional codebase foundation. One complete flow: paste text → extract claims → see results.
| Task | Status |
|---|---|
Type system foundation (src/lib/types.ts, src/lib/schemas.ts) |
✅ |
Rust module organization (src-tauri/src/commands/, types.rs) |
✅ |
Services layer (src/services/) with Zod validation |
✅ |
Zustand stores (src/stores/) for state management |
✅ |
React hooks (src/hooks/) for business logic |
✅ |
| App refactor to use hooks | ✅ |
| Quality gates (ESLint, Prettier, Clippy, pre-commit) | ✅ |
| Tauri app launches and displays UI | ✅ |
Commands:
npm run check # ESLint + TypeScript + Prettier
npm run tauri:dev # Development mode
cargo clippy # Rust linting
Week 2: LLM Integration 🔜 NEXT
Goal: Real claim extraction using Claude/Groq APIs
| Task | Status |
|---|---|
| LLM prompt for claim extraction | ⬜ |
| Claude API integration | ⬜ |
| Groq API as alternative | ⬜ |
| Structured output parsing | ⬜ |
| Batch extraction for longer text | ⬜ |
| API key settings UI | ⬜ |
| Error handling and retries | ⬜ |
Key Files to Create/Modify:
src-tauri/src/commands/llm.rs- LLM API callssrc-tauri/src/prompts/- Extraction promptssrc/components/settings-dialog.tsx- API key configuration
Week 3: Episteme Integration ⬜
Goal: Connect to knowledge graph for conflict detection
| Task | Status |
|---|---|
| Embed stemedb as Rust dependency | ⬜ |
Local database in ~/.disputed/ |
⬜ |
| Save claims with source metadata | ⬜ |
| Query existing claims for conflicts | ⬜ |
| Semantic similarity matching | ⬜ |
| Conflict status badges in UI | ⬜ |
Week 4: Audio Pipeline ⬜
Goal: Listen to system audio → transcribe → extract claims
| Task | Status |
|---|---|
| System audio capture (macOS ScreenCaptureKit) | ⬜ |
| Microphone input option | ⬜ |
| Groq Whisper API integration | ⬜ |
| Chunked streaming transcription | ⬜ |
| Real-time claim extraction | ⬜ |
| Audio source detection/labeling | ⬜ |
Phase Overview
Phase 1: Text Input MVP (Weeks 1-3)
Goal: Paste text → extract claims → save to Episteme → show conflicts
1.1 Tauri App Shell ✅
- Initialize Tauri project with Rust backend
- Basic window with text input area
- Type-safe frontend/backend communication
- Quality gates (lint, format, typecheck)
- Menubar icon (system tray) - deferred
- Global hotkey to open input window - deferred
1.2 Claim Extraction
- Structured output:
{ subject, predicate, object, confidence, quote } - LLM prompt for claim extraction
- Integration with Claude API (or local Ollama)
- Batch extraction for longer text
1.3 Episteme Integration
- Embed stemedb as Rust dependency
- Local database in
~/.disputed/ - Save claims with source metadata (manual label for now)
- Query existing claims for conflicts
1.4 Basic UI ✅
- Display extracted claims before saving
- Show status badges (new/matches/contradicts)
- Accept/reject controls
- Show matching/conflicting claims from database
- Simple claim history view
Deliverable: App where you paste text, see claims, save them, see conflicts.
Phase 2: Audio Transcription (Week 4+)
Goal: Listen to system audio → transcribe → extract claims in real-time
2.1 Audio Capture
- System audio loopback (macOS: ScreenCaptureKit)
- Microphone input option
- Audio level indicator in menubar
- Start/stop recording controls
2.2 Transcription Pipeline
- Groq Whisper API integration (fast, cheap)
- Chunked streaming (send 30s segments)
- Local Whisper option for privacy
- Handle overlapping chunks for continuity
2.3 Streaming Extraction
- Process transcript chunks as they arrive
- Deduplicate claims across chunk boundaries
- Real-time toast notifications for new claims
- Buffer for context (don't extract from single sentences)
2.4 Source Detection
- Auto-detect source from audio metadata if available
- Manual source labeling ("What are you listening to?")
- Remember recent sources for quick selection
Deliverable: Listen to a podcast, see claims pop up in real-time.
Phase 3: Conflict Intelligence
Goal: Smart conflict detection and exploration
- Semantic similarity for related claims
- Contradiction classification (agrees/contradicts/related)
- Confidence-weighted conflict scoring
- Source diversity in conflicts
- Conflict explorer view
- Trust tier system for sources
Phase 4: Browser Extension
Goal: Highlight text on any webpage → extract claims
- Chrome/Firefox extension
- Context menu: "Extract claims"
- Auto-detect article metadata
- Communicate with desktop app
Phase 5: Intelligence Features
Goal: Proactive insights, not just reactive capture
- Topic clustering and summarization
- Source reliability scoring
- Belief evolution visualization
- Export/share functionality
Tech Stack
| Component | Choice | Rationale |
|---|---|---|
| Desktop Framework | Tauri 2.4 | Rust backend, small binary, native feel |
| Frontend | React 19, TypeScript 5.7 | Type safety, ecosystem |
| Styling | Tailwind 4, Shadcn components | Utility-first, accessible |
| State | Zustand 5 | Lightweight, TypeScript-first |
| Validation | Zod 4 | Runtime type safety |
| Backend | Rust + Episteme | Already built, append-only, conflict-aware |
| Transcription | Groq Whisper API | Fast (real-time), cheap ($0.02/hr) |
| Local Transcription | whisper.cpp | Privacy option, runs on M1/M2 well |
| Claim Extraction | Claude API | Best at structured extraction |
| Local Extraction | Ollama + Llama 3 | Privacy option |
File Structure
disputed/
├── vision.md # Product vision
├── roadmap.md # You are here
└── app/ # Tauri desktop app
├── package.json
├── tsconfig.json
├── vite.config.ts
├── eslint.config.js
├── .pre-commit-config.yaml
├── src/
│ ├── main.tsx
│ ├── App.tsx
│ ├── index.css
│ ├── lib/
│ │ ├── types.ts # Domain types
│ │ ├── schemas.ts # Zod validation
│ │ └── utils.ts # Utilities (cn)
│ ├── services/
│ │ ├── index.ts
│ │ ├── claims.ts # Tauri invoke wrappers
│ │ └── settings.ts
│ ├── stores/
│ │ ├── index.ts
│ │ ├── claims.ts # Zustand stores
│ │ └── settings.ts
│ ├── hooks/
│ │ ├── index.ts
│ │ ├── useClaims.ts # React hooks
│ │ └── useSettings.ts
│ └── components/
│ └── ui/ # Shadcn components
│ ├── button.tsx
│ ├── card.tsx
│ ├── badge.tsx
│ └── textarea.tsx
└── src-tauri/
├── Cargo.toml
├── tauri.conf.json
├── capabilities/
│ └── default.json
├── icons/
└── src/
├── main.rs
├── lib.rs # Tauri setup
├── types.rs # Rust types
└── commands/
├── mod.rs
├── claims.rs # Claim commands
└── settings.rs # Settings commands
MVP Definition
MVP = Phase 1 complete (Weeks 1-3)
You can:
- Open app
- Paste text
- See extracted claims (LLM-powered)
- Save to local database (Episteme)
- See conflicts with existing claims
This validates the core loop before adding audio complexity.
Success Metrics
| Metric | Target | Why |
|---|---|---|
| Claims saved per week | 50+ | Proves capture is frictionless |
| Conflicts surfaced | 5+ | Proves the core value prop |
| Retention (weekly active) | 60%+ | Proves ongoing value |
| Time to first conflict | < 5 min | Proves immediate value |
Next Action
Week 2: LLM Integration
- Add Claude API client to Rust backend
- Create extraction prompt
- Implement
extract_claimscommand with real LLM calls - Add API key settings UI
- Handle errors gracefully
cd disputed/app
npm run tauri:dev