Wheels 2.x > 4.x Performance Comparison #2029
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Wheels Bot — Senior Advisor | |
| # LEGACY auto-fire path: this stage was the deadlock-breaker for the | |
| # Reviewer A / Reviewer B convergence loop, fired by B's `:terminal` | |
| # marker. That loop was retired per maintainer decision 2026-06-11 | |
| # (single-pass Reviewer; see bot-review.yml), so no pipeline stage emits | |
| # the trigger marker anymore — the issue_comment path below is inert and | |
| # retained only so historical PRs that already carry a terminal marker | |
| # can still be advised via a manual rerun. The bot-identity gate keeps | |
| # humans from forging the trigger by quoting the marker. A follow-up may | |
| # repurpose or remove this stage; until then it is effectively | |
| # workflow_dispatch-only (and the prompt itself exits unless a terminal | |
| # marker exists on the PR). | |
| on: | |
| issue_comment: | |
| types: [created] | |
| workflow_dispatch: | |
| inputs: | |
| pr-number: | |
| description: 'PR number with deadlocked A↔B exchange to advise on' | |
| required: true | |
| type: string | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: wheels-bot-advisor-${{ github.event.issue.number || inputs.pr-number }} | |
| cancel-in-progress: false | |
| jobs: | |
| advisor: | |
| name: Senior advisor | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 | |
| # Auto-fires only on a (legacy) Reviewer B terminal marker — no longer | |
| # produced since the A/B loop was retired; see the header comment. The | |
| # bot-identity check is load-bearing. | |
| if: | | |
| vars.WHEELS_BOT_ENABLED == 'true' | |
| && ( | |
| github.event_name == 'workflow_dispatch' | |
| || (github.event_name == 'issue_comment' | |
| && github.event.comment.user.login == 'wheels-bot[bot]' | |
| && contains(github.event.comment.body, 'wheels-bot:review-b:') | |
| && contains(github.event.comment.body, ':terminal')) | |
| ) | |
| env: | |
| PR_NUMBER: ${{ github.event.issue.number || inputs.pr-number }} | |
| steps: | |
| - name: Generate App token | |
| id: app-token | |
| uses: actions/create-github-app-token@v2 | |
| with: | |
| app-id: ${{ secrets.WHEELS_BOT_APP_ID }} | |
| private-key: ${{ secrets.WHEELS_BOT_PRIVATE_KEY }} | |
| - name: Resolve PR head ref + SHA | |
| id: pr | |
| env: | |
| GH_TOKEN: ${{ steps.app-token.outputs.token }} | |
| run: | | |
| set -euo pipefail | |
| if ! [[ "$PR_NUMBER" =~ ^[0-9]+$ ]]; then | |
| echo "::error::pr-number must be numeric, got: $PR_NUMBER" | |
| exit 1 | |
| fi | |
| info=$(gh pr view "$PR_NUMBER" --repo wheels-dev/wheels --json headRefName,headRefOid) | |
| ref=$(echo "$info" | python3 -c "import json,sys; print(json.load(sys.stdin)['headRefName'])") | |
| sha=$(echo "$info" | python3 -c "import json,sys; print(json.load(sys.stdin)['headRefOid'])") | |
| echo "head=$ref" >> "$GITHUB_OUTPUT" | |
| echo "sha=$sha" >> "$GITHUB_OUTPUT" | |
| - name: Checkout PR head | |
| uses: actions/checkout@v6 | |
| with: | |
| ref: ${{ steps.pr.outputs.sha }} | |
| fetch-depth: 0 | |
| token: ${{ steps.app-token.outputs.token }} | |
| - name: Skip check | |
| id: gate | |
| uses: ./.github/actions/wheels-bot-skip-check | |
| with: | |
| target-type: pr | |
| target-number: ${{ env.PR_NUMBER }} | |
| # Fires once per SHA. If the advisor already advised at this | |
| # SHA, the marker is already present and the workflow exits. | |
| marker-pattern: 'wheels-bot:advisor:${{ env.PR_NUMBER }}:${{ steps.pr.outputs.sha }}' | |
| github-token: ${{ steps.app-token.outputs.token }} | |
| - name: Run Senior Advisor | |
| if: steps.gate.outputs.skip == 'false' | |
| uses: anthropics/claude-code-action@v1 | |
| with: | |
| # Triggered by wheels-bot[bot]'s Reviewer B comment carrying | |
| # a terminal marker. Allow that bot identity (and | |
| # github-actions[bot] for consistency). | |
| allowed_bots: 'wheels-bot[bot],github-actions[bot]' | |
| anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} | |
| github_token: ${{ steps.app-token.outputs.token }} | |
| # Thread the head SHA resolved in "Resolve PR head ref + SHA" — the | |
| # exact commit the Checkout step pinned — into the prompt as a second | |
| # argument. The advisor emits its idempotency + convergence markers | |
| # from this value instead of re-deriving it with `gh pr view`, which | |
| # races with pushes landing mid-session and left the marker pointing | |
| # at the wrong commit (issue #2848). The Run step's Bash allowlist is | |
| # gh + read-only git (no echo/printenv), so the model can't read a | |
| # step env var — the SHA must travel in the prompt text, the same | |
| # channel the PR number already uses. | |
| prompt: | | |
| /advise-on-deadlock ${{ env.PR_NUMBER }} ${{ steps.pr.outputs.sha }} | |
| # Model policy: judging gate = fable, coding stages = opus, janitorial = sonnet. | |
| claude_args: | | |
| --model claude-opus-4-8 | |
| --max-turns 500 | |
| --allowedTools "Bash(gh:*),Bash(git log:*),Bash(git diff:*),Bash(git show:*),Bash(git grep:*),Bash(git status),Read,Grep,Glob" |