You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
ci: collapse A/B review loop into single Reviewer, opt-in address-review, model refresh (#3022)
* ci: collapse A/B review loop into single Reviewer, opt-in address-review, model refresh
Per maintainer decision 2026-06-11: the Reviewer A / Reviewer B critique
loop was expensive and flaky (green-without-posting, cancelled reruns),
B's marginal catch rate no longer justified a second model pass with
stronger models available, and the converged-changes auto-fire push
chain landed a broken spec on a PR (#3005).
- bot-review-a.yml -> bot-review.yml: single-pass Reviewer (check name
"Reviewer"); pull_request trigger, SHA-capture-once, idempotency
marker, and the #2865 post-job validation guard all kept; the
issue_comment convergence path removed. Marker strings keep the
legacy review-a names for continuity.
- bot-review-a-fork.yml -> bot-review-fork.yml: same prompt and model
consolidation; pull_request_target sandboxing preserved unchanged.
- DELETED: bot-review-b.yml, review-the-review.md,
respond-to-critique.md.
- review-pr.md: folds B's anti-sycophancy / false-positive mandate into
an explicit adversarial self-review step before posting.
- bot-address-review.yml: opt-in only (maintainer-applied
bot-address-review label or workflow_dispatch); consumes the most
recent wheels-bot review on the current head SHA; address-held and
stale-SHA (#2848/#2865) protections preserved.
- bot-propose-fix.yml: campaign pre-gate skips the model run when a
peter/issue-<N>-* branch or an open non-bot PR already targets the
issue (4 superseded bot drafts on 2026-06-10).
- Model pins: Reviewer (main+fork) -> claude-fable-5; triage,
propose-fix, address-review, resolve-conflicts, advisor, research ->
claude-opus-4-8; auto-close/write-docs/update-docs stay sonnet-4-6.
Policy: judging gate = fable, coding stages = opus, janitorial =
sonnet.
- Reference sweep: .ai/wheels/wheels-bot.md and
docs/contributing/wheels-bot.md pipeline sections rewritten;
_shared-rails.md, CONTRIBUTING.md, and prompt cross-references
updated; bot-advisor.yml + advise-on-deadlock.md marked legacy/inert.
- vendor/wheels/tests/specs/cli/BotReviewMarkerShaThreadingSpec.cfc
rewritten for the new file set (it fileExists-asserted the deleted /
renamed workflows and prompts; leaving it would have failed the core
suite on every engine). BotConvergenceMarkerShaThreadingSpec
assertions verified still green against the edited workflows.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Peter Amiri <peter@alurium.com>
* ci: address review nits on the bot consolidation
- address-held skip marker now matches the SHA-suffixed form the prompt
actually emits; the SHA-less prefix permanently no-op'd every future
label opt-in on a PR after one held round.
- campaign guard: manual workflow_dispatch bypasses the guard (explicit
maintainer intent beats a lingering stale campaign branch).
- campaign guard: jq body re-check uses a digit-boundary regex so issue
123 no longer matches a PR body referencing #1234.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Peter Amiri <peter@alurium.com>
* ci: address-held gate uses the SHA output, not the branch-name output
The prior commit claimed to SHA-scope the address-held skip gate but
interpolated steps.pr.outputs.head — the branch name — so the pattern
could never match the SHA-suffixed marker the prompt emits and the gate
was permanently fail-open. Caught by the new Reviewer on its own
consolidation PR. Now uses steps.pr.outputs.sha, pinned by a structural
spec assertion in BotConvergenceMarkerShaThreadingSpec.
Also from the same review: address-review.md now names the correct
gh pr view field (.commit.oid, not the REST shape's commit_id), and the
label-gate docs no longer claim labeling requires write access (GitHub's
triage role can label; the docs now say so and advise restricting it).
Suite evidence: full core suite on Lucee 7 + SQLite (docker) = 4374 pass /
12 fail / 0 error; all 12 are the pre-existing internal.testClientSpec
loopback-container artifacts; wheels.tests.specs.cli area 78/0/0.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Peter Amiri <peter@alurium.com>
---------
Signed-off-by: Peter Amiri <peter@alurium.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: .ai/wheels/wheels-bot.md
+11-7Lines changed: 11 additions & 7 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,24 +1,28 @@
1
1
# Wheels Bot
2
2
3
-
`wheels-bot[bot]` is a custom GitHub App that runs Claude-powered automation on issues and PRs in `wheels-dev/wheels`. Five stages, all opt-out via the `[skip-claude]` label or repo variable `WHEELS_BOT_ENABLED=false`. Slash-command prompts live in `.claude/commands/`; workflows in `.github/workflows/bot-*.yml`. Full user-facing docs: [`docs/contributing/wheels-bot.md`](../../docs/contributing/wheels-bot.md).
3
+
`wheels-bot[bot]` is a custom GitHub App that runs Claude-powered automation on issues and PRs in `wheels-dev/wheels`. All stages are opt-out via the `[skip-claude]` label or repo variable `WHEELS_BOT_ENABLED=false`. Slash-command prompts live in `.claude/commands/`; workflows in `.github/workflows/bot-*.yml`. Full user-facing docs: [`docs/contributing/wheels-bot.md`](../../docs/contributing/wheels-bot.md).
4
4
5
5
## Stages
6
6
7
7
| Stage | Trigger | Model | Output |
8
8
|---|---|---|---|
9
9
| Triage | issue opened/reopened | Opus | Comment classifying as `bug` / `framework-design` / `other` (+ confidence on `bug` path). Reads code with the allowlisted tools to resolve uncertainty before rating. |
10
10
| Research | bot triage emits `framework-design` marker | Opus | Comment comparing Rails / Laravel / Django / Phoenix / Spring Boot / +1 and recommending a Wheels-idiomatic path (+ confidence). |
11
-
| Propose Fix | bot triage emits `triage-confidence:high\|medium` OR research emits `research-confidence:high\|medium` (or `workflow_dispatch`) | Opus | TDD-mandatory draft PR on branch `fix/bot-<issue>-<slug>`. Spec-then-implementation, both required by `bot-tdd-gate.yml`. |
12
-
| Reviewer A | PR opened / synchronized / ready_for_review | Sonnet | Single PR review with line comments, verdict, and `wheels-bot:review-a:<pr>:<sha>` marker. |
13
-
| Reviewer B | Reviewer A submits a review | Sonnet | PR comment critiquing A for sycophancy, false positives, and missed issues. Loop cap = 3 rounds. |
11
+
| Propose Fix | bot triage emits `triage-confidence:high\|medium` OR research emits `research-confidence:high\|medium` (or `workflow_dispatch`). A pre-gate skips the run when a `peter/issue-<N>-*` branch or an open non-bot PR already targets the issue (campaign guard). | Opus | TDD-mandatory draft PR on branch `fix/bot-<issue>-<slug>`. Spec-then-implementation, both required by `bot-tdd-gate.yml`. |
12
+
| Reviewer | PR opened / synchronized / ready_for_review (`bot-review.yml`; fork PRs via maintainer-labeled `bot-review-fork.yml`) | Fable | Single PR review with line comments, verdict, and `wheels-bot:review-a:<pr>:<sha>` marker (legacy marker name retained). The prompt includes a self-adversarial pass — refute each finding against the actual code before posting — replacing the retired Reviewer B critique loop. |
13
+
| Address Review |**opt-in**: maintainer applies the `bot-address-review` label or dispatches `bot-address-review.yml`| Opus | Applies the most recent wheels-bot review's findings on the current head SHA, pushes to the PR branch, comments with `wheels-bot:address-review:<pr>:<sha>:<round>`. |
**Retired (2026-06-11):** the Reviewer A / Reviewer B convergence loop (`bot-review-b.yml`, `/review-the-review`, `/respond-to-critique`) and the `converged-*` auto-fire chain into address-review. The loop was expensive and flaky, B's marginal catch rate no longer justified a second model pass, and the auto-fire push chain landed a broken spec on a PR (#3005). `bot-advisor.yml` (the loop's deadlock-breaker) is retained but inert — its trigger marker is no longer produced.
14
18
15
19
## Marker conventions (HTML comments, used for idempotency)
@@ -31,7 +35,7 @@ Flip the repo variable `WHEELS_BOT_ENABLED` to `false` to halt every bot workflo
31
35
32
36
## Auto-fire safety net
33
37
34
-
The bot is permitted to chain stages (triage → research → propose-fix), and handoff fires on `*-confidence:high` OR `*-confidence:medium`. Low stays manual. Sensitive areas (security, middleware, migrations, deploy, DI, cross-engine) are caught by the propose-fix prompt's own step-4 safety net, which posts a `fix-held` marker instead of opening a PR. Reviewer A and B then critique whatever propose-fix produces, escalating to the Senior Advisor on deadlock. All bot PRs land as `--draft` and require a human approving review on `develop`.
38
+
The bot is permitted to chain stages (triage → research → propose-fix), and handoff fires on `*-confidence:high` OR `*-confidence:medium`. Low stays manual. Sensitive areas (security, middleware, migrations, deploy, DI, cross-engine) are caught by the propose-fix prompt's own step-4 safety net, which posts a `fix-held` marker instead of opening a PR. The Reviewer then reviews whatever propose-fix produces. Address-review never auto-fires — a human opts the PR in via the `bot-address-review` label. All bot PRs land as `--draft` and require a human approving review on `develop`.
0 commit comments