From f131e744e05b1639124bd670dc45c7b3cb4d9480 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 26 Jun 2026 14:38:13 +0000 Subject: [PATCH 1/4] docs: plan governance environment documentation Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .github/workflows/ace-editor.lock.yml | 4 ++-- .github/workflows/blog-auditor.lock.yml | 4 ++-- .github/workflows/cli-consistency-checker.lock.yml | 4 ++-- .github/workflows/cli-version-checker.lock.yml | 4 ++-- .github/workflows/copilot-pr-merged-report.lock.yml | 4 ++-- .github/workflows/daily-team-evolution-insights.lock.yml | 4 ++-- .github/workflows/dev.lock.yml | 4 ++-- .github/workflows/example-permissions-warning.lock.yml | 4 ++-- .github/workflows/gpclean.lock.yml | 4 ++-- .github/workflows/mcp-inspector.lock.yml | 4 ++-- 10 files changed, 20 insertions(+), 20 deletions(-) diff --git a/.github/workflows/ace-editor.lock.yml b/.github/workflows/ace-editor.lock.yml index 2064fd45062..371d60f9ef3 100644 --- a/.github/workflows/ace-editor.lock.yml +++ b/.github/workflows/ace-editor.lock.yml @@ -165,9 +165,9 @@ jobs: const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_aw_info.cjs'); await main(core, context); - name: Enforce strict mode policy - if: ${{ contains(toJSON(vars), '"GH_AW_POLICY_STRICT":') }} + if: ${{ vars.GH_AW_POLICY_STRICT == 'true' }} run: | - echo "::error::GH_AW_POLICY_STRICT is set but this workflow was not compiled in strict mode. Recompile with --strict or strict: true." + echo "::error::GH_AW_POLICY_STRICT=true but this workflow was not compiled in strict mode. Recompile with --strict or strict: true." exit 1 - name: Restore daily AIC usage cache id: restore-daily-aic-cache diff --git a/.github/workflows/blog-auditor.lock.yml b/.github/workflows/blog-auditor.lock.yml index 5aecf272a27..6ce887e0e69 100644 --- a/.github/workflows/blog-auditor.lock.yml +++ b/.github/workflows/blog-auditor.lock.yml @@ -163,9 +163,9 @@ jobs: const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_aw_info.cjs'); await main(core, context); - name: Enforce strict mode policy - if: ${{ contains(toJSON(vars), '"GH_AW_POLICY_STRICT":') }} + if: ${{ vars.GH_AW_POLICY_STRICT == 'true' }} run: | - echo "::error::GH_AW_POLICY_STRICT is set but this workflow was not compiled in strict mode. Recompile with --strict or strict: true." + echo "::error::GH_AW_POLICY_STRICT=true but this workflow was not compiled in strict mode. Recompile with --strict or strict: true." exit 1 - name: Restore daily AIC usage cache id: restore-daily-aic-cache diff --git a/.github/workflows/cli-consistency-checker.lock.yml b/.github/workflows/cli-consistency-checker.lock.yml index ad81c26e5a0..17f192a5bba 100644 --- a/.github/workflows/cli-consistency-checker.lock.yml +++ b/.github/workflows/cli-consistency-checker.lock.yml @@ -155,9 +155,9 @@ jobs: const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_aw_info.cjs'); await main(core, context); - name: Enforce strict mode policy - if: ${{ contains(toJSON(vars), '"GH_AW_POLICY_STRICT":') }} + if: ${{ vars.GH_AW_POLICY_STRICT == 'true' }} run: | - echo "::error::GH_AW_POLICY_STRICT is set but this workflow was not compiled in strict mode. Recompile with --strict or strict: true." + echo "::error::GH_AW_POLICY_STRICT=true but this workflow was not compiled in strict mode. Recompile with --strict or strict: true." exit 1 - name: Restore daily AIC usage cache id: restore-daily-aic-cache diff --git a/.github/workflows/cli-version-checker.lock.yml b/.github/workflows/cli-version-checker.lock.yml index 060fb146e3d..5521b918250 100644 --- a/.github/workflows/cli-version-checker.lock.yml +++ b/.github/workflows/cli-version-checker.lock.yml @@ -160,9 +160,9 @@ jobs: const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_aw_info.cjs'); await main(core, context); - name: Enforce strict mode policy - if: ${{ contains(toJSON(vars), '"GH_AW_POLICY_STRICT":') }} + if: ${{ vars.GH_AW_POLICY_STRICT == 'true' }} run: | - echo "::error::GH_AW_POLICY_STRICT is set but this workflow was not compiled in strict mode. Recompile with --strict or strict: true." + echo "::error::GH_AW_POLICY_STRICT=true but this workflow was not compiled in strict mode. Recompile with --strict or strict: true." exit 1 - name: Restore daily AIC usage cache id: restore-daily-aic-cache diff --git a/.github/workflows/copilot-pr-merged-report.lock.yml b/.github/workflows/copilot-pr-merged-report.lock.yml index 8b275aab671..1412de095a8 100644 --- a/.github/workflows/copilot-pr-merged-report.lock.yml +++ b/.github/workflows/copilot-pr-merged-report.lock.yml @@ -160,9 +160,9 @@ jobs: const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_aw_info.cjs'); await main(core, context); - name: Enforce strict mode policy - if: ${{ contains(toJSON(vars), '"GH_AW_POLICY_STRICT":') }} + if: ${{ vars.GH_AW_POLICY_STRICT == 'true' }} run: | - echo "::error::GH_AW_POLICY_STRICT is set but this workflow was not compiled in strict mode. Recompile with --strict or strict: true." + echo "::error::GH_AW_POLICY_STRICT=true but this workflow was not compiled in strict mode. Recompile with --strict or strict: true." exit 1 - name: Restore daily AIC usage cache id: restore-daily-aic-cache diff --git a/.github/workflows/daily-team-evolution-insights.lock.yml b/.github/workflows/daily-team-evolution-insights.lock.yml index 34daf45a20a..4766f5759ee 100644 --- a/.github/workflows/daily-team-evolution-insights.lock.yml +++ b/.github/workflows/daily-team-evolution-insights.lock.yml @@ -161,9 +161,9 @@ jobs: const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_aw_info.cjs'); await main(core, context); - name: Enforce strict mode policy - if: ${{ contains(toJSON(vars), '"GH_AW_POLICY_STRICT":') }} + if: ${{ vars.GH_AW_POLICY_STRICT == 'true' }} run: | - echo "::error::GH_AW_POLICY_STRICT is set but this workflow was not compiled in strict mode. Recompile with --strict or strict: true." + echo "::error::GH_AW_POLICY_STRICT=true but this workflow was not compiled in strict mode. Recompile with --strict or strict: true." exit 1 - name: Restore daily AIC usage cache id: restore-daily-aic-cache diff --git a/.github/workflows/dev.lock.yml b/.github/workflows/dev.lock.yml index 3364736d814..8212f7b262e 100644 --- a/.github/workflows/dev.lock.yml +++ b/.github/workflows/dev.lock.yml @@ -178,9 +178,9 @@ jobs: const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_aw_info.cjs'); await main(core, context); - name: Enforce strict mode policy - if: ${{ contains(toJSON(vars), '"GH_AW_POLICY_STRICT":') }} + if: ${{ vars.GH_AW_POLICY_STRICT == 'true' }} run: | - echo "::error::GH_AW_POLICY_STRICT is set but this workflow was not compiled in strict mode. Recompile with --strict or strict: true." + echo "::error::GH_AW_POLICY_STRICT=true but this workflow was not compiled in strict mode. Recompile with --strict or strict: true." exit 1 - name: Restore daily AIC usage cache id: restore-daily-aic-cache diff --git a/.github/workflows/example-permissions-warning.lock.yml b/.github/workflows/example-permissions-warning.lock.yml index 917a60564df..582b40ee80a 100644 --- a/.github/workflows/example-permissions-warning.lock.yml +++ b/.github/workflows/example-permissions-warning.lock.yml @@ -154,9 +154,9 @@ jobs: const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_aw_info.cjs'); await main(core, context); - name: Enforce strict mode policy - if: ${{ contains(toJSON(vars), '"GH_AW_POLICY_STRICT":') }} + if: ${{ vars.GH_AW_POLICY_STRICT == 'true' }} run: | - echo "::error::GH_AW_POLICY_STRICT is set but this workflow was not compiled in strict mode. Recompile with --strict or strict: true." + echo "::error::GH_AW_POLICY_STRICT=true but this workflow was not compiled in strict mode. Recompile with --strict or strict: true." exit 1 - name: Restore daily AIC usage cache id: restore-daily-aic-cache diff --git a/.github/workflows/gpclean.lock.yml b/.github/workflows/gpclean.lock.yml index 53269f18b23..dd210b0d32a 100644 --- a/.github/workflows/gpclean.lock.yml +++ b/.github/workflows/gpclean.lock.yml @@ -161,9 +161,9 @@ jobs: const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_aw_info.cjs'); await main(core, context); - name: Enforce strict mode policy - if: ${{ contains(toJSON(vars), '"GH_AW_POLICY_STRICT":') }} + if: ${{ vars.GH_AW_POLICY_STRICT == 'true' }} run: | - echo "::error::GH_AW_POLICY_STRICT is set but this workflow was not compiled in strict mode. Recompile with --strict or strict: true." + echo "::error::GH_AW_POLICY_STRICT=true but this workflow was not compiled in strict mode. Recompile with --strict or strict: true." exit 1 - name: Restore daily AIC usage cache id: restore-daily-aic-cache diff --git a/.github/workflows/mcp-inspector.lock.yml b/.github/workflows/mcp-inspector.lock.yml index 082429d7dfd..ee2e51d5a3c 100644 --- a/.github/workflows/mcp-inspector.lock.yml +++ b/.github/workflows/mcp-inspector.lock.yml @@ -206,9 +206,9 @@ jobs: const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_aw_info.cjs'); await main(core, context); - name: Enforce strict mode policy - if: ${{ contains(toJSON(vars), '"GH_AW_POLICY_STRICT":') }} + if: ${{ vars.GH_AW_POLICY_STRICT == 'true' }} run: | - echo "::error::GH_AW_POLICY_STRICT is set but this workflow was not compiled in strict mode. Recompile with --strict or strict: true." + echo "::error::GH_AW_POLICY_STRICT=true but this workflow was not compiled in strict mode. Recompile with --strict or strict: true." exit 1 - name: Restore daily AIC usage cache id: restore-daily-aic-cache From dcd4c8ae7b0d303753275b7c5efbfe1e531f2235 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 26 Jun 2026 14:41:52 +0000 Subject: [PATCH 2/4] docs: add governance guide for env defaults Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- docs/astro.config.mjs | 1 + docs/src/content/docs/guides/governance.md | 144 ++++++++++++++++++ .../docs/reference/environment-variables.md | 1 + 3 files changed, 146 insertions(+) create mode 100644 docs/src/content/docs/guides/governance.md diff --git a/docs/astro.config.mjs b/docs/astro.config.mjs index 3170da16ebd..a18a24f05f2 100644 --- a/docs/astro.config.mjs +++ b/docs/astro.config.mjs @@ -312,6 +312,7 @@ export default defineConfig({ items: [ { label: 'Agentic Authoring', link: '/guides/agentic-authoring/' }, { label: 'Editing Workflows', link: '/guides/editing-workflows/' }, + { label: 'Governance', link: '/guides/governance/' }, { label: 'Reusing Workflows', link: '/guides/reusing-workflows/' }, { label: 'Upgrading Workflows', link: '/guides/upgrading/' }, { label: 'Using MCPs', link: '/guides/mcps/' }, diff --git a/docs/src/content/docs/guides/governance.md b/docs/src/content/docs/guides/governance.md new file mode 100644 index 00000000000..d98b5ead176 --- /dev/null +++ b/docs/src/content/docs/guides/governance.md @@ -0,0 +1,144 @@ +--- +title: How to Govern Environment Defaults +description: Set and manage gh-aw environment defaults across enterprise, organization, and repository scopes with gh aw env. +--- + +# How to Govern Environment Defaults + +Use governance defaults when you want consistent model and +guardrail behavior across many repositories without editing +every workflow file. + +This guide shows how to manage these defaults with +`gh aw env` and how values percolate from enterprise to +organization to repository scope. + +## What `gh aw env` manages + +`gh aw env` manages `GH_AW_DEFAULT_*` variables as GitHub +Actions variables at one scope: + +- repository (`--scope repo`) +- organization (`--scope org`) +- enterprise (`--scope ent`) + +The command uses a YAML file with `default_` keys. + +```yaml title="defaults.yml" +default_max_ai_credits: "5M" +default_max_daily_ai_credits: "15M" +default_max_turns: "12" +default_timeout_minutes: "30" +default_model_copilot: "gpt-5-mini" +default_model_claude: "claude-haiku-4-5" +default_model_codex: "gpt-5.4-mini" +default_detection_model: "gpt-5.5-mini" +default_utc: "-08:00" +``` + +> [!NOTE] +> Set a key to `null` (or omit it) to delete that variable +> from the selected scope during `gh aw env update`. + +## Export current defaults + +Start by exporting current values from the target scope. + +```bash +gh aw env get ent-defaults.yml --scope ent --enterprise MY_ENT +gh aw env get org-defaults.yml --scope org --org MY_ORG +gh aw env get repo-defaults.yml --scope repo --repo OWNER/REPO +``` + +## Apply defaults safely + +After editing the YAML file, preview and apply the change. + +```bash +gh aw env update org-defaults.yml --scope org --org MY_ORG --dry-run +gh aw env update org-defaults.yml --scope org --org MY_ORG +``` + +Use `--yes` in automation to skip the interactive +confirmation prompt. + +```bash +gh aw env update org-defaults.yml --scope org --org MY_ORG --yes +``` + +## Governance rollout pattern + +Use a layered rollout to make defaults percolate down: + +1. Set enterprise baseline defaults. +2. Set organization defaults only where needed. +3. Set repository defaults only for true exceptions. +4. Keep workflow frontmatter overrides rare and explicit. + +This keeps most repositories aligned while still allowing +targeted exceptions. + +## How percolation and precedence work + +For values resolved from GitHub Actions `vars.*`, the most +specific scope wins: + +1. workflow frontmatter value (if set) +2. repository variable +3. organization variable +4. enterprise variable +5. built-in compiler fallback + +Examples using this runtime path include +`GH_AW_DEFAULT_MAX_AI_CREDITS`, +`GH_AW_DEFAULT_MAX_DAILY_AI_CREDITS`, +`GH_AW_DEFAULT_DETECTION_MAX_AI_CREDITS`, +and `GH_AW_DEFAULT_MODEL_*`. + +> [!IMPORTANT] +> Some defaults are compile-time values. +> `GH_AW_DEFAULT_MAX_TURNS`, +> `GH_AW_DEFAULT_TIMEOUT_MINUTES`, +> `GH_AW_DEFAULT_MAX_TURN_CACHE_MISSES`, +> `GH_AW_DEFAULT_DETECTION_MODEL`, and +> `GH_AW_DEFAULT_UTC` are read by the compiler process. +> If compilation runs in CI, pass these values into the +> compile step environment. + +```yaml title=".github/workflows/compile.yml" +jobs: + compile: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v5 + - name: Compile workflows + env: + GH_AW_DEFAULT_MAX_TURNS: ${{ vars.GH_AW_DEFAULT_MAX_TURNS }} + GH_AW_DEFAULT_TIMEOUT_MINUTES: ${{ vars.GH_AW_DEFAULT_TIMEOUT_MINUTES }} + GH_AW_DEFAULT_MAX_TURN_CACHE_MISSES: ${{ vars.GH_AW_DEFAULT_MAX_TURN_CACHE_MISSES }} + GH_AW_DEFAULT_DETECTION_MODEL: ${{ vars.GH_AW_DEFAULT_DETECTION_MODEL }} + GH_AW_DEFAULT_UTC: ${{ vars.GH_AW_DEFAULT_UTC }} + run: gh aw compile +``` + +## Troubleshooting + +If `gh aw env update` fails validation: + +- use positive integers for `default_max_turns`, + `default_timeout_minutes`, + `default_max_turn_cache_misses` +- use non-zero integers for + `default_max_ai_credits`, + `default_max_daily_ai_credits`, + `default_detection_max_ai_credits` +- use a numeric UTC offset for `default_utc` + (for example `+00:00` or `-08:00`) +- remove unknown YAML keys + +## Related reference + +- [Environment Variables](/gh-aw/reference/environment-variables/) +- [Compiler Enterprise Environment Controls](/gh-aw/reference/compiler-enterprise-environment-controls/) +- [Cost Management](/gh-aw/reference/cost-management/) +- [Using at Scale in Organizations](/gh-aw/guides/using-at-scale/) diff --git a/docs/src/content/docs/reference/environment-variables.md b/docs/src/content/docs/reference/environment-variables.md index 858a8b70b6b..a3e4c863bc4 100644 --- a/docs/src/content/docs/reference/environment-variables.md +++ b/docs/src/content/docs/reference/environment-variables.md @@ -279,6 +279,7 @@ jobs: ## Related Documentation - [Frontmatter Reference](/gh-aw/reference/frontmatter/) - Complete frontmatter configuration +- [Governance Guide](/gh-aw/guides/governance/) - Roll out and manage defaults across enterprise, organization, and repository scopes - [Safe Outputs](/gh-aw/reference/safe-outputs/) - Safe output environment configuration - [Sandbox](/gh-aw/reference/sandbox/) - Sandbox environment variables - [Compiler Enterprise Environment Controls](/gh-aw/reference/compiler-enterprise-environment-controls/) - Enterprise defaults for timeout, max-turns, detection model, model fallback, and max-ai-credits guardrails From 07533317396328942a08332958f82265ae851e7d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 26 Jun 2026 14:48:14 +0000 Subject: [PATCH 3/4] docs: clarify default_utc offset semantics in governance guide Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- docs/src/content/docs/guides/governance.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/content/docs/guides/governance.md b/docs/src/content/docs/guides/governance.md index d98b5ead176..5e48c7bdb5a 100644 --- a/docs/src/content/docs/guides/governance.md +++ b/docs/src/content/docs/guides/governance.md @@ -33,7 +33,7 @@ default_model_copilot: "gpt-5-mini" default_model_claude: "claude-haiku-4-5" default_model_codex: "gpt-5.4-mini" default_detection_model: "gpt-5.5-mini" -default_utc: "-08:00" +default_utc: "-08:00" # UTC offset for rendered CLI timestamps ``` > [!NOTE] From 3bbb43972462cf0c5506c560161400798dbc61e3 Mon Sep 17 00:00:00 2001 From: Peli de Halleux Date: Fri, 26 Jun 2026 10:03:40 -0700 Subject: [PATCH 4/4] Revise governance documentation title and description Updated the title and description for clarity. --- docs/src/content/docs/guides/governance.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/src/content/docs/guides/governance.md b/docs/src/content/docs/guides/governance.md index 5e48c7bdb5a..228fa9a0135 100644 --- a/docs/src/content/docs/guides/governance.md +++ b/docs/src/content/docs/guides/governance.md @@ -1,9 +1,9 @@ --- -title: How to Govern Environment Defaults +title: Governance description: Set and manage gh-aw environment defaults across enterprise, organization, and repository scopes with gh aw env. --- -# How to Govern Environment Defaults +# Governance Use governance defaults when you want consistent model and guardrail behavior across many repositories without editing