Skip to content

Fix compiler to pass --enable-opencode to AWF when engine is opencode#29431

Closed
Copilot wants to merge 4 commits intomainfrom
copilot/fix-opencode-compiler-flag
Closed

Fix compiler to pass --enable-opencode to AWF when engine is opencode#29431
Copilot wants to merge 4 commits intomainfrom
copilot/fix-opencode-compiler-flag

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented May 1, 2026

When engine: opencode is configured, the compiler now fully enables the OpenCode API proxy listener (port 10004) introduced in gh-aw-firewall#2337.

Changes Made

  • pkg/constants/version_constants.go: Added AWFEnableOpenCodeMinVersion = "v0.25.30" — minimum AWF version that supports the new flag.

  • pkg/workflow/awf_helpers.go: Added awfSupportsEnableOpenCode() version-gate function following the same pattern as awfSupportsCliProxy/awfSupportsAllowHostPorts. Modified BuildAWFArgs() to emit --enable-opencode and include port 10004 in --allow-host-ports for the opencode engine (both gated on AWF ≥ v0.25.30).

  • pkg/workflow/awf_config.go: Added EnableOpenCode bool (json:"enableOpenCode,omitempty") to AWFAPIProxyConfig. BuildAWFConfigJSON() now sets apiProxy.enableOpenCode: true for the opencode engine (gated on AWF ≥ v0.25.30), following the same pattern as apiProxy.enabled for --enable-api-proxy.

Testing

  • pkg/workflow/awf_helpers_test.go: Added TestBuildAWFArgsEnableOpenCode (flag emission, non-OpenCode engines, version gating, latest, custom MCP port) and TestAWFSupportsEnableOpenCode (version-gate edge cases).
  • pkg/workflow/awf_config_test.go: Added tests verifying enableOpenCode is present in the config JSON for opencode+new AWF, absent for other engines, and absent for old AWF versions.
  • pkg/workflow/enable_api_proxy_test.go: Added OpenCode to TestEngineAWFEnableApiProxy.

Version Gating

AWFEnableOpenCodeMinVersion (v0.25.30) > current DefaultFirewallVersion (v0.25.29), so the flag and config field are a no-op until DefaultFirewallVersion is bumped in a follow-up once gh-aw-firewall#2337 ships.

@lpcox
Copy link
Copy Markdown
Collaborator

lpcox commented May 1, 2026

@copilot look at this and make sure that enable-opencode is also passed through the stdin config file github/gh-aw-firewall#2337 (comment)

@lpcox lpcox marked this pull request as ready for review May 1, 2026 03:50
Copilot AI review requested due to automatic review settings May 1, 2026 03:50
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.

Copilot wasn't able to review any files in this pull request.

…w-firewall#2337)

When engine=opencode, BuildAWFArgs() now:
- Emits --enable-opencode (gated on AWF >= v0.25.30)
- Adds port 10004 to --allow-host-ports for the OpenCode API proxy listener

Both behaviors are gated behind awfSupportsEnableOpenCode() which checks the
AWFEnableOpenCodeMinVersion constant (v0.25.30). This follows the same pattern
as awfSupportsCliProxy and awfSupportsAllowHostPorts.

Also adds OpenCode to TestEngineAWFEnableApiProxy in enable_api_proxy_test.go.

Agent-Logs-Url: https://github.com/github/gh-aw/sessions/0f37451d-6492-43cd-89cf-150affc954f4

Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 1, 2026

🧪 Test Quality Sentinel Report

Test Quality Score: 90/100

Excellent test quality

Metric Value
New/modified tests analyzed 3
✅ Design tests (behavioral contracts) 3 (100%)
⚠️ Implementation tests (low value) 0 (0%)
Tests with error/edge cases 3 (100%)
Duplicate test clusters 0
Test inflation detected Yes (awf_helpers_test.go: +186 lines test / +46 lines production ≈ 4:1)
🚨 Coding-guideline violations 0

Test Classification Details

View All Test Classifications (3 tests)
Test File Classification Issues Detected
TestBuildAWFArgsEnableOpenCode pkg/workflow/awf_helpers_test.go:555 ✅ Design None
TestAWFSupportsEnableOpenCode pkg/workflow/awf_helpers_test.go:678 ✅ Design None
TestEngineAWFEnableApiProxy (opencode sub-test) pkg/workflow/enable_api_proxy_test.go:29 ✅ Design None

Test Details

TestBuildAWFArgsEnableOpenCode — ✅ Design Test

