OddsFox is free and open-source software (FOSS), released under the MIT License.
OddsFox is a local compiler and verifier for prediction-market contracts. It produces traceable formal interpretations and verified relationships, helping researchers compare contract meanings and inspect settlement differences. Its primary compiler output is a public, versioned semantic IR exported as canonical JSON; see the IR contract. Symbolic probability constraints are derived outputs of verified semantics. Global probability coherence and larger constraint graphs are downstream extensions. The repository now includes a runnable local implementation. Release readiness still depends on the local unanimous-consensus gates in the product specification. Synthetic examples and passing software tests do not establish those results. Unanimous local models are not independent human review and do not establish natural-language truth.
Install uv, then:
uv sync --locked
uv run oddsfox serveOpen http://127.0.0.1:8777. The home page discovers open events from Kalshi and
Polymarket International, with a default lifetime-volume
threshold strictly above $100,000 per venue event. All active markets in a qualifying
event are included. Kalshi volume is USD face-value notional; Polymarket International
uses reported USD turnover. Missing lifetime totals appear in Volume unknown.
Discovery runs on startup and every 15 minutes while the server runs. The session token printed in the terminal authorizes Refresh now, pause/resume and review changes. Partial scans and failures remain visible; last successful data is retained. Use venue/category/analysis filters and open an event to inspect its captured rules.
For automatic local explanations, install the optional model runtime and provide an explicitly downloaded quantized model:
uv sync --locked --extra model
uv run oddsfox serve --model /path/to/quantized-mlx-modelExplanations and cross-venue match suggestions are unreviewed AI outputs, with captured citations and explicit gaps. They are not verified equivalences. No model is downloaded automatically and there is no cloud fallback. Initial processing can take hours; source chunks are cached and progress appears as work completes.
One-shot discovery is also available with uv run oddsfox sync, optionally limited
by --venue kalshi or --venue polymarket.
Use one process per dataset; stop the server before invoking offline CLI commands.
The public venue endpoints require no trading credentials, but network access or
venue-side restrictions can prevent a scan; the app reports these failures.
See executed validation and coverage limits.
uv run oddsfox --data .oddsfox/demo demo
uv run oddsfox --data .oddsfox/demo serve --no-syncOpen http://127.0.0.1:8777/research for the synthetic contract/review demonstration.
Use an empty directory for a new demo. demo --approve-synthetic is available for
automated checks; synthetic approvals are never consensus or independent-human
benchmark evidence.
The review workspace also remains available from the event browser. Event details
link each captured contract version to /research?contract=<contract-version-id>.
- Capture a bounded list of native market IDs with the report or
uv run oddsfox capture kalshi <ticker> .... Alternatively,uv run oddsfox import polymarket market.jsonpreserves an exact local payload. Referenced documents can be supplied with--documents documents.json, a list of{ "url": "https://...", "text": "...", "status": "captured" }records.statusmay beinaccessiblewithouttext. A later inaccessible refetch of a previously captured official URL keeps the last governing document bytes; it does not mint a new contract version. Missing governing documents prevent approval. A contract already captured through event discovery must also be refreshed through discovery; a child-only import or capture cannot discard its known parent rules. Existing manual-only captures and imports retain their original workflow. - Register an exact reviewed observation with
uv run oddsfox register <stable-name> observation.json --reviewer <name> --rationale <reason>. The observation initially has null canonical IDs. The registry fixes every other field. The API also supports explicitly reviewed aliases with exact, positive unit conversions; model suggestions never merge definitions. - Obtain a draft through the report or
oddsfox draft <contract-version-id>. Save candidate IR withoddsfox interpret candidate.json. Each populated semantic leaf needs source evidence. Corrections create new interpretations and invalidate dependent approvals and claims. Restoring earlier candidate content creates a new revision requiring fresh review. Referenced normalization rules remain dependencies even if the canonical identity is corrected; withdrawing a rule makes its dependent interpretations and accepted claims stale. - Review through the report or
oddsfox review <interpretation-id> --approve --governing-material-complete --reviewer <name> --rationale <reason>. Omitting--approverejects or withdraws an interpretation and vetoes model consensus.oddsfox compareproduces provisional proposals;oddsfox publishchecks current human reviews or, when--allow-consensusis set, current unanimous producer-panel approvals, plus dependencies, before accepting them. Consensus publication is off by default. Record a producer-panel approval withoddsfox consensus-approve <interpretation-id> --producer-model ...(at least three disjoint local models). That command never writes a humanreviewrecord. Enable server-side publication with--enable-consensus-publication. - Export with
oddsfox export --output research.json, oroddsfox export --format parquet --output accepted.parquetfor current accepted assertions.--historyexplicitly includes obsolete JSON records. Refresh a source using capture again; governing-content changes make affected conclusions stale while their evidence remains available.
Parquet files store accepted assertions as rows and the JSON export's version,
configuration, supporting records and freshness in the oddsfox footer metadata.
This metadata is present even for an empty export; DuckDB exposes it through
parquet_kv_metadata('accepted.parquet').
Prefix these commands with uv run; use --data <directory> before the command
to select a dataset. oddsfox --help lists all commands. The local OpenAPI contract
is at /openapi.json; all API mutations require X-Oddsfox-Token. Only the exact
loopback host and origin are accepted. Imported text is rendered as text.
V1 reasoning uses exact rational arithmetic for finite threshold predicates over
a shared real-valued observation. The supported method is instantaneous.
Interval averages, maxima and unresolved methods remain unsupported. cvc5 checks
the supported encodings and probability constraints. Settlement policy prose is
not executable: the initial settlement rule produces explicit conditions for
ordinary binary resolution. Shared native outcome IDs must have matching
true-branches; inverted YES/NO maps are settlement DIFFERENT and stay in
observed-event scope. Disjoint ordinary-binary IDs (cross-venue tokens) remain
conditional. Each condition names the exact pair of contract
versions, so differently conditioned pairs cannot share probability variables or
chain into a settlement claim. Observed-event claims remain a distinct scope,
with sparse edges over both provisional and reviewed interpretations. Settlement
pairs are evaluated directly. Background comparisons retain progress per canonical
observation and process bounded batches across the complete group. The dataset is
not capped at 250 contracts; explicit capture requests remain bounded to 250 IDs.
GET /api/report includes at most 250 current comparison rows and sets
comparison_coverage when more exist; GET /api/comparisons remains paginated.
The legacy bounded candidate helper retains its limits for evaluation callers.
uv sync --locked --extra model
uv run oddsfox compile <contract-version-id> /path/to/quantized-mlx-model
# One explanation model; panels are separate flags:
uv run oddsfox serve --model /path/to/quantized-mlx-model \
--producer-model /path/to/producer-a --producer-model /path/to/producer-b --producer-model /path/to/producer-c \
--evaluator-model /path/to/evaluator-a --evaluator-model /path/to/evaluator-b --evaluator-model /path/to/evaluator-c
uv run oddsfox validate --output /path/to/new-bundle \
--producer-model /path/to/producer-a --producer-model /path/to/producer-b --producer-model /path/to/producer-c \
--evaluator-model /path/to/evaluator-a --evaluator-model /path/to/evaluator-b --evaluator-model /path/to/evaluator-cPass a single --model for explanations. Every panel model directory must have an
adjacent operator-controlled <directory>.oddsfox-lineage.json that binds its
declared architecture and lineage to a weights-only content digest. Keeping the
approval outside the downloaded model package prevents model files from
self-attesting review. Producer and evaluator panels must
each contain at least three distinct lineages and weight sets with no overlap.
validate stages, verifies, and atomically publishes a create-only hashed evidence
bundle. Consensus publication stays off until
oddsfox publish --allow-consensus.
Model weights are separate downloads. OddsFox hashes their files and records
quantization, reviewed lineage, architecture, weights-only and full-directory
digests, chat-template hash, runtime, prompt, schema and decoding settings for
each job. Initial
generation is serialized, with an 8 GiB MLX allocation limit and at most 8,192
generated tokens. A 300-second budget is checked between prefill/decode steps;
it is not a hard deadline for model loading or a stalled native backend.
The normal path uses an Outlines grammar for the IR structure, valid evidence
field names, and captured source-line spans (at most 256 lines). Large string and
array size limits are enforced by the complete public IR validator afterward,
avoiding excessive decoder automaton expansion. The explicit
--unconstrained option creates a different recorded configuration. Invalid model
outputs or invalid citations remain failed attempts with raw evidence. Citation
artifact IDs and Unicode offsets are checked against the captured source. There is no external inference
fallback or automatic approval. replay revalidates a stored response without
running inference. Inspect status for failures, pending work and measurements.
The selected local model passed a synthetic compilation smoke with 26 evidence
fields. Real-contract accuracy and the local unanimous-consensus release gates remain
unevaluated; see the validation record.
- Public JSON Schema and consumer conformance notes.
- Benchmark format and release procedure, with explicitly synthetic v3 and v4 fixtures. v3 remains compatibility-only; v4 is the consensus schema.
- Stop the server, then
oddsfox backup /path/to/new-backup. Restore into a new dataset withoddsfox --data /path/to/new-dataset restore /path/to/backup. Backups verify all database-referenced artifacts and hashes before publication. - Implementation validation record distinguishes executed software checks from outstanding product gates.
- Product specification: user, workflow, scope, and acceptance criteria.
- Technical specification: semantics, verification, and system behavior.
- Technology stack: local implementation and deployment choices.
This repository uses Universal Pad for engineering work. Agent workflow and repository-specific verification are documented in AGENTS.md and PROJECT_AGENT.md.
Install Node.js 22 or newer for the browser JavaScript regression test; it uses Node’s built-in test runner and requires no npm packages.
Run scripts/verify-fast during development and scripts/verify before completing
work. The latter runs lint, formatting, type checks, tests, schema drift checks and
a package build. A fresh clean-checkout scripts/verify run is the authoritative completion
gate. GitHub Actions is not used because hosted Actions are unavailable to the free
organization. The latest verified baseline is 274 passing tests with two upstream
dependency deprecation warnings; model and product benchmarks also remain local.
Original OddsFox source code and documentation in this repository are licensed under MIT. See LICENSE for the full terms.
Third-party dependencies, model weights, and market data retain their respective licenses and terms; this repository's MIT license does not relicense them.
Bundled Inter and JetBrains Mono variable fonts remain under the SIL Open Font
License, Version 1.1. See src/oddsfox/static/OFL-Inter.txt and
src/oddsfox/static/OFL-JetBrainsMono.txt. The OddsFox mark is a trademark and
brand asset; it is included for product identification in this application and is
not licensed under MIT.
New datasets use database version 4. Existing versions 1–3 require an explicit migration before the server or ordinary CLI commands can open them. Stop OddsFox, then run this once for each dataset (the backup directory must not exist):
uv run oddsfox --data .oddsfox migrate --backup ../oddsfox-pre-v4-backupThe migration verifies a complete backup before permanently removing retired Polymarket US data and dependent results from that dataset. Kalshi and International records, shared evidence and model weights are retained. Interrupted artifact cleanup resumes on the next startup. If migration fails before commit, the database changes roll back; if cleanup fails afterward, startup resumes cleanup before processing jobs. The command reports the backup location and deletion counts.
Restore into a new directory with oddsfox --data /path/to/new-dataset restore /path/to/backup. Restore preserves the backup's schema and never changes the source;
legacy restored datasets require the migration command before use with this release.
For rollback to the old application, use the preserved pre-upgrade backup with that
release. Database versions are independent of Semantic IR 1.0.0.
A code/model/configuration upgrade can still invalidate current conclusions under the existing reproducibility policy. Volume/status-only refreshes do not invalidate unchanged governing interpretations. Source history increases disk use over time.