Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/skills/awf-release-integrator/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ Consult these sources before editing anything:
4. The embedded AWF schema in `pkg/workflow/schemas/awf-config.schema.json`.
5. AWF config integration code in:
- `pkg/workflow/awf_config.go`
- `pkg/workflow/awf_config_build.go`
- `pkg/workflow/awf_config_schema.go`
- `pkg/workflow/awf_config_policy.go`
- `pkg/workflow/awf_helpers.go`
- related AWF tests under `pkg/workflow/`

Expand Down
4 changes: 2 additions & 2 deletions docs/adr/34693-add-antigravity-engine-deprecate-gemini.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ Mark `gemini` deprecated and remove it on a fixed date / version. Rejected becau
#### Negative
- Two engines with nearly identical wiring (`antigravity_engine.go` plus `_logs.go`, `_mcp.go`, `_tools.go` mirror the Gemini files) — every future Gemini/Antigravity engine change must be made in two places until Gemini is removed.
- Shared port (`AntigravityLLMGatewayPort = 10003 = GeminiLLMGatewayPort`) means a single workflow cannot run both engines concurrently in the same job; this is implicit and not statically enforced today.
- Domain and target aliasing (`GeminiDefaultDomains` → `AntigravityDefaultDomains`, dual keys in `awf_config.go`) is correct now but is a latent footgun: changes to one set must be mirrored to the other or one engine silently diverges.
- Domain and target aliasing (`GeminiDefaultDomains` → `AntigravityDefaultDomains`, dual keys in `awf_config_build.go`) is correct now but is a latent footgun: changes to one set must be mirrored to the other or one engine silently diverges.
- Carrying the deprecation warning indefinitely means CI logs for Gemini workflows will accumulate warning noise; there is no end-of-life date in this ADR.

#### Neutral
Expand Down Expand Up @@ -78,7 +78,7 @@ Mark `gemini` deprecated and remove it on a fixed date / version. Rejected becau

### AWF Proxy and Domain Configuration

1. `awf_config.go` **MUST** populate both `antigravity` and `gemini` target keys whenever either engine is in use.
1. `awf_config_build.go` **MUST** populate both `antigravity` and `gemini` target keys whenever either engine is in use.
2. `awf-config.schema.json` **MUST** accept `antigravity` as a valid proxy target key.
3. `GeminiDefaultDomains` **MUST** remain available as an alias of `AntigravityDefaultDomains` (or vice versa) so that existing references in the codebase compile.
4. `GetGeminiAPITarget` and `DefaultGeminiAPITarget` **MUST** remain exported as deprecated aliases and **MUST** return the same values they did before this change.
Expand Down
8 changes: 4 additions & 4 deletions docs/adr/35286-compiler-managed-enterprise-env-controls.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ We will introduce a dedicated `pkg/workflow/compilerenv` package as the single s

#### Alternative 1: Per-engine inline override chain (no shared package)

Keep the existing pattern of inline `fmt.Sprintf` expressions, and add the `GH_AW_DEFAULT_MODEL_*` term in-line at each call site (Claude, Codex, Copilot, `compiler_yaml.go`, `notify_comment.go`, `awf_config.go`). This was rejected because the override chain is a cross-cutting policy: scattering it across N files makes it easy to drift (one site forgetting the default tier), and adding a new enterprise knob would require touching every site again. Centralizing the knowledge in `compilerenv` keeps the override chain consistent and makes future additions a one-file change.
Keep the existing pattern of inline `fmt.Sprintf` expressions, and add the `GH_AW_DEFAULT_MODEL_*` term in-line at each call site (Claude, Codex, Copilot, `compiler_yaml.go`, `notify_comment.go`, `awf_config_build.go`). This was rejected because the override chain is a cross-cutting policy: scattering it across N files makes it easy to drift (one site forgetting the default tier), and adding a new enterprise knob would require touching every site again. Centralizing the knowledge in `compilerenv` keeps the override chain consistent and makes future additions a one-file change.

#### Alternative 2: YAML-only enterprise overrides (no Go-side resolver)

Implement the override chain purely as a `vars.*` expression injected into generated workflow YAML, and resolve everything at GitHub Actions runtime. This was rejected because `max-ai-credits` is also consumed at compile time inside the Go binary — `BuildAWFConfigJSON` (`pkg/workflow/awf_config.go`) and `buildConclusionJob` (`pkg/workflow/notify_comment.go`) need the numeric value to emit into the AWF config JSON and into the failure-reporting env block. A YAML-only solution would leave those compile-time paths unable to honor the enterprise default, so `ResolveDefaultMaxEffectiveTokens` (a Go-side `os.Getenv` reader) is required.
Implement the override chain purely as a `vars.*` expression injected into generated workflow YAML, and resolve everything at GitHub Actions runtime. This was rejected because `max-ai-credits` is also consumed at compile time inside the Go binary — `BuildAWFConfigJSON` (`pkg/workflow/awf_config_build.go`) and `buildConclusionJob` (`pkg/workflow/notify_comment.go`) need the numeric value to emit into the AWF config JSON and into the failure-reporting env block. A YAML-only solution would leave those compile-time paths unable to honor the enterprise default, so `ResolveDefaultMaxEffectiveTokens` (a Go-side `os.Getenv` reader) is required.

