Run Claude Code in a fix-break loop until your codebase is clean
Project description
███████╗████████╗ ██████╗██╗ ██╗
██╔════╝╚══██╔══╝██╔════╝██║ ██║
█████╗ ██║ ██║ ███████║
██╔══╝ ██║ ██║ ██╔══██║
███████╗ ██║ ╚██████╗██║ ██║
╚══════╝ ╚═╝ ╚═════╝╚═╝ ╚═╝ loop
Run Claude Code in a scan-fix-break loop until your codebase is clean.
╭───────────────────────── etch loop v0.5.5 my-project ─────────────────────────╮
│ - iteration 1 │
│ x scanner issues found 3 bugs — null deref auth.py:42, off-by-one... │
│ + fixer committed fixed 3 issues — null guard in auth.py, bounds... │
│ x breaker issues unguarded access still reachable in session.py │
│ - iteration 2 │
│ + scanner all clear no confirmed bugs found │
│ + runner all clear wrote 4 tests, all 31 passed │
╰───────────────── iterations 2 fixes 1 breaker issues 1 3m 12s elapsed ───╯
install
uv tool install etch-loop
Or with pip:
pip install etch-loop
usage
etch init # analyze codebase, write prompt files to etch-loop/
etch run # start the loop
etch run "the auth module" # focus on a specific area
etch run -n 5 # max 5 iterations
etch run --no-commit # fix without committing
etch run --no-git # disable all git operations
etch run --dry-run # preview prompt, don't run
etch run --verbose # stream full Claude output
how it works
Each iteration runs four phases: scan → fix → break, then once everything is clean: run.
1. Scanner
Reads the codebase and produces a precise list of confirmed bugs — file paths, line numbers, one-line descriptions. Only genuine issues, no style notes.
2. Fixer
Receives the scanner's list and fixes exactly those issues. Commits each fix with a summary message. Does not refactor or touch code unrelated to the reported bugs.
3. Breaker
Adversarially reviews only the files the fixer just changed, looking for anything introduced or missed. If it finds nothing, the loop stops clean. If it finds issues, the next iteration's scanner re-checks those specific spots to confirm what's actually still broken.
4. Runner (final step)
Runs only when the loop exits cleanly. Writes targeted tests for what was changed, runs the full test suite, then deletes the test files it created. Reports pass/fail.
loop exits clean
│
▼
[ runner ] → writes tests → runs suite → cleans up → ETCH_ALL_CLEAR
Each agent writes a short <etch_summary> that appears directly in the terminal dashboard. The fixer's summary doubles as the git commit message.
etch init
etch init runs Claude against your codebase, detects languages and structure, then writes four prompt files tailored to your project into an etch-loop/ subfolder. No placeholders to fill in.
╭─ etch init v0.5.5 ────────────────────────────────╮
│ > analyzing ░░░░░▓▒ ░░░░░░░░░░░░░░░░░░░░░░░░ │
│ + analyzed codebase │
│ + etch-loop/SCAN.md │
│ + etch-loop/ETCH.md │
│ + etch-loop/BREAK.md │
│ + etch-loop/RUN.md │
╰────────────────────────────────────────────────────╯
| File | Purpose |
|---|---|
etch-loop/SCAN.md |
Scanner prompt — what to look for and how to report findings |
etch-loop/ETCH.md |
Fixer prompt — surgical fixes only, no refactoring |
etch-loop/BREAK.md |
Breaker prompt — adversarial review of changed files |
etch-loop/RUN.md |
Runner prompt — write tests, run suite, clean up |
All four files are editable. The etch-loop/ directory is excluded from analysis so etch never reads its own files as part of your codebase.
Run reports are saved to etch-loop/etch-reports/ after each run.
reports
After every run, a markdown report is saved to etch-loop/etch-reports/:
etch-loop/etch-reports/etch-report-2026-03-10-15-31.md
It contains the full iteration log — what each phase found, what was fixed, and runner results.
requirements
- Python 3.11+
claudeCLI installed and authenticated- A git repository (optional — use
--no-gitto skip all git operations)
Project details
Release history Release notifications | RSS feed
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 etch_loop-0.6.0.tar.gz.
File metadata
- Download URL: etch_loop-0.6.0.tar.gz
- Upload date:
- Size: 26.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1140d9c76af78ae510a8769a3b99f443c8a2a7def986c4c97ebc36744504a900
|
|
| MD5 |
011d4fe4bd2ec785d048e6fda534bbda
|
|
| BLAKE2b-256 |
d78c33bc223a3e4c60f29b73f8947db43641c578021a072d69ad5a87bbc7c313
|
Provenance
The following attestation bundles were made for etch_loop-0.6.0.tar.gz:
Publisher:
workflow.yml on lauenborg/etch-loop
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
etch_loop-0.6.0.tar.gz -
Subject digest:
1140d9c76af78ae510a8769a3b99f443c8a2a7def986c4c97ebc36744504a900 - Sigstore transparency entry: 1076615203
- Sigstore integration time:
-
Permalink:
lauenborg/etch-loop@c58464ef53ed4c52d3666ce348f5b76e4a504594 -
Branch / Tag:
refs/tags/v0.6.0 - Owner: https://github.com/lauenborg
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
workflow.yml@c58464ef53ed4c52d3666ce348f5b76e4a504594 -
Trigger Event:
push
-
Statement type:
File details
Details for the file etch_loop-0.6.0-py3-none-any.whl.
File metadata
- Download URL: etch_loop-0.6.0-py3-none-any.whl
- Upload date:
- Size: 28.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dc97bca2419ce6aaececa986c07414bf67422a5f64529c46ada5d155693d7efd
|
|
| MD5 |
cc58c231bd3edd3e0dd363edd4fcf4dd
|
|
| BLAKE2b-256 |
d81441d68edb3f9ad00dfb9f85b93c026b7398b85dc5167d249d7d7e86f9a0c6
|
Provenance
The following attestation bundles were made for etch_loop-0.6.0-py3-none-any.whl:
Publisher:
workflow.yml on lauenborg/etch-loop
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
etch_loop-0.6.0-py3-none-any.whl -
Subject digest:
dc97bca2419ce6aaececa986c07414bf67422a5f64529c46ada5d155693d7efd - Sigstore transparency entry: 1076615211
- Sigstore integration time:
-
Permalink:
lauenborg/etch-loop@c58464ef53ed4c52d3666ce348f5b76e4a504594 -
Branch / Tag:
refs/tags/v0.6.0 - Owner: https://github.com/lauenborg
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
workflow.yml@c58464ef53ed4c52d3666ce348f5b76e4a504594 -
Trigger Event:
push
-
Statement type: