Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions .claude/scripts/seed-issues.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,19 @@
# Idempotent: existing labels are reused; an issue whose exact title already
# exists is skipped, so re-running won't create duplicates.
#
# NOTE — this is the anti-drift mechanism for module:* labels: the label block
# below derives label names straight from gates.json.modules[], so the labels
# the /pr-loop ADVANCE step looks for can never drift out of sync with the
# module map (see docs/USAGE.md → "Autonomous loop & the issue queue").
#
# NOTE — this script uses bare `gh` and runs as the OWNER (fine for a one-time,
# interactive backlog seed you run yourself). Per this project's `gh` rule,
# anything the AGENTS/loop do must go through the bot instead. If you want to
# (re)bootstrap just the module:* labels as the bot — e.g. to hand that step to
# an agent — use bot-gh.sh directly:
# node -e "require('./.claude/gates.json').modules.forEach(m=>console.log(m.name))" | \
# while read -r m; do bash .claude/scripts/bot-gh.sh label create "module:$m" --force; done
#
# Prereq: `gh auth login` completed for this repo, and `node` on PATH.
# Usage: bash .claude/scripts/seed-issues.sh
set -uo pipefail
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ config edit, not a rebuild.
1. Click **“Use this template”** on GitHub → create your repo.
2. Open it in Claude Code and follow **[`docs/GETTING_STARTED.md`](docs/GETTING_STARTED.md)** (fill `CLAUDE.md`
and `.claude/gates.json` — there are copy-paste prompts in [`docs/PROMPTS.md`](docs/PROMPTS.md) that draft
them for you).
them for you), then work through the **[new-project configuration
checklist](docs/GETTING_STARTED.md#new-project-configuration-checklist)** to wire it into the autonomous loop.
3. Drive it: see **[`docs/USAGE.md`](docs/USAGE.md)**.

## What's in here
Expand Down
23 changes: 23 additions & 0 deletions docs/GETTING_STARTED.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,29 @@ adapter-driven — you configure `gates.json`, not the YAML.
> still run and are visible on every PR, and `merge-ready.sh` only merges a PR once the owner has approved
> it *and* CI is green — so the approval+green gate holds even though GitHub doesn't hard-block the button.

## New-project configuration checklist
A copy-pasteable checklist for wiring a new project into the autonomous loop. See
[`USAGE.md` → "Autonomous loop & the issue queue"](USAGE.md#autonomous-loop--the-issue-queue) for the mental
model (the `module:*` opt-in queue + the owner-approval merge gate) that this checklist wires up.

1. **`.claude/gates.json`** — the only per-project file that must be filled: `project.{name,language,packageManager}`;
`modules[]` (one entry per independently-ownable area, each with a non-overlapping `path` — these become
both the worker boundaries and the `module:<name>` labels the loop understands; include non-code areas
like `docs` if you want them automatable); `gates.*` (real shell commands, `""` = skip); `coverage_threshold`;
`review.{lenses,consensus}`; `budget.*` (model routing, `max_parallel_workers`); `merge.{policy,baseBranch}`.
2. **`CLAUDE.md`** — project context, conventions, definition of done, merge policy.
3. **Bot machine account** — create it, add as a write collaborator, put `GH_BOT_TOKEN` in `.env` (gitignored).
All agent/loop `gh` calls run as the bot via `bot-gh.sh`; only `git` commits/pushes stay on the owner's
auth, so the owner can approve bot PRs. Setup notes live at the top of `.claude/scripts/bot-gh.sh`.
4. **Create the `module:*` labels** matching your `modules[]` names — see the bootstrap note at the top of
`.claude/scripts/seed-issues.sh`. Without the label, ADVANCE can never queue the issue.
5. **Server-side gates** — confirm `.github/workflows/gates.yml` runs your gate commands (Step 7 above), and
set branch protection / required status checks on `merge.baseBranch` if your plan supports it.
6. **Arm the loop** — run **`/pr-loop`**. It self-adjusts cadence (FAST when there's ≥1 open PR or ≥1 open
`module:*` issue, else IDLE) but the cron is session-scoped, so re-run it at the start of each session.
7. *(optional)* **Hardening** — `/harden` for the bypass + strict-sandbox profile, see
[`HARDENING.md`](HARDENING.md).

## Verification checklist
- [ ] `CLAUDE.md` describes the project and lists modules.
- [ ] `.claude/gates.json` has real commands; `gate.sh build|lint|test` behave correctly.
Expand Down
6 changes: 6 additions & 0 deletions docs/PROMPTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ Copy-paste these into Claude Code. The first two populate the files you must fil
> **Shortcut:** the **`/setup-orchestrator`** command runs an interactive interview that covers prompts 1–2
> (draft `CLAUDE.md`, fill `gates.json`) *and* the rest of onboarding (labels, bot check, CI, arming the loop,
> hardening). Use it for a fresh project; reach for the individual prompts below when you want to redo one piece.
>
> **Brand-new project?** Read the **[new-project configuration
> checklist](GETTING_STARTED.md#new-project-configuration-checklist)** and **[USAGE.md → "Autonomous loop &
> the issue queue"](USAGE.md#autonomous-loop--the-issue-queue)** first — they explain what `/setup-orchestrator`
> (and prompts 1–2 below) are actually wiring up, and the one convention that trips people up: only issues
> labelled `module:*` are ever picked up automatically.

---

Expand Down
24 changes: 24 additions & 0 deletions docs/USAGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,30 @@ run unattended (Claude Code `bypassPermissions`), first harden the environment s
by always-enforced guardrails — see **[`HARDENING.md`](HARDENING.md)** (deny list + OS sandbox + host
isolation). Don't enable bypass without it.

## Autonomous loop & the issue queue
Each `/pr-loop` tick runs, in order: **poll → merge → address-feedback → advance** — this per-tick order,
canonically defined in `.claude/commands/pr-loop.md`, is authoritative; the poll / address-feedback /
merge scripts described above are the mechanism it runs. Two human control points
decide what the loop actually touches:

- **The `module:*` label is an explicit opt-in work queue.** The ADVANCE step only picks up **open issues
labelled `module:<name>`** — lowest-numbered first, one at a time, and only when there are zero open PRs.
An unlabelled issue is never touched, no matter what its title or body say. Two reasons:
- **Intent gate** — most issues are discussions, questions, or half-scoped bugs; a bot shouldn't
auto-implement them. The label is you saying "this is scoped and ready for an autonomous worker."
- **Mechanism** — the label maps issue → module → the worker's `path` boundary (`gates.json.modules[]`).
No module ⇒ no boundary ⇒ nothing safe to hand a worker.
- **Owner-approval merge gate.** Workers author PRs as the **bot** (`bot-gh.sh`); the MERGE step (above)
only merges PRs the repo **owner** has Approved on GitHub that are CI-green and mergeable. It never
approves on the owner's behalf.

**Corollary:** non-module (docs/infra) work is not loop-eligible until (a) its area exists as a module in
`gates.json.modules[]`, and (b) the issue carries the matching `module:*` label. Commenting "approved" on an
issue does nothing — nothing watches issue text.

New project? Wire this up with the **[new-project configuration
checklist](GETTING_STARTED.md#new-project-configuration-checklist)**.

## Merge discipline
- **`pr-per-agent`** (default): each worker → branch → PR. You (or a merge step) integrate; conflicts surface
at PR time. Cleanest/auditable.
Expand Down
Loading