#### Alternative 3: Config-file-based enterprise overrides (e.g. `.gh-aw-enterprise.yml`)

Expand All @@ -44,7 +44,7 @@ Store enterprise defaults in a checked-in or repo-configured YAML file rather th
- All golden test files asserting on the legacy two-tier expression shape had to be regenerated; any out-of-tree consumer that parses the generated env-var expressions will break.

#### Neutral
- New package introduces an import edge from `claude_engine.go`, `codex_engine.go`, `copilot_engine_execution.go`, `compiler_yaml.go`, `compiler_yaml_lookups.go`, `awf_config.go`, and `notify_comment.go` into `pkg/workflow/compilerenv`.
- New package introduces an import edge from `claude_engine.go`, `codex_engine.go`, `copilot_engine_execution.go`, `compiler_yaml.go`, `compiler_yaml_lookups.go`, `awf_config_build.go`, and `notify_comment.go` into `pkg/workflow/compilerenv`.
- `GH_AW_INFO_MODEL` (run-info metadata) now follows the same override chain as the engine model env vars, so surfaced metadata matches effective model selection.
- The `EngineConfig.GetMaxEffectiveTokens()` accessor is bypassed at the two compile-time sites that now go through `ResolveDefaultMaxEffectiveTokens` plus a direct field check on `EngineConfig.MaxEffectiveTokens`; the accessor still exists for callers that don't need the enterprise default tier.

Expand All @@ -70,7 +70,7 @@ Store enterprise defaults in a checked-in or repo-configured YAML file rather th

### Max-Effective-Tokens Override

