Skip to content

Repository files navigation

Gavel

Validate first. Five AI judges when you're ready. Zero sugarcoating.

A founder workbench for stress-testing startup ideas. Capture a structured Pitch (Idea Validation Worksheet), log proof work on Case, and start a Review only when a readiness gate says the pitch is specific enough to critique (not the same as evidence-ready). Five judges — VC, engineer, product manager, customer, and competitor — debate, then a moderator delivers a structured GO / ITERATE / NO-GO call with a proof step and recommended experiment first. Numeric scores stay in the API for evaluation and sit behind Advanced model output in the web UI. Verdicts hand off into Case as concrete next steps. Disagree? Appeal with evidence and make them reconsider.

Gavel

Ideas Per-idea workspaces at /workspaces: lifecycle, linked reviews, and next action
Pitch Guided worksheet (audience, problem, solution, pricing, risks) or paste-to-draft AI
Case Proof ledger: assumptions, evidence, experiments, interviews, belief updates, staged checklist
Readiness gate Deterministic pre-review checks; optional override with an AI readiness briefing
Review panel Five parallel verdicts: concern → fix → proof ask first (critique last; wire key may remain roast)
Debate Default one dissent pass (configurable 1–5) with token streaming and every judge on the record
Re-vote Post-debate re-score; UI shows argument changed/unchanged, not score theater
Synthesis Structured GO / ITERATE / NO-GO with highest priority, proof asks, and recommended experiment first
Handoff Selected review outputs become Case work: assumptions, evidence targets, experiments
Belief updates Cited belief changes (strengthened / weakened / reframed) grounded in evidence or experiments
Review eligibility Deterministic “why review now” signals after new evidence, completed experiments, or pitch changes
Appeal Per-judge evidence coaching with experiment context; outcomes include Ask matched when artifacts overlap proof asks, otherwise judge changed/unchanged
Iteration Pitch versions plus linked runs (parent_run_id); concern diffs vs prior versions (scores demoted)
Memory Past ideas inform future reviews (recency by default; optional semantic when ENABLE_SEMANTIC_MEMORY=true)
Web app Next.js workbench: Landing → Ideas → Case / Pitch / Reviews → live SSE Run
Web research Optional Tavily lookup with cited sources in the run view (API + Streamlit)
Run metrics Per-phase latency (roast, debate, re-vote), token usage, and estimated cost (advanced view)

Core loop: Draft Pitch → Case (one next validation step) → log assumptions / evidence / experiments → pass readiness → Reviews → decision + proof step + experiment → handoff into Case → run the experiment / log proof → revise Pitch → re-run → see concern changes vs prior version.

Authoritative unfinished work lives on Case. Run and Reviews route there; they do not host a second weekly experiment workbench. Founder-facing copy prefers review over roast; schema / SSE wire keys may still say roast.

Quick start

Requirements: Python 3.11+ · Ollama (local) or DeepSeek API (cloud)

git clone https://github.com/notsubash/Gavel.git
cd Gavel
python -m venv .venv
# Windows: .venv\Scripts\activate  |  macOS/Linux: source .venv/bin/activate
pip install -r requirements.txt
ollama pull qwen3.5:9b          # default chat model; override in .env
ollama pull nomic-embed-text    # only if ENABLE_SEMANTIC_MEMORY=true
cp .env.example .env            # optional: DeepSeek, Tavily, LangSmith, semantic memory

Web app (Next.js)

The web/ frontend is the primary product UI. Landing lives at /. Create an idea at /workspaces/new (guided Pitch wizard or paste notes for AI draft), then work Case → Pitch → Reviews inside the workspace. Log evidence and experiments on Case, pass the readiness gate, start a review, watch judges debate, read the decision with proof step first, hand off into Case, and optionally appeal with experiment context. Browse ideas at /workspaces (/history redirects there).

Requirements: Node.js 20+ · API on port 8000

# Terminal 1 — API (use the venv python so optional LLM deps resolve)
python -m uvicorn api.app:app --app-dir src --reload --port 8000

# Terminal 2 — frontend
cd web
npm install
cp .env.example .env.local
npm run dev

Open http://localhost:3000. See web/README.md for OpenAPI type generation and frontend scripts.

