Skip to content

Sync AWF v0.25.43 spec updates and wire apiProxy.modelMultipliers usage#31398

Merged
pelikhan merged 6 commits into
mainfrom
copilot/update-gh-aw-firewall-spec
May 11, 2026
Merged

Sync AWF v0.25.43 spec updates and wire apiProxy.modelMultipliers usage#31398
pelikhan merged 6 commits into
mainfrom
copilot/update-gh-aw-firewall-spec

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented May 11, 2026

✨ Enhancement

This PR aligns gh-aw with the latest gh-aw-firewall release updates referenced in #31379 by syncing the embedded AWF config schema and updating feature usage in config generation. It also updates internal drift documentation so new AWF config surface is explicitly tracked.

What does this improve?
gh-aw now emits a newly supported AWF config feature from existing workflow inputs:

  • apiProxy.modelMultipliers from engine.token-weights.multipliers

It also carries the current schema contract from firewall v0.25.43.

Why is this valuable?
It reduces schema/implementation drift and ensures current AWF capabilities are expressed through gh-aw without requiring new frontmatter fields.

Implementation approach:

  • Schema alignment

    • Updated pkg/workflow/schemas/awf-config.schema.json to the latest firewall spec snapshot, including new fields such as:
      • apiProxy.maxRuns
      • apiProxy.auth.*
      • container.dockerHostPathPrefix
  • Feature usage update

    • Extended AWF config generation to emit:
      • apiProxy.modelMultipliers when engine.token-weights.multipliers is configured
  • Drift-spec refresh

    • Updated specs/awf-config-sources-spec.md “known drift” coverage list to include the newly introduced config paths.
  • Coverage updates

    • Added/updated AWF config tests for:
      • emission of modelMultipliers when configured
      • omission when multipliers are empty
{
  "apiProxy": {
    "enabled": true,
    "maxEffectiveTokens": 10000000,
    "modelMultipliers": {
      "gpt-5": 1.2,
      "gpt-5-mini": 0.8
    }
  }
}


✨ PR Review Safe Output Test - Run 25649467832

💥 [THE END] — Illustrated by Smoke Claude · ● 5.4M ·

Copilot AI and others added 3 commits May 11, 2026 01:35
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
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 Review AWF v0.25.43 spec updates and wire model multipliers usage Sync AWF v0.25.43 spec updates and wire apiProxy.modelMultipliers usage May 11, 2026
Copilot AI requested a review from pelikhan May 11, 2026 01:39
@pelikhan pelikhan marked this pull request as ready for review May 11, 2026 02:35
Copilot AI review requested due to automatic review settings May 11, 2026 02:35
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

This PR syncs gh-aw’s embedded AWF config schema to the latest gh-aw-firewall surface area and wires existing workflow engine.token-weights.multipliers inputs into generated AWF config via apiProxy.modelMultipliers.

Changes:

  • Updated the embedded AWF JSON schema snapshot and drift-tracking documentation to reflect newly available config paths.
  • Extended AWF config generation to emit apiProxy.modelMultipliers when token-weight multipliers are present.
  • Added tests covering emission and omission of modelMultipliers.
Show a summary per file
File Description
specs/awf-config-sources-spec.md Tracks newly introduced schema paths in the “known drift” list.
pkg/workflow/schemas/awf-config.schema.json Syncs embedded AWF schema and adds new config surface area (auth, maxRuns, dockerHostPathPrefix, etc.).
pkg/workflow/awf_config.go Emits apiProxy.modelMultipliers derived from engine.token-weights.multipliers.
pkg/workflow/awf_config_test.go Adds tests for modelMultipliers emission/omission behavior.
.changeset/patch-awf-spec-sync-v0-25-43.md Adds a patch changeset entry describing the schema sync + new emission behavior.

Copilot's findings

Tip

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

  • Files reviewed: 5/5 changed files
  • Comments generated: 3

Comment on lines 1 to 4
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://github.com/github/gh-aw-firewall/releases/download/v0.25.38/awf-config.schema.json",
"$id": "https://raw.githubusercontent.com/github/gh-aw-firewall/main/docs/awf-config.schema.json",
"title": "AWF Configuration",
Comment on lines 255 to +263
apiProxy := &AWFAPIProxyConfig{
Enabled: true,
MaxEffectiveTokens: maxEffectiveTokens,
}

if modelMultipliers := extractModelMultipliers(config.WorkflowData); len(modelMultipliers) > 0 {
apiProxy.ModelMultipliers = modelMultipliers
awfConfigLog.Printf("API proxy: %d model multipliers configured", len(apiProxy.ModelMultipliers))
}
if len(workflowData.EngineConfig.TokenWeights.Multipliers) == 0 {
return nil
}
return workflowData.EngineConfig.TokenWeights.Multipliers
@github-actions
Copy link
Copy Markdown
Contributor

🧪 Test Quality Sentinel Report

Test Quality Score: 75/100

⚠️ Acceptable, with suggestions

Metric Value
New/modified tests analyzed 2
✅ Design tests (behavioral contracts) 2 (100%)
⚠️ Implementation tests (low value) 0 (0%)
Tests with error/edge cases 1 (50%)
Duplicate test clusters 0
Test inflation detected Yes (50 test lines vs 18 prod lines ≈ 2.8:1)
🚨 Coding-guideline violations None

Test Classification Details

Test File Classification Issues Detected
engine token-weights multipliers are emitted in apiProxy modelMultipliers pkg/workflow/awf_config_test.go:120 ✅ Design Happy-path only; no error assertion
apiProxy modelMultipliers omitted when empty pkg/workflow/awf_config_test.go:146 ✅ Design Covers empty-map edge case ✅

Observations

Test inflation (minor)

The test file gained 50 lines against the production file's 18 lines (ratio ≈ 2.8:1, threshold 2:1). This is largely due to the verbose AWFCommandConfig struct setup required for each sub-test — no action required. The verbosity is justified by real component interactions (no mocks, real BuildAWFConfigJSON).

Error-path coverage (suggestion)

Neither new sub-test exercises an error return from BuildAWFConfigJSON. The empty-map sub-test provides good edge-case coverage for that branch, but consider adding a table-driven row for nil TokenWeights / nil WorkflowData to confirm omission behaviour for all nil branches — extractModelMultipliers has three nil guards that go untested in these new cases.

Build tag ✅

//go:build !integration is correctly placed on line 1.

Assertion messages ✅

All assertions include descriptive message strings.

No mock libraries ✅

Real component interactions — no gomock, testify/mock, .EXPECT(), or .On().


Verdict

Check passed. 0% of new tests are implementation tests (threshold: 30%). Both new sub-tests verify observable JSON output — a behavioral contract that external callers and the AWF runtime depend on.


📖 Understanding Test Classifications

Design Tests (High Value) verify what the system does — observable outputs, state changes, error handling — and catch behavioral regressions if deleted.

Implementation Tests (Low Value) verify how the system works internally — prone to breaking on legitimate refactoring even when behavior is correct.

References: §25647329883

🧪 Test quality analysis by Test Quality Sentinel · ● 5.2M ·

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: 75/100. Test quality is acceptable — 0% of new tests are implementation tests (threshold: 30%). Both new sub-tests verify observable JSON output (behavioral contracts). Minor suggestion: consider adding nil-branch table rows to cover the three nil guards in extractModelMultipliers.

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.

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · ● 3.9M

@@ -324,3 +332,13 @@
}
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.

[/tdd] extractModelMultipliers returns the original map directly — if BuildAWFConfigJSON ever mutates apiProxy.ModelMultipliers post-assignment (e.g. filtering zero values), it would silently corrupt the caller's WorkflowData. Consider returning a shallow copy:

result := make(map[string]float64, len(workflowData.EngineConfig.TokenWeights.Multipliers))
for k, v := range workflowData.EngineConfig.TokenWeights.Multipliers {
    result[k] = v
}
return result

This is also the right place to enforce the schema's exclusiveMinimum: 0 constraint — filter or reject zero/negative entries before they propagate to JSON generation.

assert.NotContains(t, jsonStr, `"modelMultipliers"`, "apiProxy should omit modelMultipliers when empty")
})

