The $110/month self-improving pipeline

digitallogic1 pts0 comments

The $110/month self-improving pipeline | Andy WidjajaI got tired of implementing my own backlog manually using claude code on my laptop. So I set up a loop, let the system triage it, decompose it if it's too big, implement it, run the tests, and open a PR. I do the merge from my phone. It's been running for 2 weeks: 27 merges, 1 failure, with $1.61 average per-issue.<br>It's been running for 2 weeks. The number will likely change. Now I'm still actively collecting data. I'll update this post as the system matures. But the pattern seems to work well enough that I wanted to share it now rather than wait for a perfect dataset.<br>The cost<br>$100.00/month Claude Max 5x (triage + implementation via Claude Code CLI)<br>$ 9.99/month VPS (Hostinger, 2 vCPU, 8GB RAM, Ubuntu)<br>$ 0.00/month GitHub<br>─────────<br>$109.99/month TotalThe config<br>The system is autoloop. One file that configures the loop:<br># autoloop.toml<br>repo = "your-org/your-repo"<br>triage_model = "sonnet"<br>impl_model = "claude-opus-4-6"<br>verify_cmd = "uv run pytest"<br>max_retries = 3<br>protected_paths = ["autoloop/", "autoloop.toml"]Three systemd timers. No Kubernetes. No orchestration framework. No fancy queue service.<br>OnCalendar=*-*-* 00:00:00 UTC # triage<br>OnCalendar=*-*-* 02:00:00 UTC # implement<br>OnCalendar=*-*-* 04:00:00 UTC # changelogWhat happens to an issue

A GitHub issue enters the queue. Unattended:<br>Triage (Sonnet, ~$0.10): Reads the issue, validates it, estimates the story points, and assigns priority. If the issue is too large, it decomposes into sub-issues with dependency ordering and triages each one. It recursively splits until every piece is buildable in one pass and generates a PR small enough for me to review on my phone.<br>Implement (Opus, ~$1.50): Picks the top ready issue with respect to dependency ordering, creates a branch, runs Claude with the issue spec and repo context, runs tests and lint, checks that test files were added, and opens a PR.<br>Verification gate : When tests fail or no test files were added, it retries up to 3 times, feeding the errors back to provide context for the next attempt. If all retries fail, it labels the issue needs-human and moves on.<br>I review queued PRs on my phone and merge. That's my contribution to the loop. Can PR merge be done automatically? Yes, but it's a deliberate architecture decision for me to be the PR gate.<br>When it breaks<br>Day 8 . Issue #40 was a duplicate. It described the issue was already implemented. The system still tried 3 times to produce a change, found nothing to change, failed verification because there was no diff. It labeled the issue needs-human and moved on to the next item in the queue.<br>I looked at the issue and read the failure explanation. I closed it. It was the right outcome. A human looks at it, realizes it's a duplicate, closes it. The system couldn't know at the time. It just knew it couldn't produce a valid PR. So it got out of the way.<br>Day 12 . Issue #159 got decomposed into 3 sub-issues. The second sub-issue produced a PR that broke an import path the first PR had introduced. Merge conflict. I fixed it from my phone in the Claude Code remote session (tmux on the VPS). It took me only 4 minutes.<br>The pattern: when it fails, it's almost always because my issue description was ambiguous or assumed context the builder didn't have. Better issues → better PRs. The system exposed my sloppy specs faster than any code review would.<br>The constraint that makes it safe<br>The system cannot modify itself.<br>protected_paths = ["autoloop/", "autoloop.toml"]If an issue targets files under protected_paths, triage routes it to needs-human. The builder never touches its own logic, pipeline, or configuration. This safety check is done at both triage (primary gate) and implementation (safety net).<br>Self-improvement without self-modification. It improves the product. It cannot improve the process. That boundary is what I believe makes it safe to run unattended.<br>What it built<br>Patina: 7,200 lines of Python, 9,200 lines of tests, 31 MCP tools.<br>I built the initial core architecture interactively. Once the foundation was solid, autoloop took over the backlog. Of the last 40 merged PRs, 27 were autonomous.<br>The pipeline itself is 3,500 lines. It was originally embedded in Patina's repo, then extracted into a standalone package that I can apply to my other repositories with one command:<br>autoloop init --repo your-org/your-repo --verify-cmd "pytest"<br>autoloop triage<br>autoloop implementWhere it works and where it doesn't<br>I want to be honest about where this applies.<br>This works for: solo builders, small teams, repos where one person or one team can hold full context. Non-critical-path systems where a 24-hour fix cycle is acceptable.<br>This doesn't work (yet) for: regulated environments, multi-team codebases, customer-facing production with SLAs that need rollback mechanisms this setup doesn't provide (yet). The pattern applies at any scale but this implementation assumes one human at the gate.<br>Two weeks isn't proof of anything long-term....

issue autoloop system triage month claude

Related Articles