1. Compile-time consumers of the AWF `apiProxy.maxEffectiveTokens` default (currently `pkg/workflow/awf_config.go` and `pkg/workflow/notify_comment.go`) **MUST** resolve the default through `compilerenv.ResolveDefaultMaxEffectiveTokens(constants.DefaultMaxEffectiveTokens)`.
1. Compile-time consumers of the AWF `apiProxy.maxEffectiveTokens` default (currently `pkg/workflow/awf_config_build.go` and `pkg/workflow/notify_comment.go`) **MUST** resolve the default through `compilerenv.ResolveDefaultMaxEffectiveTokens(constants.DefaultMaxEffectiveTokens)`.
2. When workflow frontmatter sets `max-effective-tokens` to a non-zero value, that value **MUST** take precedence over the `GH_AW_DEFAULT_MAX_EFFECTIVE_TOKENS` env var override.
3. When `GH_AW_DEFAULT_MAX_EFFECTIVE_TOKENS` is unset, empty, or not parseable as a base-10 `int64`, the resolver **MUST** return the supplied fallback unchanged.
4. The resolver **MUST NOT** panic, log a fatal error, or fail compilation for an invalid value; it **MUST** fall back silently to the supplied default.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ The AWF firewall sidecar (PR #3998) introduced `--openai-api-auth-header` and `-

### Decision

We will expose `authHeader` as a frontmatter field at `sandbox.agent.targets.<provider>.authHeader` for `provider ∈ {openai, anthropic}`. The new field is read by a dedicated helper `extractAPITargetAuthHeader` (in `pkg/workflow/engine_api_targets.go`) and applied inside `BuildAWFConfigJSON` (in `pkg/workflow/awf_config.go`) by mutating the existing `AWFAPITargetConfig` entry when one is already present, or creating a header-only entry when no host override exists. The field is emitted with `omitempty` so the generated AWF JSON stays clean when it is not configured. The frontmatter path mirrors the AWF JSON config structure 1:1, preserving the drift-tracking guarantee documented in `specs/awf-config-sources-spec.md`.
We will expose `authHeader` as a frontmatter field at `sandbox.agent.targets.<provider>.authHeader` for `provider ∈ {openai, anthropic}`. The new field is read by a dedicated helper `extractAPITargetAuthHeader` (in `pkg/workflow/engine_api_targets.go`) and applied inside `BuildAWFConfigJSON` (in `pkg/workflow/awf_config_build.go`) by mutating the existing `AWFAPITargetConfig` entry when one is already present, or creating a header-only entry when no host override exists. The field is emitted with `omitempty` so the generated AWF JSON stays clean when it is not configured. The frontmatter path mirrors the AWF JSON config structure 1:1, preserving the drift-tracking guarantee documented in `specs/awf-config-sources-spec.md`.

### Alternatives Considered

Expand Down
44 changes: 44 additions & 0 deletions docs/adr/55496-split-awf-config-into-types-schema-build-policy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# ADR-55496: Split awf_config.go into Types, Schema, Build, and Policy Files

**Date**: 2026-08-24
**Status**: Draft
**Deciders**: Unknown

---

### Context

`pkg/workflow/awf_config.go` had grown to 1,090 lines, mixing three distinct concerns: Go type definitions for the AWF configuration file, JSON schema validation, AWF config JSON construction (`BuildAWFConfigJSON`), and model-policy and domain-list resolution. It was the repository's second-largest non-test Go file and was under active churn. The `pkg/workflow` package follows a "one file per functionality" convention (e.g., `awf_helpers.go`, `awf_enclaves.go`), which this monolithic file violated. Reviewers had to scan the entire file to locate the concern they cared about.

### Decision

We will split `pkg/workflow/awf_config.go` into four focused files — `awf_config.go` (type definitions), `awf_config_schema.go` (embedded JSON schema, schema compilation/validation, `buildAWFConfigSchemaURL`), `awf_config_build.go` (`BuildAWFConfigJSON` and all build/extract helpers), and `awf_config_policy.go` (`resolveModelPolicyForAWFConfig`, `intersectModelPolicyRules`, `unionModelPolicyRules`, `splitDomainList`) — matching the "one file per functionality" convention already established in `pkg/workflow`. This is a pure code move with no logic changes.

### Alternatives Considered

#### Alternative 1: Keep the monolithic file

Add package-level or function-group comments to orient readers within the single 1,090-line file. This requires no structural change and carries no migration risk, but it does not resolve the difficulty of locating and reviewing specific concerns under ongoing churn. The file would continue to grow as new AWF config sections are added.

#### Alternative 2: Extract into a separate Go package

Move AWF config logic into `pkg/workflow/awfconfig` (a new sub-package). This would provide stronger encapsulation and cleaner import boundaries. However, it would require renaming exported types, updating all call sites across the repo, and deciding which types remain in `pkg/workflow` to avoid circular imports — significant cost for what amounts to a readability improvement.

### Consequences

#### Positive
- Each file now has a single, clearly named responsibility that matches the `pkg/workflow` "one file per functionality" convention, reducing the mental surface area for reviewers.
- Future changes to schema validation, model policy, or build logic touch only the relevant file, making diffs easier to read and review.
- Each new file carries a short cross-reference header pointing to its siblings, so navigating the split is self-documenting.

#### Negative
- `BuildAWFConfigJSON` at 339 lines remains un-decomposed inside `awf_config_build.go`; linting still flags it. Decomposing it was explicitly out of scope here to keep this a mechanical, reviewable move.
- Any tooling or documentation that enumerates `awf_config.go` as the single AWF integration file (e.g., skill manifests, README appendices) must now list all four files and must be kept in sync when further files are added.

#### Neutral
- All four files remain in the same Go package (`package workflow`), so no exported symbols are renamed, no call sites change, and existing tests compile unchanged.
- The AWF release integrator skill (`SKILL.md`) and `pkg/workflow/README.md` were updated in this PR to reflect the new file layout.

---

*ADR created by [adr-writer agent]. Review and finalize before changing status from Draft to Accepted.*
2 changes: 1 addition & 1 deletion pkg/workflow/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1173,7 +1173,7 @@ This appendix is generated from the current non-test Go source files in this pac
| `artifact_manager.go` | `(*ArtifactManager).Reset` | `func (*ArtifactManager).Reset()` | Reset clears all tracked uploads and downloads |
| `artifact_manager.go` | `NewArtifactManager` | `func NewArtifactManager() *ArtifactManager` | NewArtifactManager creates a new artifact manager |
| `auto_update_workflow.go` | `GenerateAutoUpdateWorkflow` | `func GenerateAutoUpdateWorkflow(opts GenerateAutoUpdateWorkflowOptions) error` | GenerateAutoUpdateWorkflow generates or removes the agentic-auto-upgrade. |
| `awf_config.go` | `BuildAWFConfigJSON` | `func BuildAWFConfigJSON(config AWFCommandConfig) (string, error)` | BuildAWFConfigJSON generates a compact JSON config file for AWF from the provided command configuration. |
| `awf_config_build.go` | `BuildAWFConfigJSON` | `func BuildAWFConfigJSON(config AWFCommandConfig) (string, error)` | BuildAWFConfigJSON generates a compact JSON config file for AWF from the provided command configuration. |
| `behavior_defined_engine.go` | `(*BehaviorDefinedEngine).GetAgentManifestFiles` | `func (*BehaviorDefinedEngine).GetAgentManifestFiles() []string` | Exported function or method declared in `behavior_defined_engine.go`. |
| `behavior_defined_engine.go` | `(*BehaviorDefinedEngine).GetAgentManifestPathPrefixes` | `func (*BehaviorDefinedEngine).GetAgentManifestPathPrefixes() []string` | Exported function or method declared in `behavior_defined_engine.go`. |
| `behavior_defined_engine.go` | `(*BehaviorDefinedEngine).GetModelEnvVarName` | `func (*BehaviorDefinedEngine).GetModelEnvVarName() string` | Exported function or method declared in `behavior_defined_engine.go`. |
Expand Down
Loading
Loading