Skip to content

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

Open
Copilot wants to merge 5 commits intomainfrom
copilot/update-gh-aw-firewall-spec
Open

Sync AWF v0.25.43 spec updates and wire apiProxy.modelMultipliers/apiProxy.maxRuns usage#31398
Copilot wants to merge 5 commits intomainfrom
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 newly supported AWF config features from existing workflow inputs:

  • apiProxy.modelMultipliers from engine.token-weights.multipliers
  • apiProxy.maxRuns from user-rate-limit.max-runs-per-window

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
      • apiProxy.maxRuns when user-rate-limit.max-runs-per-window 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
      • emission of maxRuns when rate limit max is configured
{
  "apiProxy": {
    "enabled": true,
    "maxEffectiveTokens": 10000000,
    "maxRuns": 7,
    "modelMultipliers": {
      "gpt-5": 1.2,
      "gpt-5-mini": 0.8
    }
  }
}

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
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