fix(engine): reorder cross-provider fallback to claude → copilot → gemini - #571
Conversation
|
Warning Review limit reached
More reviews will be available in 26 minutes and 46 seconds. Learn how PR review limits work. Your organization has run out of usage credits. Purchase more credits in the billing tab to continue. ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughThe PR reorders the AI engine fallback sequence from claude → gemini → copilot to claude → copilot → gemini, updating engine-layer iteration, batch orchestration, unit tests, and gitleaks allowlists/comments. ChangesAI Engine Fallback Reordering
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
There was a problem hiding this comment.
Code Review
This pull request updates the cross-provider fallback order from claude → gemini → copilot to claude → copilot → gemini across the engine and batch scripts, with corresponding updates to the test suites. The review feedback points out that using raw gh command checks to verify Copilot availability bypasses pre-flight checks and can cause runtime failures if unsupported classic PATs are used. It is recommended to use the pre-flight COPILOT_AVAILABLE flag and explicitly guard against ghp_* tokens to ensure a robust fallback to Gemini.
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@scripts/review-batch.sh`:
- Around line 163-181: Replace the gh-based Copilot gate with the preflight
COPILOT_AVAILABLE flag and ensure Gemini is selected when Copilot is not
available or runtime returns fallback codes: check the COPILOT_AVAILABLE
env/flag before attempting the Copilot fallback (instead of `gh`), only run
`bash scripts/review-one-pr.sh` with REVIEW_ENGINE=copilot when
COPILOT_AVAILABLE is truthy, and on failure codes (55 or 127) or when
COPILOT_AVAILABLE is false set rc=2 and export REVIEW_ENGINE=gemini (update
engine_fallbacks/fallback_engines only when Copilot actually runs) so the
cascade proceeds to Gemini as intended.
- Around line 184-186: Change the fallback conditional that checks
rc/REVIEW_ENGINE/GEMINI_AVAILABLE to use the Bash conditional form [[ ... ]]
instead of [ ... ] (locate the if block that tests rc, REVIEW_ENGINE and
GEMINI_AVAILABLE), and ensure GEMINI_AVAILABLE is referenced with the
parameter-expansion default like ${GEMINI_AVAILABLE:-false} inside the [[ ...
]]; also run ShellCheck with -x to follow sourced scripts (validate_engines.sh,
engine.sh) so SC1091 warnings are suppressed during CI validation.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 599a74b7-a08d-4413-8b60-aff20fe437fd
📒 Files selected for processing (4)
scripts/engine.shscripts/review-batch.shtests/dev-lead/unit/test_engine_fallback.batstests/dev-lead/unit/test_provider_headroom.bats
|
@coderabbitai resolve |
Dev-Lead — review-changes (applied)Changes committed and pushed. |
✅ Action performedComments resolved and changes approved. |
Dev-Lead — fix-bot-comment (applied)Changes committed and pushed. |
Dev-Lead — review-changes (applied)Changes committed and pushed. |
Dev-Lead — review-changes (no-changes)No changes were needed for this PR. |
Dev-Lead — review-changes (no-changes)No changes were needed for this PR. |
|
Auto-rebase failed — merge conflict — this branch has conflicts with Claude will attempt to resolve this automatically. If it cannot, a follow-up comment will explain what needs manual attention. To resolve manually instead: |
e0f9b7c to
d8b879f
Compare
Dev-Lead — rebase (no-changes)Agent reasoning |
…mini (#571) * fix(engine): reorder cross-provider fallback to claude -> copilot -> gemini The cross-provider rate-limit fallback was claude -> gemini -> copilot, so when Claude was exhausted it fell back to Gemini *before* Copilot. With Gemini's prepayment credits depleted, that surfaced as hard 429 RESOURCE_EXHAUSTED failures (observed on markets dev-lead fix-bot-comment). Per the intended engine preference — Claude default, then Copilot, then Gemini — make Gemini the last resort. - engine.sh run_writer_with_fallback: loop order claude copilot gemini (dev-lead path). - review-batch.sh: reorder the cascade so Claude rate-limit falls to Copilot first, then Gemini (pr-review batch path); availability checks travel with each engine. - Update comments + bats (test_engine_fallback, test_provider_headroom) to the new order; force copilot-skip via a classic-PAT token where a test targets the Gemini fallback specifically. 22/22 engine tests pass; shellcheck clean. Shared engine.sh affects BOTH agents → ship via pr-review + dev-lead releases. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore: apply manual instructions [skip ci-relay] * fix(bot): address bot feedback [skip ci-relay] * chore: apply manual instructions [skip ci-relay] * fix(tests): skip copilot fallback in writer tests after claude → copilot → gemini reorder Tests 152 and 168 in test_engine_writer.bats expected run_writer_with_fallback to reach gemini when claude is rate-limited. With the new fallback order (claude → copilot → gemini), copilot is tried first; without GH_TOKEN or COPILOT_GITHUB_TOKEN set, copilot_chat returns 1 (not 2/127) and halts fallback propagation before gemini is reached. Add `COPILOT_GITHUB_TOKEN=ghp_stub` (a classic-PAT prefix) to both tests so the copilot leg is skipped, matching the same approach used in test_engine_fallback.bats. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(bot): address bot feedback [skip ci-relay] * fix(bot): address bot feedback [skip ci-relay] --------- Co-authored-by: donpetry-bot <{}+donpetry-bot@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
…mini (#571) * fix(engine): reorder cross-provider fallback to claude -> copilot -> gemini The cross-provider rate-limit fallback was claude -> gemini -> copilot, so when Claude was exhausted it fell back to Gemini *before* Copilot. With Gemini's prepayment credits depleted, that surfaced as hard 429 RESOURCE_EXHAUSTED failures (observed on markets dev-lead fix-bot-comment). Per the intended engine preference — Claude default, then Copilot, then Gemini — make Gemini the last resort. - engine.sh run_writer_with_fallback: loop order claude copilot gemini (dev-lead path). - review-batch.sh: reorder the cascade so Claude rate-limit falls to Copilot first, then Gemini (pr-review batch path); availability checks travel with each engine. - Update comments + bats (test_engine_fallback, test_provider_headroom) to the new order; force copilot-skip via a classic-PAT token where a test targets the Gemini fallback specifically. 22/22 engine tests pass; shellcheck clean. Shared engine.sh affects BOTH agents → ship via pr-review + dev-lead releases. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore: apply manual instructions [skip ci-relay] * fix(bot): address bot feedback [skip ci-relay] * chore: apply manual instructions [skip ci-relay] * fix(tests): skip copilot fallback in writer tests after claude → copilot → gemini reorder Tests 152 and 168 in test_engine_writer.bats expected run_writer_with_fallback to reach gemini when claude is rate-limited. With the new fallback order (claude → copilot → gemini), copilot is tried first; without GH_TOKEN or COPILOT_GITHUB_TOKEN set, copilot_chat returns 1 (not 2/127) and halts fallback propagation before gemini is reached. Add `COPILOT_GITHUB_TOKEN=ghp_stub` (a classic-PAT prefix) to both tests so the copilot leg is skipped, matching the same approach used in test_engine_fallback.bats. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(bot): address bot feedback [skip ci-relay] * fix(bot): address bot feedback [skip ci-relay] --------- Co-authored-by: donpetry-bot <{}+donpetry-bot@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
…mini (#571) * fix(engine): reorder cross-provider fallback to claude -> copilot -> gemini The cross-provider rate-limit fallback was claude -> gemini -> copilot, so when Claude was exhausted it fell back to Gemini *before* Copilot. With Gemini's prepayment credits depleted, that surfaced as hard 429 RESOURCE_EXHAUSTED failures (observed on markets dev-lead fix-bot-comment). Per the intended engine preference — Claude default, then Copilot, then Gemini — make Gemini the last resort. - engine.sh run_writer_with_fallback: loop order claude copilot gemini (dev-lead path). - review-batch.sh: reorder the cascade so Claude rate-limit falls to Copilot first, then Gemini (pr-review batch path); availability checks travel with each engine. - Update comments + bats (test_engine_fallback, test_provider_headroom) to the new order; force copilot-skip via a classic-PAT token where a test targets the Gemini fallback specifically. 22/22 engine tests pass; shellcheck clean. Shared engine.sh affects BOTH agents → ship via pr-review + dev-lead releases. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore: apply manual instructions [skip ci-relay] * fix(bot): address bot feedback [skip ci-relay] * chore: apply manual instructions [skip ci-relay] * fix(tests): skip copilot fallback in writer tests after claude → copilot → gemini reorder Tests 152 and 168 in test_engine_writer.bats expected run_writer_with_fallback to reach gemini when claude is rate-limited. With the new fallback order (claude → copilot → gemini), copilot is tried first; without GH_TOKEN or COPILOT_GITHUB_TOKEN set, copilot_chat returns 1 (not 2/127) and halts fallback propagation before gemini is reached. Add `COPILOT_GITHUB_TOKEN=ghp_stub` (a classic-PAT prefix) to both tests so the copilot leg is skipped, matching the same approach used in test_engine_fallback.bats. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(bot): address bot feedback [skip ci-relay] * fix(bot): address bot feedback [skip ci-relay] --------- Co-authored-by: donpetry-bot <{}+donpetry-bot@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
…mini (#571) * fix(engine): reorder cross-provider fallback to claude -> copilot -> gemini The cross-provider rate-limit fallback was claude -> gemini -> copilot, so when Claude was exhausted it fell back to Gemini *before* Copilot. With Gemini's prepayment credits depleted, that surfaced as hard 429 RESOURCE_EXHAUSTED failures (observed on markets dev-lead fix-bot-comment). Per the intended engine preference — Claude default, then Copilot, then Gemini — make Gemini the last resort. - engine.sh run_writer_with_fallback: loop order claude copilot gemini (dev-lead path). - review-batch.sh: reorder the cascade so Claude rate-limit falls to Copilot first, then Gemini (pr-review batch path); availability checks travel with each engine. - Update comments + bats (test_engine_fallback, test_provider_headroom) to the new order; force copilot-skip via a classic-PAT token where a test targets the Gemini fallback specifically. 22/22 engine tests pass; shellcheck clean. Shared engine.sh affects BOTH agents → ship via pr-review + dev-lead releases. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore: apply manual instructions [skip ci-relay] * fix(bot): address bot feedback [skip ci-relay] * chore: apply manual instructions [skip ci-relay] * fix(tests): skip copilot fallback in writer tests after claude → copilot → gemini reorder Tests 152 and 168 in test_engine_writer.bats expected run_writer_with_fallback to reach gemini when claude is rate-limited. With the new fallback order (claude → copilot → gemini), copilot is tried first; without GH_TOKEN or COPILOT_GITHUB_TOKEN set, copilot_chat returns 1 (not 2/127) and halts fallback propagation before gemini is reached. Add `COPILOT_GITHUB_TOKEN=ghp_stub` (a classic-PAT prefix) to both tests so the copilot leg is skipped, matching the same approach used in test_engine_fallback.bats. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(bot): address bot feedback [skip ci-relay] * fix(bot): address bot feedback [skip ci-relay] --------- Co-authored-by: donpetry-bot <{}+donpetry-bot@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
…mini (#571) * fix(engine): reorder cross-provider fallback to claude -> copilot -> gemini The cross-provider rate-limit fallback was claude -> gemini -> copilot, so when Claude was exhausted it fell back to Gemini *before* Copilot. With Gemini's prepayment credits depleted, that surfaced as hard 429 RESOURCE_EXHAUSTED failures (observed on markets dev-lead fix-bot-comment). Per the intended engine preference — Claude default, then Copilot, then Gemini — make Gemini the last resort. - engine.sh run_writer_with_fallback: loop order claude copilot gemini (dev-lead path). - review-batch.sh: reorder the cascade so Claude rate-limit falls to Copilot first, then Gemini (pr-review batch path); availability checks travel with each engine. - Update comments + bats (test_engine_fallback, test_provider_headroom) to the new order; force copilot-skip via a classic-PAT token where a test targets the Gemini fallback specifically. 22/22 engine tests pass; shellcheck clean. Shared engine.sh affects BOTH agents → ship via pr-review + dev-lead releases. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore: apply manual instructions [skip ci-relay] * fix(bot): address bot feedback [skip ci-relay] * chore: apply manual instructions [skip ci-relay] * fix(tests): skip copilot fallback in writer tests after claude → copilot → gemini reorder Tests 152 and 168 in test_engine_writer.bats expected run_writer_with_fallback to reach gemini when claude is rate-limited. With the new fallback order (claude → copilot → gemini), copilot is tried first; without GH_TOKEN or COPILOT_GITHUB_TOKEN set, copilot_chat returns 1 (not 2/127) and halts fallback propagation before gemini is reached. Add `COPILOT_GITHUB_TOKEN=ghp_stub` (a classic-PAT prefix) to both tests so the copilot leg is skipped, matching the same approach used in test_engine_fallback.bats. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(bot): address bot feedback [skip ci-relay] * fix(bot): address bot feedback [skip ci-relay] --------- Co-authored-by: donpetry-bot <{}+donpetry-bot@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
…mini (#571) * fix(engine): reorder cross-provider fallback to claude -> copilot -> gemini The cross-provider rate-limit fallback was claude -> gemini -> copilot, so when Claude was exhausted it fell back to Gemini *before* Copilot. With Gemini's prepayment credits depleted, that surfaced as hard 429 RESOURCE_EXHAUSTED failures (observed on markets dev-lead fix-bot-comment). Per the intended engine preference — Claude default, then Copilot, then Gemini — make Gemini the last resort. - engine.sh run_writer_with_fallback: loop order claude copilot gemini (dev-lead path). - review-batch.sh: reorder the cascade so Claude rate-limit falls to Copilot first, then Gemini (pr-review batch path); availability checks travel with each engine. - Update comments + bats (test_engine_fallback, test_provider_headroom) to the new order; force copilot-skip via a classic-PAT token where a test targets the Gemini fallback specifically. 22/22 engine tests pass; shellcheck clean. Shared engine.sh affects BOTH agents → ship via pr-review + dev-lead releases. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore: apply manual instructions [skip ci-relay] * fix(bot): address bot feedback [skip ci-relay] * chore: apply manual instructions [skip ci-relay] * fix(tests): skip copilot fallback in writer tests after claude → copilot → gemini reorder Tests 152 and 168 in test_engine_writer.bats expected run_writer_with_fallback to reach gemini when claude is rate-limited. With the new fallback order (claude → copilot → gemini), copilot is tried first; without GH_TOKEN or COPILOT_GITHUB_TOKEN set, copilot_chat returns 1 (not 2/127) and halts fallback propagation before gemini is reached. Add `COPILOT_GITHUB_TOKEN=ghp_stub` (a classic-PAT prefix) to both tests so the copilot leg is skipped, matching the same approach used in test_engine_fallback.bats. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(bot): address bot feedback [skip ci-relay] * fix(bot): address bot feedback [skip ci-relay] --------- Co-authored-by: donpetry-bot <{}+donpetry-bot@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
The compliance test encoded the pre-#571 contract — it required the reusable `with:` to source target_discussion/enhance_backlog from `${{ inputs.* }}`, the exact pattern that fails at workflow setup on the discussion trigger. Update the assertions to the prep-routed shape (needs.prep.outputs.*, booleans via fromJSON) and add a guard that no reusable `with:` value references the `inputs` context. Refs: petry-projects/.github#571
…1113) * fix(feature-ideation): route caller inputs through a prep job (#571) This repo's feature-ideation caller carried the same #571 defect fixed in the central template (petry-projects/.github#615): the `ideate` job's reusable `with:` referenced `${{ inputs.* }}`, which is evaluated at workflow setup regardless of the job `if:` and so fails the whole run (zero jobs) on the `discussion: created` trigger — the exact path that auto-enhances new Ideas. Resolve dispatch inputs in a gated `prep` job and pass them to `ideate` via `needs.prep.outputs.*` (booleans via fromJSON). The `feature-ideation/next` channel pin is unchanged. As the `next` ring this dogfoods the fix ahead of the fleet rollout tracked in petry-projects/.github#614. Refs: petry-projects/.github#571, petry-projects/.github#614 * test(feature-ideation): assert prep-routed inputs, add #571 guard The compliance test encoded the pre-#571 contract — it required the reusable `with:` to source target_discussion/enhance_backlog from `${{ inputs.* }}`, the exact pattern that fails at workflow setup on the discussion trigger. Update the assertions to the prep-routed shape (needs.prep.outputs.*, booleans via fromJSON) and add a guard that no reusable `with:` value references the `inputs` context. Refs: petry-projects/.github#571 --------- Co-authored-by: donpetry-bot <{}+donpetry-bot@users.noreply.github.com>
…mini (#571) * fix(engine): reorder cross-provider fallback to claude -> copilot -> gemini The cross-provider rate-limit fallback was claude -> gemini -> copilot, so when Claude was exhausted it fell back to Gemini *before* Copilot. With Gemini's prepayment credits depleted, that surfaced as hard 429 RESOURCE_EXHAUSTED failures (observed on markets dev-lead fix-bot-comment). Per the intended engine preference — Claude default, then Copilot, then Gemini — make Gemini the last resort. - engine.sh run_writer_with_fallback: loop order claude copilot gemini (dev-lead path). - review-batch.sh: reorder the cascade so Claude rate-limit falls to Copilot first, then Gemini (pr-review batch path); availability checks travel with each engine. - Update comments + bats (test_engine_fallback, test_provider_headroom) to the new order; force copilot-skip via a classic-PAT token where a test targets the Gemini fallback specifically. 22/22 engine tests pass; shellcheck clean. Shared engine.sh affects BOTH agents → ship via pr-review + dev-lead releases. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore: apply manual instructions [skip ci-relay] * fix(bot): address bot feedback [skip ci-relay] * chore: apply manual instructions [skip ci-relay] * fix(tests): skip copilot fallback in writer tests after claude → copilot → gemini reorder Tests 152 and 168 in test_engine_writer.bats expected run_writer_with_fallback to reach gemini when claude is rate-limited. With the new fallback order (claude → copilot → gemini), copilot is tried first; without GH_TOKEN or COPILOT_GITHUB_TOKEN set, copilot_chat returns 1 (not 2/127) and halts fallback propagation before gemini is reached. Add `COPILOT_GITHUB_TOKEN=ghp_stub` (a classic-PAT prefix) to both tests so the copilot leg is skipped, matching the same approach used in test_engine_fallback.bats. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(bot): address bot feedback [skip ci-relay] * fix(bot): address bot feedback [skip ci-relay] --------- Co-authored-by: donpetry-bot <{}+donpetry-bot@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
…1113) * fix(feature-ideation): route caller inputs through a prep job (#571) This repo's feature-ideation caller carried the same #571 defect fixed in the central template (petry-projects/.github#615): the `ideate` job's reusable `with:` referenced `${{ inputs.* }}`, which is evaluated at workflow setup regardless of the job `if:` and so fails the whole run (zero jobs) on the `discussion: created` trigger — the exact path that auto-enhances new Ideas. Resolve dispatch inputs in a gated `prep` job and pass them to `ideate` via `needs.prep.outputs.*` (booleans via fromJSON). The `feature-ideation/next` channel pin is unchanged. As the `next` ring this dogfoods the fix ahead of the fleet rollout tracked in petry-projects/.github#614. Refs: petry-projects/.github#571, petry-projects/.github#614 * test(feature-ideation): assert prep-routed inputs, add #571 guard The compliance test encoded the pre-#571 contract — it required the reusable `with:` to source target_discussion/enhance_backlog from `${{ inputs.* }}`, the exact pattern that fails at workflow setup on the discussion trigger. Update the assertions to the prep-routed shape (needs.prep.outputs.*, booleans via fromJSON) and add a guard that no reusable `with:` value references the `inputs` context. Refs: petry-projects/.github#571 --------- Co-authored-by: donpetry-bot <{}+donpetry-bot@users.noreply.github.com>
…mini (#571) * fix(engine): reorder cross-provider fallback to claude -> copilot -> gemini The cross-provider rate-limit fallback was claude -> gemini -> copilot, so when Claude was exhausted it fell back to Gemini *before* Copilot. With Gemini's prepayment credits depleted, that surfaced as hard 429 RESOURCE_EXHAUSTED failures (observed on markets dev-lead fix-bot-comment). Per the intended engine preference — Claude default, then Copilot, then Gemini — make Gemini the last resort. - engine.sh run_writer_with_fallback: loop order claude copilot gemini (dev-lead path). - review-batch.sh: reorder the cascade so Claude rate-limit falls to Copilot first, then Gemini (pr-review batch path); availability checks travel with each engine. - Update comments + bats (test_engine_fallback, test_provider_headroom) to the new order; force copilot-skip via a classic-PAT token where a test targets the Gemini fallback specifically. 22/22 engine tests pass; shellcheck clean. Shared engine.sh affects BOTH agents → ship via pr-review + dev-lead releases. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore: apply manual instructions [skip ci-relay] * fix(bot): address bot feedback [skip ci-relay] * chore: apply manual instructions [skip ci-relay] * fix(tests): skip copilot fallback in writer tests after claude → copilot → gemini reorder Tests 152 and 168 in test_engine_writer.bats expected run_writer_with_fallback to reach gemini when claude is rate-limited. With the new fallback order (claude → copilot → gemini), copilot is tried first; without GH_TOKEN or COPILOT_GITHUB_TOKEN set, copilot_chat returns 1 (not 2/127) and halts fallback propagation before gemini is reached. Add `COPILOT_GITHUB_TOKEN=ghp_stub` (a classic-PAT prefix) to both tests so the copilot leg is skipped, matching the same approach used in test_engine_fallback.bats. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(bot): address bot feedback [skip ci-relay] * fix(bot): address bot feedback [skip ci-relay] --------- Co-authored-by: donpetry-bot <{}+donpetry-bot@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
…1113) * fix(feature-ideation): route caller inputs through a prep job (#571) This repo's feature-ideation caller carried the same #571 defect fixed in the central template (petry-projects/.github#615): the `ideate` job's reusable `with:` referenced `${{ inputs.* }}`, which is evaluated at workflow setup regardless of the job `if:` and so fails the whole run (zero jobs) on the `discussion: created` trigger — the exact path that auto-enhances new Ideas. Resolve dispatch inputs in a gated `prep` job and pass them to `ideate` via `needs.prep.outputs.*` (booleans via fromJSON). The `feature-ideation/next` channel pin is unchanged. As the `next` ring this dogfoods the fix ahead of the fleet rollout tracked in petry-projects/.github#614. Refs: petry-projects/.github#571, petry-projects/.github#614 * test(feature-ideation): assert prep-routed inputs, add #571 guard The compliance test encoded the pre-#571 contract — it required the reusable `with:` to source target_discussion/enhance_backlog from `${{ inputs.* }}`, the exact pattern that fails at workflow setup on the discussion trigger. Update the assertions to the prep-routed shape (needs.prep.outputs.*, booleans via fromJSON) and add a guard that no reusable `with:` value references the `inputs` context. Refs: petry-projects/.github#571 --------- Co-authored-by: donpetry-bot <{}+donpetry-bot@users.noreply.github.com>
…mini (#571) * fix(engine): reorder cross-provider fallback to claude -> copilot -> gemini The cross-provider rate-limit fallback was claude -> gemini -> copilot, so when Claude was exhausted it fell back to Gemini *before* Copilot. With Gemini's prepayment credits depleted, that surfaced as hard 429 RESOURCE_EXHAUSTED failures (observed on markets dev-lead fix-bot-comment). Per the intended engine preference — Claude default, then Copilot, then Gemini — make Gemini the last resort. - engine.sh run_writer_with_fallback: loop order claude copilot gemini (dev-lead path). - review-batch.sh: reorder the cascade so Claude rate-limit falls to Copilot first, then Gemini (pr-review batch path); availability checks travel with each engine. - Update comments + bats (test_engine_fallback, test_provider_headroom) to the new order; force copilot-skip via a classic-PAT token where a test targets the Gemini fallback specifically. 22/22 engine tests pass; shellcheck clean. Shared engine.sh affects BOTH agents → ship via pr-review + dev-lead releases. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore: apply manual instructions [skip ci-relay] * fix(bot): address bot feedback [skip ci-relay] * chore: apply manual instructions [skip ci-relay] * fix(tests): skip copilot fallback in writer tests after claude → copilot → gemini reorder Tests 152 and 168 in test_engine_writer.bats expected run_writer_with_fallback to reach gemini when claude is rate-limited. With the new fallback order (claude → copilot → gemini), copilot is tried first; without GH_TOKEN or COPILOT_GITHUB_TOKEN set, copilot_chat returns 1 (not 2/127) and halts fallback propagation before gemini is reached. Add `COPILOT_GITHUB_TOKEN=ghp_stub` (a classic-PAT prefix) to both tests so the copilot leg is skipped, matching the same approach used in test_engine_fallback.bats. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(bot): address bot feedback [skip ci-relay] * fix(bot): address bot feedback [skip ci-relay] --------- Co-authored-by: donpetry-bot <{}+donpetry-bot@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
…1113) * fix(feature-ideation): route caller inputs through a prep job (#571) This repo's feature-ideation caller carried the same #571 defect fixed in the central template (petry-projects/.github#615): the `ideate` job's reusable `with:` referenced `${{ inputs.* }}`, which is evaluated at workflow setup regardless of the job `if:` and so fails the whole run (zero jobs) on the `discussion: created` trigger — the exact path that auto-enhances new Ideas. Resolve dispatch inputs in a gated `prep` job and pass them to `ideate` via `needs.prep.outputs.*` (booleans via fromJSON). The `feature-ideation/next` channel pin is unchanged. As the `next` ring this dogfoods the fix ahead of the fleet rollout tracked in petry-projects/.github#614. Refs: petry-projects/.github#571, petry-projects/.github#614 * test(feature-ideation): assert prep-routed inputs, add #571 guard The compliance test encoded the pre-#571 contract — it required the reusable `with:` to source target_discussion/enhance_backlog from `${{ inputs.* }}`, the exact pattern that fails at workflow setup on the discussion trigger. Update the assertions to the prep-routed shape (needs.prep.outputs.*, booleans via fromJSON) and add a guard that no reusable `with:` value references the `inputs` context. Refs: petry-projects/.github#571 --------- Co-authored-by: donpetry-bot <{}+donpetry-bot@users.noreply.github.com>
…mini (#571) * fix(engine): reorder cross-provider fallback to claude -> copilot -> gemini The cross-provider rate-limit fallback was claude -> gemini -> copilot, so when Claude was exhausted it fell back to Gemini *before* Copilot. With Gemini's prepayment credits depleted, that surfaced as hard 429 RESOURCE_EXHAUSTED failures (observed on markets dev-lead fix-bot-comment). Per the intended engine preference — Claude default, then Copilot, then Gemini — make Gemini the last resort. - engine.sh run_writer_with_fallback: loop order claude copilot gemini (dev-lead path). - review-batch.sh: reorder the cascade so Claude rate-limit falls to Copilot first, then Gemini (pr-review batch path); availability checks travel with each engine. - Update comments + bats (test_engine_fallback, test_provider_headroom) to the new order; force copilot-skip via a classic-PAT token where a test targets the Gemini fallback specifically. 22/22 engine tests pass; shellcheck clean. Shared engine.sh affects BOTH agents → ship via pr-review + dev-lead releases. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore: apply manual instructions [skip ci-relay] * fix(bot): address bot feedback [skip ci-relay] * chore: apply manual instructions [skip ci-relay] * fix(tests): skip copilot fallback in writer tests after claude → copilot → gemini reorder Tests 152 and 168 in test_engine_writer.bats expected run_writer_with_fallback to reach gemini when claude is rate-limited. With the new fallback order (claude → copilot → gemini), copilot is tried first; without GH_TOKEN or COPILOT_GITHUB_TOKEN set, copilot_chat returns 1 (not 2/127) and halts fallback propagation before gemini is reached. Add `COPILOT_GITHUB_TOKEN=ghp_stub` (a classic-PAT prefix) to both tests so the copilot leg is skipped, matching the same approach used in test_engine_fallback.bats. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(bot): address bot feedback [skip ci-relay] * fix(bot): address bot feedback [skip ci-relay] --------- Co-authored-by: donpetry-bot <{}+donpetry-bot@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
…1113) * fix(feature-ideation): route caller inputs through a prep job (#571) This repo's feature-ideation caller carried the same #571 defect fixed in the central template (petry-projects/.github#615): the `ideate` job's reusable `with:` referenced `${{ inputs.* }}`, which is evaluated at workflow setup regardless of the job `if:` and so fails the whole run (zero jobs) on the `discussion: created` trigger — the exact path that auto-enhances new Ideas. Resolve dispatch inputs in a gated `prep` job and pass them to `ideate` via `needs.prep.outputs.*` (booleans via fromJSON). The `feature-ideation/next` channel pin is unchanged. As the `next` ring this dogfoods the fix ahead of the fleet rollout tracked in petry-projects/.github#614. Refs: petry-projects/.github#571, petry-projects/.github#614 * test(feature-ideation): assert prep-routed inputs, add #571 guard The compliance test encoded the pre-#571 contract — it required the reusable `with:` to source target_discussion/enhance_backlog from `${{ inputs.* }}`, the exact pattern that fails at workflow setup on the discussion trigger. Update the assertions to the prep-routed shape (needs.prep.outputs.*, booleans via fromJSON) and add a guard that no reusable `with:` value references the `inputs` context. Refs: petry-projects/.github#571 --------- Co-authored-by: donpetry-bot <{}+donpetry-bot@users.noreply.github.com>
…mini (#571) * fix(engine): reorder cross-provider fallback to claude -> copilot -> gemini The cross-provider rate-limit fallback was claude -> gemini -> copilot, so when Claude was exhausted it fell back to Gemini *before* Copilot. With Gemini's prepayment credits depleted, that surfaced as hard 429 RESOURCE_EXHAUSTED failures (observed on markets dev-lead fix-bot-comment). Per the intended engine preference — Claude default, then Copilot, then Gemini — make Gemini the last resort. - engine.sh run_writer_with_fallback: loop order claude copilot gemini (dev-lead path). - review-batch.sh: reorder the cascade so Claude rate-limit falls to Copilot first, then Gemini (pr-review batch path); availability checks travel with each engine. - Update comments + bats (test_engine_fallback, test_provider_headroom) to the new order; force copilot-skip via a classic-PAT token where a test targets the Gemini fallback specifically. 22/22 engine tests pass; shellcheck clean. Shared engine.sh affects BOTH agents → ship via pr-review + dev-lead releases. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore: apply manual instructions [skip ci-relay] * fix(bot): address bot feedback [skip ci-relay] * chore: apply manual instructions [skip ci-relay] * fix(tests): skip copilot fallback in writer tests after claude → copilot → gemini reorder Tests 152 and 168 in test_engine_writer.bats expected run_writer_with_fallback to reach gemini when claude is rate-limited. With the new fallback order (claude → copilot → gemini), copilot is tried first; without GH_TOKEN or COPILOT_GITHUB_TOKEN set, copilot_chat returns 1 (not 2/127) and halts fallback propagation before gemini is reached. Add `COPILOT_GITHUB_TOKEN=ghp_stub` (a classic-PAT prefix) to both tests so the copilot leg is skipped, matching the same approach used in test_engine_fallback.bats. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(bot): address bot feedback [skip ci-relay] * fix(bot): address bot feedback [skip ci-relay] --------- Co-authored-by: donpetry-bot <{}+donpetry-bot@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
…1113) * fix(feature-ideation): route caller inputs through a prep job (#571) This repo's feature-ideation caller carried the same #571 defect fixed in the central template (petry-projects/.github#615): the `ideate` job's reusable `with:` referenced `${{ inputs.* }}`, which is evaluated at workflow setup regardless of the job `if:` and so fails the whole run (zero jobs) on the `discussion: created` trigger — the exact path that auto-enhances new Ideas. Resolve dispatch inputs in a gated `prep` job and pass them to `ideate` via `needs.prep.outputs.*` (booleans via fromJSON). The `feature-ideation/next` channel pin is unchanged. As the `next` ring this dogfoods the fix ahead of the fleet rollout tracked in petry-projects/.github#614. Refs: petry-projects/.github#571, petry-projects/.github#614 * test(feature-ideation): assert prep-routed inputs, add #571 guard The compliance test encoded the pre-#571 contract — it required the reusable `with:` to source target_discussion/enhance_backlog from `${{ inputs.* }}`, the exact pattern that fails at workflow setup on the discussion trigger. Update the assertions to the prep-routed shape (needs.prep.outputs.*, booleans via fromJSON) and add a guard that no reusable `with:` value references the `inputs` context. Refs: petry-projects/.github#571 --------- Co-authored-by: donpetry-bot <{}+donpetry-bot@users.noreply.github.com>
…mini (#571) * fix(engine): reorder cross-provider fallback to claude -> copilot -> gemini The cross-provider rate-limit fallback was claude -> gemini -> copilot, so when Claude was exhausted it fell back to Gemini *before* Copilot. With Gemini's prepayment credits depleted, that surfaced as hard 429 RESOURCE_EXHAUSTED failures (observed on markets dev-lead fix-bot-comment). Per the intended engine preference — Claude default, then Copilot, then Gemini — make Gemini the last resort. - engine.sh run_writer_with_fallback: loop order claude copilot gemini (dev-lead path). - review-batch.sh: reorder the cascade so Claude rate-limit falls to Copilot first, then Gemini (pr-review batch path); availability checks travel with each engine. - Update comments + bats (test_engine_fallback, test_provider_headroom) to the new order; force copilot-skip via a classic-PAT token where a test targets the Gemini fallback specifically. 22/22 engine tests pass; shellcheck clean. Shared engine.sh affects BOTH agents → ship via pr-review + dev-lead releases. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore: apply manual instructions [skip ci-relay] * fix(bot): address bot feedback [skip ci-relay] * chore: apply manual instructions [skip ci-relay] * fix(tests): skip copilot fallback in writer tests after claude → copilot → gemini reorder Tests 152 and 168 in test_engine_writer.bats expected run_writer_with_fallback to reach gemini when claude is rate-limited. With the new fallback order (claude → copilot → gemini), copilot is tried first; without GH_TOKEN or COPILOT_GITHUB_TOKEN set, copilot_chat returns 1 (not 2/127) and halts fallback propagation before gemini is reached. Add `COPILOT_GITHUB_TOKEN=ghp_stub` (a classic-PAT prefix) to both tests so the copilot leg is skipped, matching the same approach used in test_engine_fallback.bats. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(bot): address bot feedback [skip ci-relay] * fix(bot): address bot feedback [skip ci-relay] --------- Co-authored-by: donpetry-bot <{}+donpetry-bot@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
…mini (#571) * fix(engine): reorder cross-provider fallback to claude -> copilot -> gemini The cross-provider rate-limit fallback was claude -> gemini -> copilot, so when Claude was exhausted it fell back to Gemini *before* Copilot. With Gemini's prepayment credits depleted, that surfaced as hard 429 RESOURCE_EXHAUSTED failures (observed on markets dev-lead fix-bot-comment). Per the intended engine preference — Claude default, then Copilot, then Gemini — make Gemini the last resort. - engine.sh run_writer_with_fallback: loop order claude copilot gemini (dev-lead path). - review-batch.sh: reorder the cascade so Claude rate-limit falls to Copilot first, then Gemini (pr-review batch path); availability checks travel with each engine. - Update comments + bats (test_engine_fallback, test_provider_headroom) to the new order; force copilot-skip via a classic-PAT token where a test targets the Gemini fallback specifically. 22/22 engine tests pass; shellcheck clean. Shared engine.sh affects BOTH agents → ship via pr-review + dev-lead releases. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore: apply manual instructions [skip ci-relay] * fix(bot): address bot feedback [skip ci-relay] * chore: apply manual instructions [skip ci-relay] * fix(tests): skip copilot fallback in writer tests after claude → copilot → gemini reorder Tests 152 and 168 in test_engine_writer.bats expected run_writer_with_fallback to reach gemini when claude is rate-limited. With the new fallback order (claude → copilot → gemini), copilot is tried first; without GH_TOKEN or COPILOT_GITHUB_TOKEN set, copilot_chat returns 1 (not 2/127) and halts fallback propagation before gemini is reached. Add `COPILOT_GITHUB_TOKEN=ghp_stub` (a classic-PAT prefix) to both tests so the copilot leg is skipped, matching the same approach used in test_engine_fallback.bats. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(bot): address bot feedback [skip ci-relay] * fix(bot): address bot feedback [skip ci-relay] --------- Co-authored-by: donpetry-bot <{}+donpetry-bot@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
…1113) * fix(feature-ideation): route caller inputs through a prep job (#571) This repo's feature-ideation caller carried the same #571 defect fixed in the central template (petry-projects/.github#615): the `ideate` job's reusable `with:` referenced `${{ inputs.* }}`, which is evaluated at workflow setup regardless of the job `if:` and so fails the whole run (zero jobs) on the `discussion: created` trigger — the exact path that auto-enhances new Ideas. Resolve dispatch inputs in a gated `prep` job and pass them to `ideate` via `needs.prep.outputs.*` (booleans via fromJSON). The `feature-ideation/next` channel pin is unchanged. As the `next` ring this dogfoods the fix ahead of the fleet rollout tracked in petry-projects/.github#614. Refs: petry-projects/.github#571, petry-projects/.github#614 * test(feature-ideation): assert prep-routed inputs, add #571 guard The compliance test encoded the pre-#571 contract — it required the reusable `with:` to source target_discussion/enhance_backlog from `${{ inputs.* }}`, the exact pattern that fails at workflow setup on the discussion trigger. Update the assertions to the prep-routed shape (needs.prep.outputs.*, booleans via fromJSON) and add a guard that no reusable `with:` value references the `inputs` context. Refs: petry-projects/.github#571 --------- Co-authored-by: donpetry-bot <{}+donpetry-bot@users.noreply.github.com>
…mini (#571) * fix(engine): reorder cross-provider fallback to claude -> copilot -> gemini The cross-provider rate-limit fallback was claude -> gemini -> copilot, so when Claude was exhausted it fell back to Gemini *before* Copilot. With Gemini's prepayment credits depleted, that surfaced as hard 429 RESOURCE_EXHAUSTED failures (observed on markets dev-lead fix-bot-comment). Per the intended engine preference — Claude default, then Copilot, then Gemini — make Gemini the last resort. - engine.sh run_writer_with_fallback: loop order claude copilot gemini (dev-lead path). - review-batch.sh: reorder the cascade so Claude rate-limit falls to Copilot first, then Gemini (pr-review batch path); availability checks travel with each engine. - Update comments + bats (test_engine_fallback, test_provider_headroom) to the new order; force copilot-skip via a classic-PAT token where a test targets the Gemini fallback specifically. 22/22 engine tests pass; shellcheck clean. Shared engine.sh affects BOTH agents → ship via pr-review + dev-lead releases. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore: apply manual instructions [skip ci-relay] * fix(bot): address bot feedback [skip ci-relay] * chore: apply manual instructions [skip ci-relay] * fix(tests): skip copilot fallback in writer tests after claude → copilot → gemini reorder Tests 152 and 168 in test_engine_writer.bats expected run_writer_with_fallback to reach gemini when claude is rate-limited. With the new fallback order (claude → copilot → gemini), copilot is tried first; without GH_TOKEN or COPILOT_GITHUB_TOKEN set, copilot_chat returns 1 (not 2/127) and halts fallback propagation before gemini is reached. Add `COPILOT_GITHUB_TOKEN=ghp_stub` (a classic-PAT prefix) to both tests so the copilot leg is skipped, matching the same approach used in test_engine_fallback.bats. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(bot): address bot feedback [skip ci-relay] * fix(bot): address bot feedback [skip ci-relay] --------- Co-authored-by: donpetry-bot <{}+donpetry-bot@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
…1113) * fix(feature-ideation): route caller inputs through a prep job (#571) This repo's feature-ideation caller carried the same #571 defect fixed in the central template (petry-projects/.github#615): the `ideate` job's reusable `with:` referenced `${{ inputs.* }}`, which is evaluated at workflow setup regardless of the job `if:` and so fails the whole run (zero jobs) on the `discussion: created` trigger — the exact path that auto-enhances new Ideas. Resolve dispatch inputs in a gated `prep` job and pass them to `ideate` via `needs.prep.outputs.*` (booleans via fromJSON). The `feature-ideation/next` channel pin is unchanged. As the `next` ring this dogfoods the fix ahead of the fleet rollout tracked in petry-projects/.github#614. Refs: petry-projects/.github#571, petry-projects/.github#614 * test(feature-ideation): assert prep-routed inputs, add #571 guard The compliance test encoded the pre-#571 contract — it required the reusable `with:` to source target_discussion/enhance_backlog from `${{ inputs.* }}`, the exact pattern that fails at workflow setup on the discussion trigger. Update the assertions to the prep-routed shape (needs.prep.outputs.*, booleans via fromJSON) and add a guard that no reusable `with:` value references the `inputs` context. Refs: petry-projects/.github#571 --------- Co-authored-by: donpetry-bot <{}+donpetry-bot@users.noreply.github.com>
Why
The cross-provider rate-limit fallback chain was
claude → gemini → copilot, so when Claude is exhausted it falls to Gemini before Copilot. With Gemini's prepayment credits depleted, that surfaced as hard429 RESOURCE_EXHAUSTEDfailures (found by the post-implementation health check — markets dev-leadfix-bot-comment).Per the intended engine preference — Claude default → Copilot → Gemini — Gemini should be the last resort. (Note:
DEV_LEAD_ENGINEdefault is alreadyclaudeand no override is set; the bug was purely the fallback order.)Change
engine.shrun_writer_with_fallback(dev-lead path): loop orderclaude copilot gemini.review-batch.sh(pr-review batch path): reorder the cascade so a Claude rate-limit falls to Copilot first, then Gemini; each engine's availability check travels with it.test_engine_fallback,test_provider_headroom); where a test specifically targets the Gemini fallback, Copilot is forced to skip via a classic-PAT token.Validation
Rollout
engine.shis shared, so this ships via both agent releases: cutpr-review/vX+dev-lead/vXand promote both channels.🤖 Generated with Claude Code
Summary by CodeRabbit
Chores
Tests
Documentation / Config