Skip to content

Repository files navigation

Theoria

Don't trust an LLM's answer — make it prove the answer, then have independent judges check every step of the proof.

Theoria is a verified-reasoning harness. Instead of asking a model a question and hoping the answer is right, Theoria makes the model produce a step-by-step proof of its answer — a chain of explicit state-to-state transitions, each carrying a justification — and then audits every transition with independent, skeptical judges. If every step survives the judges, Theoria marks the answer JUDGE-PASSED. If any step can't be justified, it declines rather than shipping a guess.

The point is calibration: a system that tells you when it knows — it judge-passes only the answers whose every step survives the judges, and declines the rest. On a text-only sample of HLE-Verified Gold (n=184), Theoria judge-passed 57% of the questions and declined the rest; of the ones it passed, 88% matched the answer key — rising to ~99%* once you credit cases where Theoria's answer was right and the key was wrong. Run it yourself and see.

*Strict floor is 88%. The 99% figure additionally counts answers that disagreed with the key but appear to have caught an error in the key as correct.

Heads up: I used an LLM to port my original implementation into this cleaner, public repo. It's been reviewed but not exhaustively tested — if you hit a bug, open an issue or ping me @theoriacy.


How it works

For each problem Theoria runs a loop of specialized LLM roles. See docs/ARCHITECTURE.md for the full picture; in brief:

  1. Solve — a solver answers the question (web search encouraged).
  2. Formalize — a formalizer rewrites the solution as a Proof: an initial_state plus steps, where each step is a new state justified by exactly one of three types — computation (an operation actually carried out), citation (a theorem/identity/definition), or problem_given (a fact from the problem text).
  3. Judge — every step is audited in parallel by a judge specialized to its justification type, plus a judge for the initial state. Judges are deliberately brutal: they recompute, web-search to verify citations, and reject hidden assumptions.
  4. Pedantry filter — re-examines each rejection: real error, or just nitpicking? Pedantic rejections are overridden.
  5. Convention lift — a surviving rejection gets one last check: does a single standard, citable domain convention fully resolve it? If so, the step is accepted under that explicitly-recorded assumption.
  6. Repair loop — anything still failing goes back to the formalizer, which fixes the proof or sends the solver back for a new answer.

A result is verified only if the initial state and every step are accepted.

The method lives in pipeline.py; every role's actual prompt is data in configs/defaults.yaml.


Requirements

This release runs on subscription access to two CLIs, not API keys:

  • Claude Code (claude) — runs the formalizer.
  • Codex (codex) — runs the solver and judges.

Both are required: every run uses Codex for the solver/judges and Claude for the formalizer.

  • Docker — each problem runs in its own hardened container.
  • Python ≥ 3.12 and macOS.

Why macOS (for now): the subscription path mounts your Claude credentials into the sandbox by reading them from the macOS Keychain. The Codex side is a plain ~/.codex bind-mount and is cross-platform, but the formalizer needs Claude, so macOS is currently required for the subscription path end-to-end. The API-key path below works on any OS and skips Docker entirely.

Running Theoria on the subscription path costs nothing beyond your existing Claude/Codex subscriptions — there are no API keys or per-call charges.


API-key mode (any OS, no subscription)

Skip the CLIs, the Keychain, and Docker — call the Anthropic and OpenAI APIs directly. Works on Linux, Windows, and macOS.

pip install -e ".[api]"               # adds the official SDKs
export ANTHROPIC_API_KEY=sk-ant-...   # formalizer (always Anthropic)
export OPENAI_API_KEY=sk-...          # solver + judges
theoria doctor                        # confirms both keys + SDKs
theoria hle 1 --api                   # API-key run

What --api does: stacks configs/api.yaml which routes the formalizer to Anthropic (Opus 4.7, adaptive thinking, xhigh effort) and every other role — solver, judges, pedantry, convention lift — to OpenAI (gpt-5.5, xhigh reasoning). Web search and code execution use each provider's server-side sandbox; no local Docker container is started.

