Skip to content

feat: Migrate compiler to use AWF JSON config file instead of CLI flags #29220

Description

@lpcox

Problem

The gh-aw compiler currently generates AWF invocations using command-line flags:

awf --allow-domains github.com github.com/ghapi \
    --enable-api-proxy \
    --dns-servers 8.8.8.8,8.8.4.4 \
    --image-tag v0.25.29 \
    --agent-timeout 300 \
    ...
    -- "claude ..."

As AWF gains more configuration surface (model policies, rate limits, api-proxy targets, container settings), this approach has scaling problems:

  1. Shell escaping — Complex values (JSON objects, multi-line strings) are fragile in shell argv
  2. Readability — Long flag lists in lock files are hard to audit
  3. Composability — No clean way to layer org-level defaults with workflow-level overrides
  4. Validation — Flags are validated only at runtime; config files can be schema-validated at compile time

Proposed Solution

AWF already supports --config <path|-> which loads a JSON/YAML config file (gh-aw-firewall src/config-file.ts). The compiler should generate a config file and invoke AWF with it:

awf --config .awf-config.json -- "claude ..."

Where .awf-config.json contains the structured configuration:

{
  "$schema": "https://github.com/github/gh-aw-firewall/schemas/awf-config.v1.json",
  "network": {
    "allowDomains": ["github.com", "github.com/ghapi", "*.actions.githubusercontent.com"],
    "dnsServers": ["8.8.8.8", "8.8.4.4"]
  },
  "apiProxy": {
    "enabled": true,
    "targets": {
      "openai": { "host": "api.openai.com" },
      "anthropic": { "host": "api.anthropic.com" },
      "copilot": { "host": "api.githubcopilot.com" }
    }
  },
  "container": {
    "imageTag": "v0.25.29",
    "agentTimeout": 300,
    "buildLocal": false
  },
  "modelPolicy": {
    "model": { "id": "claude-sonnet-4-20250514", "provider": "anthropic" },
    "fallback": [{ "strategy": "auto" }],
    "onUnavailable": "fail"
  }
}

Benefits

Aspect CLI flags (current) Config file (proposed)
Complex values Shell escaping issues Native JSON types
Auditability Long one-liner Structured, diffable
Schema validation Runtime only Compile-time + IDE support
Composability Flag precedence only File merging + overlays
New features New flag per feature Add to schema, no argv changes
Model policy Not expressible First-class object (#2309)

Implementation Plan

Phase 1: Compiler generates config file

  1. Compiler emits .awf-config.json alongside the lock file (or inline via --config - on stdin)
  2. Lock file run: step changes from flag soup to awf --config .awf-config.json -- "..."
  3. Backwards compatible: AWF already supports --config; CLI flags still override for user ad-hoc runs

Phase 2: Schema validation at compile time

  1. Publish JSON Schema in gh-aw-firewall (schemas/awf-config.v1.json)
  2. gh aw compile --validate validates the generated config against the schema
  3. IDE support via $schema field for autocomplete in editors

Phase 3: Composable config layers

  1. Org-level defaults (.github/awf-config.json)
  2. Workflow-level overrides (frontmatter → config)
  3. CLI flags as final override layer
  4. Merge semantics: deep merge with arrays replaced (not appended)

AWF Config File Support (already implemented)

The firewall already supports config files via --config <path|->:

  • Parses JSON or YAML
  • Validates against known schema sections: network, apiProxy, container
  • Maps config keys to CLI option equivalents
  • CLI flags take precedence over file values

Key source files:

Related

  • gh-aw-firewall#2309 — Model-selection policy schema (new config section)
  • gh-aw#29191 — Model fallback feature request
  • AWF --config docs: awf --help--config <path|-> Load configuration from JSON/YAML file (use - for stdin)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions