Skip to content

Add max-ai-credits budget support across frontmatter, AWF config, imports, and failure reporting, and remove default max-effective-tokens 25M fallback#37235

Merged
pelikhan merged 4 commits into
mainfrom
copilot/add-max-ai-credits-field
Jun 6, 2026
Merged

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Jun 6, 2026

This change introduces a new top-level frontmatter field, max-ai-credits, as a templatable integer budget (default 1000), parallel to existing budget controls. It propagates through compile/import resolution into AWF apiProxy.maxAiCredits, and surfaces budget overage as a dedicated failure context in agent issues/comments.

In addition, based on PR feedback, this update removes the built-in 25M default for max-effective-tokens. When unset, ET budget is now omitted unless provided explicitly (frontmatter/imports) or via environment default override.

  • Frontmatter + schema contract

    • Added max-ai-credits to main workflow schema and typed frontmatter config.
    • Enforced positive integer semantics (including K/M suffix and expression support via existing limit parsing patterns).
    • Updated editor autocomplete metadata for the new field.
    • Removed schema-level max-effective-tokens default (25000000) and updated description text to reflect unset-by-default behavior.
  • Import + compiler resolution

    • Added first-wins import merge support for max-ai-credits (matching other scalar budget fields).
    • Extended engine budget extraction/parsing to carry MaxAICredits through orchestration paths.
    • Preserved precedence model: explicit workflow value > imported value > environment default > built-in default (for max-ai-credits).
  • Environment defaults (gh aw env)

    • Added compiler env var support: GH_AW_DEFAULT_MAX_AI_CREDITS.
    • Exposed YAML key in gh aw env flows: default_max_ai_credits.
    • Added validation and binding updates so org/repo/enterprise defaults can manage this budget consistently.
  • AWF config mapping

    • Extended generated AWF config to emit apiProxy.maxAiCredits.
    • Updated embedded AWF config schema/types to include maxAiCredits.
    • Updated ET default behavior so apiProxy.maxEffectiveTokens is omitted when unset by configuration.
  • Failure issue/comment overage reporting

    • Added AI-credits overage signal parsing from firewall audit content and env fallback.
    • Added dedicated context builder + template (ai_credits_rate_limit_error.md).
    • Wired new context into both failure issue and failure comment templates, plus failure-category matching.
# workflow frontmatter
max-ai-credits: "2k"
// generated awf-config.json (apiProxy excerpt)
{
  "apiProxy": {
    "enabled": true,
    "maxAiCredits": 2000
  }
}

Copilot AI and others added 2 commits June 6, 2026 02:07
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title Add max-ai-credits frontmatter support and failure reporting Add max-ai-credits budget support across frontmatter, AWF config, imports, and failure reporting Jun 6, 2026
Copilot AI requested a review from pelikhan June 6, 2026 02:29
@pelikhan pelikhan marked this pull request as ready for review June 6, 2026 02:30
Copilot AI review requested due to automatic review settings June 6, 2026 02:30
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 6, 2026

PR Code Quality Reviewer completed the code quality review.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 6, 2026

🧪 Test Quality Sentinel completed test quality analysis.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 6, 2026

🧠 Matt Pocock Skills Reviewer failed during the skills-based review.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 6, 2026

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

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a new per-run AI credits budget control (max-ai-credits) and propagates it through workflow frontmatter/schema, import merging, compiler env defaults, AWF config generation (apiProxy.maxAiCredits), and failure reporting (issue/comment contexts + template) when the budget is exceeded.

Changes:

  • Introduces max-ai-credits frontmatter field (schema + typed config), plus import “first-wins” merging and engine config extraction.
  • Adds enterprise/repo/org default support via GH_AW_DEFAULT_MAX_AI_CREDITS and gh aw env YAML key default_max_ai_credits.
  • Extends AWF config output + schemas and adds dedicated failure context/template for AI credits budget exhaustion.