Streamlit (dev / reference only — not the v1 product UI)

streamlit run src/app.py

Maintainer reference only: paste a pitch and hit Roast It! It has no Case / Pitch workbench. Use the Next.js app for the founder product. Streamlit also hosts the experimental DeepAgents flow; the web app and streaming API use the deterministic pipeline only.

Streaming API

The FastAPI backend powers the Next.js app and any custom frontend:

python -m uvicorn api.app:app --app-dir src --reload --port 8000

Endpoints:

Runs (review pipeline)

Method Path Purpose
GET /health Liveness check
POST /api/runs Create a run (workspace_id required; parent_run_id optional), returns run_id immediately
GET /api/runs Paginated run history (limit, offset)
GET /api/runs/{run_id} Poll run status
GET /api/runs/{run_id}/similar Similar past reviews (semantic or recency)
GET /api/runs/{run_id}/events SSE stream of roast/debate events
GET /api/runs/{run_id}/handoff Post-review Case tasks (assumptions, evidence targets, experiments)
POST /api/runs/{run_id}/cancel Cooperatively stop a run (emits run_cancelled)
POST /api/runs/{run_id}/appeal Founder appeal (one per run; optional target_judges); returns revised panel

Workspaces (Case workbench; prefix /api/workspaces)

Method Path Purpose
POST /api/workspaces Create workspace + initial Pitch version
GET /api/workspaces List ideas
GET /api/workspaces/{id} Workspace detail + current Pitch
GET /api/workspaces/{id}/overview Case progress, confidence, next action
GET /api/workspaces/{id}/readiness Pre-review readiness checks
GET /api/workspaces/{id}/checklist Staged validation checklist
GET /api/workspaces/{id}/review-eligibility Deterministic “why review now” signals
GET/PUT /api/workspaces/{id}/founder-constraints Opt-in prefs (effort/method); never auto-applied to Case
POST /api/workspaces/{id}/versions Save a new Pitch version
GET /api/workspaces/{id}/runs Reviews linked to this idea
CRUD /api/workspaces/{id}/assumptions Track testable assumptions
CRUD /api/workspaces/{id}/evidence Log interviews, metrics, LOIs, research
CRUD /api/workspaces/{id}/experiments Plan and record validation experiments
CRUD /api/workspaces/{id}/interviews Customer discovery notes
CRUD /api/workspaces/{id}/belief-updates Cited belief changes grounded in proof
POST /api/workspaces/{id}/assist/* AI assists: draft, clarify, coach, falsification plan, weekly review, competitor scan, and more
GET /api/workspaces/{id}/export/markdown Export workspace as Markdown
GET /api/workspaces/{id}/export/judge-brief Export a judge-ready pitch brief

Create a run with workspace_id (and optional parent_run_id / readiness_override), then open an EventSource (or equivalent) on /api/runs/{run_id}/events. The pitch text is compiled from the workspace worksheet. When web research is enabled, the stream may emit research_findings before roast events. The stream then emits ordered pipeline envelopes: roast and debate phases, optional revote_started / revote_judge_completed events, debate_completed (includes structured_synthesis and initial vs revised verdicts when re-vote ran), run_metrics (roast/debate/re-vote latency, token counts, estimated cost), then run_completed, run_cancelled, or run_failed. After completion, handoff items are available via GET /api/runs/{run_id}/handoff. After a successful appeal, an appeal_completed event is appended to the log (appeal itself is a REST call, not streamed).

The run engine is decoupled from the HTTP connection: RunManager drives the pipeline once into a durable SQLite event log (data/runs.db). Multiple tabs can watch the same run; disconnect and reconnect with the SSE Last-Event-ID header to resume without gaps. Heartbeat comment frames keep idle connections alive (SSE_HEARTBEAT_SECONDS, default 15s).

Set ROAST_CORS_ORIGINS in .env for your frontend origin (comma-separated). Default includes http://localhost:3000 and http://127.0.0.1:3000 (plus :3001 variants in .env.example).

Run uvicorn with a single worker per machine; background tasks and in-process subscribers are not coordinated across workers yet. Compose publishes the API without auth on purpose (local/self-host); put a reverse-proxy auth layer in front if you expose it beyond your LAN.

Rate limits: POST /api/runs and POST /api/runs/{run_id}/appeal are token-bucket limited per client IP (RATE_LIMIT_* and RATE_LIMIT_APPEAL_* in .env). Returns 429 when exceeded. Disable with RATE_LIMIT_ENABLED=false. Set TRUST_PROXY=true only when the API sits behind a reverse proxy that sets X-Forwarded-For (Fly, Render, nginx). Otherwise clients could spoof that header to bypass limits.

Run budget: MAX_RUN_SECONDS (default 600) fails long runs cleanly between roast/debate boundaries and debate turns. In-flight judge LLM calls during roast may still finish after cancel/budget. Set 0 to disable.

Cancel: POST /api/runs/{run_id}/cancel is cooperative and asynchronous for running runs — the HTTP response may still show status: "running". Poll GET /api/runs/{run_id} or watch SSE for the terminal run_cancelled event. Cancelling a created run (before SSE connect) is immediate.

Docker (API + web)

cp .env.example .env   # set DEEPSEEK_API_KEY and/or point LOCAL_MODEL at host Ollama
# Keep E2E_TEST_MODE unset/false — stub reviews must never ship as “real”
docker compose up --build

Compose binds 127.0.0.1 only — the API has no auth. Do not republish 0.0.0.0:8000 without a reverse-proxy auth layer.

SQLite files (runs.db, workspaces.db, ideas.db) persist in the gavel-data volume under /data. API only: docker compose up --build api.

For local Ollama from inside the container, point LOCAL_MODEL at host.docker.internal (compose sets extra_hosts for Linux). Or run the API on the host and skip Docker. Behind nginx or a PaaS load balancer, set TRUST_PROXY=true in .env.

What it does

Phase What happens
Pitch Structured idea capture: audience, problem, workaround, solution, pricing, competitors, top risky assumption
Case Track assumptions, evidence, experiments, interviews, and cited belief updates; staged checklist and confidence
Readiness Deterministic gate before reviews (specificity, human evidence, worksheet completeness); optional override
Review panel Five judges (VC, Engineer, PM, Customer, Competitor) evaluate in parallel
Debate LangGraph runs configurable multi-round debate with fixed turn order and live token streaming
Re-vote Each judge re-scores against the full debate transcript (optional; ENABLE_REVOTE)
Synthesis Moderator returns structured GO / ITERATE / NO-GO with strengths, risks, and biggest disagreement
Handoff Verdict fields become Case tasks: assumptions to test, evidence targets, experiment suggestions
Appeal (optional) Per-judge evidence coaching → founder rebuttal (optional judge targeting) → revised panel
Iteration (optional) New Pitch versions and linked reviews; compare concerns and fixes vs prior versions
Memory Prior ideas summarized into future judge prompts (SQLite; optional semantic retrieval)
Web research Optional Tavily search with cited sources when judges need factual context
Metrics Wall-clock per phase (including re-vote), token counts, and estimated API cost (run_metrics event)

Each judge returns structured output prioritized as: key concern, recommended fix, evidence that would change their verdict, then a short critique. The UI renders a decision card, judge cards with proof bars, re-vote argument changes, debate transcript, version comparison, Case handoff, and Markdown export.

Screenshots

App UI

Ideas Case
Ideas Case
Case validation Pitch
Case validation Pitch
Reviews Review complete
Reviews Review complete
Ideas list Observability
Ideas list Observability

Architecture

Built with LangGraph, LangChain, Ollama, and the DeepAgents SDK. Two execution paths exist; only one is production-ready.

Pitch (Idea Validation Worksheet)
  → Case loop: assumptions, evidence, experiments, interviews, belief updates
  → Readiness gate (+ optional review-eligibility signals)
  → Phase 1: parallel structured judge calls (review panel)
  → Phase 2: LangGraph debate graph
  → Phase 2b: post-debate re-vote (optional)
  → Moderator structured synthesis
  → Handoff → Case tasks (founder-confirmed)
  → Optional appeal re-evaluation (against post-revote panel when present)
  → Pitch revision → next version
  → Persist compact idea memory (with optional parent/version lineage)

Deterministic pipeline (src/pipeline.py): Direct model calls plus LangGraph guarantee all five judges speak, debate rounds advance predictably, and Pydantic validates every boundary. Debate streams token deltas (DebateTokenDelta) for live UI updates; re-vote streams RevoteJudgeCompleted with score deltas. At completion the pipeline emits RunMetrics (roast/debate/re-vote seconds, tokens, estimated cost) before PipelineCompleted.

Decision-ready verdict (src/judges/synthesis.py, extended Verdict schema): Judges return recommended_fix and evidence_to_change_verdict. The moderator returns a structured Synthesis (GO / ITERATE / NO-GO, confidence, top strengths/risks, biggest disagreement) with prose fallback. assess_verdict_output_quality flags degraded local-model output in the UI.

Post-debate re-vote (src/debate/revote.py): After debate, each judge revises their verdict against the full transcript. Guardrails cap score movement (MAX_REVOTE_SCORE_DELTA); assess_revote_quality detects herding and unexplained deltas. Appeal re-evaluates against the post-revote panel when present (appeal_baseline_panel).

Pitch iteration (src/memory/lineage.py, src/validation/versioning.py): Workspaces carry versioned worksheets (WorksheetVersion with parent_version_id). Reviews link to a workspace and worksheet version. Parent-linked runs can show a compact “Since last review” summary; full comparison stays available.

Case handoff (src/validation/ingest.py): After a run completes, judge fixes, proof asks, and synthesis problems become RunHandoffItem records. Founder confirmation writes them into Case; Run’s primary CTA is Continue on Case.

Case workbench (src/validation/): Deterministic readiness, confidence, checklist, staged progress, belief updates (cited only), review eligibility, AI provenance stamps on founder-confirmed assist writeback, and stage-aware assist context. CRUD for assumptions, evidence, experiments, interviews, and belief updates in data/workspaces.db. LLM assists for Pitch draft/clarify, validation coach, falsification plan, readiness briefing, weekly review, competitor scan, interview questions, and experiment suggestions.

Appeal coaching (src/appeal/coaching.py, mirrored in web/src/lib/appeal/coaching.ts): Surfaces per-judge evidence asks above the appeal form. API accepts optional target_judges; response includes per-judge evidence outcomes.

Run engine (src/api/run_manager.py): Background task per run, durable event log in SQLite, subscriber-based SSE with reconnect support. Structured run_metrics JSON is logged once per API run (with run_id). API runs require a workspace_id, compile pitch text from the worksheet, persist to idea memory under a stable local user id, and support appeal, run history, similar-review lookup, and Case handoff ingest.

Web frontend (web/): Next.js App Router workbench with Landing, Ideas list, Case shell, Pitch wizard/editor, Reviews launch with readiness gate, live SSE Run view, structured synthesis cards, handoff into Case, appeal coaching, related reviews, and Settings. Brand visual world: Precision Workbench (see PRODUCT.md / DESIGN.md).

Verification (src/verification/): Shared invariants and quality checks (score/verdict alignment, degenerate panels/fixes, re-vote quality) used by guardrails, eval scorers, and UI degradation hints.

DeepAgents orchestrator (src/orchestrator/deep_agent.py): Agent harness that dispatches subagents via task() with stronger tool-calling models. Streamlit-only; not exposed via the streaming API.

Design principles

  • Case is the ledger of truth: reviews diagnose; Case records learning. Unfinished proof work does not live on Run.
  • Orchestration over autonomy: the debate is a workflow, not a free-form agent task. LangGraph owns state and routing.
  • Structured output at boundaries: verdict and synthesis schemas in src/judges/schemas.py and src/judges/synthesis.py are the contract between phases, charts, memory, and exports. Post-validation guardrails in src/judges/guardrails.py and shared checks in src/verification/ reject score/verdict mismatches, degenerate panels, and weak re-vote movement.
  • Untrusted user input: startup idea, memory, research, and appeal text are wrapped in tagged blocks with delimiter escaping (src/idea_context.py); prompts treat that content as data, not instructions.
  • Compact memory: SQLite stores full records, but prompts receive only short summaries (scores, concerns, synthesis). Full transcripts are never injected into judge prompts; local models drift under long context. Optional semantic retrieval (sqlite-vector) surfaces similar past ideas instead of only the most recent.
  • Appeal as a third phase: re-evaluates judges against founder evidence (post-revote baseline when re-vote ran). Does not rerun the multi-round debate. Coaching surfaces what evidence each judge needs before the founder writes.
  • Proof before grades: completed reviews lead with highest priority, proof bar, and recommended experiment; scores sit under Advanced model output.
  • Cited belief only: belief updates must cite evidence, experiment, worksheet version, or run (src/validation/belief.py).

Configuration

Copy .env.example to .env. Key variables:

LOCAL_MODEL=ollama:qwen3.5:9b
DEEPSEEK_MODEL=deepseek-v4-pro
DEEPSEEK_BASE_URL=https://api.deepseek.com
DEEPSEEK_API_KEY=your_deepseek_api_key
MAX_DEBATE_ROUNDS=1
ENABLE_WEB_SEARCH=false
WEB_SEARCH_MAX_RESULTS=3
TAVILY_API_KEY=your_tavily_api_key
ROAST_CORS_ORIGINS=http://localhost:3000,http://127.0.0.1:3000
SSE_HEARTBEAT_SECONDS=15
STALE_RUN_MINUTES=30
RUNS_DB_PATH=data/runs.db
WORKSPACES_DB_PATH=data/workspaces.db
IDEAS_DB_PATH=data/ideas.db
RATE_LIMIT_ENABLED=true
RATE_LIMIT_REQUESTS=30
RATE_LIMIT_BURST=10
RATE_LIMIT_WINDOW_SECONDS=60
RATE_LIMIT_APPEAL_REQUESTS=5
RATE_LIMIT_APPEAL_BURST=2
RATE_LIMIT_APPEAL_WINDOW_SECONDS=60
LIST_RUNS_DEFAULT_LIMIT=20
LIST_RUNS_MAX_LIMIT=100
ENABLE_SEMANTIC_MEMORY=false
EMBEDDING_MODEL=ollama:nomic-embed-text
EMBEDDING_DIMENSION=768
ENABLE_REVOTE=true
MAX_REVOTE_SCORE_DELTA=3
MAX_RUN_SECONDS=600
Runtime When to use
local Default. Ollama via LOCAL_MODEL.
deepseek Cloud API via DEEPSEEK_API_KEY and langchain_deepseek.

Pick a model with solid instruction-following and structured output. If verdict validation fails, try a stronger instruct or tool-calling model.

Web research: optional Tavily search, gated by a model policy prompt (not keyword matching).

Semantic memory: set ENABLE_SEMANTIC_MEMORY=true and pull the embedding model (ollama pull nomic-embed-text by default). When enabled, similar past ideas are retrieved via sqlite-vector; otherwise memory falls back to recency.

Re-vote: set ENABLE_REVOTE=false to skip post-debate re-scoring (rollback to pre-revote behavior). MAX_REVOTE_SCORE_DELTA caps how far each judge can move their score in one re-vote (default 3).

Debate rounds: default is one dissent pass (MAX_DEBATE_ROUNDS=1). Raise only when you want longer multi-round argument (still capped in the UI/settings).

LangSmith observability

Tracing is opt-in. Set credentials in .env:

LANGSMITH_TRACING=true
LANGSMITH_API_KEY=your_langsmith_api_key
LANGSMITH_PROJECT=gavel

Legacy LANGCHAIN_TRACING_V2, LANGCHAIN_API_KEY, and LANGCHAIN_PROJECT are also supported.

Traces cover roast panel calls, LangGraph debate, re-vote, appeal flows, and experimental DeepAgents runs. Metadata includes execution flow, app version, and a privacy-safe idea_fingerprint (SHA-256 hash + 80-char preview). Full startup text is never sent.

Filter by tags such as phase:roast, phase:debate, phase:revote, phase:appeal, or flow:deterministic.

Run metrics (in-app): the deterministic Streamlit path and API SSE stream surface per-run cost and latency without opening LangSmith — roast, debate, and re-vote wall-clock, token totals, and a static DeepSeek/local cost estimate from src/observability/metrics.py. Token counts use provider metadata when available, otherwise a chars÷4 fallback. Assist funnel events are also logged for Case AI assists (src/observability/assist_events.py).

Using the app

Web app

  1. Open http://localhost:3000 — Landing. Start free goes to /workspaces/new.
  2. Create an idea via the Pitch wizard: fill guided fields step-by-step, or paste rough notes and use Draft from notes AI. Sharpen individual fields with Clarify.
  3. On Case, follow the primary next proof step: plan interviews, add evidence, start or continue an experiment, or update assumptions / beliefs.
  4. Edit the pitch under Pitch; each save creates a new version with a diff summary.
  5. When readiness passes (and optionally when review eligibility signals “why now”), open Reviews, check the readiness briefing, and Start review. Advanced settings (model runtime, debate rounds, web research) live under Settings.
  6. Watch the live run at /run/{runId}: review panel, debate transcript, re-vote argument changes, structured synthesis, and sources when research ran.
  7. After completion, Continue on Case for the next proof step. Pull additional handoff items into Case from Reviews when needed. Use Appeal with experiment context when you have results, or Revise pitch and re-run.
  8. Re-run with parent_run_id linked to the prior completed review; concern diffs show what moved.

Streamlit

  1. Enter a startup idea (optionally expand Optional details for target customer, pricing, traction, and competitors).
  2. Choose execution flow: Deterministic (production) or DeepAgents (experimental).
  3. Choose model runtime: local or deepseek.
  4. Optionally enable Web research (Tavily).
  5. Review verdicts (including recommended fixes), radar chart, debate transcript, re-vote deltas, structured synthesis card, and the run metrics footer on deterministic runs.
  6. Use Refine this idea to iterate on a pitch and see version-to-version score and concern deltas.
  7. Use Appeal Mode with the per-judge evidence checklist (LOIs, pilots, buyer persona, not persuasion alone).
  8. Download the Markdown transcript if needed (includes run metrics when available).

Memory

Stored at data/ideas.db. Streamlit uses a stable local user id (data/local_user_id via src/memory/identity.py); API runs use the same id so memory and similar-review lookup work across both UIs. Retrieval (src/memory/retrieval.py) prefers semantically similar past ideas when ENABLE_SEMANTIC_MEMORY=true; otherwise it uses the most recent entries. Context builder (src/memory/context.py) injects compact summaries (idea text, average score, top concerns, previous synthesis, appeal outcome). Full transcripts are never injected. The web app surfaces similar past reviews on the run page via GET /api/runs/{run_id}/similar. Founder constraints can quarantine memory ids without mutating Case rows.

Appeal mode

Founder appeal is sent to all five judges with the original idea, their baseline verdict (post-revote panel when re-vote ran), moderator synthesis, optional memory context, and appeal text. Optional target_judges labels which evidence asks the founder is answering; every judge still re-scores. Appeal coaching surfaces each judge's evidence ask before submission. Each judge returns a fresh validated Verdict; the UI shows whether targeted evidence moved the argument.

Pitch iteration

Workspaces version the Idea Validation Worksheet (POST /api/workspaces/{id}/versions). Reviews link to a workspace and worksheet version via workspace_id and worksheet_version_id. Optional parent_run_id chains refined reviews within a workspace. The UI compares concerns and recommended-fix status against prior versions and derives the next Case or review action from staged progress.

Migrating legacy runs: if you have pre-workspace runs in data/runs.db, run python scripts/migrate_runs_to_workspaces.py to group them into workspaces (use --dry-run first).

Repository layout

src/
  app.py                         Streamlit entry point (direct-submit reference UI)
  api/                           FastAPI streaming API (RunManager, WorkspaceStore, durable SSE log)
  pipeline.py                    Frontend-agnostic production pipeline
  config.py                      Model and app settings
  events.py                      Frontend-agnostic pipeline event types
  idea_context.py                Untrusted user-input wrapping for prompts
  judges/                        Schemas, guardrails, synthesis, single-judge service, panel
  debate/                        LangGraph graph, nodes, router, revote, state
  memory/                        SQLite store, semantic retrieval, lineage, prompt context
  appeal/                        Re-evaluation, synthesis, coaching hints
  validation/                    Case workbench: readiness, checklist, belief, eligibility, provenance, assists, handoff
  verification/                  Shared invariants and panel/re-vote quality checks
  research/                      Tavily web search (model-gated policy)
  orchestrator/deep_agent.py     Experimental DeepAgents path (Streamlit only)
  observability/                 LangSmith bootstrap; run metrics; assist funnel events
  ui/streamlit_runner.py         Streamlit pipeline adapter + metrics footer
  utils/                         Parser fallback, radar chart, transcript export
web/                             Next.js workbench (see web/README.md)
scripts/                         One-off utilities (e.g. migrate_runs_to_workspaces.py)
docs/                            Loop contract, product docs, design system, specs
tests/                           Unit tests (unittest, fake models, no Ollama required)
evals/                           Regression evals and monthly audit (see evals/README.md)

Development

pip install -r requirements-dev.txt
pre-commit install                # Ruff on every commit

python -m unittest discover -s tests
python -m compileall src
ruff check src tests evals
ruff format src tests evals

Web frontend (web/): npm run lint, npm run test:unit (reducer, coaching, synthesis, copy/UX lints, Case helpers, and more), npm run test:e2e:core, and npm run build (see web/README.md). Regenerate API types with npm run gen:types when backend schemas change.

CI (.github/workflows/ci.yml) runs on push/PR to main: Ruff lint and format, pinned deps, version resolution check, unit tests on Python 3.11-3.13, compile check.

Evals: see evals/README.md.

Tier When Command
0 (CI) Every PR python -m unittest discover -s tests
1 (Local) Before prompt/model changes python -m evals.run_eval --runtime local --full
2 (DeepSeek audit) Monthly (1st) or manual python -m evals.run_audit --no-reuse-last-local --baseline-only

Tier 1 checks structural reliability ($0, Ollama). Tier 2 uses one DeepSeek LLM-as-judge call per idea (~$0.50-2/month on committed baselines).

Version lives in pyproject.toml ([project].version); runtime reads it via src/version.py. Product positioning and surface ownership live in PRODUCT.md and docs/loop-contract.md.

Scope and limitations

Honest boundaries, not bugs. Current design:

V1 ships

  • Case-first Next.js workbench + FastAPI deterministic review pipeline
  • Local Ollama and/or DeepSeek; optional Tavily research
  • Single-box SQLite persistence (workspaces, runs, ideas)

V1 does not ship

  • Accounts / multi-user auth (local identity only)

  • Multi-worker API coordination

  • Streamlit as product UI (reference/dev only)

  • Cloud multi-tenant hosting defaults (Compose binds 127.0.0.1)

  • Case-first web app: Next.js is the primary UI (Landing, Ideas, Case, Pitch, Reviews, Run, Settings). Streamlit remains a direct-submit reference UI without Case support.

  • /history redirects to /workspaces (Ideas list); there is no separate history surface.

  • Memory identity is local-only, not account-based. A stable id in data/local_user_id is shared by Streamlit and the API.

  • Semantic retrieval and similar-review lookup are optional and local-only (ENABLE_SEMANTIC_MEMORY=true).

  • Readiness gate blocks reviews until the Pitch is specific enough; founders can override with readiness_override after reviewing checks.

  • Appeal re-evaluates judges against the post-revote baseline when re-vote ran; it does not run a second multi-round debate. API runs allow one appeal per run.

  • Re-vote quality depends on model instruction-following; weak local models may produce herded or unexplained score moves (the UI surfaces degradation hints).

  • Pitch iteration is explicit (revise Pitch + re-run), not auto-detected via semantic similarity.

  • Belief updates require a citation; they are not free-form “I feel better about this” notes.

  • Founder constraints personalize assist suggestions but are never auto-applied into Case rows.

  • SQLite storage is local-only (data/workspaces.db for Case, data/ideas.db for memory, data/runs.db for API runs).

  • Streamlit supports the experimental DeepAgents flow; the web app and streaming API use the deterministic pipeline only.

  • API runs need a single uvicorn worker per machine; multi-worker coordination is not implemented.

  • DeepAgents is experimental, not the production orchestrator.

Generated artifacts

data/workspaces.db
data/ideas.db
data/runs.db
data/local_user_id
transcripts/*.md
roast_radar.png

Runtime outputs. Keep out of commits unless you intentionally want samples.

About

Workspace for shaping startup ideas, collecting evidence, and running structured multi-agent judgment.

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages