Skip to content

Commit 86e6248

Browse files
committed
docs(autopilot-batch): require per-agent RAILS_ENV=test test-DB isolation
1 parent 2a865da commit 86e6248

1 file changed

Lines changed: 3 additions & 2 deletions

File tree

  • claude/.claude/skills/autopilot-batch

‎claude/.claude/skills/autopilot-batch/SKILL.md‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ For each issue, spawn a **background** subagent:
6363
- `isolation: worktree` — its own checkout, so parallel edits across issues can't collide.
6464
- `run_in_background: true` — they run concurrently.
6565
- `model:` the issue's assigned build model (Sonnet or Opus per the policy above; Opus for any `--to merge` issue).
66-
- prompt: run `/autopilot <n> --to <tier>` to completion — running any `bin/ci` invocation serially (`PARALLEL_WORKERS=1 bin/ci`; see the serial-CI note under **Important**) — then report back, as the final message, the PR number and URL, the loop outcome (which steps ran / were n·a), a one-line summary of the change, and, if it stopped at the escape hatch, exactly where and why.
66+
- prompt: run `/autopilot <n> --to <tier>` to completion — running every `bin/ci` / test / `db:test:prepare` invocation on the agent's **own isolated test database, serially** (`PARALLEL_WORKERS=1 RAILS_ENV=test DATABASE_URL=postgres:///<app>_test_i<n> bin/ci`; see the test-DB-isolation and serial-CI notes under **Important**) — then report back, as the final message, the PR number and URL, the loop outcome (which steps ran / were n·a), a one-line summary of the change, and, if it stopped at the escape hatch, exactly where and why.
6767

6868
Spawn them together so they run in parallel. Each subagent lands on an auto-named worktree branch (`worktree-agent-…`); inside it, `/autopilot` → `/resolve-issue` creates the proper `feat/gh-<n>-…` branch, commits, pushes, and opens the PR from it. Nothing to pre-create.
6969

@@ -81,7 +81,7 @@ A subagent that **stopped** at the escape hatch keeps its `autopilot-queued` lab
8181
For each PR built by a **Sonnet** subagent, spawn an **Opus** review subagent:
8282

8383
- `model: opus`, `isolation: worktree`.
84-
- prompt: check out the PR branch (`gh pr checkout <PR>`), run `/code-review` at `high` (escalate to `max` for a large or security-/data-sensitive diff), fix real correctness bugs and clear quality wins, commit and push (this updates the open PR), then re-run `bin/ci` **serially** (`PARALLEL_WORKERS=1 bin/ci`; see the serial-CI note under **Important**) so the required sign-off attaches to the final commit. Report the verdict: clean / _N_ fixes applied / a finding that needs a product decision (→ flag it for the human, don't guess).
84+
- prompt: check out the PR branch (`gh pr checkout <PR>`), run `/code-review` at `high` (escalate to `max` for a large or security-/data-sensitive diff), fix real correctness bugs and clear quality wins, commit and push (this updates the open PR), then re-run `bin/ci` on that issue's **isolated test database, serially** (`PARALLEL_WORKERS=1 RAILS_ENV=test DATABASE_URL=postgres:///<app>_test_i<n> bin/ci` — reuse the build agent's DB for the issue; see the test-DB-isolation and serial-CI notes under **Important**) so the required sign-off attaches to the final commit. Report the verdict: clean / _N_ fixes applied / a finding that needs a product decision (→ flag it for the human, don't guess).
8585

8686
This is the Opus floor: it runs on every Sonnet build before the PR is "review-ready" for you, so a Sonnet miss is caught and fixed, never shipped. `--to merge` issues don't pass through here — they were Opus-built and Opus-reviewed inside their own `/autopilot` run, and merged there only if the narrow-class gate passed.
8787

@@ -115,4 +115,5 @@ Post a batch summary:
115115
- **Every autonomous merge is Opus-decided** — `--merge` issues are Opus-built, so the merge go/no-go is Opus. Every Sonnet build is Opus-reviewed (Step 4) before it reaches you.
116116
- **One stop never halts the batch.** A stopped issue is set aside with its label intact; the rest continue. A wrong merge is the only truly bad outcome, and the gates above prevent it.
117117
- **Compose, don't re-implement.** Build subagents run the real `/autopilot`; review subagents run the real `/code-review`. This skill only orchestrates, gates the model floor, and manages the queue label and worktrees — so improvements to those skills flow through untouched.
118+
- **Isolate each agent's test database (`RAILS_ENV=test DATABASE_URL=…` per agent).** Several worktree agents run `bin/ci` at once; if they all share the project's one default test DB they deadlock against each other — and against any _other_ session using that same DB (a common case: a second Claude working in the primary checkout). `PARALLEL_WORKERS=1` does **not** solve this — it only fixes fork-starvation _within_ one run. Give each agent its own database — a name distinct from the project's default test DB, e.g. `<app>_test_i<issue#>` (`…_test_i847`) — and pass it on **every** test/CI/db command: `PARALLEL_WORKERS=1 RAILS_ENV=test DATABASE_URL=postgres:///<app>_test_i<issue#> bin/ci`. Pre-create it once with `PARALLEL_WORKERS=1 RAILS_ENV=test DATABASE_URL=postgres:///<app>_test_i<issue#> bin/rails db:test:prepare` before the first `bin/ci`, and reuse the same DB for that issue's Opus gating review (Step 4). **`RAILS_ENV=test` is not optional:** `DATABASE_URL` only maps to the _test_ connection under `RAILS_ENV=test`. Omit it and `db:test:prepare` silently falls through to the shared default test DB (clobbering the other session), while `bin/ci`'s setup runs `db:prepare` in _development_ — creating the isolated DB stamped `development` and seeding it, which then breaks data-counting tests and makes `db:seed:replant` abort with `EnvironmentMismatchError`. Batch-scoped: standalone `/autopilot` runs (one worktree, no contention) don't need it.
118119
- **Run `bin/ci` serially in the batch (`PARALLEL_WORKERS=1 bin/ci`).** Several worktree subagents run `bin/ci` at once, and on macOS the parallel Minitest system-test workers fork-starve under that combined load — producing flaky failures and fork-crash storms that aren't real, then costly retries. A single test worker sidesteps it. This applies to both the build subagents' internal `bin/ci` (Step 2) and the Opus gating review's `bin/ci` (Step 4). It is batch-scoped: standalone `/autopilot` runs (one worktree, no contention) can stay parallel.

0 commit comments

Comments
 (0)