Show a summary per file
File Description
pkg/workflow/testdata/TestWasmGolden_CompileFixtures/with-imports.golden Updates golden output to include apiProxy.maxAiCredits.
pkg/workflow/testdata/TestWasmGolden_CompileFixtures/smoke-copilot.golden Updates golden output to include apiProxy.maxAiCredits.
pkg/workflow/testdata/TestWasmGolden_CompileFixtures/playwright-cli-mode.golden Updates golden output to include apiProxy.maxAiCredits.
pkg/workflow/testdata/TestWasmGolden_CompileFixtures/basic-copilot.golden Updates golden output to include apiProxy.maxAiCredits.
pkg/workflow/testdata/TestWasmGolden_AllEngines/pi.golden Updates golden output to include apiProxy.maxAiCredits.
pkg/workflow/testdata/TestWasmGolden_AllEngines/gemini.golden Updates golden output to include apiProxy.maxAiCredits.
pkg/workflow/testdata/TestWasmGolden_AllEngines/copilot.golden Updates golden output to include apiProxy.maxAiCredits.
pkg/workflow/testdata/TestWasmGolden_AllEngines/codex.golden Updates golden output to include apiProxy.maxAiCredits.
pkg/workflow/testdata/TestWasmGolden_AllEngines/claude.golden Updates golden output to include apiProxy.maxAiCredits.
pkg/workflow/schemas/awf-config.schema.json Adds apiProxy.maxAiCredits to the embedded AWF config schema.
pkg/workflow/frontmatter_types.go Adds typed frontmatter field MaxAICredits (max-ai-credits).
pkg/workflow/engine.go Carries MaxAICredits through EngineConfig and extraction paths.
pkg/workflow/engine_config_parser.go Adds parsing for max-ai-credits in engine/frontmatter extraction.
pkg/workflow/compilerenv/manager.go Adds env default resolver for GH_AW_DEFAULT_MAX_AI_CREDITS.
pkg/workflow/compilerenv/manager_test.go Tests ResolveDefaultMaxAICredits.
pkg/workflow/compiler_orchestrator_engine.go Preserves/applies max-ai-credits across import/default resolution.
pkg/workflow/awf_config.go Emits apiProxy.maxAiCredits in generated AWF config JSON.
pkg/parser/schemas/main_workflow_schema.json Adds max-ai-credits to the main workflow schema contract.
pkg/parser/schema_test.go Extends schema validation tests for expressions/suffixes and invalid zero.
pkg/parser/import_processor.go Extends ImportsResult to carry merged max-ai-credits.
pkg/parser/import_field_extractor.go Extracts max-ai-credits from imports using first-wins semantics.
pkg/parser/import_field_extractor_test.go Tests import extraction/first-wins for max-ai-credits.
pkg/constants/constants.go Introduces DefaultMaxAICredits constant.
pkg/cli/env_command.go Adds default_max_ai_credits YAML binding + validation.
pkg/cli/env_command_test.go Updates env command tests for the new defaults binding.
docs/public/editor/autocomplete-data.json Adds editor autocomplete metadata for max-ai-credits.
actions/setup/md/ai_credits_rate_limit_error.md Adds dedicated rendered context template for AI credits budget exceeded.
actions/setup/md/agent_failure_issue.md Wires AI credits failure context into failure issue template.
actions/setup/md/agent_failure_comment.md Wires AI credits failure context into failure comment template.
actions/setup/js/handle_agent_failure.test.cjs Adds template vars + tests for AI credits failure state resolution.
actions/setup/js/handle_agent_failure.cjs Adds AI credits failure detection, categorization, and context rendering.
actions/setup/js/effective_tokens_context.cjs Adds parsing/suppression logic for AI credits signals from audit/env.
.github/workflows/smoke-update-cross-repo-pr.lock.yml Regenerates locked workflow content; adds checkout manifest step.
.github/workflows/smoke-create-cross-repo-pr.lock.yml Regenerates locked workflow content; adds checkout manifest step.
.github/workflows/smoke-copilot.lock.yml Regenerates locked workflow content.
.github/workflows/smoke-copilot-arm.lock.yml Regenerates locked workflow content.
.github/workflows/smoke-copilot-aoai-apikey.lock.yml Regenerates locked workflow content.
.github/workflows/daily-regulatory.lock.yml Regenerates locked workflow content.
.github/workflows/daily-performance-summary.lock.yml Regenerates locked workflow content.

Copilot's findings

Tip

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

  • Files reviewed: 39/39 changed files
  • Comments generated: 2

