@guilz-dev/sdlc-gh 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (176) hide show
  1. package/.github/CODEOWNERS +5 -0
  2. package/.github/ISSUE_TEMPLATE/bug_report.yml +68 -0
  3. package/.github/ISSUE_TEMPLATE/config.yml +1 -0
  4. package/.github/ISSUE_TEMPLATE/feature_request.yml +39 -0
  5. package/.github/ISSUE_TEMPLATE/support.yml +56 -0
  6. package/.github/ISSUE_TEMPLATE/task.yml +89 -0
  7. package/.github/agents/implementer.agent.md +17 -0
  8. package/.github/agents/reviewer.agent.md +18 -0
  9. package/.github/agents/triager.agent.md +13 -0
  10. package/.github/aw/actions-lock.json +9 -0
  11. package/.github/copilot-instructions.md +35 -0
  12. package/.github/hooks/hooks.json +12 -0
  13. package/.github/instructions/core.instructions.md +11 -0
  14. package/.github/instructions/profiles/go.instructions.md +10 -0
  15. package/.github/instructions/profiles/php.instructions.md +11 -0
  16. package/.github/instructions/profiles/python.instructions.md +11 -0
  17. package/.github/instructions/profiles/ruby.instructions.md +11 -0
  18. package/.github/instructions/profiles/typescript.instructions.md +11 -0
  19. package/.github/labels.yml +55 -0
  20. package/.github/pull_request_template.md +33 -0
  21. package/.github/ruleset.example.json +33 -0
  22. package/.github/ruleset.harness-eval.example.json +29 -0
  23. package/.github/skills/quality-loop/SKILL.md +23 -0
  24. package/.github/workflows/agent-retry-orchestrator.yml +161 -0
  25. package/.github/workflows/copilot-setup-steps.yml +64 -0
  26. package/.github/workflows/eval-ci.yml +169 -0
  27. package/.github/workflows/eval-drift.yml +75 -0
  28. package/.github/workflows/gh-aw-dogfood-ci.yml +73 -0
  29. package/.github/workflows/harness-ci.yml +244 -0
  30. package/.github/workflows/harness-sync.yml +28 -0
  31. package/.github/workflows/l1-readiness-check.yml +45 -0
  32. package/.github/workflows/labels-sync.yml +24 -0
  33. package/.github/workflows/nightly-harness-review.lock.yml +1643 -0
  34. package/.github/workflows/nightly-harness-review.md +87 -0
  35. package/.github/workflows/nightly-harness-review.yml +63 -0
  36. package/.github/workflows/npm-publish.yml +49 -0
  37. package/.github/workflows/pr-context-comment.yml +138 -0
  38. package/.github/workflows/product-ci-go.yml +33 -0
  39. package/.github/workflows/product-ci-php.yml +39 -0
  40. package/.github/workflows/product-ci-python.yml +34 -0
  41. package/.github/workflows/product-ci-ruby.yml +35 -0
  42. package/.github/workflows/product-ci-ts.yml +37 -0
  43. package/.github/workflows/task-issue-label-sync.yml +50 -0
  44. package/.github/workflows/weekly-redteam.lock.yml +1571 -0
  45. package/.github/workflows/weekly-redteam.md +76 -0
  46. package/.github/zizmor.yml +11 -0
  47. package/AGENTS.md +54 -0
  48. package/LICENSE +21 -0
  49. package/README.md +366 -0
  50. package/config/stacks.json +55 -0
  51. package/docs/adoption.md +126 -0
  52. package/docs/arch.md +535 -0
  53. package/docs/auth-boundaries.md +16 -0
  54. package/docs/coding-agent-l1.md +152 -0
  55. package/docs/exceptions/README.md +25 -0
  56. package/docs/exceptions/TEMPLATE.md +8 -0
  57. package/docs/failure-taxonomy.md +23 -0
  58. package/docs/gh-aw-dogfood.md +109 -0
  59. package/docs/kpi-baseline.md +9 -0
  60. package/docs/nightly-harness-review.md +94 -0
  61. package/docs/operations.md +108 -0
  62. package/docs/publishing.md +79 -0
  63. package/docs/revert-playbook.md +44 -0
  64. package/docs/shared-config.md +30 -0
  65. package/docs/telemetry-artifacts.md +78 -0
  66. package/docs/telemetry-schema.md +60 -0
  67. package/evals/.score-baseline.json +6 -0
  68. package/evals/e2e-bench/README.md +28 -0
  69. package/evals/e2e-bench/manifest.json +16 -0
  70. package/evals/e2e-bench/tasks/e2e-001.yml +10 -0
  71. package/evals/e2e-bench/tasks/e2e-002.yml +11 -0
  72. package/evals/e2e-bench/tasks/e2e-003.yml +10 -0
  73. package/evals/e2e-bench/tasks/e2e-004.yml +14 -0
  74. package/evals/e2e-bench/tasks/e2e-005.yml +11 -0
  75. package/evals/e2e-bench/tasks/e2e-006.yml +10 -0
  76. package/evals/e2e-bench/tasks/e2e-007.yml +10 -0
  77. package/evals/e2e-bench/tasks/e2e-008.yml +10 -0
  78. package/evals/e2e-bench/tasks/e2e-009.yml +10 -0
  79. package/evals/trajectories/rubric.md +12 -0
  80. package/evals/trajectories/test_harness_conventions.py +271 -0
  81. package/infra/README.md +49 -0
  82. package/infra/langfuse/docker-compose.yml +25 -0
  83. package/infra/otel/collector-config.yml +24 -0
  84. package/infra/samples/gh-aw-dogfood-report.json +44 -0
  85. package/infra/samples/harness-review-routing-plan.json +19 -0
  86. package/infra/samples/harness-review-summary.json +61 -0
  87. package/infra/samples/telemetry-artifact.json +29 -0
  88. package/infra/samples/telemetry-payload.json +19 -0
  89. package/package.json +85 -0
  90. package/prompts/triager-classify.prompt.yml +10 -0
  91. package/sample/go/add.go +5 -0
  92. package/sample/go/add_test.go +9 -0
  93. package/sample/go/go.mod +3 -0
  94. package/sample/php/composer.json +26 -0
  95. package/sample/php/composer.lock +1881 -0
  96. package/sample/php/phpunit.xml +8 -0
  97. package/sample/php/src/Add.php +13 -0
  98. package/sample/php/tests/AddTest.php +16 -0
  99. package/sample/python/requirements-dev.txt +2 -0
  100. package/sample/python/src/__init__.py +0 -0
  101. package/sample/python/src/greet.py +3 -0
  102. package/sample/python/tests/conftest.py +4 -0
  103. package/sample/python/tests/test_greet.py +5 -0
  104. package/sample/ruby/.rubocop.yml +10 -0
  105. package/sample/ruby/Gemfile +6 -0
  106. package/sample/ruby/Gemfile.lock +58 -0
  107. package/sample/ruby/lib/add.rb +9 -0
  108. package/sample/ruby/spec/add_spec.rb +11 -0
  109. package/sample/ts/biome.json +6 -0
  110. package/sample/ts/package-lock.json +1763 -0
  111. package/sample/ts/package.json +15 -0
  112. package/sample/ts/src/add.ts +3 -0
  113. package/sample/ts/tests/add.test.ts +8 -0
  114. package/sample/ts/tsconfig.json +12 -0
  115. package/scripts/aggregate-harness-review.mjs +48 -0
  116. package/scripts/bootstrap-harness.sh +411 -0
  117. package/scripts/check-diff-size.mjs +46 -0
  118. package/scripts/check-e2e-manifest.mjs +35 -0
  119. package/scripts/check-eval-score-drift.mjs +31 -0
  120. package/scripts/check-gh-aw-dogfood-scope.mjs +51 -0
  121. package/scripts/check-issue-spec.mjs +215 -0
  122. package/scripts/check-l1-readiness.mjs +82 -0
  123. package/scripts/check-open-pr-limit.mjs +34 -0
  124. package/scripts/doctor.mjs +177 -0
  125. package/scripts/emit-gh-aw-dogfood-report.mjs +112 -0
  126. package/scripts/emit-telemetry-artifact.mjs +99 -0
  127. package/scripts/fetch-telemetry-artifacts.mjs +176 -0
  128. package/scripts/harness-drift-report.mjs +99 -0
  129. package/scripts/lib/bootstrap-copy.mjs +123 -0
  130. package/scripts/lib/ccsd-contract.mjs +212 -0
  131. package/scripts/lib/diff-size.mjs +103 -0
  132. package/scripts/lib/doctor-local.mjs +179 -0
  133. package/scripts/lib/e2e-manifest.mjs +76 -0
  134. package/scripts/lib/gh-aw-dogfood.mjs +293 -0
  135. package/scripts/lib/github-config.mjs +94 -0
  136. package/scripts/lib/harness-ci-fragments.mjs +98 -0
  137. package/scripts/lib/harness-review-routing.mjs +244 -0
  138. package/scripts/lib/harness-review.mjs +388 -0
  139. package/scripts/lib/issue-form-label-sync.mjs +56 -0
  140. package/scripts/lib/l1-readiness.mjs +258 -0
  141. package/scripts/lib/merge-harness-package.mjs +36 -0
  142. package/scripts/lib/npm-package.mjs +129 -0
  143. package/scripts/lib/setup-wizard.mjs +224 -0
  144. package/scripts/lib/stacks.mjs +138 -0
  145. package/scripts/lib/telemetry-artifact.mjs +253 -0
  146. package/scripts/lib/template-root.mjs +39 -0
  147. package/scripts/merge-harness-package.mjs +14 -0
  148. package/scripts/route-harness-review.mjs +168 -0
  149. package/scripts/run-e2e-bench.mjs +216 -0
  150. package/scripts/sdlc-gh-cli.mjs +91 -0
  151. package/scripts/select-eval-jobs.mjs +41 -0
  152. package/scripts/setup-github.mjs +242 -0
  153. package/scripts/setup-github.sh +4 -0
  154. package/scripts/setup-wizard.mjs +426 -0
  155. package/scripts/test-bootstrap-guidance-scenarios.mjs +94 -0
  156. package/scripts/test-diff-size-scenarios.mjs +88 -0
  157. package/scripts/test-doctor-scenarios.mjs +70 -0
  158. package/scripts/test-e2e-manifest-scenarios.mjs +65 -0
  159. package/scripts/test-gh-aw-dogfood-scenarios.mjs +74 -0
  160. package/scripts/test-harness-review-routing-scenarios.mjs +130 -0
  161. package/scripts/test-harness-review-scenarios.mjs +92 -0
  162. package/scripts/test-hooks-scenarios.mjs +44 -0
  163. package/scripts/test-issue-form-label-sync-scenarios.mjs +48 -0
  164. package/scripts/test-issue-spec-scenarios.mjs +258 -0
  165. package/scripts/test-l1-readiness-scenarios.mjs +204 -0
  166. package/scripts/test-merge-harness-package-scenarios.mjs +53 -0
  167. package/scripts/test-npm-package-scenarios.mjs +31 -0
  168. package/scripts/test-sdlc-gh-cli-scenarios.mjs +54 -0
  169. package/scripts/test-setup-github-scenarios.mjs +103 -0
  170. package/scripts/test-setup-wizard-scenarios.mjs +114 -0
  171. package/scripts/test-telemetry-artifact-scenarios.mjs +69 -0
  172. package/scripts/trim-harness-ci.mjs +18 -0
  173. package/scripts/validate-gh-aw-compile.mjs +64 -0
  174. package/scripts/validate-harness.mjs +199 -0
  175. package/scripts/validate-telemetry.mjs +21 -0
  176. package/scripts/verify-bootstrap-stacks.sh +192 -0
