PatchProof
Deterministic exploit repro + AI patch verification engine. Bridging the gap between "we found a bug" and "we proved the fix works."
PatchProof takes a target source tree and a Proof-of-Concept exploit (curl,
raw HTTP, Nuclei template, Python script), spins up an ephemeral Docker
sandbox, confirms the exploit reproduces (🔴 Red), iteratively asks an
LLM to draft a fix, hot-reloads the app, re-runs the exact same PoC, and
emits a verified .patch + regression test + signed attestation when
the exploit is blocked (🟢 Green) without breaking the rest of the test
suite.
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Ingest PoC │ → │ Sandbox │ → │ Red state │
└─────────────┘ └─────────────┘ └──────┬──────┘
▼
┌───────────────┐
│ AI patch loop│
│ (≤N attempts)│
└──────┬────────┘
▼
┌──────────────────────────────┐
▼ ▼
┌─────────────┐ ┌─────────────┐
│ Still red? │ │ Green ✔ │
│ refine… │ │ regression? │
└─────────────┘ └──────┬──────┘
▼
┌───────────────────────────┐
│ fix.patch + regression │
│ test + signed attestation │
└───────────────────────────┘
Install
PyPI/npm name:
patchproof-repro(thepatchproofnames were taken). Import aspatchproof, run aspatchproof.
pip install patchproof-repro
# or from source:
git clone https://github.com/purvanshbhatt/patchproof
cd patchproof
uv pip install -e '.[all]' # or: pip install -e '.[all]'
Requires a running Docker daemon.
CLI
patchproof --help
patchproof run --app ./tests/fixtures/vuln-fastapi-sqli/app \
--poc ./tests/fixtures/vuln-fastapi-sqli/poc.txt
patchproof run --app ./my-app --poc ./sqli.curl --max-attempts 5 --model gpt-4o-mini
patchproof verify --app ./my-app --poc ./sqli.curl --patch ./fix.patch
patchproof init # scaffold ./patchproof.toml
Run artifacts land in patchproof-out/<run-id>/:
fix.patch ← drop-in git diff
attestation.json ← signed evidence (target SHA + PoC SHA + verdict)
evidence/red.json ← red baseline response
evidence/attempt_<n>.json ← every retry
test_security_patchproof.py ← regression test, ready for CI
Use as a library
from pathlib import Path
from patchproof.pipeline import Pipeline
Pipeline(
app_path=Path("./my-app"),
poc=Path("./sqli.curl"),
max_attempts=5,
model="gpt-4o-mini",
).run()
MCP server (Cursor / Claude Code)
{
"mcpServers": {
"patchproof": {
"command": "python",
"args": ["-m", "patchproof.mcp.server"],
"cwd": "<path to patchproof checkout>"
}
}
}
Tools exposed:
patchproof_run(app_path, poc_path, hardcoded_patch?, max_attempts?, model?)patchproof_verify(app_path, poc_path, patch_path)
CI / pre-commit
- GitHub Actions: see
examples/github/patchproof.yml. - pre-commit hook: see
examples/hooks/pre-commit(symlink into.git/hooks/).
Architecture
| module | role |
|---|---|
ingest.normalize |
curl / raw HTTP / Nuclei / Python → normalized PoC |
sandbox.app_spec |
Detect runtime + framework, pick base image & reload cmd |
sandbox.docker |
Ephemeral container, hot-reload, exec PoC, run tests |
patch.locator |
tree-sitter / regex → most likely vulnerable file:line |
patch.llm |
LiteLLM → unified diff |
patch.apply |
git apply (or hand-rolled) + snapshot rollback |
regression.runner |
docker exec the framework test suite |
report.attestation |
JSON evidence + optional ed25519 signature |
report.tui |
Rich live display |
Development
uv pip install -e '.[dev]'
pytest -m 'not integration' # unit tests (no Docker)
pytest # all tests (needs Docker)
ruff check src tests
License
Apache-2.0.
Metadata
Release files for patchproof-repro 0.1.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 | |
|---|---|---|---|
| patchproof_repro-0.1.0.tar.gz | 23.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| patchproof_repro-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 49.6 kB
Release files / patchproof_repro-0.1.0.tar.gz
| Download URL | patchproof_repro-0.1.0.tar.gz |
|---|---|
| Size | 23.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
64019370b719481d679720646ff14a7f3474b57b835ac1a332227135fc5344c2
|
|
BLAKE2b-256 checksum How to use checksums |
34e8140313278c5c152e9c0d3cba895b510dd531310d42ddff3cb25fc7a39174
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.3
|
Release files / patchproof_repro-0.1.0-py3-none-any.whl
| Download URL | patchproof_repro-0.1.0-py3-none-any.whl |
|---|---|
| Size | 26.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
2686a7451e2668e7d6f68917df08b00e9e71c2ca401260fd5a98d81d6f05f6e7
|
|
BLAKE2b-256 checksum How to use checksums |
8318ed8de6289de6eb5cf05e5b36b78e41bac9741c8144f0ec6c450cdba8a5c9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.3
|