A battle-tested, local-first GitHub agent loop for reviews, patches, and review feedback repair
PatchLoop turns GitHub issue and pull request work into a durable local loop. It was extracted from real automation used on ZhuLinsen/daily_stock_analysis, a public AI-driven stock analysis project, where the loop handled issue triage, pull request review, and review-feedback-driven patch repair in a live repository.
The core idea is simple: do not stop at "the agent opened a PR." Keep the PR moving after review.
Issue / TODO / idle finding
|
v
Plan and policy gate
|
v
Local patch in isolated worktree
|
v
Validation and patch inspection
|
v
Pull request
|
v
Review feedback
|
+----> repair queue ----> local patch ----> push update
It is designed for maintainers who want agent automation without handing the entire repository workflow to a hosted service. PatchLoop runs on your machine or server, talks to GitHub, drives your installed coding CLI, and persists enough state to recover from restarts, retries, and missed webhook events.
- Battle-tested on a real public repo: extracted from the automation loop used on daily_stock_analysis.
- Local-first by design: your clone, your tokens, your validation commands, your machine.
- Multi-CLI execution: use
codex,copilot,cursor,opencode, or a custom command profile. - Not just PR creation: PatchLoop tracks review feedback, queues repair work, and pushes follow-up patches to the same PR branch.
- Durable long-running service: polling cursors, idempotency keys, task queues, dead letters, state snapshots, and restore APIs.
- Conservative by default: dry-run examples, manual execution mode, no auto-merge, and no direct pushes to the default branch.
PatchLoop contains two cooperating services.
| Service | Role | GitHub write surface |
|---|---|---|
openreview |
Read-only issue analysis and PR review follow-up | Comments and PR reviews only |
autocode |
Issue-to-PR execution, backlog sync, idle scan, and PR feedback repair | Branch pushes and PR create/update |
- Analyzes issues with local repository context, similar issues, related PRs, and discussion history.
- Reviews non-draft PRs after CI succeeds, with controlled follow-up when new discussion appears.
- Uses polling cursors and discussion fingerprints to reduce missed events and duplicate reviews.
- Keeps a strict read-only implementation boundary: it never edits files or pushes code.
- Turns eligible issues into structured plans, applies policy gates, and creates scoped patches.
- Runs each coding task in an isolated worktree before validation and publication.
- Opens or updates PRs, but never merges and never pushes directly to the default branch.
- Tracks PR review feedback, queues repair tasks, and pushes follow-up fixes to the PR branch.
- Can sync Markdown backlog items and idle findings into GitHub issues before entering the same execution loop.
- Local-first control: use your own clone, tokens, validation commands, and CLI tools.
- CLI-agnostic adapters: supports
codex,copilot,cursor, andopencodestyle execution backends. - Durable queues: issue execution, PR repair, and source sync tasks survive restarts.
- Polling plus webhook: webhook can reduce latency, polling provides recovery and long-running stability.
- Feedback repair loop: review feedback is not just summarized; it can be converted into follow-up patches.
- Conservative safety model: no auto-merge, no default-branch pushes, diff size limits, blocked paths, and dry-run defaults.
PatchLoop supports both GitHub event ingestion styles:
| Mode | Best for | Notes |
|---|---|---|
polling |
Long-running local/server deployments | Recommended default. Uses cursors and overlap windows to recover from missed webhook delivery, restarts, and transient GitHub/API failures. |
webhook |
Low-latency event delivery | Requires a public or tunneled HTTP endpoint and GITHUB_WEBHOOK_SECRET. |
Recommended setup:
- Start with
EVENT_SOURCE=pollingandENABLE_WEBHOOK=false. - For faster response, keep polling as the safety net and enable webhook where supported.
openreviewcurrently treatsEVENT_SOURCE=webhookas the webhook-serving mode; when it runs in polling mode,/webhookis disabled.autocodecan run withEVENT_SOURCE=pollingandENABLE_WEBHOOK=true, using webhook as an accelerator while background polling and queues handle recovery.
Minimal polling config:
EVENT_SOURCE=polling
ENABLE_WEBHOOK=false
POLL_INTERVAL_SECONDS=60Webhook config:
EVENT_SOURCE=webhook
ENABLE_WEBHOOK=true
GITHUB_WEBHOOK_SECRET=replace_me_webhook_secretPatchLoop does not require one hosted agent runtime. It shells out to a local CLI adapter, so you can choose the model/tooling stack that fits your environment.
| Backend | Typical use |
|---|---|
codex |
OpenAI/Codex-style local coding sessions |
copilot |
GitHub Copilot CLI workflows |
cursor |
Cursor agent CLI workflows |
opencode |
OpenCode-style local execution |
| Custom command | Any compatible CLI configured through *_CLI_COMMAND |
PatchLoop is currently source-run infrastructure. Start with dry-run mode, then turn on write operations only after the queues and validation commands behave as expected on your repository.
git clone https://github.com/your-org/patchloop.git
cd patchloop
python3 -m venv .venv
. .venv/bin/activate
pip install -r requirements.txt
pip install -e .You also need at least one supported local coding CLI installed and authenticated on the machine running PatchLoop.
cd openreview
cp .env.example .envEdit openreview/.env:
GITHUB_TOKEN=replace_me_read_token
GITHUB_REPO=owner/repo
LOCAL_REPO_PATH=/path/to/your/repo
PRIMARY_CLI=codex
EVENT_SOURCE=polling
ENABLE_WEBHOOK=false
DRY_RUN=trueStart the review service:
python3 review.py
# or, from the repository root after `pip install -e .`:
patchloop reviewHealth check:
curl http://127.0.0.1:8000/healthcd ../autocode
cp .env.example .envEdit autocode/.env:
GITHUB_TOKEN=replace_me_read_token
GITHUB_REPO=owner/repo
LOCAL_REPO_PATH=/path/to/your/repo
PRIMARY_CLI=codex
EVENT_SOURCE=polling
ENABLE_WEBHOOK=false
DRY_RUN=true
ENABLE_EXECUTION=true
EXECUTION_MODE=manual
EXECUTION_AUTO_IMPLEMENT_ON_ISSUE_OPEN=false
EXECUTION_ENABLE_PR_QUEUE=trueStart the coding service:
python3 autocode.py
# or, from the repository root after `pip install -e .`:
patchloop codeUseful endpoints:
curl http://127.0.0.1:8001/health
curl http://127.0.0.1:8001/observability
curl "http://127.0.0.1:8001/tasks?limit=20"Manually approve an issue implementation:
curl -X POST http://127.0.0.1:8001/issues/123/implementBefore disabling dry-run:
- Use a dedicated local clone or worktree root.
- Keep
GITHUB_TOKENread-only where possible. - Set
GITHUB_WRITE_TOKENseparately for branch pushes and PR updates. - Configure
EXECUTION_FORMAT_COMMANDS,EXECUTION_LINT_COMMANDS, andEXECUTION_TEST_COMMANDS. - Keep
EXECUTION_MODE=manualuntil you trust the policy gates on your repository. - Review
EXECUTION_BLOCKED_PATHS, diff limits, and maximum open PR limits. - Keep
.env, state files, logs, generated patches, and worktrees out of Git.
patchloop/
openreview/ # read-only issue and PR review service
autocode/ # coding, PR creation, queueing, and feedback repair service
README.md
LICENSE
CONTRIBUTING.md
SECURITY.md
The two services are intentionally still separated. openreview can run with
comment-only permissions, while autocode requires write permissions only when
DRY_RUN=false.
PatchLoop is alpha software extracted from a working local automation setup. The core loop is present, but the public packaging is intentionally conservative:
- Single-repository operation is the primary target.
- Multi-tenant SaaS deployment is not a goal of this repository.
- GitHub App packaging, dashboards, and richer policy configuration are future work.
- Package both services behind a single
patchloopCLI. - Share common GitHub, CLI adapter, context, and state utilities between services.
- Add Docker Compose examples for local deployment.
- Add GitHub App installation docs for teams that prefer app-based permissions.
- Expand policy presets for docs-only, bug-fix, and high-risk repository areas.
Apache-2.0 License. See LICENSE for details.