@@ -0,0 +1,1571 @@
1
+ # gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"4fe30e266ba4e7d293a13f050e7efa0125b77fdac6a0e2a9c3be7e8aca20e799","body_hash":"b51fbe615108c2d178bd2b07cda493adc6e84ba5e39c1aa029f7672ef11fa844","compiler_version":"v0.81.6","strict":true,"agent_id":"copilot","engine_versions":{"copilot":"1.0.65"}}
2
+ # gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN"],"actions":[{"repo":"actions/cache/restore","sha":"27d5ce7f107fe9357f9df03efb73ab90386fccae","version":"v5.0.5"},{"repo":"actions/cache/save","sha":"27d5ce7f107fe9357f9df03efb73ab90386fccae","version":"v5.0.5"},{"repo":"actions/checkout","sha":"9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0","version":"v7.0.0"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e","version":"v6.4.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"ba6380cc6e5be5d21677bebe04d52fb48e3abec7","version":"v0.81.6"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.27.11","digest":"sha256:979723c628182da7729333f2208bb249fd25ddee579645cf9a3892d681a929c7","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.27.11@sha256:979723c628182da7729333f2208bb249fd25ddee579645cf9a3892d681a929c7"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.11","digest":"sha256:807e4831999b44513b0a66e5859d478dc4da7ae74ab1918cec967d513f95bf9d","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.11@sha256:807e4831999b44513b0a66e5859d478dc4da7ae74ab1918cec967d513f95bf9d"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.27.11","digest":"sha256:ff27ea0525ad953a6adee28a5fbe9d2e22be47dbec755c15767af4ea3f91df7d","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.27.11@sha256:ff27ea0525ad953a6adee28a5fbe9d2e22be47dbec755c15767af4ea3f91df7d"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.3.30","digest":"sha256:35625d1a2269b1238606078c879f59a91cffc4ac33eb54bf39c6418822c1a8be","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.3.30@sha256:35625d1a2269b1238606078c879f59a91cffc4ac33eb54bf39c6418822c1a8be"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b","pinned_image":"ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b"},{"image":"ghcr.io/github/github-mcp-server:v1.4.0","digest":"sha256:2afb26356481d1a350e14544a6e160f7f7ec1561a1ea309b823665abf0309036","pinned_image":"ghcr.io/github/github-mcp-server:v1.4.0@sha256:2afb26356481d1a350e14544a6e160f7f7ec1561a1ea309b823665abf0309036"}]}
3
+ # This file was automatically generated by gh-aw (v0.81.6). DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md
4
+ #
5
+ # ___ _ _
6
+ # / _ \ | | (_)
7
+ # | |_| | __ _ ___ _ __ | |_ _ ___
8
+ # | _ |/ _` |/ _ \ '_ \| __| |/ __|
9
+ # | | | | (_| | __/ | | | |_| | (__
10
+ # \_| |_/\__, |\___|_| |_|\__|_|\___|
11
+ # __/ |
12
+ # _ _ |___/
13
+ # | | | | / _| |
14
+ # | | | | ___ _ __ _ __| |_| | _____ ____
15
+ # | |/\| |/ _ \ '__| |/ /| _| |/ _ \ \ /\ / / ___|
16
+ # \ /\ / (_) | | | | ( | | | | (_) \ V V /\__ \
17
+ # \/ \/ \___/|_| |_|\_\|_| |_|\___/ \_/\_/ |___/
18
+ #
19
+ #
20
+ # To update this file, edit the corresponding .md file and run:
21
+ # gh aw compile
22
+ # Not all edits will cause changes to this file.
23
+ #
24
+ # For more information: https://github.github.com/gh-aw/introduction/overview/
25
+ #
26
+ # Weekly red team probe suite (garak).
27
+ #
28
+ # Secrets used:
29
+ # - COPILOT_GITHUB_TOKEN
30
+ # - GH_AW_GITHUB_MCP_SERVER_TOKEN
31
+ # - GH_AW_GITHUB_TOKEN
32
+ # - GITHUB_TOKEN
33
+ #
34
+ # Custom actions used:
35
+ # - actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
36
+ # - actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
37
+ # - actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
38
+ # - actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
39
+ # - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
40
+ # - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 (source v9)
41
+ # - actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
42
+ # - actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
43
+ # - github/gh-aw-actions/setup@ba6380cc6e5be5d21677bebe04d52fb48e3abec7 # v0.81.6
44
+ #
45
+ # Container images used:
46
+ # - ghcr.io/github/gh-aw-firewall/agent:0.27.11@sha256:979723c628182da7729333f2208bb249fd25ddee579645cf9a3892d681a929c7
47
+ # - ghcr.io/github/gh-aw-firewall/api-proxy:0.27.11@sha256:807e4831999b44513b0a66e5859d478dc4da7ae74ab1918cec967d513f95bf9d
48
+ # - ghcr.io/github/gh-aw-firewall/squid:0.27.11@sha256:ff27ea0525ad953a6adee28a5fbe9d2e22be47dbec755c15767af4ea3f91df7d
49
+ # - ghcr.io/github/gh-aw-mcpg:v0.3.30@sha256:35625d1a2269b1238606078c879f59a91cffc4ac33eb54bf39c6418822c1a8be
50
+ # - ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b
51
+ # - ghcr.io/github/github-mcp-server:v1.4.0@sha256:2afb26356481d1a350e14544a6e160f7f7ec1561a1ea309b823665abf0309036
52
+
53
+ name: "Weekly red team"
54
+ on:
55
+ schedule:
56
+ - cron: "0 3 * * 0"
57
+ workflow_dispatch:
58
+ inputs:
59
+ aw_context:
60
+ default: ""
61
+ description: "Agent caller context (used internally by Agentic Workflows)."
62
+ required: false
63
+ type: string
64
+
65
+ permissions: {}
66
+
67
+ concurrency:
68
+ group: "gh-aw-${{ github.workflow }}"
69
+
70
+ run-name: "Weekly red team"
71
+
72
+ jobs:
73
+ activation:
74
+ runs-on: ubuntu-slim
75
+ permissions:
76
+ actions: read
77
+ contents: read
78
+ env:
79
+ GH_AW_MAX_DAILY_AI_CREDITS: ${{ vars.GH_AW_DEFAULT_MAX_DAILY_AI_CREDITS || '5000' }}
80
+ GH_AW_RUNTIME_FEATURES: ${{ vars.GH_AW_RUNTIME_FEATURES }}
81
+ outputs:
82
+ comment_id: ""
83
+ comment_repo: ""
84
+ daily_ai_credits_exceeded: ${{ steps.daily-effective-workflow-guardrail.outputs.daily_ai_credits_exceeded == 'true' }}
85
+ daily_ai_credits_threshold: ${{ steps.daily-effective-workflow-guardrail.outputs.daily_ai_credits_threshold || '' }}
86
+ daily_ai_credits_total_effective_tokens: ${{ steps.daily-effective-workflow-guardrail.outputs.daily_ai_credits_total_effective_tokens || '' }}
87
+ engine_id: ${{ steps.generate_aw_info.outputs.engine_id }}
88
+ lockdown_check_failed: ${{ steps.generate_aw_info.outputs.lockdown_check_failed == 'true' }}
89
+ model: ${{ steps.generate_aw_info.outputs.model }}
90
+ secret_verification_result: ${{ steps.validate-secret.outputs.verification_result }}
91
+ setup-parent-span-id: ${{ steps.setup.outputs.parent-span-id || steps.setup.outputs.span-id }}
92
+ setup-span-id: ${{ steps.setup.outputs.span-id }}
93
+ setup-trace-id: ${{ steps.setup.outputs.trace-id }}
94
+ stale_lock_file_failed: ${{ steps.check-lock-file.outputs.stale_lock_file_failed == 'true' }}
95
+ steps:
96
+ - name: Setup Scripts
97
+ id: setup
98
+ uses: github/gh-aw-actions/setup@ba6380cc6e5be5d21677bebe04d52fb48e3abec7 # v0.81.6
99
+ with:
100
+ destination: ${{ runner.temp }}/gh-aw/actions
101
+ job-name: ${{ github.job }}
102
+ safe-output-artifact-client: ${{ env.GH_AW_MAX_DAILY_AI_CREDITS != '' }}
103
+ env:
104
+ GH_AW_SETUP_WORKFLOW_NAME: "Weekly red team"
105
+ GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/weekly-redteam.lock.yml@${{ github.ref }}
106
+ GH_AW_INFO_VERSION: "1.0.65"
107
+ GH_AW_INFO_AWF_VERSION: "v0.27.11"
108
+ GH_AW_INFO_ENGINE_ID: "copilot"
109
+ - name: Generate agentic run info
110
+ id: generate_aw_info
111
+ env:
112
+ GH_AW_INFO_ENGINE_ID: "copilot"
113
+ GH_AW_INFO_ENGINE_NAME: "GitHub Copilot CLI"
114
+ GH_AW_INFO_MODEL: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || vars.GH_AW_DEFAULT_MODEL_COPILOT || 'claude-sonnet-4.6' }}
115
+ GH_AW_INFO_VERSION: "1.0.65"
116
+ GH_AW_INFO_AGENT_VERSION: "1.0.65"
117
+ GH_AW_INFO_CLI_VERSION: "v0.81.6"
118
+ GH_AW_INFO_WORKFLOW_NAME: "Weekly red team"
119
+ GH_AW_INFO_EXPERIMENTAL: "false"
120
+ GH_AW_INFO_SUPPORTS_TOOLS_ALLOWLIST: "true"
121
+ GH_AW_INFO_STAGED: "false"
122
+ GH_AW_INFO_ALLOWED_DOMAINS: '["defaults"]'
123
+ GH_AW_INFO_FIREWALL_ENABLED: "true"
124
+ GH_AW_INFO_AWF_VERSION: "v0.27.11"
125
+ GH_AW_INFO_AWMG_VERSION: ""
126
+ GH_AW_INFO_FIREWALL_TYPE: "squid"
127
+ GH_AW_COMPILED_STRICT: "true"
128
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
129
+ with:
130
+ script: |
131
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
132
+ setupGlobals(core, github, context, exec, io, getOctokit);
133
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_aw_info.cjs');
134
+ await main(core, context);
135
+ - name: Restore daily AIC usage cache
136
+ id: restore-daily-aic-cache
137
+ if: ${{ env.GH_AW_MAX_DAILY_AI_CREDITS != '' }}
138
+ continue-on-error: true
139
+ uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
140
+ with:
141
+ key: agentic-workflow-usage-weeklyredteam-${{ github.run_id }}
142
+ restore-keys: agentic-workflow-usage-weeklyredteam-
143
+ path: /tmp/gh-aw/agentic-workflow-usage-cache.jsonl
144
+ - name: Restore daily AIC usage cache (artifact fallback)
145
+ id: restore-daily-aic-cache-fallback
146
+ if: ${{ env.GH_AW_MAX_DAILY_AI_CREDITS != '' }}
147
+ continue-on-error: true
148
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
149
+ env:
150
+ GH_AW_RESTORE_DAILY_AIC_CACHE_HIT: ${{ steps.restore-daily-aic-cache.outputs.cache-hit }}
151
+ GH_AW_RESTORE_DAILY_AIC_CACHE_MATCHED_KEY: ${{ steps.restore-daily-aic-cache.outputs.cache-matched-key }}
152
+ with:
153
+ github-token: ${{ secrets.GITHUB_TOKEN }}
154
+ script: |
155
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
156
+ setupGlobals(core, github, context, exec, io, getOctokit);
157
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/restore_aic_usage_cache_fallback.cjs');
158
+ await main();
159
+ - name: Check daily workflow token guardrail
160
+ id: daily-effective-workflow-guardrail
161
+ if: ${{ env.GH_AW_MAX_DAILY_AI_CREDITS != '' }}
162
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
163
+ env:
164
+ GH_AW_WORKFLOW_NAME: "Weekly red team"
165
+ GH_AW_WORKFLOW_ID: "weekly-redteam"
166
+ GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
167
+ GH_AW_WORKFLOW_DISPATCH_AW_CONTEXT: ${{ github.event.inputs.aw_context || '' }}
168
+ GH_AW_HAS_SLASH_COMMAND: "false"
169
+ GH_AW_HAS_LABEL_COMMAND: "false"
170
+ GH_AW_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
171
+ GH_AW_MAX_DAILY_AI_CREDITS: ${{ vars.GH_AW_DEFAULT_MAX_DAILY_AI_CREDITS || '5000' }}
172
+ with:
173
+ github-token: ${{ secrets.GITHUB_TOKEN }}
174
+ script: |
175
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
176
+ setupGlobals(core, github, context, exec, io, getOctokit);
177
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/check_daily_aic_workflow_guardrail.cjs');
178
+ await main();
179
+ - name: Validate COPILOT_GITHUB_TOKEN secret
180
+ id: validate-secret
181
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/validate_multi_secret.sh" COPILOT_GITHUB_TOKEN 'GitHub Copilot CLI' https://github.github.com/gh-aw/reference/engines/#github-copilot-default
182
+ env:
183
+ COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
184
+ - name: Checkout .github and .agents folders
185
+ uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
186
+ with:
187
+ persist-credentials: false
188
+ sparse-checkout: |
189
+ .github
190
+ .agents
191
+ .antigravity
192
+ .claude
193
+ .codex
194
+ .crush
195
+ .gemini
196
+ .opencode
197
+ .pi
198
+ sparse-checkout-cone-mode: true
199
+ fetch-depth: 1
200
+ - name: Save agent config folders for base branch restoration
201
+ env:
202
+ GH_AW_AGENT_FOLDERS: ".agents .antigravity .claude .codex .crush .gemini .github .opencode .pi"
203
+ GH_AW_AGENT_FILES: ".crush.json AGENTS.md ANTIGRAVITY.md CLAUDE.md GEMINI.md PI.md opencode.jsonc"
204
+ # poutine:ignore untrusted_checkout_exec
205
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/save_base_github_folders.sh"
206
+ - name: Check workflow lock file
207
+ id: check-lock-file
208
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
209
+ env:
210
+ GH_AW_WORKFLOW_FILE: "weekly-redteam.lock.yml"
211
+ GH_AW_CONTEXT_WORKFLOW_REF: "${{ github.workflow_ref }}"
212
+ with:
213
+ script: |
214
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
215
+ setupGlobals(core, github, context, exec, io, getOctokit);
216
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/check_workflow_timestamp_api.cjs');
217
+ await main();
218
+ - name: Check compile-agentic version
219
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
220
+ env:
221
+ GH_AW_COMPILED_VERSION: "v0.81.6"
222
+ with:
223
+ script: |
224
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
225
+ setupGlobals(core, github, context, exec, io, getOctokit);
226
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/check_version_updates.cjs');
227
+ await main();
228
+ - name: Log runtime features
229
+ if: ${{ contains(toJSON(vars), '"GH_AW_RUNTIME_FEATURES":') }}
230
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/log_runtime_features_summary.sh"
231
+ - name: Create prompt with built-in context
232
+ env:
233
+ GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
234
+ GH_AW_SAFE_OUTPUTS: ${{ runner.temp }}/gh-aw/safeoutputs/outputs.jsonl
235
+ GH_AW_EXPR_1A3A194A: ${{ github.event.discussion.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'discussion' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }}
236
+ GH_AW_EXPR_463A214A: ${{ github.event.pull_request.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'pull_request' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }}
237
+ GH_AW_EXPR_802A9F6A: ${{ github.event.issue.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'issue' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }}
238
+ GH_AW_EXPR_FF1D34CE: ${{ github.event.comment.id || fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').comment_id }}
239
+ GH_AW_GITHUB_ACTOR: ${{ github.actor }}
240
+ GH_AW_GITHUB_REPOSITORY: ${{ github.repository }}
241
+ GH_AW_GITHUB_RUN_ID: ${{ github.run_id }}
242
+ GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }}
243
+ # poutine:ignore untrusted_checkout_exec
244
+ run: |
245
+ bash "${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh"
246
+ {
247
+ cat << 'GH_AW_PROMPT_9ef9cfb34e9a95c8_EOF'
248
+ <system>
249
+ GH_AW_PROMPT_9ef9cfb34e9a95c8_EOF
250
+ cat "${RUNNER_TEMP}/gh-aw/prompts/xpia.md"
251
+ cat "${RUNNER_TEMP}/gh-aw/prompts/temp_folder_prompt.md"
252
+ cat "${RUNNER_TEMP}/gh-aw/prompts/markdown.md"
253
+ cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_prompt.md"
254
+ cat << 'GH_AW_PROMPT_9ef9cfb34e9a95c8_EOF'
255
+ <safe-output-tools>
256
+ Tools: create_issue(max:2), missing_tool, missing_data, noop
257
+ </safe-output-tools>
258
+ GH_AW_PROMPT_9ef9cfb34e9a95c8_EOF
259
+ cat "${RUNNER_TEMP}/gh-aw/prompts/mcp_cli_tools_prompt.md"
260
+ cat << 'GH_AW_PROMPT_9ef9cfb34e9a95c8_EOF'
261
+ <github-context>
262
+ The following GitHub context information is available for this workflow:
263
+ {{#if github.actor}}
264
+ - **actor**: __GH_AW_GITHUB_ACTOR__
265
+ {{/if}}
266
+ {{#if github.repository}}
267
+ - **repository**: __GH_AW_GITHUB_REPOSITORY__
268
+ {{/if}}
269
+ {{#if github.workspace}}
270
+ - **workspace**: __GH_AW_GITHUB_WORKSPACE__
271
+ {{/if}}
272
+ {{#if github.event.issue.number || (github.aw.context.item_type == 'issue' && github.aw.context.item_number)}}
273
+ - **issue-number**: #__GH_AW_EXPR_802A9F6A__
274
+ {{/if}}
275
+ {{#if github.event.discussion.number || (github.aw.context.item_type == 'discussion' && github.aw.context.item_number)}}
276
+ - **discussion-number**: #__GH_AW_EXPR_1A3A194A__
277
+ {{/if}}
278
+ {{#if github.event.pull_request.number || (github.aw.context.item_type == 'pull_request' && github.aw.context.item_number)}}
279
+ - **pull-request-number**: #__GH_AW_EXPR_463A214A__
280
+ {{/if}}
281
+ {{#if github.event.comment.id || github.aw.context.comment_id}}
282
+ - **comment-id**: __GH_AW_EXPR_FF1D34CE__
283
+ {{/if}}
284
+ {{#if github.run_id}}
285
+ - **workflow-run-id**: __GH_AW_GITHUB_RUN_ID__
286
+ {{/if}}
287
+ </github-context>
288
+
289
+ GH_AW_PROMPT_9ef9cfb34e9a95c8_EOF
290
+ cat "${RUNNER_TEMP}/gh-aw/prompts/github_mcp_tools_with_safeoutputs_prompt.md"
291
+ cat << 'GH_AW_PROMPT_9ef9cfb34e9a95c8_EOF'
292
+ </system>
293
+ {{#runtime-import .github/workflows/weekly-redteam.md}}
294
+ GH_AW_PROMPT_9ef9cfb34e9a95c8_EOF
295
+ } > "$GH_AW_PROMPT"
296
+ - name: Interpolate variables and render templates
297
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
298
+ env:
299
+ GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
300
+ GH_AW_ENGINE_ID: "copilot"
301
+ with:
302
+ script: |
303
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
304
+ setupGlobals(core, github, context, exec, io, getOctokit);
305
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/interpolate_prompt.cjs');
306
+ await main();
307
+ - name: Substitute placeholders
308
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
309
+ env:
310
+ GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
311
+ GH_AW_EXPR_1A3A194A: ${{ github.event.discussion.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'discussion' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }}
312
+ GH_AW_EXPR_463A214A: ${{ github.event.pull_request.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'pull_request' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }}
313
+ GH_AW_EXPR_802A9F6A: ${{ github.event.issue.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'issue' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }}
314
+ GH_AW_EXPR_FF1D34CE: ${{ github.event.comment.id || fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').comment_id }}
315
+ GH_AW_GITHUB_ACTOR: ${{ github.actor }}
316
+ GH_AW_GITHUB_REPOSITORY: ${{ github.repository }}
317
+ GH_AW_GITHUB_RUN_ID: ${{ github.run_id }}
318
+ GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }}
319
+ GH_AW_MCP_CLI_SERVERS_LIST: '- `safeoutputs` — run `safeoutputs --help` to see available tools'
320
+ with:
321
+ script: |
322
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
323
+ setupGlobals(core, github, context, exec, io, getOctokit);
324
+
325
+ const substitutePlaceholders = require('${{ runner.temp }}/gh-aw/actions/substitute_placeholders.cjs');
326
+
327
+ // Call the substitution function
328
+ return await substitutePlaceholders({
329
+ file: process.env.GH_AW_PROMPT,
330
+ substitutions: {
331
+ GH_AW_EXPR_1A3A194A: process.env.GH_AW_EXPR_1A3A194A,
332
+ GH_AW_EXPR_463A214A: process.env.GH_AW_EXPR_463A214A,
333
+ GH_AW_EXPR_802A9F6A: process.env.GH_AW_EXPR_802A9F6A,
334
+ GH_AW_EXPR_FF1D34CE: process.env.GH_AW_EXPR_FF1D34CE,
335
+ GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR,
336
+ GH_AW_GITHUB_REPOSITORY: process.env.GH_AW_GITHUB_REPOSITORY,
337
+ GH_AW_GITHUB_RUN_ID: process.env.GH_AW_GITHUB_RUN_ID,
338
+ GH_AW_GITHUB_WORKSPACE: process.env.GH_AW_GITHUB_WORKSPACE,
339
+ GH_AW_MCP_CLI_SERVERS_LIST: process.env.GH_AW_MCP_CLI_SERVERS_LIST
340
+ }
341
+ });
342
+ - name: Validate prompt placeholders
343
+ env:
344
+ GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
345
+ # poutine:ignore untrusted_checkout_exec
346
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/validate_prompt_placeholders.sh"
347
+ - name: Print prompt
348
+ env:
349
+ GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
350
+ # poutine:ignore untrusted_checkout_exec
351
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/print_prompt_summary.sh"
352
+ - name: Upload activation artifact
353
+ if: success()
354
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
355
+ with:
356
+ name: activation
357
+ include-hidden-files: true
358
+ path: |
359
+ /tmp/gh-aw/aw_info.json
360
+ /tmp/gh-aw/models.json
361
+ /tmp/gh-aw/aw-prompts/prompt.txt
362
+ /tmp/gh-aw/aw-prompts/prompt-template.txt
363
+ /tmp/gh-aw/aw-prompts/prompt-import-tree.json
364
+ /tmp/gh-aw/github_rate_limits.jsonl
365
+ /tmp/gh-aw/base
366
+ /tmp/gh-aw/.github/agents
367
+ /tmp/gh-aw/.github/skills
368
+ if-no-files-found: ignore
369
+ retention-days: 1
370
+
371
+ agent:
372
+ needs: activation
373
+ if: needs.activation.outputs.daily_ai_credits_exceeded != 'true'
374
+ runs-on: ubuntu-latest
375
+ permissions:
376
+ contents: read
377
+ issues: read
378
+ concurrency:
379
+ group: "gh-aw-copilot-${{ github.workflow }}"
380
+ queue: max
381
+ env:
382
+ DEFAULT_BRANCH: ${{ github.event.repository.default_branch }}
383
+ GH_AW_ASSETS_ALLOWED_EXTS: ""
384
+ GH_AW_ASSETS_BRANCH: ""
385
+ GH_AW_ASSETS_MAX_SIZE_KB: 0
386
+ GH_AW_MCP_LOG_DIR: /tmp/gh-aw/mcp-logs/safeoutputs
387
+ GH_AW_RUNTIME_FEATURES: ${{ vars.GH_AW_RUNTIME_FEATURES }}
388
+ GH_AW_WORKFLOW_ID_SANITIZED: weeklyredteam
389
+ outputs:
390
+ agentic_engine_timeout: ${{ steps.detect-agent-errors.outputs.agentic_engine_timeout || 'false' }}
391
+ ai_credits_rate_limit_error: ${{ steps.parse-mcp-gateway.outputs.ai_credits_rate_limit_error || 'false' }}
392
+ aic: ${{ steps.parse-mcp-gateway.outputs.aic }}
393
+ ambient_context: ${{ steps.parse-mcp-gateway.outputs.ambient_context }}
394
+ checkout_pr_success: ${{ steps.checkout-pr.outputs.checkout_pr_success || 'true' }}
395
+ effective_tokens: ${{ steps.parse-mcp-gateway.outputs.effective_tokens }}
396
+ has_patch: ${{ steps.collect_output.outputs.has_patch }}
397
+ inference_access_error: ${{ steps.detect-agent-errors.outputs.inference_access_error || 'false' }}
398
+ mcp_policy_error: ${{ steps.detect-agent-errors.outputs.mcp_policy_error || 'false' }}
399
+ model: ${{ needs.activation.outputs.model }}
400
+ model_not_supported_error: ${{ steps.detect-agent-errors.outputs.model_not_supported_error || 'false' }}
401
+ output: ${{ steps.collect_output.outputs.output }}
402
+ output_types: ${{ steps.collect_output.outputs.output_types }}
403
+ setup-parent-span-id: ${{ steps.setup.outputs.parent-span-id || steps.setup.outputs.span-id }}
404
+ setup-span-id: ${{ steps.setup.outputs.span-id }}
405
+ setup-trace-id: ${{ steps.setup.outputs.trace-id }}
406
+ unknown_model_ai_credits: ${{ steps.parse-mcp-gateway.outputs.unknown_model_ai_credits || 'false' }}
407
+ steps:
408
+ - name: Setup Scripts
409
+ id: setup
410
+ uses: github/gh-aw-actions/setup@ba6380cc6e5be5d21677bebe04d52fb48e3abec7 # v0.81.6
411
+ with:
412
+ destination: ${{ runner.temp }}/gh-aw/actions
413
+ job-name: ${{ github.job }}
414
+ trace-id: ${{ needs.activation.outputs.setup-trace-id }}
415
+ parent-span-id: ${{ needs.activation.outputs.setup-parent-span-id || needs.activation.outputs.setup-span-id }}
416
+ env:
417
+ GH_AW_SETUP_WORKFLOW_NAME: "Weekly red team"
418
+ GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/weekly-redteam.lock.yml@${{ github.ref }}
419
+ GH_AW_INFO_VERSION: "1.0.65"
420
+ GH_AW_INFO_AWF_VERSION: "v0.27.11"
421
+ GH_AW_INFO_ENGINE_ID: "copilot"
422
+ - name: Set runtime paths
423
+ id: set-runtime-paths
424
+ run: |
425
+ {
426
+ echo "GH_AW_SAFE_OUTPUTS=${RUNNER_TEMP}/gh-aw/safeoutputs/outputs.jsonl"
427
+ echo "GH_AW_SAFE_OUTPUTS_CONFIG_PATH=${RUNNER_TEMP}/gh-aw/safeoutputs/config.json"
428
+ echo "GH_AW_SAFE_OUTPUTS_TOOLS_PATH=${RUNNER_TEMP}/gh-aw/safeoutputs/tools.json"
429
+ } >> "$GITHUB_OUTPUT"
430
+ - name: Checkout repository
431
+ uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
432
+ with:
433
+ persist-credentials: false
434
+ - name: Create gh-aw temp directory
435
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/create_gh_aw_tmp_dir.sh"
436
+ - name: Configure gh CLI for GitHub Enterprise
437
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/configure_gh_for_ghe.sh"
438
+ env:
439
+ GH_TOKEN: ${{ github.token }}
440
+ - name: Configure Git credentials
441
+ env:
442
+ GITHUB_REPOSITORY: ${{ github.repository }}
443
+ GITHUB_SERVER_URL: ${{ github.server_url }}
444
+ GITHUB_TOKEN: ${{ github.token }}
445
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/configure_git_credentials.sh"
446
+ - name: Checkout PR branch
447
+ id: checkout-pr
448
+ if: |
449
+ github.event.pull_request || github.event.issue.pull_request || github.event_name == 'workflow_dispatch' && fromJSON(github.event.inputs.aw_context || '{}').item_type == 'pull_request'
450
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
451
+ env:
452
+ GH_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
453
+ with:
454
+ github-token: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
455
+ script: |
456
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
457
+ setupGlobals(core, github, context, exec, io, getOctokit);
458
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/checkout_pr_branch.cjs');
459
+ await main();
460
+ - name: Install GitHub Copilot CLI
461
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.65
462
+ env:
463
+ GH_HOST: github.com
464
+ - name: Install AWF binary
465
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.11
466
+ - name: Determine automatic lockdown mode for GitHub MCP Server
467
+ id: determine-automatic-lockdown
468
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 (source v9)
469
+ env:
470
+ GH_AW_GITHUB_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN }}
471
+ GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }}
472
+ with:
473
+ script: |
474
+ const determineAutomaticLockdown = require('${{ runner.temp }}/gh-aw/actions/determine_automatic_lockdown.cjs');
475
+ await determineAutomaticLockdown(github, context, core);
476
+ - name: Download activation artifact
477
+ uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
478
+ with:
479
+ name: activation
480
+ path: /tmp/gh-aw
481
+ - name: Restore agent config folders from base branch
482
+ if: steps.checkout-pr.outcome == 'success'
483
+ env:
484
+ GH_AW_AGENT_FOLDERS: ".agents .antigravity .claude .codex .crush .gemini .github .opencode .pi"
485
+ GH_AW_AGENT_FILES: ".crush.json AGENTS.md ANTIGRAVITY.md CLAUDE.md GEMINI.md PI.md opencode.jsonc"
486
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_base_github_folders.sh"
487
+ - name: Restore inline sub-agents from activation artifact
488
+ env:
489
+ GH_AW_SUB_AGENT_DIR: ".github/agents"
490
+ GH_AW_SUB_AGENT_EXT: ".agent.md"
491
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_inline_sub_agents.sh"
492
+ - name: Restore inline skills from activation artifact
493
+ env:
494
+ GH_AW_SKILL_DIR: ".github/skills"
495
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_inline_skills.sh"
496
+ - name: Download container images
497
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.27.11@sha256:979723c628182da7729333f2208bb249fd25ddee579645cf9a3892d681a929c7 ghcr.io/github/gh-aw-firewall/api-proxy:0.27.11@sha256:807e4831999b44513b0a66e5859d478dc4da7ae74ab1918cec967d513f95bf9d ghcr.io/github/gh-aw-firewall/squid:0.27.11@sha256:ff27ea0525ad953a6adee28a5fbe9d2e22be47dbec755c15767af4ea3f91df7d ghcr.io/github/gh-aw-mcpg:v0.3.30@sha256:35625d1a2269b1238606078c879f59a91cffc4ac33eb54bf39c6418822c1a8be ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b ghcr.io/github/github-mcp-server:v1.4.0@sha256:2afb26356481d1a350e14544a6e160f7f7ec1561a1ea309b823665abf0309036
498
+ - name: Generate Safe Outputs Config
499
+ run: |
500
+ mkdir -p "${RUNNER_TEMP}/gh-aw/safeoutputs"
501
+ mkdir -p /tmp/gh-aw/safeoutputs
502
+ mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs
503
+ cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_1f6d8873e56b224d_EOF'
504
+ {"create_issue":{"max":2},"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"report_incomplete":{}}
505
+ GH_AW_SAFE_OUTPUTS_CONFIG_1f6d8873e56b224d_EOF
506
+ - name: Generate Safe Outputs Tools
507
+ env:
508
+ GH_AW_TOOLS_META_JSON: |
509
+ {
510
+ "description_suffixes": {
511
+ "create_issue": " CONSTRAINTS: Maximum 2 issue(s) can be created."
512
+ },
513
+ "repo_params": {},
514
+ "dynamic_tools": []
515
+ }
516
+ GH_AW_VALIDATION_JSON: |
517
+ {
518
+ "create_issue": {
519
+ "defaultMax": 1,
520
+ "fields": {
521
+ "body": {
522
+ "required": true,
523
+ "type": "string",
524
+ "sanitize": true,
525
+ "maxLength": 65000,
526
+ "minLength": 20
527
+ },
528
+ "fields": {
529
+ "type": "array"
530
+ },
531
+ "labels": {
532
+ "type": "array",
533
+ "itemType": "string",
534
+ "itemSanitize": true,
535
+ "itemMaxLength": 128
536
+ },
537
+ "parent": {
538
+ "issueOrPRNumber": true
539
+ },
540
+ "repo": {
541
+ "type": "string",
542
+ "maxLength": 256
543
+ },
544
+ "temporary_id": {
545
+ "type": "string"
546
+ },
547
+ "title": {
548
+ "required": true,
549
+ "type": "string",
550
+ "sanitize": true,
551
+ "maxLength": 128
552
+ }
553
+ }
554
+ },
555
+ "missing_data": {
556
+ "defaultMax": 20,
557
+ "fields": {
558
+ "alternatives": {
559
+ "type": "string",
560
+ "sanitize": true,
561
+ "maxLength": 256
562
+ },
563
+ "context": {
564
+ "type": "string",
565
+ "sanitize": true,
566
+ "maxLength": 256
567
+ },
568
+ "data_type": {
569
+ "type": "string",
570
+ "sanitize": true,
571
+ "maxLength": 128
572
+ },
573
+ "reason": {
574
+ "type": "string",
575
+ "sanitize": true,
576
+ "maxLength": 256
577
+ }
578
+ }
579
+ },
580
+ "missing_tool": {
581
+ "defaultMax": 20,
582
+ "fields": {
583
+ "alternatives": {
584
+ "type": "string",
585
+ "sanitize": true,
586
+ "maxLength": 512
587
+ },
588
+ "reason": {
589
+ "required": true,
590
+ "type": "string",
591
+ "sanitize": true,
592
+ "maxLength": 256
593
+ },
594
+ "tool": {
595
+ "type": "string",
596
+ "sanitize": true,
597
+ "maxLength": 128
598
+ }
599
+ }
600
+ },
601
+ "noop": {
602
+ "defaultMax": 1,
603
+ "fields": {
604
+ "message": {
605
+ "required": true,
606
+ "type": "string",
607
+ "sanitize": true,
608
+ "maxLength": 65000
609
+ }
610
+ }
611
+ },
612
+ "report_incomplete": {
613
+ "defaultMax": 5,
614
+ "fields": {
615
+ "details": {
616
+ "type": "string",
617
+ "sanitize": true,
618
+ "maxLength": 65000
619
+ },
620
+ "reason": {
621
+ "required": true,
622
+ "type": "string",
623
+ "sanitize": true,
624
+ "maxLength": 1024
625
+ }
626
+ }
627
+ }
628
+ }
629
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
630
+ with:
631
+ script: |
632
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
633
+ setupGlobals(core, github, context, exec, io, getOctokit);
634
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_safe_outputs_tools.cjs');
635
+ await main();
636
+ - name: Start MCP Gateway
637
+ id: start-mcp-gateway
638
+ env:
639
+ GH_AW_POLICY_ALLOW_CREATE_PULL_REQUEST: ${{ vars.GH_AW_POLICY_ALLOW_CREATE_PULL_REQUEST || 'true' }}
640
+ GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
641
+ GH_AW_SAFE_OUTPUTS_CONFIG_PATH: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS_CONFIG_PATH }}
642
+ GH_AW_SAFE_OUTPUTS_TOOLS_PATH: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS_TOOLS_PATH }}
643
+ GITHUB_MCP_GUARD_MIN_INTEGRITY: ${{ steps.determine-automatic-lockdown.outputs.min_integrity }}
644
+ GITHUB_MCP_GUARD_REPOS: ${{ steps.determine-automatic-lockdown.outputs.repos }}
645
+ GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
646
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
647
+ run: |
648
+ set -eo pipefail
649
+ mkdir -p "${RUNNER_TEMP}/gh-aw/mcp-config"
650
+
651
+ # Export gateway environment variables for MCP config and gateway script
652
+ export MCP_GATEWAY_PORT="8080"
653
+ export MCP_GATEWAY_DOMAIN="host.docker.internal"
654
+ export MCP_GATEWAY_HOST_DOMAIN="localhost"
655
+ MCP_GATEWAY_API_KEY=$(openssl rand -base64 45 | tr -d '/+=')
656
+ echo "::add-mask::${MCP_GATEWAY_API_KEY}"
657
+ export MCP_GATEWAY_API_KEY
658
+ export MCP_GATEWAY_PAYLOAD_DIR="/tmp/gh-aw/mcp-payloads"
659
+ mkdir -p "${MCP_GATEWAY_PAYLOAD_DIR}"
660
+ export MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD="524288"
661
+ export DEBUG="*"
662
+
663
+ export GH_AW_ENGINE="copilot"
664
+ MCP_GATEWAY_UID=$(id -u 2>/dev/null || echo '0')
665
+ MCP_GATEWAY_GID=$(id -g 2>/dev/null || echo '0')
666
+ case "${DOCKER_HOST:-}" in
667
+ unix://* ) DOCKER_SOCK_PATH="${DOCKER_HOST#unix://}" ;;
668
+ /* ) DOCKER_SOCK_PATH="$DOCKER_HOST" ;;
669
+ * ) DOCKER_SOCK_PATH=/var/run/docker.sock ;;
670
+ esac
671
+ DOCKER_SOCK_GID=$(stat -c '%g' "$DOCKER_SOCK_PATH" 2>/dev/null || echo '0')
672
+ export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host --name awmg-mcpg --add-host host.docker.internal:127.0.0.1 --user '"${MCP_GATEWAY_UID}"':'"${MCP_GATEWAY_GID}"' --group-add '"${DOCKER_SOCK_GID}"' -v '"${DOCKER_SOCK_PATH}"':/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DOCKER_HOST=unix:///var/run/docker.sock -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_POLICY_ALLOW_CREATE_PULL_REQUEST -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e RUNNER_TEMP -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw -v '"${RUNNER_TEMP}"'/gh-aw/safeoutputs:'"${RUNNER_TEMP}"'/gh-aw/safeoutputs:rw ghcr.io/github/gh-aw-mcpg:v0.3.30'
673
+
674
+ mkdir -p "$HOME/.copilot"
675
+ GH_AW_NODE=$(which node 2>/dev/null || command -v node 2>/dev/null || echo node)
676
+ cat << GH_AW_MCP_CONFIG_f014db59cae17bc3_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs"
677
+ {
678
+ "mcpServers": {
679
+ "github": {
680
+ "type": "stdio",
681
+ "container": "ghcr.io/github/github-mcp-server:v1.4.0",
682
+ "env": {
683
+ "GITHUB_HOST": "${GITHUB_SERVER_URL}",
684
+ "GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_MCP_SERVER_TOKEN}",
685
+ "GITHUB_READ_ONLY": "1",
686
+ "GITHUB_TOOLSETS": "context,repos,issues,pull_requests"
687
+ },
688
+ "guard-policies": {
689
+ "allow-only": {
690
+ "min-integrity": "$GITHUB_MCP_GUARD_MIN_INTEGRITY",
691
+ "repos": "$GITHUB_MCP_GUARD_REPOS"
692
+ }
693
+ }
694
+ },
695
+ "safeoutputs": {
696
+ "type": "stdio",
697
+ "container": "ghcr.io/github/gh-aw-node",
698
+ "mounts": ["\${GITHUB_WORKSPACE}:\${GITHUB_WORKSPACE}:rw", "${RUNNER_TEMP}/gh-aw/safeoutputs:${RUNNER_TEMP}/gh-aw/safeoutputs:rw", "/tmp/gh-aw:/tmp/gh-aw:rw"],
699
+ "args": ["-w", "\${GITHUB_WORKSPACE}"],
700
+ "entrypoint": "sh",
701
+ "entrypointArgs": ["-c", "sh ${RUNNER_TEMP}/gh-aw/safeoutputs/start_safe_outputs_mcp.sh"],
702
+ "env": {
703
+ "DEBUG": "*",
704
+ "DEFAULT_BRANCH": "\${DEFAULT_BRANCH}",
705
+ "GH_AW_ASSETS_ALLOWED_EXTS": "\${GH_AW_ASSETS_ALLOWED_EXTS}",
706
+ "GH_AW_ASSETS_BRANCH": "\${GH_AW_ASSETS_BRANCH}",
707
+ "GH_AW_ASSETS_MAX_SIZE_KB": "\${GH_AW_ASSETS_MAX_SIZE_KB}",
708
+ "GH_AW_MCP_LOG_DIR": "\${GH_AW_MCP_LOG_DIR}",
709
+ "GH_AW_SAFE_OUTPUTS": "\${GH_AW_SAFE_OUTPUTS}",
710
+ "GH_AW_SAFE_OUTPUTS_CONFIG_PATH": "\${GH_AW_SAFE_OUTPUTS_CONFIG_PATH}",
711
+ "GH_AW_SAFE_OUTPUTS_TOOLS_PATH": "\${GH_AW_SAFE_OUTPUTS_TOOLS_PATH}",
712
+ "GH_AW_POLICY_ALLOW_CREATE_PULL_REQUEST": "\${GH_AW_POLICY_ALLOW_CREATE_PULL_REQUEST}",
713
+ "GITHUB_REPOSITORY": "\${GITHUB_REPOSITORY}",
714
+ "GITHUB_TOKEN": "\${GITHUB_TOKEN}",
715
+ "GITHUB_WORKSPACE": "\${GITHUB_WORKSPACE}",
716
+ "RUNNER_TEMP": "\${RUNNER_TEMP}"
717
+ },
718
+ "guard-policies": {
719
+ "write-sink": {
720
+ "accept": [
721
+ "*"
722
+ ]
723
+ }
724
+ }
725
+ }
726
+ },
727
+ "gateway": {
728
+ "port": $MCP_GATEWAY_PORT,
729
+ "domain": "${MCP_GATEWAY_DOMAIN}",
730
+ "apiKey": "${MCP_GATEWAY_API_KEY}",
731
+ "payloadDir": "${MCP_GATEWAY_PAYLOAD_DIR}"
732
+ }
733
+ }
734
+ GH_AW_MCP_CONFIG_f014db59cae17bc3_EOF
735
+ - name: Mount MCP servers as CLIs
736
+ id: mount-mcp-clis
737
+ continue-on-error: true
738
+ env:
739
+ MCP_GATEWAY_API_KEY: ${{ steps.start-mcp-gateway.outputs.gateway-api-key }}
740
+ MCP_GATEWAY_DOMAIN: ${{ steps.start-mcp-gateway.outputs.gateway-domain }}
741
+ MCP_GATEWAY_PORT: ${{ steps.start-mcp-gateway.outputs.gateway-port }}
742
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
743
+ with:
744
+ script: |
745
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
746
+ setupGlobals(core, github, context, exec, io);
747
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/mount_mcp_as_cli.cjs');
748
+ await main();
749
+ - name: Clean credentials
750
+ continue-on-error: true
751
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/clean_git_credentials.sh"
752
+ - name: Audit pre-agent workspace
753
+ id: pre_agent_audit
754
+ continue-on-error: true
755
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/audit_pre_agent_workspace.sh"
756
+ - name: Execute GitHub Copilot CLI
757
+ id: agentic_execution
758
+ # Copilot CLI tool arguments (sorted):
759
+ timeout-minutes: 20
760
+ run: |
761
+ set -o pipefail
762
+ printf '%s' "$(date +%s%3N)" > /tmp/gh-aw/agent_cli_start_ms.txt
763
+ trap 'rm -f "$HOME/.copilot/settings.json"' EXIT
764
+ mkdir -p "$HOME/.copilot"
765
+ printf '%s' '{"builtInAgents":{"rubberDuck":false}}' > "$HOME/.copilot/settings.json"
766
+ export XDG_CONFIG_HOME="$HOME"
767
+ export GH_AW_MCP_CONFIG="$HOME/.copilot/mcp-config.json"
768
+ touch /tmp/gh-aw/agent-step-summary.md
769
+ GH_AW_NODE_BIN=$(command -v node 2>/dev/null || true)
770
+ export GH_AW_NODE_BIN
771
+ export COPILOT_API_KEY="$COPILOT_DUMMY_BYOK"
772
+ (umask 177 && touch /tmp/gh-aw/agent-stdio.log)
773
+ GH_AW_MAX_AI_CREDITS="${GH_AW_MAX_AI_CREDITS:-1000}"
774
+ printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.27.11/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"api.business.githubcopilot.com\",\"api.enterprise.githubcopilot.com\",\"api.github.com\",\"api.githubcopilot.com\",\"api.individual.githubcopilot.com\",\"api.snapcraft.io\",\"archive.ubuntu.com\",\"azure.archive.ubuntu.com\",\"crl.geotrust.com\",\"crl.globalsign.com\",\"crl.identrust.com\",\"crl.sectigo.com\",\"crl.thawte.com\",\"crl.usertrust.com\",\"crl.verisign.com\",\"crl3.digicert.com\",\"crl4.digicert.com\",\"crls.ssl.com\",\"github.com\",\"host.docker.internal\",\"json-schema.org\",\"json.schemastore.org\",\"keyserver.ubuntu.com\",\"ocsp.digicert.com\",\"ocsp.geotrust.com\",\"ocsp.globalsign.com\",\"ocsp.identrust.com\",\"ocsp.sectigo.com\",\"ocsp.ssl.com\",\"ocsp.thawte.com\",\"ocsp.usertrust.com\",\"ocsp.verisign.com\",\"packagecloud.io\",\"packages.cloud.google.com\",\"packages.microsoft.com\",\"ppa.launchpad.net\",\"raw.githubusercontent.com\",\"registry.npmjs.org\",\"s.symcb.com\",\"s.symcd.com\",\"security.ubuntu.com\",\"telemetry.enterprise.githubcopilot.com\",\"ts-crl.ws.symantec.com\",\"ts-ocsp.ws.symantec.com\",\"www.googleapis.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS},\"maxCacheMisses\":5,\"models\":{\"agent\":[\"sonnet-6x\",\"gpt-5.5\",\"gpt-5.4\",\"gpt-5.3\",\"gemini-pro\",\"any\"],\"antigravity\":[\"copilot/antigravity*\",\"google/antigravity*\",\"gemini/antigravity*\"],\"any\":[\"copilot/*\",\"anthropic/*\",\"openai/*\",\"google/*\",\"gemini/*\"],\"claude\":[\"agent\"],\"codex\":[\"agent\"],\"coding\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\",\"gpt-5-codex\"],\"computer-use\":[\"copilot/*computer-use*\",\"google/*computer-use*\",\"gemini/*computer-use*\",\"openai/*computer-use*\"],\"copilot\":[\"agent\"],\"deep-research\":[\"copilot/deep-research*\",\"copilot/o3-deep-research*\",\"copilot/o4-mini-deep-research*\",\"google/deep-research*\",\"gemini/deep-research*\",\"openai/o3-deep-research*\",\"openai/o4-mini-deep-research*\"],\"gemini\":[\"agent\"],\"gemini-3-flash\":[\"copilot/gemini-3*flash*\",\"google/gemini-3*flash*\",\"gemini/gemini-3*flash*\"],\"gemini-3-pro\":[\"copilot/gemini-3*pro*\",\"google/gemini-3*pro*\",\"google/nano-banana*\",\"gemini/gemini-3*pro*\"],\"gemini-3.1-flash\":[\"copilot/gemini-3.1*flash*\",\"google/gemini-3.1*flash*\",\"gemini/gemini-3.1*flash*\"],\"gemini-3.1-pro\":[\"copilot/gemini-3.1*pro*\",\"google/gemini-3.1*pro*\",\"gemini/gemini-3.1*pro*\"],\"gemini-3.5-flash\":[\"copilot/gemini-3.5*flash*\",\"google/gemini-3.5*flash*\",\"gemini/gemini-3.5*flash*\"],\"gemini-flash\":[\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"],\"gemini-flash-lite\":[\"copilot/gemini-*flash*lite*\",\"google/gemini-*flash*lite*\",\"gemini/gemini-*flash*lite*\"],\"gemini-pro\":[\"copilot/gemini-*pro*\",\"google/gemini-*pro*\",\"gemini/gemini-*pro*\"],\"gemma\":[\"copilot/gemma*\",\"google/gemma*\",\"gemini/gemma*\"],\"gpt-5\":[\"copilot/gpt-5*\",\"openai/gpt-5*\"],\"gpt-5-codex\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\"],\"gpt-5-mini\":[\"copilot/gpt-5*mini*\",\"openai/gpt-5*mini*\"],\"gpt-5-nano\":[\"copilot/gpt-5*nano*\",\"openai/gpt-5*nano*\"],\"gpt-5-pro\":[\"copilot/gpt-5*pro*\",\"openai/gpt-5*pro*\"],\"gpt-5.1\":[\"copilot/gpt-5.1*\",\"openai/gpt-5.1*\"],\"gpt-5.2\":[\"copilot/gpt-5.2*\",\"openai/gpt-5.2*\"],\"gpt-5.3\":[\"copilot/gpt-5.3*\",\"openai/gpt-5.3*\"],\"gpt-5.4\":[\"copilot/gpt-5.4*\",\"openai/gpt-5.4*\"],\"gpt-5.5\":[\"copilot/gpt-5.5*\",\"openai/gpt-5.5*\"],\"haiku\":[\"copilot/*haiku*\",\"anthropic/*haiku*\"],\"image-generation\":[\"copilot/gpt-image*\",\"openai/gpt-image*\",\"openai/chatgpt-image*\",\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"google/imagen*\"],\"large\":[\"sonnet\",\"gpt-5-pro\",\"gpt-5\",\"gemini-pro\"],\"mai-code\":[\"copilot/MAI-Code*\",\"copilot/mai-code*\",\"openai/MAI-Code*\"],\"mini\":[\"haiku\",\"gpt-5-mini\",\"gpt-5-nano\",\"gemini-flash-lite\"],\"nano-banana\":[\"copilot/nano-banana*\",\"google/nano-banana*\",\"gemini/nano-banana*\"],\"opus\":[\"copilot/*opus*\",\"anthropic/*opus*\"],\"opusplan\":[\"opus?effort=high\"],\"reasoning\":[\"copilot/o1*\",\"copilot/o3*\",\"copilot/o4*\",\"openai/o1*\",\"openai/o3*\",\"openai/o4*\"],\"robotics\":[\"copilot/*robotics*\",\"google/*robotics*\",\"gemini/*robotics*\"],\"small\":[\"mini\"],\"small-agent\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash\"],\"sonnet\":[\"copilot/*sonnet*\",\"anthropic/*sonnet*\"],\"sonnet-6x\":[\"copilot/*sonnet-4.5*\",\"copilot/*sonnet-4.6*\",\"copilot/*sonnet-4-5-*\",\"anthropic/*sonnet-4-5-*\",\"copilot/*sonnet-4-6*\",\"anthropic/*sonnet-4-6*\"],\"summarization\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash-lite\",\"mini\"],\"vision\":[\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"]}},\"container\":{\"imageTag\":\"0.27.11,squid=sha256:ff27ea0525ad953a6adee28a5fbe9d2e22be47dbec755c15767af4ea3f91df7d,agent=sha256:979723c628182da7729333f2208bb249fd25ddee579645cf9a3892d681a929c7,api-proxy=sha256:807e4831999b44513b0a66e5859d478dc4da7ae74ab1918cec967d513f95bf9d\"}}" > "${RUNNER_TEMP}/gh-aw/awf-config.json"
775
+ cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json
776
+ export GH_AW_MODELS_JSON_PATH="/tmp/gh-aw/models.json"
777
+ GH_AW_DOCKER_HOST=""
778
+ if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then
779
+ GH_AW_DOCKER_HOST="${DOCKER_HOST}"
780
+ fi
781
+ GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS=""
782
+ if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then
783
+ GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS="--docker-host-path-prefix /tmp/gh-aw"
784
+ GH_AW_CHROOT_BINARIES_SOURCE_PATH=/tmp/gh-aw GH_AW_CHROOT_IDENTITY_HOME=/tmp/gh-aw/home node "${RUNNER_TEMP}/gh-aw/actions/patch_awf_chroot_config.cjs"
785
+ fi
786
+ GH_AW_TOOL_CACHE_MOUNT=""
787
+ GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"
788
+ if [ -d "$GH_AW_TOOL_CACHE" ]; then
789
+ if [[ "$GH_AW_TOOL_CACHE" != /opt/* ]]; then
790
+ GH_AW_TOOL_CACHE_MOUNT="$GH_AW_TOOL_CACHE:$GH_AW_TOOL_CACHE:ro"
791
+ fi
792
+ fi
793
+ # shellcheck disable=SC1003,SC2086
794
+ sudo -E awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} ${GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS} --env-all --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --allow-host-ports 80,443,8080 --skip-pull \
795
+ -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log
796
+ env:
797
+ AWF_REFLECT_ENABLED: 1
798
+ COPILOT_AGENT_RUNNER_TYPE: STANDALONE
799
+ COPILOT_DUMMY_BYOK: dummy-byok-key-for-offline-mode
800
+ COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
801
+ COPILOT_MODEL: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || vars.GH_AW_DEFAULT_MODEL_COPILOT || 'claude-sonnet-4.6' }}
802
+ GH_AW_LLM_PROVIDER: github
803
+ GH_AW_MAX_AI_CREDITS: ${{ vars.GH_AW_DEFAULT_MAX_AI_CREDITS || '1000' }}
804
+ GH_AW_MAX_TURNS: ${{ vars.GH_AW_DEFAULT_MAX_TURNS || '' }}
805
+ GH_AW_PHASE: agent
806
+ GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
807
+ GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
808
+ GH_AW_TIMEOUT_MINUTES: 20
809
+ GH_AW_VERSION: v0.81.6
810
+ GITHUB_API_URL: ${{ github.api_url }}
811
+ GITHUB_AW: true
812
+ GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows
813
+ GITHUB_HEAD_REF: ${{ github.head_ref }}
814
+ GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
815
+ GITHUB_REF_NAME: ${{ github.ref_name }}
816
+ GITHUB_SERVER_URL: ${{ github.server_url }}
817
+ GITHUB_STEP_SUMMARY: /tmp/gh-aw/agent-step-summary.md
818
+ GITHUB_WORKSPACE: ${{ github.workspace }}
819
+ GIT_AUTHOR_EMAIL: github-actions[bot]@users.noreply.github.com
820
+ GIT_AUTHOR_NAME: github-actions[bot]
821
+ GIT_COMMITTER_EMAIL: github-actions[bot]@users.noreply.github.com
822
+ GIT_COMMITTER_NAME: github-actions[bot]
823
+ RUNNER_TEMP: ${{ runner.temp }}
824
+ TRACEPARENT: ${{ env.GITHUB_AW_OTEL_TRACE_ID != '' && env.GITHUB_AW_OTEL_PARENT_SPAN_ID != '' && format('00-{0}-{1}-01', env.GITHUB_AW_OTEL_TRACE_ID, env.GITHUB_AW_OTEL_PARENT_SPAN_ID) || '' }}
825
+ - name: Detect agent errors
826
+ if: always()
827
+ id: detect-agent-errors
828
+ continue-on-error: true
829
+ run: node "${RUNNER_TEMP}/gh-aw/actions/detect_agent_errors.cjs"
830
+ - name: Configure Git credentials
831
+ env:
832
+ GITHUB_REPOSITORY: ${{ github.repository }}
833
+ GITHUB_SERVER_URL: ${{ github.server_url }}
834
+ GITHUB_TOKEN: ${{ github.token }}
835
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/configure_git_credentials.sh"
836
+ - name: Copy Copilot session state files to logs
837
+ if: always()
838
+ continue-on-error: true
839
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/copy_copilot_session_state.sh"
840
+ - name: Stop MCP Gateway
841
+ if: always()
842
+ continue-on-error: true
843
+ env:
844
+ MCP_GATEWAY_PORT: ${{ steps.start-mcp-gateway.outputs.gateway-port }}
845
+ MCP_GATEWAY_API_KEY: ${{ steps.start-mcp-gateway.outputs.gateway-api-key }}
846
+ GATEWAY_PID: ${{ steps.start-mcp-gateway.outputs.gateway-pid }}
847
+ run: |
848
+ bash "${RUNNER_TEMP}/gh-aw/actions/stop_mcp_gateway.sh" "$GATEWAY_PID"
849
+ - name: Redact secrets in logs
850
+ if: always()
851
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
852
+ with:
853
+ script: |
854
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
855
+ setupGlobals(core, github, context, exec, io, getOctokit);
856
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/redact_secrets.cjs');
857
+ await main();
858
+ env:
859
+ GH_AW_SECRET_NAMES: 'COPILOT_GITHUB_TOKEN,GH_AW_GITHUB_MCP_SERVER_TOKEN,GH_AW_GITHUB_TOKEN,GITHUB_TOKEN'
860
+ SECRET_COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
861
+ SECRET_GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }}
862
+ SECRET_GH_AW_GITHUB_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN }}
863
+ SECRET_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
864
+ - name: Append agent step summary
865
+ if: always()
866
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/append_agent_step_summary.sh"
867
+ - name: Copy Safe Outputs
868
+ if: always()
869
+ env:
870
+ GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
871
+ run: |
872
+ mkdir -p /tmp/gh-aw
873
+ cp "$GH_AW_SAFE_OUTPUTS" /tmp/gh-aw/safeoutputs.jsonl 2>/dev/null || true
874
+ - name: Ingest agent output
875
+ id: collect_output
876
+ if: always()
877
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
878
+ env:
879
+ GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
880
+ GH_AW_ALLOWED_DOMAINS: "api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,github.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,ppa.launchpad.net,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,telemetry.enterprise.githubcopilot.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.googleapis.com"
881
+ GITHUB_SERVER_URL: ${{ github.server_url }}
882
+ GITHUB_API_URL: ${{ github.api_url }}
883
+ with:
884
+ script: |
885
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
886
+ setupGlobals(core, github, context, exec, io, getOctokit);
887
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/collect_ndjson_output.cjs');
888
+ await main();
889
+ - name: Parse agent logs for step summary
890
+ if: always()
891
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
892
+ env:
893
+ GH_AW_AGENT_OUTPUT: /tmp/gh-aw/sandbox/agent/logs/
894
+ with:
895
+ script: |
896
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
897
+ setupGlobals(core, github, context, exec, io, getOctokit);
898
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_copilot_log.cjs');
899
+ await main();
900
+ - name: Parse MCP Gateway logs for step summary
901
+ if: always()
902
+ id: parse-mcp-gateway
903
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
904
+ with:
905
+ script: |
906
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
907
+ setupGlobals(core, github, context, exec, io, getOctokit);
908
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_mcp_gateway_log.cjs');
909
+ await main();
910
+ - name: Print firewall logs
911
+ if: always()
912
+ continue-on-error: true
913
+ env:
914
+ AWF_LOGS_DIR: /tmp/gh-aw/sandbox/firewall/logs
915
+ run: |
916
+ # Fix permissions on firewall logs/audit dirs so they can be uploaded as artifacts
917
+ # AWF runs with sudo, creating files owned by root
918
+ sudo chmod -R a+rX /tmp/gh-aw/sandbox/firewall 2>/dev/null || true
919
+ # Only run awf logs summary if awf command exists (it may not be installed if workflow failed before install step)
920
+ if command -v awf &> /dev/null; then
921
+ awf logs summary | tee -a "$GITHUB_STEP_SUMMARY"
922
+ else
923
+ echo 'AWF binary not installed, skipping firewall log summary'
924
+ fi
925
+ - name: Parse token usage for step summary
926
+ if: always()
927
+ continue-on-error: true
928
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
929
+ with:
930
+ script: |
931
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
932
+ setupGlobals(core, github, context, exec, io, getOctokit);
933
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_token_usage.cjs');
934
+ await main();
935
+ - name: Print AWF reflect summary
936
+ if: always()
937
+ continue-on-error: true
938
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
939
+ with:
940
+ script: |
941
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
942
+ setupGlobals(core, github, context, exec, io, getOctokit);
943
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/awf_reflect_summary.cjs');
944
+ await main();
945
+ - name: Write agent output placeholder if missing
946
+ if: always()
947
+ run: |
948
+ if [ ! -f /tmp/gh-aw/agent_output.json ]; then
949
+ echo '{"items":[]}' > /tmp/gh-aw/agent_output.json
950
+ fi
951
+ - name: Upload agent artifacts
952
+ if: always()
953
+ continue-on-error: true
954
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
955
+ with:
956
+ name: agent
957
+ path: |
958
+ /tmp/gh-aw/aw-prompts/prompt.txt
959
+ /tmp/gh-aw/sandbox/agent/logs/
960
+ /tmp/gh-aw/redacted-urls.log
961
+ /tmp/gh-aw/mcp-logs/
962
+ /tmp/gh-aw/agent_usage.json
963
+ /tmp/gh-aw/agent-stdio.log
964
+ /tmp/gh-aw/pre-agent-audit.txt
965
+ /tmp/gh-aw/agent/
966
+ /tmp/gh-aw/github_rate_limits.jsonl
967
+ /tmp/gh-aw/safeoutputs.jsonl
968
+ /tmp/gh-aw/agent_output.json
969
+ /tmp/gh-aw/aw-*.patch
970
+ /tmp/gh-aw/aw-*.bundle
971
+ /tmp/gh-aw/awf-config.json
972
+ /tmp/gh-aw/sandbox/firewall/logs/
973
+ /tmp/gh-aw/sandbox/firewall/audit/
974
+ /tmp/gh-aw/sandbox/firewall/awf-reflect.json
975
+ if-no-files-found: ignore
976
+
977
+ conclusion:
978
+ needs:
979
+ - activation
980
+ - agent
981
+ - detection
982
+ - safe_outputs
983
+ if: >
984
+ always() && (needs.agent.result != 'skipped' || needs.activation.outputs.lockdown_check_failed == 'true' ||
985
+ needs.activation.outputs.stale_lock_file_failed == 'true' || needs.activation.outputs.daily_ai_credits_exceeded == 'true')
986
+ runs-on: ubuntu-slim
987
+ permissions:
988
+ contents: read
989
+ issues: write
990
+ concurrency:
991
+ group: "gh-aw-conclusion-weekly-redteam"
992
+ cancel-in-progress: false
993
+ queue: max
994
+ env:
995
+ GH_AW_RUNTIME_FEATURES: ${{ vars.GH_AW_RUNTIME_FEATURES }}
996
+ outputs:
997
+ incomplete_count: ${{ steps.report_incomplete.outputs.incomplete_count }}
998
+ noop_message: ${{ steps.noop.outputs.noop_message }}
999
+ tools_reported: ${{ steps.missing_tool.outputs.tools_reported }}
1000
+ total_count: ${{ steps.missing_tool.outputs.total_count }}
1001
+ steps:
1002
+ - name: Setup Scripts
1003
+ id: setup
1004
+ uses: github/gh-aw-actions/setup@ba6380cc6e5be5d21677bebe04d52fb48e3abec7 # v0.81.6
1005
+ with:
1006
+ destination: ${{ runner.temp }}/gh-aw/actions
1007
+ job-name: ${{ github.job }}
1008
+ trace-id: ${{ needs.activation.outputs.setup-trace-id }}
1009
+ parent-span-id: ${{ needs.activation.outputs.setup-parent-span-id || needs.activation.outputs.setup-span-id }}
1010
+ env:
1011
+ GH_AW_SETUP_WORKFLOW_NAME: "Weekly red team"
1012
+ GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/weekly-redteam.lock.yml@${{ github.ref }}
1013
+ GH_AW_INFO_VERSION: "1.0.65"
1014
+ GH_AW_INFO_AWF_VERSION: "v0.27.11"
1015
+ GH_AW_INFO_ENGINE_ID: "copilot"
1016
+ - name: Download agent output artifact
1017
+ id: download-agent-output
1018
+ continue-on-error: true
1019
+ uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
1020
+ with:
1021
+ name: agent
1022
+ path: /tmp/gh-aw/
1023
+ - name: Setup agent output environment variable
1024
+ id: setup-agent-output-env
1025
+ if: steps.download-agent-output.outcome == 'success'
1026
+ run: |
1027
+ mkdir -p /tmp/gh-aw/
1028
+ find "/tmp/gh-aw/" -type f -print
1029
+ echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT"
1030
+ - name: Collect usage artifact files
1031
+ if: always()
1032
+ continue-on-error: true
1033
+ run: |
1034
+ mkdir -p /tmp/gh-aw/usage/agent /tmp/gh-aw/usage/detection
1035
+ echo "Usage artifact source file status:"
1036
+ for file in /tmp/gh-aw/aw_info.json /tmp/gh-aw/aw-info.jsonl /tmp/gh-aw/agent_usage.json /tmp/gh-aw/agent_usage.jsonl /tmp/gh-aw/detection_usage.jsonl /tmp/gh-aw/github_rate_limits.jsonl /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl; do
1037
+ [ -f "$file" ] && echo "FOUND: $file" || echo "MISSING: $file"
1038
+ done
1039
+ [ -f /tmp/gh-aw/aw_info.json ] && cp /tmp/gh-aw/aw_info.json /tmp/gh-aw/usage/aw_info.json || true
1040
+ [ -f /tmp/gh-aw/aw-info.jsonl ] && cp /tmp/gh-aw/aw-info.jsonl /tmp/gh-aw/usage/aw-info.jsonl || true
1041
+ [ -f /tmp/gh-aw/agent_usage.json ] && cp /tmp/gh-aw/agent_usage.json /tmp/gh-aw/usage/agent_usage.json || true
1042
+ [ -f /tmp/gh-aw/agent_usage.jsonl ] && cp /tmp/gh-aw/agent_usage.jsonl /tmp/gh-aw/usage/agent_usage.jsonl || true
1043
+ [ -f /tmp/gh-aw/detection_usage.jsonl ] && cp /tmp/gh-aw/detection_usage.jsonl /tmp/gh-aw/usage/detection_usage.jsonl || true
1044
+ [ -f /tmp/gh-aw/github_rate_limits.jsonl ] && cp /tmp/gh-aw/github_rate_limits.jsonl /tmp/gh-aw/usage/github_rate_limits.jsonl || true
1045
+ [ -s /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true
1046
+ [ -s /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true
1047
+ [ -s /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true
1048
+ [ -s /tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl || true
1049
+ [ -s /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl || true
1050
+ [ -s /tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl || true
1051
+ [ -f /tmp/gh-aw/usage/agent/token_usage.jsonl ] || : > /tmp/gh-aw/usage/agent/token_usage.jsonl
1052
+ [ -f /tmp/gh-aw/usage/detection/token_usage.jsonl ] || : > /tmp/gh-aw/usage/detection/token_usage.jsonl
1053
+ mkdir -p /tmp/gh-aw/usage/activity
1054
+ node ${{ runner.temp }}/gh-aw/actions/generate_usage_activity_summary.cjs
1055
+ find /tmp/gh-aw/usage -type f -print | sort
1056
+ - name: Upload usage artifact
1057
+ if: always()
1058
+ continue-on-error: true
1059
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
1060
+ with:
1061
+ name: usage
1062
+ path: |
1063
+ /tmp/gh-aw/usage/aw_info.json
1064
+ /tmp/gh-aw/usage/aw-info.jsonl
1065
+ /tmp/gh-aw/usage/agent_usage.json
1066
+ /tmp/gh-aw/usage/agent_usage.jsonl
1067
+ /tmp/gh-aw/usage/detection_usage.jsonl
1068
+ /tmp/gh-aw/usage/github_rate_limits.jsonl
1069
+ /tmp/gh-aw/usage/agent/token_usage.jsonl
1070
+ /tmp/gh-aw/usage/detection/token_usage.jsonl
1071
+ /tmp/gh-aw/usage/activity/summary.json
1072
+ if-no-files-found: ignore
1073
+ - name: Restore daily AIC usage cache
1074
+ id: restore-daily-aic-cache-conclusion
1075
+ if: always()
1076
+ continue-on-error: true
1077
+ uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
1078
+ with:
1079
+ key: agentic-workflow-usage-weeklyredteam-${{ github.run_id }}
1080
+ restore-keys: agentic-workflow-usage-weeklyredteam-
1081
+ path: /tmp/gh-aw/agentic-workflow-usage-cache.jsonl
1082
+ - name: Write daily AIC usage cache entry
1083
+ id: write-daily-aic-cache
1084
+ if: always()
1085
+ continue-on-error: true
1086
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
1087
+ with:
1088
+ github-token: ${{ github.token }}
1089
+ script: |
1090
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
1091
+ setupGlobals(core, github, context);
1092
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/write_daily_aic_usage_cache.cjs');
1093
+ await main();
1094
+ - name: Save daily AIC usage cache
1095
+ id: save-daily-aic-cache
1096
+ if: always()
1097
+ continue-on-error: true
1098
+ uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
1099
+ with:
1100
+ key: agentic-workflow-usage-weeklyredteam-${{ github.run_id }}
1101
+ path: /tmp/gh-aw/agentic-workflow-usage-cache.jsonl
1102
+ - name: Upload daily AIC usage cache artifact
1103
+ id: upload-daily-aic-cache
1104
+ if: always()
1105
+ continue-on-error: true
1106
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
1107
+ with:
1108
+ name: aic-usage-cache
1109
+ path: /tmp/gh-aw/agentic-workflow-usage-cache.jsonl
1110
+ if-no-files-found: ignore
1111
+ retention-days: 7
1112
+ - name: Process no-op messages
1113
+ id: noop
1114
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
1115
+ env:
1116
+ GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
1117
+ GH_AW_NOOP_MAX: "1"
1118
+ GH_AW_WORKFLOW_NAME: "Weekly red team"
1119
+ GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/weekly-redteam.md"
1120
+ GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
1121
+ GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }}
1122
+ GH_AW_NOOP_REPORT_AS_ISSUE: "true"
1123
+ GH_AW_AIC: ${{ needs.agent.outputs.aic }}
1124
+ GH_AW_THREAT_DETECTION_AIC: ${{ needs.detection.outputs.aic }}
1125
+ GH_AW_AMBIENT_CONTEXT: ${{ needs.agent.outputs.ambient_context }}
1126
+ GH_AW_WORKFLOW_ID: "weekly-redteam"
1127
+ with:
1128
+ github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
1129
+ script: |
1130
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
1131
+ setupGlobals(core, github, context, exec, io, getOctokit);
1132
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_noop_message.cjs');
1133
+ await main();
1134
+ - name: Log detection run
1135
+ id: detection_runs
1136
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
1137
+ env:
1138
+ GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
1139
+ GH_AW_WORKFLOW_NAME: "Weekly red team"
1140
+ GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/weekly-redteam.md"
1141
+ GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
1142
+ GH_AW_DETECTION_CONCLUSION: ${{ needs.detection.outputs.detection_conclusion }}
1143
+ GH_AW_DETECTION_REASON: ${{ needs.detection.outputs.detection_reason }}
1144
+ with:
1145
+ github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
1146
+ script: |
1147
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
1148
+ setupGlobals(core, github, context, exec, io, getOctokit);
1149
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_detection_runs.cjs');
1150
+ await main();
1151
+ - name: Record missing tool
1152
+ id: missing_tool
1153
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
1154
+ env:
1155
+ GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
1156
+ GH_AW_MISSING_TOOL_CREATE_ISSUE: "true"
1157
+ GH_AW_WORKFLOW_NAME: "Weekly red team"
1158
+ GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/weekly-redteam.md"
1159
+ with:
1160
+ github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
1161
+ script: |
1162
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
1163
+ setupGlobals(core, github, context, exec, io, getOctokit);
1164
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/missing_tool.cjs');
1165
+ await main();
1166
+ - name: Record incomplete
1167
+ id: report_incomplete
1168
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
1169
+ env:
1170
+ GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
1171
+ GH_AW_REPORT_INCOMPLETE_CREATE_ISSUE: "true"
1172
+ GH_AW_WORKFLOW_NAME: "Weekly red team"
1173
+ GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/weekly-redteam.md"
1174
+ with:
1175
+ github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
1176
+ script: |
1177
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
1178
+ setupGlobals(core, github, context, exec, io, getOctokit);
1179
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/report_incomplete_handler.cjs');
1180
+ await main();
1181
+ - name: Handle agent failure
1182
+ id: handle_agent_failure
1183
+ if: always()
1184
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
1185
+ env:
1186
+ GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
1187
+ GH_AW_WORKFLOW_NAME: "Weekly red team"
1188
+ GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/weekly-redteam.md"
1189
+ GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
1190
+ GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }}
1191
+ GH_AW_WORKFLOW_ID: "weekly-redteam"
1192
+ GH_AW_ACTION_FAILURE_ISSUE_EXPIRES_HOURS: "168"
1193
+ GH_AW_ENGINE_ID: "copilot"
1194
+ GH_AW_SECRET_VERIFICATION_RESULT: ${{ needs.activation.outputs.secret_verification_result }}
1195
+ GH_AW_CHECKOUT_PR_SUCCESS: ${{ needs.agent.outputs.checkout_pr_success }}
1196
+ GH_AW_EFFECTIVE_TOKENS: ${{ needs.agent.outputs.effective_tokens || '' }}
1197
+ GH_AW_AI_CREDITS_RATE_LIMIT_ERROR: ${{ needs.agent.outputs.ai_credits_rate_limit_error || 'false' }}
1198
+ GH_AW_UNKNOWN_MODEL_AI_CREDITS: ${{ needs.agent.outputs.unknown_model_ai_credits || 'false' }}
1199
+ GH_AW_AIC: ${{ needs.agent.outputs.aic }}
1200
+ GH_AW_THREAT_DETECTION_AIC: ${{ needs.detection.outputs.aic }}
1201
+ GH_AW_MAX_AI_CREDITS: ${{ vars.GH_AW_DEFAULT_MAX_AI_CREDITS || '1000' }}
1202
+ GH_AW_INFERENCE_ACCESS_ERROR: ${{ needs.agent.outputs.inference_access_error }}
1203
+ GH_AW_MCP_POLICY_ERROR: ${{ needs.agent.outputs.mcp_policy_error }}
1204
+ GH_AW_AGENTIC_ENGINE_TIMEOUT: ${{ needs.agent.outputs.agentic_engine_timeout }}
1205
+ GH_AW_MODEL_NOT_SUPPORTED_ERROR: ${{ needs.agent.outputs.model_not_supported_error }}
1206
+ GH_AW_ENGINE_API_HOSTS: "api.enterprise.githubcopilot.com,api.githubcopilot.com,api.business.githubcopilot.com,api.individual.githubcopilot.com"
1207
+ GH_AW_LOCKDOWN_CHECK_FAILED: ${{ needs.activation.outputs.lockdown_check_failed }}
1208
+ GH_AW_STALE_LOCK_FILE_FAILED: ${{ needs.activation.outputs.stale_lock_file_failed }}
1209
+ GH_AW_DAILY_AI_CREDITS_EXCEEDED: ${{ needs.activation.outputs.daily_ai_credits_exceeded }}
1210
+ GH_AW_DAILY_AI_CREDITS_TOTAL_EFFECTIVE_TOKENS: ${{ needs.activation.outputs.daily_ai_credits_total_effective_tokens }}
1211
+ GH_AW_DAILY_AI_CREDITS_THRESHOLD: ${{ needs.activation.outputs.daily_ai_credits_threshold }}
1212
+ GH_AW_GROUP_REPORTS: "false"
1213
+ GH_AW_FAILURE_REPORT_AS_ISSUE: "true"
1214
+ GH_AW_MISSING_TOOL_REPORT_AS_FAILURE: "true"
1215
+ GH_AW_MISSING_DATA_REPORT_AS_FAILURE: "true"
1216
+ GH_AW_TIMEOUT_MINUTES: "20"
1217
+ with:
1218
+ github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
1219
+ script: |
1220
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
1221
+ setupGlobals(core, github, context, exec, io, getOctokit);
1222
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_agent_failure.cjs');
1223
+ await main();
1224
+
1225
+ detection:
1226
+ needs:
1227
+ - activation
1228
+ - agent
1229
+ if: always() && needs.agent.result != 'skipped'
1230
+ runs-on: ubuntu-latest
1231
+ permissions:
1232
+ contents: read
1233
+ env:
1234
+ GH_AW_RUNTIME_FEATURES: ${{ vars.GH_AW_RUNTIME_FEATURES }}
1235
+ outputs:
1236
+ aic: ${{ steps.parse_detection_token_usage.outputs.aic }}
1237
+ detection_conclusion: ${{ steps.detection_conclusion.outputs.conclusion }}
1238
+ detection_reason: ${{ steps.detection_conclusion.outputs.reason }}
1239
+ detection_success: ${{ steps.detection_conclusion.outputs.success }}
1240
+ steps:
1241
+ - name: Setup Scripts
1242
+ id: setup
1243
+ uses: github/gh-aw-actions/setup@ba6380cc6e5be5d21677bebe04d52fb48e3abec7 # v0.81.6
1244
+ with:
1245
+ destination: ${{ runner.temp }}/gh-aw/actions
1246
+ job-name: ${{ github.job }}
1247
+ trace-id: ${{ needs.activation.outputs.setup-trace-id }}
1248
+ parent-span-id: ${{ needs.activation.outputs.setup-parent-span-id || needs.activation.outputs.setup-span-id }}
1249
+ env:
1250
+ GH_AW_SETUP_WORKFLOW_NAME: "Weekly red team"
1251
+ GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/weekly-redteam.lock.yml@${{ github.ref }}
1252
+ GH_AW_INFO_VERSION: "1.0.65"
1253
+ GH_AW_INFO_AWF_VERSION: "v0.27.11"
1254
+ GH_AW_INFO_ENGINE_ID: "copilot"
1255
+ - name: Download agent output artifact
1256
+ id: download-agent-output
1257
+ continue-on-error: true
1258
+ uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
1259
+ with:
1260
+ name: agent
1261
+ path: /tmp/gh-aw/
1262
+ - name: Setup agent output environment variable
1263
+ id: setup-agent-output-env
1264
+ if: steps.download-agent-output.outcome == 'success'
1265
+ run: |
1266
+ mkdir -p /tmp/gh-aw/
1267
+ find "/tmp/gh-aw/" -type f -print
1268
+ echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT"
1269
+ - name: Checkout repository for patch context
1270
+ if: needs.agent.outputs.has_patch == 'true'
1271
+ uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
1272
+ with:
1273
+ persist-credentials: false
1274
+ # --- Threat Detection ---
1275
+ - name: Clean stale firewall files from agent artifact
1276
+ run: |
1277
+ rm -rf /tmp/gh-aw/sandbox/firewall/logs
1278
+ rm -rf /tmp/gh-aw/sandbox/firewall/audit
1279
+ - name: Download container images
1280
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.27.11@sha256:979723c628182da7729333f2208bb249fd25ddee579645cf9a3892d681a929c7 ghcr.io/github/gh-aw-firewall/api-proxy:0.27.11@sha256:807e4831999b44513b0a66e5859d478dc4da7ae74ab1918cec967d513f95bf9d ghcr.io/github/gh-aw-firewall/squid:0.27.11@sha256:ff27ea0525ad953a6adee28a5fbe9d2e22be47dbec755c15767af4ea3f91df7d
1281
+ - name: Check if detection needed
1282
+ id: detection_guard
1283
+ if: always()
1284
+ env:
1285
+ OUTPUT_TYPES: ${{ needs.agent.outputs.output_types }}
1286
+ HAS_PATCH: ${{ needs.agent.outputs.has_patch }}
1287
+ run: |
1288
+ if [[ -n "$OUTPUT_TYPES" || "$HAS_PATCH" == "true" ]]; then
1289
+ echo "run_detection=true" >> "$GITHUB_OUTPUT"
1290
+ echo "Detection will run: output_types=$OUTPUT_TYPES, has_patch=$HAS_PATCH"
1291
+ else
1292
+ echo "run_detection=false" >> "$GITHUB_OUTPUT"
1293
+ echo "Detection skipped: no agent outputs or patches to analyze"
1294
+ fi
1295
+ - name: Clear MCP Config for detection
1296
+ if: always() && steps.detection_guard.outputs.run_detection == 'true'
1297
+ run: |
1298
+ rm -f "${RUNNER_TEMP}/gh-aw/mcp-config/mcp-servers.json"
1299
+ rm -f "$HOME/.copilot/mcp-config.json"
1300
+ rm -f "$GITHUB_WORKSPACE/.gemini/settings.json"
1301
+ - name: Prepare threat detection files
1302
+ if: always() && steps.detection_guard.outputs.run_detection == 'true'
1303
+ run: |
1304
+ mkdir -p /tmp/gh-aw/threat-detection/aw-prompts
1305
+ rm -f /tmp/gh-aw/agent_usage.json
1306
+ cp /tmp/gh-aw/aw-prompts/prompt.txt /tmp/gh-aw/threat-detection/aw-prompts/prompt.txt 2>/dev/null || true
1307
+ if [ ! -s /tmp/gh-aw/threat-detection/aw-prompts/prompt.txt ]; then
1308
+ echo "::warning::ERR_VALIDATION: Missing or empty detection context prompt at /tmp/gh-aw/threat-detection/aw-prompts/prompt.txt. Ensure the agent artifact includes /tmp/gh-aw/aw-prompts/prompt.txt. Detection will continue with fallback workflow context."
1309
+ fi
1310
+ cp /tmp/gh-aw/agent_output.json /tmp/gh-aw/threat-detection/agent_output.json 2>/dev/null || true
1311
+ for f in /tmp/gh-aw/aw-*.patch; do
1312
+ [ -f "$f" ] && cp "$f" /tmp/gh-aw/threat-detection/ 2>/dev/null || true
1313
+ done
1314
+ for f in /tmp/gh-aw/aw-*.bundle; do
1315
+ [ -f "$f" ] && cp "$f" /tmp/gh-aw/threat-detection/ 2>/dev/null || true
1316
+ done
1317
+ echo "Prepared threat detection files:"
1318
+ ls -la /tmp/gh-aw/threat-detection/ 2>/dev/null || true
1319
+ - name: Setup threat detection
1320
+ if: always() && steps.detection_guard.outputs.run_detection == 'true'
1321
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
1322
+ env:
1323
+ WORKFLOW_NAME: "Weekly red team"
1324
+ WORKFLOW_DESCRIPTION: "Weekly red team probe suite (garak)."
1325
+ HAS_PATCH: ${{ needs.agent.outputs.has_patch }}
1326
+ with:
1327
+ script: |
1328
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
1329
+ setupGlobals(core, github, context, exec, io, getOctokit);
1330
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/setup_threat_detection.cjs');
1331
+ await main();
1332
+ - name: Ensure threat-detection directory and log
1333
+ if: always() && steps.detection_guard.outputs.run_detection == 'true'
1334
+ run: |
1335
+ mkdir -p /tmp/gh-aw/threat-detection
1336
+ touch /tmp/gh-aw/threat-detection/detection.log
1337
+ - name: Setup Node.js
1338
+ uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
1339
+ with:
1340
+ node-version: '24'
1341
+ package-manager-cache: false
1342
+ - name: Install GitHub Copilot CLI
1343
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.65
1344
+ env:
1345
+ GH_HOST: github.com
1346
+ - name: Install AWF binary
1347
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.11
1348
+ - name: Execute GitHub Copilot CLI
1349
+ if: always() && steps.detection_guard.outputs.run_detection == 'true'
1350
+ continue-on-error: true
1351
+ id: detection_agentic_execution
1352
+ # Copilot CLI tool arguments (sorted):
1353
+ timeout-minutes: 20
1354
+ run: |
1355
+ set -o pipefail
1356
+ printf '%s' "$(date +%s%3N)" > /tmp/gh-aw/agent_cli_start_ms.txt
1357
+ trap 'rm -f "$HOME/.copilot/settings.json"' EXIT
1358
+ mkdir -p "$HOME/.copilot"
1359
+ printf '%s' '{"builtInAgents":{"rubberDuck":false}}' > "$HOME/.copilot/settings.json"
1360
+ export XDG_CONFIG_HOME="$HOME"
1361
+ touch /tmp/gh-aw/agent-step-summary.md
1362
+ GH_AW_NODE_BIN=$(command -v node 2>/dev/null || true)
1363
+ export GH_AW_NODE_BIN
1364
+ export COPILOT_API_KEY="$COPILOT_DUMMY_BYOK"
1365
+ (umask 177 && touch /tmp/gh-aw/threat-detection/detection.log)
1366
+ GH_AW_MAX_AI_CREDITS="${GH_AW_MAX_AI_CREDITS:-400}"
1367
+ printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.27.11/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"api.business.githubcopilot.com\",\"api.enterprise.githubcopilot.com\",\"api.github.com\",\"api.githubcopilot.com\",\"api.individual.githubcopilot.com\",\"github.com\",\"host.docker.internal\",\"registry.npmjs.org\",\"telemetry.enterprise.githubcopilot.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS},\"maxCacheMisses\":5},\"container\":{\"imageTag\":\"0.27.11,squid=sha256:ff27ea0525ad953a6adee28a5fbe9d2e22be47dbec755c15767af4ea3f91df7d,agent=sha256:979723c628182da7729333f2208bb249fd25ddee579645cf9a3892d681a929c7,api-proxy=sha256:807e4831999b44513b0a66e5859d478dc4da7ae74ab1918cec967d513f95bf9d\"}}" > "${RUNNER_TEMP}/gh-aw/awf-config.json"
1368
+ cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json
1369
+ export GH_AW_MODELS_JSON_PATH="/tmp/gh-aw/models.json"
1370
+ GH_AW_DOCKER_HOST=""
1371
+ if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then
1372
+ GH_AW_DOCKER_HOST="${DOCKER_HOST}"
1373
+ fi
1374
+ GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS=""
1375
+ if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then
1376
+ GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS="--docker-host-path-prefix /tmp/gh-aw"
1377
+ _GH_AW_CHROOT_JSON=$(jq -c --arg src /tmp/gh-aw --arg user "$(id -un)" --argjson uid "$(id -u)" --argjson gid "$(id -g)" --arg home /tmp/gh-aw/home '.chroot={"binariesSourcePath":$src,"identity":{"user":$user,"uid":$uid,"gid":$gid,"home":$home}}' "${RUNNER_TEMP}/gh-aw/awf-config.json") || { echo "chroot config patch failed" >&2; exit 1; }
1378
+ printf '%s\n' "$_GH_AW_CHROOT_JSON" > "${RUNNER_TEMP}/gh-aw/awf-config.json"
1379
+ printf '%s\n' "$_GH_AW_CHROOT_JSON" > "/tmp/gh-aw/awf-config.json"
1380
+ fi
1381
+ GH_AW_TOOL_CACHE_MOUNT=""
1382
+ GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"
1383
+ if [ -d "$GH_AW_TOOL_CACHE" ]; then
1384
+ if [[ "$GH_AW_TOOL_CACHE" != /opt/* ]]; then
1385
+ GH_AW_TOOL_CACHE_MOUNT="$GH_AW_TOOL_CACHE:$GH_AW_TOOL_CACHE:ro"
1386
+ fi
1387
+ fi
1388
+ # shellcheck disable=SC1003,SC2086
1389
+ sudo -E awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} ${GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS} --env-all --exclude-env COPILOT_GITHUB_TOKEN --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --allow-host-ports 80,443,8080 --skip-pull \
1390
+ -- /bin/bash -c 'set +o histexpand; : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log
1391
+ env:
1392
+ AWF_REFLECT_ENABLED: 1
1393
+ COPILOT_AGENT_RUNNER_TYPE: STANDALONE
1394
+ COPILOT_DUMMY_BYOK: dummy-byok-key-for-offline-mode
1395
+ COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
1396
+ COPILOT_MODEL: ${{ vars.GH_AW_MODEL_DETECTION_COPILOT || vars.GH_AW_DEFAULT_MODEL_COPILOT || 'claude-sonnet-4.6' }}
1397
+ GH_AW_LLM_PROVIDER: github
1398
+ GH_AW_MAX_AI_CREDITS: ${{ vars.GH_AW_DEFAULT_DETECTION_MAX_AI_CREDITS || '400' }}
1399
+ GH_AW_MAX_TURNS: ${{ vars.GH_AW_DEFAULT_MAX_TURNS || '' }}
1400
+ GH_AW_PHASE: detection
1401
+ GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
1402
+ GH_AW_TIMEOUT_MINUTES: 20
1403
+ GH_AW_VERSION: v0.81.6
1404
+ GITHUB_API_URL: ${{ github.api_url }}
1405
+ GITHUB_AW: true
1406
+ GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows
1407
+ GITHUB_HEAD_REF: ${{ github.head_ref }}
1408
+ GITHUB_REF_NAME: ${{ github.ref_name }}
1409
+ GITHUB_SERVER_URL: ${{ github.server_url }}
1410
+ GITHUB_STEP_SUMMARY: /tmp/gh-aw/agent-step-summary.md
1411
+ GITHUB_WORKSPACE: ${{ github.workspace }}
1412
+ GIT_AUTHOR_EMAIL: github-actions[bot]@users.noreply.github.com
1413
+ GIT_AUTHOR_NAME: github-actions[bot]
1414
+ GIT_COMMITTER_EMAIL: github-actions[bot]@users.noreply.github.com
1415
+ GIT_COMMITTER_NAME: github-actions[bot]
1416
+ RUNNER_TEMP: ${{ runner.temp }}
1417
+ TRACEPARENT: ${{ env.GITHUB_AW_OTEL_TRACE_ID != '' && env.GITHUB_AW_OTEL_PARENT_SPAN_ID != '' && format('00-{0}-{1}-01', env.GITHUB_AW_OTEL_TRACE_ID, env.GITHUB_AW_OTEL_PARENT_SPAN_ID) || '' }}
1418
+ - name: Parse threat detection token usage for step summary
1419
+ id: parse_detection_token_usage
1420
+ if: always()
1421
+ continue-on-error: true
1422
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
1423
+ env:
1424
+ GH_AW_TOKEN_USAGE_SUMMARY_TITLE: Threat Detection Token Usage
1425
+ with:
1426
+ script: |
1427
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
1428
+ setupGlobals(core, github, context, exec, io, getOctokit);
1429
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_token_usage.cjs');
1430
+ await main();
1431
+ - name: Upload threat detection log
1432
+ if: always() && steps.detection_guard.outputs.run_detection == 'true'
1433
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
1434
+ with:
1435
+ name: detection
1436
+ path: /tmp/gh-aw/threat-detection/detection.log
1437
+ if-no-files-found: ignore
1438
+ - name: Parse and conclude threat detection
1439
+ id: detection_conclusion
1440
+ if: always()
1441
+ continue-on-error: true
1442
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
1443
+ env:
1444
+ RUN_DETECTION: ${{ steps.detection_guard.outputs.run_detection }}
1445
+ DETECTION_AGENTIC_EXECUTION_OUTCOME: ${{ steps.detection_agentic_execution.outcome }}
1446
+ GH_AW_DETECTION_CONTINUE_ON_ERROR: "true"
1447
+ with:
1448
+ script: |
1449
+ try {
1450
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
1451
+ setupGlobals(core, github, context, exec, io, getOctokit);
1452
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_threat_detection_results.cjs');
1453
+ await main();
1454
+ } catch (loadErr) {
1455
+ const continueOnError = process.env.GH_AW_DETECTION_CONTINUE_ON_ERROR !== 'false';
1456
+ const detectionExecutionFailed = process.env.DETECTION_AGENTIC_EXECUTION_OUTCOME === 'failure';
1457
+ const msg = 'ERR_SYSTEM: \u274C Unexpected error loading threat detection module: ' + (loadErr && loadErr.message ? loadErr.message : String(loadErr));
1458
+ core.error(msg);
1459
+ core.setOutput('reason', 'parse_error');
1460
+ if (continueOnError && !detectionExecutionFailed) {
1461
+ core.warning('\u26A0\uFE0F ' + msg);
1462
+ core.setOutput('conclusion', 'warning');
1463
+ core.setOutput('success', 'false');
1464
+ } else {
1465
+ core.setOutput('conclusion', 'failure');
1466
+ core.setOutput('success', 'false');
1467
+ core.setFailed(msg);
1468
+ }
1469
+ }
1470
+
1471
+ safe_outputs:
1472
+ needs:
1473
+ - activation
1474
+ - agent
1475
+ - detection
1476
+ if: (!cancelled()) && needs.agent.result != 'skipped' && needs.detection.result == 'success'
1477
+ runs-on: ubuntu-slim
1478
+ permissions:
1479
+ contents: read
1480
+ issues: write
1481
+ timeout-minutes: 45
1482
+ env:
1483
+ GH_AW_AGENT_AIC: ${{ needs.agent.outputs.aic }}
1484
+ GH_AW_AIC: ${{ needs.agent.outputs.aic }}
1485
+ GH_AW_AMBIENT_CONTEXT: ${{ needs.agent.outputs.ambient_context }}
1486
+ GH_AW_CALLER_WORKFLOW_ID: "${{ github.repository }}/weekly-redteam"
1487
+ GH_AW_DETECTION_CONCLUSION: ${{ needs.detection.outputs.detection_conclusion }}
1488
+ GH_AW_DETECTION_REASON: ${{ needs.detection.outputs.detection_reason }}
1489
+ GH_AW_EFFECTIVE_TOKENS: ${{ needs.agent.outputs.effective_tokens }}
1490
+ GH_AW_ENGINE_ID: "copilot"
1491
+ GH_AW_ENGINE_MODEL: ${{ needs.agent.outputs.model }}
1492
+ GH_AW_ENGINE_VERSION: "1.0.65"
1493
+ GH_AW_RUNTIME_FEATURES: ${{ vars.GH_AW_RUNTIME_FEATURES }}
1494
+ GH_AW_THREAT_DETECTION_AIC: ${{ needs.detection.outputs.aic }}
1495
+ GH_AW_WORKFLOW_ID: "weekly-redteam"
1496
+ GH_AW_WORKFLOW_NAME: "Weekly red team"
1497
+ GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/weekly-redteam.md"
1498
+ outputs:
1499
+ code_push_failure_count: ${{ steps.process_safe_outputs.outputs.code_push_failure_count }}
1500
+ code_push_failure_errors: ${{ steps.process_safe_outputs.outputs.code_push_failure_errors }}
1501
+ create_discussion_error_count: ${{ steps.process_safe_outputs.outputs.create_discussion_error_count }}
1502
+ create_discussion_errors: ${{ steps.process_safe_outputs.outputs.create_discussion_errors }}
1503
+ created_issue_number: ${{ steps.process_safe_outputs.outputs.created_issue_number }}
1504
+ created_issue_url: ${{ steps.process_safe_outputs.outputs.created_issue_url }}
1505
+ process_safe_outputs_processed_count: ${{ steps.process_safe_outputs.outputs.processed_count }}
1506
+ process_safe_outputs_temporary_id_map: ${{ steps.process_safe_outputs.outputs.temporary_id_map }}
1507
+ steps:
1508
+ - name: Setup Scripts
1509
+ id: setup
1510
+ uses: github/gh-aw-actions/setup@ba6380cc6e5be5d21677bebe04d52fb48e3abec7 # v0.81.6
1511
+ with:
1512
+ destination: ${{ runner.temp }}/gh-aw/actions
1513
+ job-name: ${{ github.job }}
1514
+ trace-id: ${{ needs.activation.outputs.setup-trace-id }}
1515
+ parent-span-id: ${{ needs.activation.outputs.setup-parent-span-id || needs.activation.outputs.setup-span-id }}
1516
+ env:
1517
+ GH_AW_SETUP_WORKFLOW_NAME: "Weekly red team"
1518
+ GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/weekly-redteam.lock.yml@${{ github.ref }}
1519
+ GH_AW_INFO_VERSION: "1.0.65"
1520
+ GH_AW_INFO_AWF_VERSION: "v0.27.11"
1521
+ GH_AW_INFO_ENGINE_ID: "copilot"
1522
+ - name: Download agent output artifact
1523
+ id: download-agent-output
1524
+ continue-on-error: true
1525
+ uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
1526
+ with:
1527
+ name: agent
1528
+ path: /tmp/gh-aw/
1529
+ - name: Setup agent output environment variable
1530
+ id: setup-agent-output-env
1531
+ if: steps.download-agent-output.outcome == 'success'
1532
+ run: |
1533
+ mkdir -p /tmp/gh-aw/
1534
+ find "/tmp/gh-aw/" -type f -print
1535
+ echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT"
1536
+ - name: Configure GH_HOST for enterprise compatibility
1537
+ id: ghes-host-config
1538
+ shell: bash
1539
+ run: | # zizmor: ignore[github-env] - GITHUB_SERVER_URL is set by GitHub Actions, not user input.
1540
+ # Derive GH_HOST from GITHUB_SERVER_URL so the gh CLI targets the correct
1541
+ # GitHub instance (GHES/GHEC). On github.com this is a harmless no-op.
1542
+ GH_HOST="${GITHUB_SERVER_URL#https://}"
1543
+ GH_HOST="${GH_HOST#http://}"
1544
+ echo "GH_HOST=${GH_HOST}" >> "$GITHUB_ENV"
1545
+ - name: Process Safe Outputs
1546
+ id: process_safe_outputs
1547
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
1548
+ env:
1549
+ GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
1550
+ GH_AW_COMMENT_ID: ${{ needs.activation.outputs.comment_id }}
1551
+ GH_AW_ALLOWED_DOMAINS: "api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,github.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,ppa.launchpad.net,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,telemetry.enterprise.githubcopilot.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.googleapis.com"
1552
+ GITHUB_SERVER_URL: ${{ github.server_url }}
1553
+ GITHUB_API_URL: ${{ github.api_url }}
1554
+ GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_issue\":{\"max\":2},\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"true\"},\"report_incomplete\":{}}"
1555
+ with:
1556
+ github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
1557
+ script: |
1558
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
1559
+ setupGlobals(core, github, context, exec, io, getOctokit);
1560
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/safe_output_handler_manager.cjs');
1561
+ await main();
1562
+ - name: Upload Safe Outputs Items
1563
+ if: always()
1564
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
1565
+ with:
1566
+ name: safe-outputs-items
1567
+ path: |
1568
+ /tmp/gh-aw/safe-output-items.jsonl
1569
+ /tmp/gh-aw/temporary-id-map.json
1570
+ if-no-files-found: ignore
1571
+