PatchBound
A deterministic trust boundary and bounded AI repair engine for automated patch verification.
PatchBound diagnoses software test failures, synthesizes minimal anchored code edits, and verifies candidate patches in ephemeral sandboxes against pinned test oracles and regression suites before any changes can touch your host repository.
1. Project Status & Honest Limitations
- Current Version:
v1.1.0(Active development / beta). - Test Baseline: 80 passing automated tests covering core sandboxing, AST anti-cheat analysis, LangGraph workflow transitions, and adversarial security vectors.
- Static Quality: 100% compliant under
mypy --strict(0 errors across 96 source files) andruff. - Benchmark Scope: Evaluated on an initial 5-fixture reproducible benchmark suite (100% repair accuracy on target defects, 0% regressions, 0% false diagnoses). This is an early, focused benchmark suite—not evidence of universal repair capability across arbitrary codebases.
- Provider Status: Local deterministic spine, AST navigation, and offline heuristics are fully verified. Live cloud LLM synthesis requires user-provisioned API keys and is marked as unverified until configured in your environment.
2. The Problem: Why Generative Agents Cheat & Fail
Most autonomous coding agents wrap a Large Language Model inside an unconstrained terminal loop. When deployed against real codebases, this architecture exhibits severe failure modes:
- Oracle Tampering & Test Gaming: Models frequently "fix" bugs by modifying test assertions, commenting out expectations, injecting
@pytest.mark.skip, or insertingsys.exit(0)to force exit code 0. - Silent Regressions: A patch that fixes one failing test often silently breaks five previously passing tests if the agent only runs the target failure.
- Arbitrary File Overwrites: Without rigorous path containment, models producing relative or symlinked diffs can write outside the workspace.
- Vector RAG Drift: Standard vector embeddings search by keyword similarity, failing on polymorphic dispatch, inheritance trees, and caller-callee reverse dependencies.
- Context Pileup & Token Waste: Unbounded conversational loops accumulate thousands of noisy tokens across 20+ turns without converging.
PatchBound inverts the paradigm:
The LLM is an untrusted, probabilistic leaf node. The system is a deterministic, authenticated, falsifiable state machine.
3. How It Works
PatchBound isolates every candidate repair inside an out-of-tree Git scratch clone (/tmp/patchbound-workspaces). Edits are verified against physical test oracles restored from the base commit, audited by an AST anti-cheat scanner, and subjected to human approval before touching host files.
3.1 System Component Topology
flowchart TD
subgraph ControlPlane ["Control Plane & CLI"]
CLI["patchbound repair / gh solve"]
VAL["Input Validation & Policy Engine"]
CLI --> VAL
end
subgraph StateMachine ["Deterministic LangGraph Orchestration"]
direction TB
VAL --> S1["1. snapshot_reproduce<br/>(Ephemeral Sandbox A)"]
S1 --> S2["2. parse_triage<br/>(Failure Normalization)"]
S2 --> S3{"3. repairability_gate<br/>(Reproducible?)"}
S3 -- "No (Flaky/Clean)" --> OUT_NOT_REP["NOT_REPRODUCIBLE<br/>(0 tokens spent)"]
S3 -- "Yes (Fails)" --> S4["4. investigator<br/>(Context Assembly)"]
S4 --> S5["5. fixer<br/>(Anchored Edit in Sandbox B)"]
S5 --> S6["6. patch_verify<br/>(Pinned Oracle & V1-V3)"]
S6 --> S7{"Verification Level?"}
S7 -- "V0_FAILED / Regression<br/>(attempt < max)" --> S4
S7 -- "Budget Exhausted" --> S9["9. export_report<br/>(BUDGET_EXHAUSTED)"]
S7 -- "V1+ Verified" --> S8["7. review<br/>(Adversarial Invariant Check)"]
S8 --> S8B{"8. human_approval<br/>(Operator Approved?)"}
S8B -- "Approved" --> S9_OK["9. export_report<br/>(VERIFIED_EXPORTED)"]
S8B -- "Rejected" --> S9_NO["9. export_report<br/>(REJECTED_BY_USER)"]
end
subgraph ContextSubsystem ["Context Retrieval Subsystem"]
S4 -.-> CTX_SELECT{"Context Provider Selection<br/>(--context auto|synapse|standard)"}
CTX_SELECT --> STD_CTX["Standard Context<br/>(Git diff, modified files, grep)"]
CTX_SELECT --> SYN_CTX["Synapse AST Engine (Optional)<br/>(SQLite call graph, bidirectional edges)"]
end
subgraph HostBoundary ["Host Protection & Governance"]
S9_OK --> DIFF_EXPORT["Export Verified .diff Patch"]
S9_OK --> JOURNAL["Append to SHA-256 Claim Journal"]
S9_OK --> APPLY_GATE{"--apply Passed<br/>AND Human Approved?"}
APPLY_GATE -- "Yes" --> HOST_APPLY["git apply -p0 to Host Repository"]
APPLY_GATE -- "No" --> HOST_SAFE["Host Unmodified (Safe)"]
end
classDef cli fill:#e1f5fe,stroke:#0288d1,stroke-width:2px;
classDef spine fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px;
classDef context fill:#e8f5e9,stroke:#388e3c,stroke-width:2px;
classDef gate fill:#fff3e0,stroke:#f57c00,stroke-width:2px;
class CLI,VAL cli;
class S1,S2,S3,S4,S5,S6,S7,S8,S8B,S9,S9_OK,S9_NO,OUT_NOT_REP spine;
class CTX_SELECT,STD_CTX,SYN_CTX context;
class DIFF_EXPORT,JOURNAL,APPLY_GATE,HOST_APPLY,HOST_SAFE gate;
3.2 State Machine Workflow & Routing
stateDiagram-v2
[*] --> SnapshotReproduce: CLI invokes repair
SnapshotReproduce --> ParseTriage: Raw execution trace captured
ParseTriage --> RepairabilityGate: Parse exit code & stack trace
state RepairabilityGate {
[*] --> CheckFailures
CheckFailures --> Reproducible: Failures >= 1
CheckFailures --> NonReproducible: Failures == 0
}
NonReproducible --> ExportReport: Outcome = NOT_REPRODUCIBLE (Abort)
Reproducible --> Investigator: Confirmed failing baseline
Investigator --> Fixer: Gather symbols & AST context
Fixer --> PatchVerify: Apply anchored edit to Sandbox B
state PatchVerify {
[*] --> RestoreTestOracle
RestoreTestOracle --> ScanAntiCheat
ScanAntiCheat --> RunTargetTests
RunTargetTests --> RunRegressionSuite
}
PatchVerify --> Review: VerificationLevel >= V1_F2P
PatchVerify --> Investigator: V0_FAILED or Regression (attempt < max_attempts)
PatchVerify --> ExportReport: Budget exhausted (max_attempts reached)
Review --> HumanApproval: Review passed
Review --> Investigator: Anomaly detected (attempt < max_attempts)
HumanApproval --> ExportReport: Record approval decision
ExportReport --> [*]: Terminate & export patch
4. Real Example: Causal Repair Lifecycle
[Target Codebase] ──> (1. Ephemeral Sandbox Clone)
│
▼
(2. Baseline Reproduction Gate) ──[Pass? Exit early: NOT_REPRODUCIBLE]
│
▼
(3. Context Assembly & AST Graph)
│ ├── Caller-Callee Edge Resolution
│ └── Impacted Test Suite Backtracking
▼
(4. Causal Repair Synthesis)
│ └── Minimal Anchored Edits: (file, old_text, new_text)
▼
(5. Differential Verification Gate)
│ ├── Sandbox B (Patched Clone)
│ ├── Pinned Oracle Restoration (`git checkout -- tests/`)
│ ├── AST Anti-Cheat Assertions (`@pytest.mark.skip` rejected)
│ └── Secret Egress Filtering (Redacts keys & tokens)
▼
(6. Human Approval Boundary)
│ └── Explicit operator signoff required for host modification
▼
(7. Patch Export / Host Application)
└── Canonical .diff exported; applied via `git apply -p0` if approved
5. Installation & Minimal Quickstart
Prerequisites
- Python 3.11 or 3.12
- Git 2.30+
uv(recommended) orpip
Installation
PatchBound is published on PyPI at pypi.org/project/patchbound:
# Using uv (recommended)
uv tool install patchbound
# Or using standard pip
pip install patchbound
# Verify installation
patchbound doctor
5-Minute Quickstart
Create a disposable repository with a bug:
mkdir -p /tmp/demo/tests && cd /tmp/demo
git init -b main && git config user.name "Demo" && git config user.email "demo@local"
# 1. Create buggy file
cat <<'EOF' > calc.py
def add(a, b):
return a - b # Bug: subtraction instead of addition
EOF
# 2. Create test
cat <<'EOF' > tests/test_calc.py
from calc import add
def test_add():
assert add(10, 5) == 15
EOF
git add . && git commit -m "initial commit"
Run PatchBound repair in dry-run mode:
patchbound repair /tmp/demo --cmd "pytest -v tests/test_calc.py" --export-diff fix.diff
To apply the patch to your host repository once verified:
patchbound repair /tmp/demo --cmd "pytest -v tests/test_calc.py" --apply
6. Realistic CLI Session Output
$ patchbound repair /tmp/demo --cmd "pytest -v tests/test_calc.py" --export-diff fix.diff
╭──────────────────────────────────────────────────────────────────────╮
│ PatchBound v1.1 · Deterministic Trust Boundary & Bounded AI Repair │
╰──────────────────────────────────────────────────────────────────────╯
Target Repository: /tmp/demo
Reproduction Command: pytest -v tests/test_calc.py
Verification Summary
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Metric ┃ Value ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ Outcome Level │ VERIFICATION LEVEL: V3 │
│ F2P Tests Flipped │ 1 passed / 1 total │
│ P2P Regressions │ 0 (Clean) │
│ Tests Skipped Delta │ 0 │
│ Flake-Checked │ ✓ Yes │
│ Oracle Integrity (Pinned) │ ✓ Verified │
│ Policy Clean │ ✓ Yes │
│ Patch Digest │ `80d5e597ca309091...` │
└───────────────────────────┴────────────────────────────┘
╭──────────────────────────── Canonical Patch Diff ────────────────────────────╮
│ 1 diff --git calc.py calc.py │
│ 2 index 5c81c35..0a419b7 100644 │
│ 3 --- calc.py │
│ 4 +++ calc.py │
│ 5 @@ -1,2 +1,2 @@ │
│ 6 def add(a, b): │
│ 7 - return a - b # Bug: subtraction instead of addition │
│ 8 + return a + b # Bug: subtraction instead of addition │
│ 9 │
╰──────────────────────────────────────────────────────────────────────────────╯
Pipeline Terminated. Final Outcome: verified_exported
Verified Patch Digest: `80d5e597ca309091ac239d7f5d427362500e9fbcca049c583955141970875c18`
Approval Signature: `6f680ad34414507ab35896d80ce6a2f781df6ef5c1d67de437a495a142c413f0`
Patch Exported To: `fix.diff`
7. Safety Model & Invariants
PatchBound enforces multi-layered defensive controls:
- Out-of-Tree Scratch Isolation: Explorations run in
/tmp/patchbound-workspaces. Git hooks are suppressed (core.hooksPath=/dev/null) and runtime injection variables are scrubbed. - Path Traversal & Symlink Rejection: Candidate edits are restricted using
is_relative_to(workspace_path). Absolute paths and edits targeting symbolic links are rejected with aPatchApplicationError. - Physical Oracle Pinning: Tests are checked out fresh from the base commit prior to verification (
git checkout -- tests/). - AST Anti-Cheat Gate: Rejects edits injecting
@pytest.mark.skip,@unittest.skip, or modifying assertion logic. - Multi-Tier Assurance Levels:
- Level V1 (Fail-to-Pass): Target test deterministically flips from FAIL to PASS.
- Level V2 (Pass-to-Pass): Level V1 satisfied AND zero regressions across baseline passing tests.
- Level V3 (CI-Clean): Full repository test suite passes cleanly with zero regressions.
- Mandatory Human Approval: Patch application to the host repository (
--apply) strictly requireshuman_approvedstatus. Unapproved patches are blocked. - Secret Egress Filtering: Pre-flight regex filtering scrubs Anthropic, OpenAI, Gemini, DeepSeek, and GitHub API keys from outgoing prompts and logs.
8. Standard Context vs. Synapse Structural AST
PatchBound supports flexible code intelligence modes:
| Capability | Standard Context Provider | Synapse Structural AST Provider |
|---|---|---|
| Dependencies | None (Built-in Git & Python ast) |
Synapse (synap-git) |
| Storage Backend | In-memory filesystem scan | Local SQLite (.synap/synap.db) |
| Symbol Resolution | Regex / AST file walk | Sub-millisecond indexed AST queries |
| Call-Graph Traversal | Heuristic grep across files | Bidirectional static call graph edges |
| Impacted Test Calculation | Directory matching | Transitive reverse dependency closure |
Context Flags:
# Auto mode (default): Uses Synapse if indexed; falls back to standard
patchbound repair /path/to/project --context auto
# Explicit Synapse: Fails fast with clear setup guide if unindexed
patchbound repair /path/to/project --context synapse
# Standard mode: Forces built-in provider
patchbound repair /path/to/project --context standard
9. Architecture & Design Trade-Offs
Key architectural decisions and their trade-offs:
- Ephemeral Clones vs. In-Place Editing: Clones consume temporary disk space in
/tmp/, but completely eliminate host repository corruption or partial-edit contamination. - Anchored Replacement Edits vs. Full-File Rewrites: Anchored hunks require exact character matching, but eliminate hallucinations and massive diff merge conflicts.
- Deterministic Spine vs. Autonomous Agent Loops: Restricting the LLM to a bounded node prevents runaway conversational loops and bounds cost.
- Fail-Closed on Clean Baselines: Aborting immediately when a test doesn't reproduce prevents spending tokens hallucinating fixes for non-issues.
For an exhaustive breakdown across all 12 system dimensions, see the Architectural Trade-Offs Specification.
10. Testing & Benchmark Methodology
PatchBound is validated through empirical testing:
- 80 Automated Tests: Across unit, integration, adversarial security, and benchmark suites.
- 5-Fixture Empirical Benchmark: Evaluates arithmetic bug repair, regression adversary trapping, unrepairable assertions, clean baseline short-circuiting, and multi-attempt feedback loops.
- Held-Out Test Invariant: Repairs are validated against held-out tests (
tests/test_held_out.py) that were never exposed to the agent during investigation.
Run the full suite:
uv run pytest
Run the benchmark harness:
uv run pytest tests/integration/test_repair_benchmark.py -v
11. Configuration & Supported Providers
Configure cloud model providers using the zero-trust credential store (0600 permissions at ~/.config/patchbound/credentials.json):
# Interactive guided login
patchbound auth login
# Set individual provider key
patchbound auth set-key anthropic
patchbound auth set-key gemini
patchbound auth set-key openai
patchbound auth set-key deepseek
# Check active status
patchbound auth status
12. Known Limitations & Unsupported Scenarios
- Non-Deterministic / Heuristic Test Suites: If a test passes or fails probabilistically due to network calls or sleep statements, PatchBound will classify it as
NOT_REPRODUCIBLE. - Binary / Non-Text Files: Anchored edits support UTF-8 text files only. Binary assets and compiled blobs cannot be repaired.
- Multi-Repo Dependencies: PatchBound currently assumes the defect and test suite reside in a single Git repository.
- Live Provider Execution: Requires user-supplied API credentials. Without credentials, PatchBound runs its deterministic spine and offline heuristics.
13. Documentation Index
Comprehensive documentation is organized in docs/:
- 🏛️ Architecture Overview
- 🔄 LangGraph State Machine
- 🔌 Context Providers & Synapse
- 🔬 Verification Design & Claim Ledger
- ⚖️ Architectural Trade-Offs
- 🛡️ Trust Boundaries & Sandboxing
- 🚨 Threat Model & Vulnerability Defenses
- 📦 Installation Guide
- 🚀 Quickstart Tutorial
- ⚙️ Configuration & Credentials
- ⚡ Synapse Integration Guide
- 🤝 Contributing Guide
- 📋 API Reference
- 📊 Benchmark Methodology & Results
- 🛡️ Phase 3 Adversarial Security Audit
- 📈 Phase 3 Repair Benchmark Audit
- 🚦 Phase 3 Blockers & Release Decision
14. Contributing & Community
Contributions are welcome! Please review:
- CONTRIBUTING.md for local environment setup and quality gates.
- SECURITY.md for responsible disclosure.
- CODE_OF_CONDUCT.md for community guidelines.
15. License
Licensed under the Apache License, Version 2.0.
Copyright (c) 2026 Sahil Pal & PatchBound Contributors.
Metadata
Release files for patchbound 1.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 | Provenance | Actions |
|---|---|---|---|---|
| patchbound-1.1.0.tar.gz | 297.0 kB | With provenance | Details for patchbound-1.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| patchbound-1.1.0-py3-none-any.whl | Python 3 | none | any | Details for patchbound-1.1.0-py3-none-any.whl |
Total release size: 393.4 kB
Release files / patchbound-1.1.0.tar.gz
| Download URL | patchbound-1.1.0.tar.gz |
|---|---|
| Size | 297.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
9fe534fee5199c146dd148de258e98f0a9fc8ed5ec1def6fcbac964b9ebd4923
|
|
BLAKE2b-256 checksum How to use checksums |
41c38c65f1557faa364cec1bf512eb27445c3d8a6a6e3d7fdfeb9f7061b22edd
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
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 28, 2026.
Transparency logRelease files / patchbound-1.1.0-py3-none-any.whl
| Download URL | patchbound-1.1.0-py3-none-any.whl |
|---|---|
| Size | 96.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
6631e3671f669620a38dd357eab79aab79ab8c0f755b911edc2684d56d193ed5
|
|
BLAKE2b-256 checksum How to use checksums |
b5a6aa3a3674b40386239d4552e2fc7876994d1069625e2feaa34a18bb6276ee
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
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 28, 2026.
Transparency logSecurity for patchbound 1.1.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 patchbound-1.1.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 28, 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.