Comment on lines +72 to +76
"maxAiCredits": {
"type": "number",
"exclusiveMinimum": 0,
"description": "Maximum cumulative AI credits allowed for a run. When reached, the API proxy rejects subsequent requests with HTTP 429 and error type 'ai_credits_limit_exceeded'."
},
Comment on lines +41 to +53
/** @param {unknown} value */
function parsePositiveNumberString(value) {
if (typeof value === "number" && Number.isFinite(value) && value > 0) {
return String(value);
}
if (typeof value === "string") {
const trimmed = value.trim();
if (trimmed === "") return "";
const parsed = Number.parseFloat(trimmed);
if (Number.isFinite(parsed) && parsed > 0) return trimmed;
}
return "";
}
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 6, 2026

🏗️ Design Decision Gate — ADR Required

This PR makes significant changes to core business logic (185 new lines across pkg/ budget, import, compiler, env, and AWF-config paths) but does not have a linked Architecture Decision Record (ADR).

📄 Draft ADR committed: docs/adr/37235-top-level-max-ai-credits-budget-field.md — review and complete it before merging.

🔒 This PR cannot merge until an ADR is linked in the PR body.

📋 What to do next
  1. Review the draft ADR committed to your branch — it was generated from the PR diff and description.
  2. Complete the missing sections — confirm the decision rationale, validate the alternatives, and refine the consequences (especially the chosen built-in default of 1000 and the firewall-audit overage signal).
  3. Commit the finalized ADR to docs/adr/ on your branch.
  4. Reference the ADR in this PR body by adding a line such as:

    ADR: ADR-37235: Top-level max-ai-credits budget field

Once an ADR is linked in the PR body, this gate will re-run and verify the implementation matches the decision.

❓ Why ADRs Matter

ADRs create a searchable, permanent record of why the codebase looks the way it does — for example, why AI credit budgeting reuses the existing budget-field machinery instead of a standalone subsystem. Future contributors (and your future self) will thank you.

📋 Michael Nygard ADR Format Reference

An ADR must contain these four sections to be considered complete:

  • Context — What is the problem? What forces are at play?
  • Decision — What did you decide? Why?
  • Alternatives Considered — What else could have been done?
  • Consequences — What are the trade-offs (positive and negative)?