t.Run("anthropic API target is included in apiProxy targets", func(t *testing.T) {
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.

[/tdd] The two new test cases exercise the empty-multipliers path but not the nil-EngineConfig or nil-TokenWeights guard branches in extractModelMultipliers. Since those nil paths flow through the public BuildAWFConfigJSON function, they can be tested without reaching into the private function:

t.Run("apiProxy modelMultipliers omitted when EngineConfig is nil", func(t *testing.T) {
    config := AWFCommandConfig{
        EngineName:     "copilot",
        AllowedDomains: "github.com",
        WorkflowData: &WorkflowData{
            // EngineConfig intentionally nil
            NetworkPermissions: &NetworkPermissions{
                Firewall: &FirewallConfig{Enabled: true},
            },
        },
    }
    jsonStr, err := BuildAWFConfigJSON(config)
    require.NoError(t, err)
    assert.NotContains(t, jsonStr, `"modelMultipliers"`, "apiProxy should omit modelMultipliers when EngineConfig is nil")
})

This ensures the guard clauses are exercised through the same public interface the rest of the tests use.

@github-actions
Copy link
Copy Markdown
Contributor

Commit pushed: 0992994

🏗️ ADR gate enforced by Design Decision Gate 🏗️

@github-actions
Copy link
Copy Markdown
Contributor

🏗️ Design Decision Gate — ADR Required

This PR introduces significant changes to core business logic (190 new lines in pkg/workflow/) but does not have a linked Architecture Decision Record (ADR).

AI has analyzed the PR diff and generated a draft ADR to help you get started:

📄 Draft ADR: docs/adr/31398-sync-awf-firewall-spec-and-wire-model-multipliers.md

The draft has been committed to this PR's branch (copilot/update-gh-aw-firewall-spec).

What to do next

  1. Pull the latest branch — the draft ADR is now on your branch
  2. Review the draft ADR — it was generated from the PR diff and may oversimplify, miss context, or make assumptions you disagree with
  3. Complete the missing sections — refine the rationale, validate the alternatives, and confirm the consequences match your intent
  4. Reference the ADR in this PR body by adding a line such as:

    ADR: ADR-31398: Sync AWF v0.25.43 schema and wire apiProxy.modelMultipliers

  5. Flip the status from Draft to Proposed once you are happy with the content

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

What the draft captured

The draft identifies two coupled decisions in this PR:

  1. Sync the embedded AWF schema from firewall v0.25.38v0.25.43 (adds apiProxy.modelMultipliers, apiProxy.maxRuns, apiProxy.auth.*, container.dockerHostPathPrefix).
  2. Wire apiProxy.modelMultipliers from the existing engine.token-weights.multipliers workflow input rather than introducing a new dedicated frontmatter field.

The second decision is the more architecturally significant one — it gives engine.token-weights.multipliers a second runtime effect (proxy-side 429 enforcement), which the draft flags under Consequences → Negative. Please confirm this dual semantics is intentional, or amend the ADR if a separate field is preferred.

Why ADRs Matter

"AI made me procrastinate on key design decisions. Because refactoring was cheap, I could always say 'I'll deal with this later.' Deferring decisions corroded my ability to think clearly."

ADRs create a searchable, permanent record of why the codebase looks the way it does. 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)?

This repository's ADRs also include a Part 2 — Normative Specification in RFC 2119 language to make the decision machine-checkable. The draft for this PR follows that two-part structure.

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

References: §25647329877

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

🏗️ ADR gate enforced by Design Decision Gate 🏗️ · ● 6.5M ·

@pelikhan
Copy link
Copy Markdown
Collaborator

@copilot also wore a top level max-runs field to the maxRuns in config

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented May 11, 2026

@copilot also wore a top level max-runs field to the maxRuns in config

Updated in b63cb2b. BuildAWFConfigJSON now maps workflow user-rate-limit.max-runs-per-window (RateLimit.Max) into apiProxy.maxRuns, with a test covering emission in pkg/workflow/awf_config_test.go.

Copilot AI changed the title Sync AWF v0.25.43 spec updates and wire apiProxy.modelMultipliers usage Sync AWF v0.25.43 spec updates and wire apiProxy.modelMultipliers/apiProxy.maxRuns usage May 11, 2026
@pelikhan
Copy link
Copy Markdown
Collaborator

@copilot revert b63cb2b

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented May 11, 2026

@copilot revert b63cb2b

Done in c6b33e8.

Copilot AI changed the title Sync AWF v0.25.43 spec updates and wire apiProxy.modelMultipliers/apiProxy.maxRuns usage Sync AWF v0.25.43 spec updates and wire apiProxy.modelMultipliers usage May 11, 2026
@pelikhan pelikhan added the smoke label May 11, 2026
@github-actions
Copy link
Copy Markdown
Contributor

📰 BREAKING: Smoke Copilot is now investigating this pull request. Sources say the story is developing...

@github-actions github-actions Bot removed the smoke label May 11, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 11, 2026

⚠️ Smoke Gemini failed. Gemini encountered unexpected challenges...

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 11, 2026

🌑 The shadows whisper... Smoke Codex failed to deliver outputs. The oracle requires further meditation...

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 11, 2026

💫 TO BE CONTINUED... Smoke Claude failed to deliver outputs! Our hero faces unexpected challenges...

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 11, 2026

🚀 Smoke Pi MISSION COMPLETE! Pi delivered. 🥧

@github-actions
Copy link
Copy Markdown
Contributor

Agent Container Tool Check

Tool Status Version
bash 5.2.21
sh available
git 2.53.0
jq 1.7
yq 4.52.5
curl 8.5.0
gh 2.89.0
node 22.22.2
python3 3.10.16 (PyPy 7.3.19)
go 1.24.13
java openjdk 21.0.10
dotnet 10.0.201

Result: 12/12 tools available ✅

Overall Status: PASS

🔧 Tool validation by Agent Container Smoke Test · ● 2.4M ·

@github-actions
Copy link
Copy Markdown
Contributor

Smoke Test: Codex - 25649467850
PRs: #31401 [compiler-threat-spec] spec: add CTR-013 Argument Injection via Package/Image Names; #31377 feat: add gh aw forecast command for projecting workflow effective token usage (experimental)
Tests 1-10: ✅ ✅ ✅ ❌ ✅ ✅ ✅ ❌ ✅ ✅
Overall: FAIL

Warning

Firewall blocked 6 domains

The following domains were blocked by the firewall during workflow execution:

  • accounts.google.com
  • android.clients.google.com
  • clients2.google.com
  • contentautofill.googleapis.com
  • safebrowsingohttpgateway.googleapis.com
  • www.google.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "accounts.google.com"
    - "android.clients.google.com"
    - "clients2.google.com"
    - "contentautofill.googleapis.com"
    - "safebrowsingohttpgateway.googleapis.com"
    - "www.google.com"

See Network Configuration for more information.

🔮 The oracle has spoken through Smoke Codex ·

@github-actions
Copy link
Copy Markdown
Contributor

Smoke Test: Claude — Run 25649467832

Core #1#12: ✅ ✅ ✅ ✅ ❌(playwright) ✅ ✅ ✅ ✅ ✅ ✅ ✅
PR review #13#19: ✅ ✅ ✅ ✅ ✅ ✅ ⚠️(skip close)
Status: PARTIAL (1 ❌ tool unavailable, 1 ⚠️ skipped)

💥 [THE END] — Illustrated by Smoke Claude · ● 5.4M ·

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.

💥 Automated smoke test review - all systems nominal!

💥 [THE END] — Illustrated by Smoke Claude · ● 5.4M

MaxEffectiveTokens int64 `json:"maxEffectiveTokens,omitempty"`

// ModelMultipliers configures per-model ET accounting multipliers in AWF.
ModelMultipliers map[string]float64 `json:"modelMultipliers,omitempty"`
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.

📝 Smoke test review comment: consider documenting the expected value range for ModelMultipliers (e.g., positive floats; semantics when a model is missing). — Run 25649467832

}

if modelMultipliers := extractModelMultipliers(config.WorkflowData); len(modelMultipliers) > 0 {
apiProxy.ModelMultipliers = modelMultipliers
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.

📝 Smoke test review comment: log line could include a sampled key for easier debugging when multipliers are unexpectedly empty. — Run 25649467832

@github-actions
Copy link
Copy Markdown
Contributor

CAVEMAN WAS HERE! UGH! Me smoke test agent. Me visit. Me test all thing. All work good! 🔥

Warning

Firewall blocked 6 domains

The following domains were blocked by the firewall during workflow execution:

  • accounts.google.com
  • android.clients.google.com
  • clients2.google.com
  • contentautofill.googleapis.com
  • safebrowsingohttpgateway.googleapis.com
  • www.google.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "accounts.google.com"
    - "android.clients.google.com"
    - "clients2.google.com"
    - "contentautofill.googleapis.com"
    - "safebrowsingohttpgateway.googleapis.com"
    - "www.google.com"

See Network Configuration for more information.

📰 BREAKING: Report filed by Smoke Copilot · ● 12.7M ·

@github-actions
Copy link
Copy Markdown
Contributor

PR #31398: Sync AWF v0.25.43 spec\n\n1 GitHub MCP ✅ | 2 MCP Scripts ✅ | 3 Serena ✅ | 4 Playwright ✅ | 5 Web Fetch ✅ | 6 File Write ✅ | 7 Bash ✅ | 8 Discussion ✅ | 9 Build ✅ | 10 Artifact ✅ | 11 New Discussion ✅ | 12 Dispatch ✅ | 13 PR Review ✅ | 14 Comment Memory ⚠️ | 15 Sub-Agent ✅\n\nOverall: PASS ✅ | Author: @app/copilot-swe-agent | Assignees: @pelikhan @Copilot

Warning

Firewall blocked 6 domains

The following domains were blocked by the firewall during workflow execution:

  • accounts.google.com
  • android.clients.google.com
  • clients2.google.com
  • contentautofill.googleapis.com
  • safebrowsingohttpgateway.googleapis.com
  • www.google.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "accounts.google.com"
    - "android.clients.google.com"
    - "clients2.google.com"
    - "contentautofill.googleapis.com"
    - "safebrowsingohttpgateway.googleapis.com"
    - "www.google.com"

See Network Configuration for more information.

📰 BREAKING: Report filed by Smoke Copilot · ● 12.7M ·

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.

UGH! Caveman look at code. Code good. Remove maxRuns clean. Wire modelMultipliers smart. Me say LGTM!

Warning

Firewall blocked 6 domains

The following domains were blocked by the firewall during workflow execution:

  • accounts.google.com
  • android.clients.google.com
  • clients2.google.com
  • contentautofill.googleapis.com
  • safebrowsingohttpgateway.googleapis.com
  • www.google.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "accounts.google.com"
    - "android.clients.google.com"
    - "clients2.google.com"
    - "contentautofill.googleapis.com"
    - "safebrowsingohttpgateway.googleapis.com"
    - "www.google.com"

See Network Configuration for more information.

📰 BREAKING: Report filed by Smoke Copilot · ● 12.7M

// MaxEffectiveTokens is the explicit ET budget enforced by the API proxy.
MaxEffectiveTokens int64 `json:"maxEffectiveTokens,omitempty"`

// ModelMultipliers configures per-model ET accounting multipliers in AWF.
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.

Caveman see ModelMultipliers field. Good field. Me like JSON tag with omitempty. Very clean!

}

if modelMultipliers := extractModelMultipliers(config.WorkflowData); len(modelMultipliers) > 0 {
apiProxy.ModelMultipliers = modelMultipliers
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.

Caveman approve! modelMultipliers wiring good. Short. Clean. No big mess. UGH!

@github-actions
Copy link
Copy Markdown
Contributor

📰 VERDICT: Smoke Copilot has concluded. All systems operational. This is a developing story. 🎤

@pelikhan pelikhan merged commit 46a837c into main May 11, 2026
275 of 281 checks passed
@pelikhan pelikhan deleted the copilot/update-gh-aw-firewall-spec branch May 11, 2026 04:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants