This release has been yanked by its maintainers, and will be ignored by installers, except when explicitly specified.
Consider using release 0.1.3 instead.
Reason given by maintainers: Bugs
Angrist
"As Angrist carved the Silmaril from the Iron Crown of Morgoth: excise the flaw, preserve the tree."
Angrist repairs bugs in Python functions using LLMs while strictly locking edits to the target AST node. It tests every patch in an isolated Git worktree before touching your code, preventing unintended modifications across the rest of the file.
Overview
Most AI coding tools operate with full write access to your files. When asked to fix a bug inside a specific function, models frequently rewrite unrelated lines, remove comments, or break sibling methods.
Angrist prevents this through strict architectural boundaries:
- Target Scope Locking: Tree-sitter isolates the exact target function or method. Every byte outside that target node is guaranteed to remain untouched.
- Isolated Worktrees: Patches, tests, and linter runs execute in temporary Git worktrees. Your active workspace and uncommitted edits are never modified.
- Delta Regression Gating: Candidate patches must pass existing tests and introduce zero new lint errors before they can be merged.
- Model Agnostic: Connects to any OpenAI-compatible endpoint, including local models (Ollama, vLLM) and cloud APIs (Groq, OpenAI).
Installation
Install using uv (recommended) or pipx:
uv tool install angrist
# or
pipx install angrist
# or for local development
pip install -e ".[dev]"
Dependencies
- Python 3.11+
- Git 2.20+
- Tree-sitter & Tree-sitter Python
Configuration
Angrist resolves configuration in order: CLI Flags > Environment Variables > .env file > Defaults.
Copy .env.example to .env and set your provider credentials:
# --- Default: Groq (Free & Fast) ---
ANGRIST_LLM_BASE_URL=https://api.groq.com/openai/v1
ANGRIST_LLM_API_KEY=gsk_your_groq_api_key_here
ANGRIST_LLM_MODEL=llama-3.3-70b-versatile
# --- Preset: Local Ollama ---
# ANGRIST_LLM_BASE_URL=http://localhost:11434/v1
# ANGRIST_LLM_MODEL=qwen2.5-coder:7b
# --- Preset: Local vLLM ---
# ANGRIST_LLM_BASE_URL=http://localhost:8000/v1
# ANGRIST_LLM_MODEL=deepseek-ai/DeepSeek-Coder-V2-Lite-Instruct
Quick Start
1. Fix a Method or Function
Target a specific class method or top-level function without affecting surrounding code:
angrist fix \
--file demo/payment_processor.py \
--target PaymentProcessor.settle_batch \
--instruction "Fix fee deduction precedence and update transaction status" \
--test-cmd "pytest demo/test_payment_processor.py"
2. Automatic Safe Merge
Merge the verified patch into your current branch once all AST, lint, and test gates pass:
angrist fix \
--file service/auth.py \
--target authenticate_user \
--instruction "Reject expired tokens" \
--auto-merge
3. Run SWE-bench Lite Benchmark
Evaluate Angrist against 10 real-world open-source bug instances:
angrist benchmark
Command-Line Options
| Option | Default | Description |
|---|---|---|
--file PATH |
Required | Relative path to target Python file. |
--target IDENT |
Required | Target name (function_name or ClassName.method_name). |
--instruction TEXT |
Optional | Plain-text repair instructions or bug description. |
--instruction-file PATH |
Optional | File path containing repair instructions. |
--test-cmd CMD |
"pytest" |
Test command to run before and after patching. |
--lint-cmd CMD |
"ruff check ." |
Linter command used to verify no regressions. |
--auto-merge |
False |
Merge verified patch into current branch automatically. |
--max-retries INT |
3 |
Maximum LLM regeneration attempts on gate failure. |
Architecture
Angrist uses a unidirectional, decoupled pipeline:
Python File & Target
│
▼
[ ast_guard ] Tree-sitter AST coordinate lock (preserves all sibling code)
│
▼
[ sandbox ] Isolated Git worktree creation & baseline verification
│
▼
[ patcher ] Model-agnostic prompt synthesis & syntactic sanitization
│
▼
[ gate ] AST invariance check, delta test run & lint comparison
│
▼
[ merge ] Atomic branch merge or immediate rollback on failure
Benchmarks
SWE-bench Lite (10-Instance Curated Suite)
Evaluated live against openai/gpt-oss-120b via Groq across 10 real-world bug instances from 7 major open-source repositories:
| Instance ID | Repository | Target Function | Status | AST Scope | Regressions | Duration |
|---|---|---|---|---|---|---|
psf__requests-1142 |
psf/requests |
PreparedRequest.prepare_url |
PASS | 100% Locked | 0 | 2.52s |
marshmallow__marshmallow-1343 |
marshmallow |
Schema._do_load |
PASS | 100% Locked | 0 | 2.50s |
pallets__flask-4045 |
pallets/flask |
Blueprint.add_url_rule |
PASS | 100% Locked | 0 | 2.52s |
django__django-11099 |
django/django |
ASCIIUsernameValidator.__init__ |
PASS | 100% Locked | 0 | 2.15s |
pallets__flask-4992 |
pallets/flask |
Config.from_file |
PASS | 100% Locked | 0 | 3.16s |
pylint-dev__pylint-5859 |
pylint-dev/pylint |
EncodingChecker.open |
PASS | 100% Locked | 0 | 2.04s |
pytest-dev__pytest-11148 |
pytest-dev/pytest |
import_path |
FAIL | 100% Locked | 0 | 4.72s |
django__django-11049 |
django/django |
DurationField.get_error_message |
FAIL | 100% Locked | 0 | 2.94s |
sphinx-doc__sphinx-10325 |
sphinx-doc/sphinx |
inherited_members_option |
PASS | 100% Locked | 0 | 3.29s |
psf__requests-1963 |
psf/requests |
SessionRedirect.resolve_redirect_method |
PASS | 100% Locked | 0 | 2.58s |
Benchmark Insights:
- 80.0% Pass Rate (8/10): 8 of 10 real-world bugs resolved on the first attempt (Total duration: 29.56s).
- Gate Safety: 2 incomplete candidate patches were rejected cleanly by the delta test gate, preventing workspace pollution.
- Full 300-Instance Manifest: All 300 instances from
princeton-nlp/SWE-bench_Liteare indexed inbenchmarks/swe_bench/official_manifest.json(297/300 verified single-function targets).
Failure Case Root-Cause Analysis:
pytest-dev__pytest-11148(import_path): The model over-engineered the fix by synthesizing a fullimportlibfile loader instead of readingsys.modules, raising anImportErroron a virtual path. The patch was safely rejected by test and lint gates.django__django-11049(DurationField.get_error_message): On the first attempt, string replacement left remnants of the old format string, failing the negative assertion. The delta gate caught the incomplete fix and aborted the merge.
Scope & Boundaries
- Supported: Logic bugs, boundary conditions, query string parsing, regex repairs, type coercion, and single-function fixes with full layout and comment preservation.
- Out of Scope: Multi-file refactors, architecture migrations, and module-level import injections. The target function must already exist and parse cleanly.
Supported Platforms
- Linux (x86_64 / ARM64): Fully supported.
- macOS (Apple Silicon / Intel): Fully supported.
- Windows (x86_64): Fully supported with atomic
onexcread-only Git metadata handling.
Roadmap
- Core Engine: Tree-sitter AST guard, Git-worktree sandbox isolation, and LLM patcher.
- Delta Gating: Multi-format JSON/concise lint parsing and test regression detection.
- SWE-bench Suite: Integrated benchmark runner with Rich terminal output.
- Multi-Language AST: Expanding Tree-sitter guards to TypeScript and Go.
- Interactive TUI: In-terminal side-by-side AST diff inspector before merging.
Contributing
Contributions are welcome! Please see CONTRIBUTING.md for guidelines and review our Code of Conduct.
Security
To report security issues, please review our Security Policy.
License
MIT License. See LICENSE for details.
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 angrist-0.1.0.tar.gz.
File metadata
- Download URL: angrist-0.1.0.tar.gz
- Upload date:
- Size: 33.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
772cb153c1aea4010c350e921534d87f203e8ea03282e79cd12e5da3983790c9
|
|
| MD5 |
9b45f199b8650063e24379c52bf39223
|
|
| BLAKE2b-256 |
6947ce969831ae1cfa0058613db458a4e25dc4ad8c08be1f35be7f6df9dfa459
|
Provenance
The following attestation bundles were made for angrist-0.1.0.tar.gz:
Publisher:
release.yml on flxhrdyn/angrist
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
angrist-0.1.0.tar.gz -
Subject digest:
772cb153c1aea4010c350e921534d87f203e8ea03282e79cd12e5da3983790c9 - Sigstore transparency entry: 2694396082
- Sigstore integration time:
-
Permalink:
flxhrdyn/angrist@a7d25e954cd97e8ff904cacd4f2dc9f925e2555f -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/flxhrdyn
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@a7d25e954cd97e8ff904cacd4f2dc9f925e2555f -
Trigger Event:
push
-
Statement type:
File details
Details for the file angrist-0.1.0-py3-none-any.whl.
File metadata
- Download URL: angrist-0.1.0-py3-none-any.whl
- Upload date:
- Size: 23.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6cb0dc61bb9a69397ebfcabd513aa173b096b5bd7fde91230dce5f4311095152
|
|
| MD5 |
1db468dbb82835b8357769ad3b0e79db
|
|
| BLAKE2b-256 |
9600452c3da6202d3ce10b29419fc256d76e20581c8ec5770e50050a5ff7ca81
|
Provenance
The following attestation bundles were made for angrist-0.1.0-py3-none-any.whl:
Publisher:
release.yml on flxhrdyn/angrist
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
angrist-0.1.0-py3-none-any.whl -
Subject digest:
6cb0dc61bb9a69397ebfcabd513aa173b096b5bd7fde91230dce5f4311095152 - Sigstore transparency entry: 2694396151
- Sigstore integration time:
-
Permalink:
flxhrdyn/angrist@a7d25e954cd97e8ff904cacd4f2dc9f925e2555f -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/flxhrdyn
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@a7d25e954cd97e8ff904cacd4f2dc9f925e2555f -
Trigger Event:
push
-
Statement type: