30fe48d265
CI / test (push) Successful in 18s
CI / review (anthropic--claude-4.6-sonnet, sonnet, SONNET_REVIEW_TOKEN) (push) Has been skipped
CI / review (gpt-5, gpt, GPT_REVIEW_TOKEN) (push) Has been skipped
CI / review (gpt-5, security, ., rodin/security-patterns, SECURITY_REVIEW.md, SECURITY_REVIEW_TOKEN) (push) Has been skipped
130 lines
5.2 KiB
Markdown
130 lines
5.2 KiB
Markdown
# Dev-Loop Skill: review-bot
|
|
|
|
This file documents the dev-loop architecture for the `review-bot` project.
|
|
It lives in the repo so changes are version-controlled alongside the code.
|
|
|
|
## Architecture
|
|
|
|
Dispatch is a **pure shell script** — no model reasoning.
|
|
|
|
```
|
|
Cron (agentTurn, toolsAllow: [exec, sessions_spawn, read])
|
|
→ runs dispatch script
|
|
→ reads output for SPAWN or HANDOFF lines
|
|
→ spawns worker if instructed
|
|
|
|
Dispatch script (~/.openclaw/workspace/scripts/dev-loop-dispatch.sh)
|
|
→ pure bash, all decisions are curl API calls + branches
|
|
→ exits after emitting one SPAWN line (at most one worker per run)
|
|
→ emits HANDOFF for each qualifying PR (does not exit after HANDOFF)
|
|
|
|
Workers (Opus, spawned by cron model)
|
|
→ receive precise task description
|
|
→ do one job: self-review, fix CI, address feedback, or implement
|
|
→ remove wip label when done, reply NO_REPLY
|
|
```
|
|
|
|
The cron model's **only** job: run script, read output, spawn worker if told to.
|
|
The model **never** assesses project state or makes dispatch decisions.
|
|
|
|
## Safety Invariants
|
|
|
|
1. **NEVER MERGE** — no merge API call exists anywhere in the script or worker templates
|
|
2. **REQUEST_CHANGES always blocks** — checked first, before CI, before self-review, before handoff
|
|
3. **WIP mutex** — one active worker per repo; WIP label gates new issue pickup
|
|
4. **One SPAWN per run** — script emits at most one SPAWN line per execution
|
|
5. **set -euo pipefail** — any curl failure aborts immediately, no partial actions
|
|
6. **Workers reply NO_REPLY** — no dispatch-level side effects (workers may push changes and manage labels as part of their task)
|
|
|
|
## Dispatch Rules (in order)
|
|
|
|
| Rule | Condition | Action |
|
|
|------|-----------|--------|
|
|
| 0 | WIP label > 1hr old | Remove stale WIP, continue |
|
|
| 0b | WIP label ≤ 1hr old | Mark ACTIVE_WIP=1, continue (only gates Rule 10) |
|
|
| _(1)_ | _(reserved — intentionally unused)_ | — |
|
|
| 2 | Any reviewer has REQUEST_CHANGES | SPAWN:findings |
|
|
| 3 | PR not mergeable | SPAWN:rebase |
|
|
| 4 | CI failure, no fix plan | SPAWN:ci-fix |
|
|
| 4b | CI failure, fix plan exists | Skip (worker in progress) |
|
|
| 5 | Bot review missing | Wait |
|
|
| 6 | CI pending/unknown | Wait |
|
|
| 7 | No clean self-review, no fix plan | SPAWN:self-review |
|
|
| 7b | Self-review needs attention, no fix plan | SPAWN:sr-fix |
|
|
| 8 | Unacknowledged bot review findings | SPAWN:address-feedback |
|
|
| 9 | Unresolved inline diff comments | SPAWN:address-feedback |
|
|
| 10 | All checks pass | HANDOFF |
|
|
| 11 | No open PRs + no ACTIVE_WIP | SPAWN:impl (next issue) |
|
|
|
|
## Files
|
|
|
|
| File | Description |
|
|
|------|-------------|
|
|
| `~/.openclaw/workspace/scripts/dev-loop-dispatch.sh` | Dispatch script — pure bash |
|
|
| `~/.openclaw/workspace/scripts/worker-tasks/self-review.md` | Self-review worker template |
|
|
| `~/.openclaw/workspace/scripts/worker-tasks/sr-fix.md` | Fix findings from self-review |
|
|
| `~/.openclaw/workspace/scripts/worker-tasks/ci-fix.md` | CI fix worker template |
|
|
| `~/.openclaw/workspace/scripts/worker-tasks/address-feedback.md` | Address feedback worker template |
|
|
| `~/.openclaw/workspace/scripts/worker-tasks/findings.md` | Address REQUEST_CHANGES findings |
|
|
| `~/.openclaw/workspace/scripts/worker-tasks/rebase.md` | Rebase worker template |
|
|
| `~/.openclaw/workspace/scripts/worker-tasks/impl.md` | Issue implementation worker template |
|
|
| `~/.openclaw/workspace/scripts/test/dispatch.bats` | Unit tests (bats) |
|
|
| `~/.openclaw/workspace/scripts/test/check-invariants.sh` | Static invariant checks |
|
|
| `~/.openclaw/workspace/memory/projects/review-bot.yaml` | Project config |
|
|
|
|
## Project Config
|
|
|
|
Config is at `~/.openclaw/workspace/memory/projects/review-bot.yaml`.
|
|
|
|
Key fields:
|
|
- `repo`: `rodin/review-bot`
|
|
- `api_base`: `https://gitea.weiker.me/api/v1`
|
|
- `user`: `rodin` (bot Gitea username)
|
|
- `labels.wip`: WIP label ID
|
|
- `labels.ready`: ready label ID
|
|
- `review_bots`: list of bot sentinel names
|
|
|
|
## Cron Config
|
|
|
|
```yaml
|
|
- label: review-bot-dev-loop
|
|
schedule: "*/15 * * * *"
|
|
prompt: |
|
|
Run: bash ~/.openclaw/workspace/scripts/dev-loop-dispatch.sh review-bot
|
|
|
|
Read the output. If it contains a SPAWN line, load the matching template from
|
|
~/.openclaw/workspace/scripts/worker-tasks/<type>.md, substitute {{PROJECT}},
|
|
{{PR_NUM}}, and {{HEAD_SHA}}, then spawn with sessions_spawn(mode: "run",
|
|
model: "hai-anthropic/anthropic--claude-4.6-opus", thinking: "high").
|
|
|
|
If no SPAWN line in output, reply NO_REPLY.
|
|
|
|
See ~/.openclaw/workspace/skills/dev-loop/SKILL.md for full instructions.
|
|
(This repo's SKILL.md is deployed to that workspace path.)
|
|
model: hai-anthropic/anthropic--claude-4.5-haiku
|
|
toolsAllow: [exec, sessions_spawn, read]
|
|
```
|
|
|
|
## Tests
|
|
|
|
```bash
|
|
# Unit tests (no real API calls):
|
|
bats ~/.openclaw/workspace/scripts/test/dispatch.bats
|
|
|
|
# Invariant checks (static analysis):
|
|
bash ~/.openclaw/workspace/scripts/test/check-invariants.sh
|
|
|
|
# Dry-run against real API:
|
|
DRY_RUN=1 bash ~/.openclaw/workspace/scripts/dev-loop-dispatch.sh review-bot
|
|
```
|
|
|
|
## Related Issues
|
|
|
|
- **#144** — autonomous merge: eliminated by removing all merge API calls from dispatch
|
|
- **#145** — merged despite REQUEST_CHANGES: eliminated by checking REQUEST_CHANGES first, unconditionally
|
|
- **#148** — this redesign
|
|
|
|
## Spec
|
|
|
|
Full design spec: `docs/dev-loop-spec.md`
|