All ADRs are stored in docs/adr/ as Markdown files numbered by PR number (e.g., 37235-...md for PR #37235).

🔒 Blocking: link a completed ADR in the PR body to clear this gate.

🏗️ ADR gate enforced by Design Decision Gate 🏗️ · opus48 393.1K · 117.9 AIC · ⌖ 10.1 AIC ·

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 6, 2026

🧪 Test Quality Sentinel Report

Test Quality Score: 85/100 — Excellent

Analyzed 11 test(s): 11 design, 0 implementation, 0 coding-guideline violations. All new and modified tests enforce behavioral contracts for the new max-ai-credits budget feature.

📊 Metrics & Test Classification (11 tests analyzed)
Metric Value
New/modified tests analyzed 11
✅ Design tests (behavioral contracts) 11 (100%)
⚠️ Implementation tests (low value) 0 (0%)
Tests with error/edge cases 9 (82%)
Duplicate test clusters 0
Test inflation detected YES — pkg/cli/env_command_test.go (+10 lines vs +3 in production = 3.3:1 ratio)
🚨 Coding-guideline violations 0 (no mock libraries; no missing build tags in new files)

Test Classification Details

Test File Classification Issues Detected
it("suppresses AI credits budget exhaustion when usage is below the configured maximum") handle_agent_failure.test.cjs:2705 ✅ Design
it("keeps AI credits budget exhaustion when usage meets the configured maximum") handle_agent_failure.test.cjs:2731 ✅ Design
TestDefaultsFileYAMLKeys (modified) pkg/cli/env_command_test.go:72 ✅ Design Missing assertion message on assert.Contains
TestDefaultsValidateFile (modified) pkg/cli/env_command_test.go:133 ✅ Design Missing assertion messages; has both valid and error sub-tests
TestDefaultsBuildUpdateChanges (modified) pkg/cli/env_command_test.go:185 ✅ Design Missing assertion messages on index checks
TestExtractConfigFields_FirstWinsAndAccumulates (modified) pkg/parser/import_field_extractor_test.go:650 ✅ Design — (assertion has message ✅)
TestValidateMainWorkflowFrontmatterWithSchemaAndLocation_MaxLimitsAllowExpr... (modified) pkg/parser/schema_test.go:526 ✅ Design
TestValidateMainWorkflowFrontmatterWithSchemaAndLocation_MaxLimitsAllowSuffix... (modified) pkg/parser/schema_test.go:541 ✅ Design
TestValidateMainWorkflowFrontmatterWithSchemaAndLocation_MaxLimitsAllowSuffixCaseVariants (modified) pkg/parser/schema_test.go:556 ✅ Design
TestValidateMainWorkflowFrontmatterWithSchemaAndLocation_MaxAICreditsZeroInvalid (new) pkg/parser/schema_test.go:571 ✅ Design
TestResolveDefaultMaxAICredits (new, table-driven, 6 subtests) pkg/workflow/compilerenv/manager_test.go:65 ✅ Design Missing assertion messages; manager_test.go has no //go:build tag (existing file, not newly added — not a hard violation)

Language Support

Tests analyzed:

  • 🐹 Go (*_test.go): 9 tests — unit (//go:build !integration) and integration files
  • 🟨 JavaScript (*.test.cjs): 2 tests (vitest)
⚠️ Flagged Tests — Suggestions Only (2 issue(s))

⚠️ TestResolveDefaultMaxAICredits (pkg/workflow/compilerenv/manager_test.go:65)

Classification: Design test (not a violation — suggestions only)
Issue 1 — Missing assertion messages: All 6 sub-test assertions use bare assert.Equal(t, int64(1000), ResolveDefaultMaxAICredits(1000)) without a descriptive message argument. Per project guidelines, every testify assertion should include a context message so failures are self-explanatory.
Suggested improvement: Add descriptive messages, e.g. assert.Equal(t, int64(1000), ResolveDefaultMaxAICredits(1000), "unset env var should return fallback"). Mirrors the pattern used in TestExtractConfigFields_FirstWinsAndAccumulates.

Issue 2 — Missing //go:build tag: manager_test.go does not start with //go:build !integration or //go:build integration. This is an existing file (MODIFIED, not newly ADDED), so it does not trigger the hard failure rule — but it should be fixed for consistency with the rest of the test suite.


⚠️ Test inflation in pkg/cli/env_command_test.go

Issue: +10 lines added to the test file vs. +3 lines in the production file (env_command.go) → 3.3:1 ratio (threshold: 2:1).
Context: The additional lines are proportional to the number of assertions needed to cover the new field across multiple existing test functions (YAML keys, validation, update-changes ordering). This is mechanical coverage growth and not copy-paste inflation, but the ratio triggers the scoring penalty.

Verdict

Check passed. 0% of new tests are implementation tests (threshold: 30%). No coding-guideline violations detected.

📖 Understanding Test Classifications

Design Tests (High Value) verify what the system does:

  • Assert on observable outputs, return values, or state changes
  • Cover error paths and boundary conditions
  • Would catch a behavioral regression if deleted
  • Remain valid even after internal refactoring

Implementation Tests (Low Value) verify how the system does it:

  • Assert on internal function calls (mocking internals)
  • Only test the happy path with typical inputs
  • Break during legitimate refactoring even when behavior is correct
  • Give false assurance: they pass even when the system is wrong

Goal: Shift toward tests that describe the system's behavioral contract — the promises it makes to its users and collaborators.

References:

🧪 Test quality analysis by Test Quality Sentinel · sonnet46 2M · 612.6 AIC · ⌖ 28 AIC ·

Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

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

✅ Test Quality Sentinel: 85/100. Test quality is excellent — 0% of new tests are implementation tests (threshold: 30%). All 11 analyzed tests enforce behavioral contracts. Minor suggestions only: add assertion messages to TestResolveDefaultMaxAICredits sub-tests and add //go:build !integration to manager_test.go for consistency.

@pelikhan
Copy link
Copy Markdown
Collaborator

pelikhan commented Jun 6, 2026

@copilot remove the default 25M max-effective-token

Copilot AI and others added 2 commits June 6, 2026 03:03
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Jun 6, 2026

@copilot remove the default 25M max-effective-token

Done in 6cc276f.

I removed the built-in 25M default for max-effective-tokens so it is now unset by default, updated schema metadata to remove the 25M default text, and updated AWF config tests/goldens accordingly.

Copilot AI changed the title Add max-ai-credits budget support across frontmatter, AWF config, imports, and failure reporting Add max-ai-credits budget support across frontmatter, AWF config, imports, and failure reporting, and remove default max-effective-tokens 25M fallback Jun 6, 2026
@pelikhan pelikhan merged commit 9804320 into main Jun 6, 2026
@pelikhan pelikhan deleted the copilot/add-max-ai-credits-field branch June 6, 2026 03:28
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.

3 participants