ordeal
Find a real failure. Keep it fixed.
Ordeal scans existing Python code with generated inputs, reproduces failures, and can turn a supported finding into a pytest regression. The first scan needs no test code or configuration.
See it find a bug
Given this function:
# risky.py
def average(values: list[float]) -> float:
"""Return the arithmetic mean."""
return sum(values) / len(values)
Run Ordeal without installing it:
uvx ordeal scan risky.py
The relevant part of the output is:
ordeal scan: risky
status: findings found
evidence cards:
- risky.average [supported]
claim: The recorded input reproducibly makes risky.average raise
ZeroDivisionError: division by zero.
witness: input={"values": []}
replay: verified (2/2 exact matches)
boundary: Same exception type, message, and terminal source location.
next: ordeal scan risky.py --save
supported is deliberately narrow. It means the same input reproduced the same
recorded failure during immediate replay. It does not prove the root cause,
untested behavior, or that a future fix works.
Run it on your project
pip install ordeal # or: uv tool install ordeal
cd your-project
ordeal scan . # auto-detect; write no project artifacts
A normal scan imports and executes target code. Isolate code that can send email, mutate production data, or call live services.
Keep the failure fixed
ordeal scan . --save
uv run pytest tests/test_ordeal_regressions.py -q # prove it fails before the fix
# fix the product code
ordeal verify <finding-id> --allow-unsafe-artifacts
ordeal verify --ci
Commit tests/test_ordeal_regressions.py with
tests/ordeal-regressions.json. The richer .ordeal/findings/ review history
may stay local.
The complete beginner workflow is:
scan → save one witness → fix → verify the same witness → guard it in CI
What the result means
| Result | Meaning | Next action |
|---|---|---|
supported |
The recorded failure matched during immediate replay | Save, fix, verify |
exploratory |
Interesting signal without the same replay support | Investigate; do not call it a proven bug |
expected |
The input violated a known precondition | Usually no product fix |
blocked |
Ordeal could not construct enough of the target | Inspect targets or add a harness |
no findings yet |
Nothing failed in the sampled run | Useful evidence, not a correctness proof |
Each scan also emits a reliability map from source-backed retry, recovery, I/O,
transaction, and ML/data seams to candidate properties. PASS,
NOT EXERCISED, and FAIL describe the observed operation × fault × property
evidence; mined properties remain hypotheses. Use --deepen --time-limit 60
for one safe planned follow-up, or --base-ref origin/main to prioritize
changed operations. Fault probes close only their narrow operational cell after
the named injection boundary is actually reached.
Why Ordeal
- No test boilerplate for the first signal. Point it at a project, module, Python file, or callable.
- Evidence instead of a generic warning. A supported finding binds the source, exact input, exception seam, and replay result.
- A bug can become protection.
--saveproduces the review bundle and, when the witness is renderable, a durable pytest regression.
Start with the Scan Quickstart. If a method needs setup or state, continue to Object Harnesses. The Durable Regression Workflow and CI guide cover the full red-fix-green loop.
Advanced workflows
Use these only when the default scan or your specific goal requires them.
| Goal | Start here |
|---|---|
| Judge whether tests detect real changes | Test Protection |
| Write a custom stateful chaos test | Custom Chaos Tests |
| Exercise long-lived services | Service Evidence Loop and Compose Evidence Loop |
| Put service recovery in CI | Compose CI and operations |
| Compare two functions | Differential Quickstart and Divergence Evidence |
| Compare committed revisions | Revision Diff, troubleshooting, and schema |
| Compare a stateful refactor | System Differential Testing |
| Replace a module without preserving old bugs | Safe Migrations and Migration Workflow |
| Inspect every command or Python type | CLI reference and API reference |
AI coding agents
Ordeal ships with AGENTS.md, which teaches coding agents to start with the same scan-first workflow and keep advanced commands behind an explicit need.
Development
git clone https://github.com/teilomillet/ordeal
cd ordeal
uv sync --locked --extra dev
uv run pytest
See CONTRIBUTING.md and CHANGELOG.md.
License
Apache 2.0
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ordeal-0.3.42.tar.gz.
File metadata
- Download URL: ordeal-0.3.42.tar.gz
- Upload date:
- Size: 886.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bb87873e62986a7a215c6fd9f4fb3a1ff151bb5e566a58023b2a5e17047ee3ba
|
|
| MD5 |
543f4ba624b9d513731f88b28ff22fad
|
|
| BLAKE2b-256 |
5195c308be2b7fcfda01a6206f8a71686d081f4c1d68b30dac4595c0b2eb9725
|
Provenance
The following attestation bundles were made for ordeal-0.3.42.tar.gz:
Publisher:
ci.yml on teilomillet/ordeal
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ordeal-0.3.42.tar.gz -
Subject digest:
bb87873e62986a7a215c6fd9f4fb3a1ff151bb5e566a58023b2a5e17047ee3ba - Sigstore transparency entry: 2138851005
- Sigstore integration time:
-
Permalink:
teilomillet/ordeal@c729d4f395db9ea720a96841ef3b4fa77ec61c96 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/teilomillet
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
ci.yml@c729d4f395db9ea720a96841ef3b4fa77ec61c96 -
Trigger Event:
push
-
Statement type:
File details
Details for the file ordeal-0.3.42-py3-none-any.whl.
File metadata
- Download URL: ordeal-0.3.42-py3-none-any.whl
- Upload date:
- Size: 649.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b64622344d43bc9a5294f58e8531c2eb9d4064b9c661c02039162e7ef323edb9
|
|
| MD5 |
514b3ad3977b4d4fbdc42576ee02ee69
|
|
| BLAKE2b-256 |
83fc25be9de86ae59e416b7a4f0b77abdecbcc429d75f2622ad88f2643e69a4f
|
Provenance
The following attestation bundles were made for ordeal-0.3.42-py3-none-any.whl:
Publisher:
ci.yml on teilomillet/ordeal
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ordeal-0.3.42-py3-none-any.whl -
Subject digest:
b64622344d43bc9a5294f58e8531c2eb9d4064b9c661c02039162e7ef323edb9 - Sigstore transparency entry: 2138851012
- Sigstore integration time:
-
Permalink:
teilomillet/ordeal@c729d4f395db9ea720a96841ef3b4fa77ec61c96 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/teilomillet
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
ci.yml@c729d4f395db9ea720a96841ef3b4fa77ec61c96 -
Trigger Event:
push
-
Statement type: