Ratchet
Ratchet turns observed agent failures into tested, signed guard changes.
When an agent fails, Ratchet writes a guard: a small rule that checks each tool call before it runs. It adopts the guard only after a replay (rerunning recorded past conversations through it) and fresh tests on held-out cases (test cases the improver never sees). Each decision is a receipt, a signed record anyone can verify offline.
It is for teams running tool-using agents that touch money, accounts or tickets, and need a fix to a failing agent to be proven before it ships.
Install
git clone --branch probity-ratchet-v0.2.0 https://github.com/probityai/probity && cd probity/packages/ratchet
uv sync
Python 3.12 or later. The guard sandbox needs Linux.
pip install probity-ratchet-cases==0.2.0 && ratchet-cases selftest # the case suite alone: probity-ratchet-cases/README.md
Try it in 30 seconds
No database, no model key. This guard stops force pushes to main. It is a single standard-library file, exported from an admitted guard, and it is a Claude Code hook (a script run before each tool call). It denies the call:
echo '{"hook_event_name": "PreToolUse", "tool_name": "Bash", "cwd": ".", "tool_input": {"command": "git push --force origin main"}}' \
| python3 examples/claude-code/hooks/ratchet_no_force_push_main.py; echo "exit $?"
blocked by guard no-force-push-main: force push to main rewrites shared history; push a branch and open a pull request instead
{"hookSpecificOutput": {"hookEventName": "PreToolUse", "permissionDecision": "deny", "permissionDecisionReason": "blocked by guard no-force-push-main: force push to main rewrites shared history; push a branch and open a pull request instead"}}exit 2
Before export, the guard was replayed over six recorded Claude Code sessions: it fired on the three calls it was written for and on none of the other twelve (examples/claude-code/replay.json). The hook's header names the receipt (the signed decision) that admitted it; uv run python -m ratchet.export.claude_code --verify examples/claude-code/hooks/ratchet_no_force_push_main.py checks that receipt.
A signed refusal you can check offline is in examples/refusal-v3-cell/: uv run python examples/refusal-v3-cell/verify.py regrades 80 executions and prints decision verified, candidate refused, reason: identity controls breached. "Decision verified" is not "candidate accepted": it says the signed record is genuine, and here the record is a refusal. It is single-cell evidence from one run by the operator.
What it does
A support agent works in a simulated company: a billing provider, tickets, approvals and mail. Its eight case families are seven kinds of trap, each with benign twins (matching cases where the action is allowed, so a rule that blocks them fails), plus ordinary requests that must succeed. Every case is graded on the final state of every system, never on the agent's words.
When the agent fails, the improver proposes a guard or a procedure (written steps for the agent). A change is adopted only if four checks pass: replay; fresh paired tests on held-out cases against the parent harness (the code around the model: prompt, tools and rules); no growth of the agent's authority; and a signed receipt, which verifies offline against a pinned public key. The gates are in docs/ADMISSION.md. Every version, trace, evaluation and decision, rejections included, lives in MongoDB Atlas.
Status
Version 0.2.0, built on 2026-10-11 at the MongoDB harness hackathon. The suite, graders and rule are frozen before each run. Measured results, with denominators, are in docs/RESULTS.md.
Docs
| Page | What is in it |
|---|---|
| Running | Local Atlas, environment and every command |
| Admission rule | The gates in plain words |
| k-session rule | The replicated rule, runner and offline check |
| Architecture | Packages, guard sandbox, storage |
| Verifying a decision | Check a receipt offline |
| Results | Every measured result and its records |
| Claude Code hook | Prove a guard on your own sessions, then install it |
| Built today and reused | What was written at the event and what is pinned |
| Signed refusal example | Check a refused candidate offline |
| Build contract | Types, lane interfaces and the full admission rule |
Metadata
Release files for probity-ratchet 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| probity_ratchet-0.2.0.tar.gz | 1.8 MB | With provenance | Details for probity_ratchet-0.2.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| probity_ratchet-0.2.0-py3-none-any.whl | Python 3 | none | any | Details for probity_ratchet-0.2.0-py3-none-any.whl |
Total release size: 2.4 MB
Release files / probity_ratchet-0.2.0.tar.gz
| Download URL | probity_ratchet-0.2.0.tar.gz |
|---|---|
| Size | 1.8 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
4428a3e9d42c394563b06f61449edb11ceccfc87f9b3304d55777a3d28c5e260
|
|
BLAKE2b-256 checksum How to use checksums |
aa71f3fb4538eaa87cfd79efc094641d9581800d6e6fc62af93b86f7d39da713
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 20, 2026.
Transparency logRelease files / probity_ratchet-0.2.0-py3-none-any.whl
| Download URL | probity_ratchet-0.2.0-py3-none-any.whl |
|---|---|
| Size | 517.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
698c31f0240627c8f099ddfcace5b764201f4bcce6e8a8e7373abd45e58c9f96
|
|
BLAKE2b-256 checksum How to use checksums |
af12ddc7ba7401a738c668c7cdbd6274d9277853f5e8cadaed0f0f5d1d75199c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 20, 2026.
Transparency logSecurity for probity-ratchet 0.2.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
Both files in this release have been uploaded with provenance metadata.
Attestation for probity_ratchet-0.2.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 20, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.