Five sub-tests covering the end-to-end BuildAWFArgs() output for the opencode engine:

  1. Default AWF version emits --enable-opencode and port 10004 ✅
  2. Non-opencode engines do not emit the flag (loops over copilot, claude, codex, gemini) ✅
  3. Version gate: AWF v0.25.29 (below minimum) suppresses the flag ✅
  4. Latest AWF version includes the flag ✅
  5. Custom MCP gateway port is respected alongside port 10004 ✅

All assertions include descriptive messages. Covers happy path, negative engines, version boundary, and port customization. High value — a behavioral regression in BuildAWFArgs() would be caught immediately.

TestAWFSupportsEnableOpenCode — ✅ Design Test

Table-driven test with 9 cases covering the version-gate function awfSupportsEnableOpenCode():

  • Nil/empty config → false
  • latest → true
  • Exact boundary v0.25.30 → true
  • Just below boundary v0.25.29 → false
  • Older versions (v0.25.24, v0.1.0) → false
  • Non-semver branch name → false (conservative)

All 9 rows have assertion messages. This is the ideal table-driven pattern for a version comparison function.

TestEngineAWFEnableApiProxy (OpenCode sub-test added) — ✅ Design Test

The existing TestEngineAWFEnableApiProxy test function gained an OpenCode sub-test alongside the pre-existing Claude, Copilot, Codex, and Gemini sub-tests. The new sub-test verifies that NewOpenCodeEngine().GetExecutionSteps() embeds "enabled":true in the AWF config JSON — the observable behavior that the firewall/proxy integration depends on.


⚠️ Inflation Note

awf_helpers_test.go grew by +186 lines while the corresponding production file awf_helpers.go grew by +46 lines (ratio ≈ 4:1, threshold 2:1). This is expected for this PR: the two new test functions (TestBuildAWFArgsEnableOpenCode with 5 sub-tests and TestAWFSupportsEnableOpenCode with 9 table rows) provide thorough coverage of a small but security-relevant feature flag, so the higher ratio is justified rather than a sign of inflated coverage.

i️ Pre-existing Note


Language Support

Tests analyzed:


Verdict

Check passed. 0% of new tests are implementation tests (threshold: 30%). All three test functions verify behavioral contracts with strong edge-case coverage.


📖 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: §25201347434

🧪 Test quality analysis by Test Quality Sentinel · ● 725.9K ·

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: 90/100. Test quality is excellent — 0% of new tests are implementation tests (threshold: 30%). All 3 test functions verify behavioral contracts with strong edge-case coverage.

Copy link
Copy Markdown
Collaborator

@lpcox lpcox left a comment

Choose a reason for hiding this comment

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

Review

Overall this is a solid implementation that follows existing patterns well. A few items to address:

🔴 Port 10004 should be a constant

All other LLM gateway ports are defined in pkg/constants/constants.go:

ClaudeLLMGatewayPort  = 10000
CodexLLMGatewayPort   = 10001
CopilotLLMGatewayPort = 10002
GeminiLLMGatewayPort  = 10003

Port 10004 is hardcoded as a string literal in both awf_helpers.go and the test file. Add:

// OpenCodeLLMGatewayPort is the port for the OpenCode LLM gateway
OpenCodeLLMGatewayPort = 10004

Then reference constants.OpenCodeLLMGatewayPort instead of the magic number.

🟡 Missing spec_test.go entry

Existing AWF min version constants (AWFExcludeEnvMinVersion, AWFCliProxyMinVersion) have entries in pkg/constants/spec_test.go. The new AWFEnableOpenCodeMinVersion should be added there too for consistency.

🟡 Version v0.25.30 is speculative

Firewall PR #2337 hasn't been released yet. If it ships as a different version, this constant will be wrong. Consider adding a comment noting this dependency, e.g.:

// NOTE: version must be updated to match the actual release containing gh-aw-firewall#2337
const AWFEnableOpenCodeMinVersion Version = "v0.25.30"

ℹ️ No lock file impact yet (expected)

Since DefaultFirewallVersion is still v0.25.29, the flag won't be emitted for any compiled workflows until the default is bumped. This is correct — a follow-up version bump PR will activate the feature.

✅ What looks good

  • opencodeEnabled pre-computed once — clean, no duplicate checks
  • Version gating mirrors awfSupportsAllowHostPorts pattern exactly
  • Correct observation that AWFEnableOpenCodeMinVersion > AWFAllowHostPortsMinVersion so port support is guaranteed
  • Test coverage is thorough: default/old/latest versions, non-semver, custom MCP port, all non-opencode engines
  • The enable_api_proxy_test.go addition for OpenCode is correct (empty model won't panic — extractProviderFromModel("") returns "", nil)

Records the architectural decision to emit --enable-opencode and port 10004
only when the workflow engine is opencode and AWF version >= v0.25.30.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 1, 2026

Commit pushed: 2421a7b

🏗️ ADR gate enforced by Design Decision Gate 🏗️

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 1, 2026

🏗️ Design Decision Gate — ADR Required

This PR makes significant changes to core business logic (267 new lines in pkg/) 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/29431-version-gated-engine-specific-awf-flags-for-opencode.md

What to do next

  1. Review the draft ADR committed to your branch — it was generated from the PR diff
  2. Complete the missing sections — add context the AI couldn't infer, refine the decision rationale, and list real alternatives you considered
  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-29431: Version-Gated Engine-Specific AWF Flags for OpenCode

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

What the draft covers

The draft ADR captures the following from the diff:

  • Decision: Emit --enable-opencode and port 10004 in --allow-host-ports from BuildAWFArgs() only when engine is opencode and AWF version ≥ v0.25.30 (via new awfSupportsEnableOpenCode gate function and AWFEnableOpenCodeMinVersion constant).
  • Alternatives documented: (1) unconditional flag emission without version gating; (2) a dedicated firewall config field for OpenCode ports.
  • Key trade-off: Each new AWF feature flag requires a minimum-version constant, a gate function, and associated tests — the pattern scales linearly with features.

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

All ADRs are stored in docs/adr/ as Markdown files numbered by PR number (e.g., 29431-version-gated-engine-specific-awf-flags-for-opencode.md for PR #29431).

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

References: §25201347429

🏗️ ADR gate enforced by Design Decision Gate 🏗️ · ● 135.2K ·

Adds apiProxy.enableOpenCode: true to the AWF JSON config file when
engine=opencode and AWF >= v0.25.30, alongside the existing --enable-opencode
CLI flag in BuildAWFArgs(). This follows the established pattern where
--enable-api-proxy is expressed as apiProxy.enabled in the config file.

- AWFAPIProxyConfig gains EnableOpenCode bool (omitempty)
- BuildAWFConfigJSON sets it for opencode engine (gated on awfSupportsEnableOpenCode)
- awf_config_test.go covers: enabled for opencode+new AWF, absent for other
  engines, absent for old AWF version
- BuildAWFArgs comment updated to document the config-file mapping

Agent-Logs-Url: https://github.com/github/gh-aw/sessions/2900a3d6-1809-4cbc-a64e-9dda48d019a3

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

Copilot AI commented May 1, 2026

@copilot look at this and make sure that enable-opencode is also passed through the stdin config file github/gh-aw-firewall#2337 (comment)

Done in commit 1a0ed51. Added apiProxy.enableOpenCode: true to the AWF JSON config file (via BuildAWFConfigJSON) for the opencode engine when AWF ≥ v0.25.30, following the same pattern as apiProxy.enabled for --enable-api-proxy. Also added EnableOpenCode bool to AWFAPIProxyConfig and tests in awf_config_test.go covering the enabled/disabled cases.

Copilot AI changed the title [WIP] Fix compiler to pass --enable-opencode to AWF when engine is opencode Fix compiler to pass --enable-opencode to AWF when engine is opencode May 1, 2026
Copilot finished work on behalf of lpcox May 1, 2026 04:02
Copilot AI requested a review from lpcox May 1, 2026 04:02
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! Minor documentation suggestions on the version constant and the omitempty JSON tag rationale.

💥 [THE END] — Illustrated by Smoke Claude · ● 340.4K

// on port 10004 (dynamic provider routing). Workflows pinning an older AWF
// version must not emit --enable-opencode or the run will fail at startup.
// Introduced in gh-aw-firewall PR #2337.
const AWFEnableOpenCodeMinVersion Version = "v0.25.30"
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.

Good use of a named constant for the version threshold. One suggestion: consider adding a link to the specific AWF release notes or changelog entry (not just the PR number) so future maintainers can quickly verify what changed in that version without needing access to the internal firewall repo.

// Maps to: --enable-api-proxy
Enabled bool `json:"enabled"`

// EnableOpenCode enables the OpenCode API proxy listener on port 10004
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.

The omitempty tag is correct here — this avoids emitting "enableOpenCode":false in the JSON config for non-opencode engines. Worth adding a note in the comment that this field is intentionally omitted (not just false) when opencode is not active, to avoid confusion for anyone reading the generated AWF config files.

@pelikhan pelikhan closed this May 1, 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.

Compiler must pass --enable-opencode to AWF when engine=opencode

4 participants