# 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/.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`