Not the audited HLE configuration. The 88% / 99% / 57% numbers in the intro come from the subscription path with --docker + the Sage image. The API-key path uses the same prompts and pipeline but different model endpoints and a different code-execution sandbox, so results may differ. Grade with theoria grade to compare runs head-to-head.

--api is mutually exclusive with --docker. Override the per-role mapping with your own --config some.yaml stacked on top.


Quickstart

python3 -m venv .venv && source .venv/bin/activate   # Python ≥3.12 (3.13 matches the reference runs)
pip install -e .          # installs the `theoria` command + dependencies
theoria doctor              # check your setup (CLIs, Docker, images)
theoria build               # build the two Docker sandbox images
theoria hle 1               # reproduce HLE problem 1 (streams live by default)

theoria doctor tells you exactly what's missing and how to fix it. theoria build builds both sandbox images (theoria-sandbox and the Sage math/science variant theoria-sandbox-sage); the Sage image installs SageMath via conda, so its first build takes several minutes.

Results land in runs/<command>_<tag>_<timestamp>.json; full per-call artifacts (every prompt, response, tool call, and event stream) under runs/artifacts/. Both are gitignored.

Reproducing the HLE results

theoria hle runs the audited default configuration: every role on Codex except the formalizer (always Claude), --docker, the Sage image, and the default prompts. (The HLE-Verified dataset is pulled live from Hugging Face and isn't version-pinned, so upstream dataset edits can shift results over time.) To run a span of problems:

theoria hle --skip 100 --max 50 --tag myrun --watch

Each problem runs in its own container; --parallel N only changes throughput, not per-problem results.


Run your own question

Same engine, same setup as HLE — just pass a question with a definite, checkable answer:

theoria custom "Prove there are infinitely many primes"

Read and grade your results

# Render a run as readable markdown: a verified answer + its proof, plus a
# full trace of every attempt, judge verdict, and filter decision.
theoria show runs/custom_<timestamp>.json        # one run file at a time

# Grade answers vs. expected with an LLM grader (handles equivalent
# notations/forms) — a stronger check than the built-in `correct` substring
# flag, though still an LLM judgment, not ground truth.
theoria grade runs/hle_<timestamp>.json          # one run file at a time

theoria grade writes per-problem key_match + dispute_category to runs/grades/.


Configuration

theoria defaults to the audited HLE setup; advanced users can override individual knobs:

Flag Default Effect
--docker / --no-docker on Per-problem container isolation (keep on).
--image NAME sage Which sandbox image when Docker is on.
--config PATH none Stack an extra YAML on configs/defaults.yaml (repeatable).
--parallel N 1 Concurrency (does not affect per-problem results).
--watch / --no-watch on Stream live LLM events to stderr.

Stackable config presets in configs/: defaults.yaml (base — every role's prompt), sage.yaml, restricted.yaml (tool allowlists), tuned.yaml, audit_grader.yaml (the grader role).


Scope and honesty notes

  • The judges are LLMs. Verification is looped LLM auditing plus real tool/code execution in the sandbox — not a fixed formal proof checker. It raises the bar far above a single model's say-so; it is not a theorem prover.
  • The built-in correct flag is a naive substring check, for scanning only. The real signals are the verified flag and theoria grade.
  • Answers are extracted as the first element of the proof's final state; occasionally a correct conclusion sits behind a placeholder. Read the proof, not just the headline.
  • Every run records its exact models, CLI versions, and sandbox image in runs/artifacts/<run_id>/meta.json for reproducibility.
  • Grading. The bundled theoria grade shows the LLM grader slightly more per-attempt context than the internal audit grader it's ported from, so its grades may differ marginally on borderline cases — the JUDGE-PASSED/REJECTED verdict itself is unaffected.

Data & credits

HLE problems come from HLE-Verified (skylenage/HLE-Verified on Hugging Face) — an expert-verified version of Humanity's Last Exam. Theoria pulls it live from Hugging Face at runtime and does not redistribute it; consult the dataset's page for its own terms of use. By default Theoria uses the Gold subset, text-only.


License

Copyright 2026 Michael Saldivar. Released under the Apache License 2.0 — see LICENSE.

About

Deductive Reasoning System

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages