@juangcarmona/lighthouse-sdlc 0.11.0 → 0.13.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 (34) hide show
  1. package/README.md +45 -9
  2. package/completion.md +48 -0
  3. package/host-contract.md +2 -0
  4. package/package.json +2 -1
  5. package/skills/integrate/SKILL.md +7 -1
  6. package/skills/propose/SKILL.md +1 -1
  7. package/skills/refine/SKILL.md +1 -1
  8. package/skills/review/SKILL.md +7 -1
  9. package/src/completion-actions.mjs +114 -0
  10. package/src/completion.mjs +169 -0
  11. package/src/github-profile.mjs +9 -1
  12. package/src/host-contract.mjs +8 -4
  13. package/src/implementation-runtime.mjs +66 -0
  14. package/src/implementation.mjs +143 -0
  15. package/src/install-workflows.mjs +30 -0
  16. package/src/integration-evidence.mjs +56 -0
  17. package/src/issue-actions.mjs +189 -0
  18. package/src/observe-protection.mjs +24 -0
  19. package/src/opencode-execute.mjs +188 -0
  20. package/src/opencode-progress.mjs +48 -0
  21. package/src/process-publication.mjs +90 -0
  22. package/src/proposal.mjs +96 -0
  23. package/workflows/lighthouse-sdlc-implement.lock.yml +251 -1085
  24. package/workflows/lighthouse-sdlc-implement.md +165 -29
  25. package/workflows/lighthouse-sdlc-integrate.lock.yml +257 -1076
  26. package/workflows/lighthouse-sdlc-integrate.md +175 -29
  27. package/workflows/lighthouse-sdlc-propose.lock.yml +241 -1085
  28. package/workflows/lighthouse-sdlc-propose.md +155 -29
  29. package/workflows/lighthouse-sdlc-refine.lock.yml +239 -1085
  30. package/workflows/lighthouse-sdlc-refine.md +151 -29
  31. package/workflows/lighthouse-sdlc-review.lock.yml +257 -1076
  32. package/workflows/lighthouse-sdlc-review.md +175 -29
  33. package/workflows/lighthouse-sdlc-router.yml +84 -145
  34. package/workflows/shared/lighthouse-opencode.md +22 -0
@@ -1,21 +1,35 @@
1
- # gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"eb70f1d711ea5126bbe478ec05c0e7a68cb4c3bed9d2987449aa740d2c5db7e5","body_hash":"ecf132f588f1691b697be174527c5f7342d2f769678480dec54fd189a3f8d98e","compiler_version":"v0.93.2","strict":true,"agent_id":"copilot","engine_versions":{"copilot":"1.0.101"},"agent_image_runner":"[\"self-hosted\",\"linux\",\"lighthouse-sdlc\"]"}
2
- # gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_DEFAULT_OTLP_ENDPOINT","GH_AW_DEFAULT_OTLP_HEADERS","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN"],"actions":[{"repo":"actions/checkout","sha":"3d3c42e5aac5ba805825da76410c181273ba90b1","version":"v7.0.1"},{"repo":"actions/download-artifact","sha":"9000827ccba6bdab643e8b6fd33ac0654aef8333","version":"v8.0.2"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"949feb2413d6458794dcd2491c4babbbce0c15c1","version":"v7.1.0"},{"repo":"actions/upload-artifact","sha":"cf430e030ddbb5b0abf93d22962f4752f3646cd9","version":"v7.0.2"},{"repo":"github/gh-aw-actions/setup","sha":"d9128eb3ea40c18b77c76184eda03c0ff2608d79","version":"v0.93.2"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.28.70","digest":"sha256:b15ab48cbbab02904eb9bbd359a398db59690eebbea1e6934d47ed2bb407dd34","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.28.70@sha256:b15ab48cbbab02904eb9bbd359a398db59690eebbea1e6934d47ed2bb407dd34"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.28.70","digest":"sha256:9ac8f9c7294e892c916de3da9d2588dfd8cd4931e5c39b00143266d7ed9fd52a","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.28.70@sha256:9ac8f9c7294e892c916de3da9d2588dfd8cd4931e5c39b00143266d7ed9fd52a"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.28.70","digest":"sha256:b5bc53f4becfd96e926e63c83831f1b3c9512f713c83161d2b8c9b7204b3e917","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.28.70@sha256:b5bc53f4becfd96e926e63c83831f1b3c9512f713c83161d2b8c9b7204b3e917"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.4.37","digest":"sha256:9c7f242f6dec2d7d7b55d4c9e07872d59b85377c6cb3de46c915a5d1ffb91442","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.4.37@sha256:9c7f242f6dec2d7d7b55d4c9e07872d59b85377c6cb3de46c915a5d1ffb91442"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:41835613992df88f51e923bad486f96dfb2e6cda29f13e217df41833284ae382","pinned_image":"ghcr.io/github/gh-aw-node@sha256:41835613992df88f51e923bad486f96dfb2e6cda29f13e217df41833284ae382"},{"image":"ghcr.io/github/github-mcp-server:v2.0.2","digest":"sha256:ffced0d76e77428532a2ced185516992d77fd146d69eec2f244e6237d1a97796","pinned_image":"ghcr.io/github/github-mcp-server:v2.0.2@sha256:ffced0d76e77428532a2ced185516992d77fd146d69eec2f244e6237d1a97796"}],"mcp_servers":[{"name":"github","tools":["get_commit","get_file_contents","get_latest_release","get_pull_request","get_pull_request_comments","get_pull_request_diff","get_pull_request_files","get_pull_request_review_comments","get_pull_request_reviews","get_pull_request_status","get_release_by_tag","get_tag","issue_read","list_branches","list_commits","list_issue_types","list_issues","list_pull_requests","list_releases","list_starred_repositories","list_tags","pull_request_read","search_code","search_issues","search_pull_requests","search_repositories"]},{"name":"safeoutputs","tools":["noop","report_incomplete","report_missing_data","report_missing_tool"]}],"threat_detection":{"mode":"enabled"},"admission":false}
1
+ # gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"4df4392c97dcd16b9b8df8b015b9e277fcd8b223db9a68927ff90d54c1799f7a","body_hash":"13d2a6e093a7dc59f842bf0e8e8ea2a1c5a2879c8608b026dac1197b022baebe","compiler_version":"v0.93.2","agent_id":"opencode","engine_versions":{"opencode":"2.1.0"},"agent_image_runner":"[\"self-hosted\",\"linux\",\"lighthouse-workflow\"]"}
2
+ # gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_DEFAULT_OTLP_ENDPOINT","GH_AW_DEFAULT_OTLP_HEADERS","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN"],"actions":[{"repo":"actions/checkout","sha":"3d3c42e5aac5ba805825da76410c181273ba90b1","version":"v7.0.1"},{"repo":"actions/checkout","sha":"fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09","version":"v5"},{"repo":"actions/download-artifact","sha":"9000827ccba6bdab643e8b6fd33ac0654aef8333","version":"v8.0.2"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"949feb2413d6458794dcd2491c4babbbce0c15c1","version":"v7.1.0"},{"repo":"actions/setup-node","sha":"a0853c24544627f65ddf259abe73b1d18a591444","version":"v5"},{"repo":"actions/upload-artifact","sha":"cf430e030ddbb5b0abf93d22962f4752f3646cd9","version":"v7.0.2"},{"repo":"github/gh-aw-actions/setup","sha":"d9128eb3ea40c18b77c76184eda03c0ff2608d79","version":"v0.93.2"}],"containers":[{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:41835613992df88f51e923bad486f96dfb2e6cda29f13e217df41833284ae382","pinned_image":"ghcr.io/github/gh-aw-node@sha256:41835613992df88f51e923bad486f96dfb2e6cda29f13e217df41833284ae382"}],"mcp_servers":[{"name":"safeoutputs","tools":["noop"]}],"threat_detection":{"mode":"disabled"},"admission":false}
3
3
  # This file was automatically generated by gh-aw (v0.93.2). DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md
4
4
  #
5
+ # ___ _ _
6
+ # / _ \ | | (_)
7
+ # | |_| | __ _ ___ _ __ | |_ _ ___
8
+ # | _ |/ _` |/ _ \ '_ \| __| |/ __|
9
+ # | | | | (_| | __/ | | | |_| | (__
10
+ # \_| |_/\__, |\___|_| |_|\__|_|\___|
11
+ # __/ |
12
+ # _ _ |___/
13
+ # | | | | / _| |
14
+ # | | | | ___ _ __ _ __| |_| | _____ ____
15
+ # | |/\| |/ _ \ '__| |/ /| _| |/ _ \ \ /\ / / ___|
16
+ # \ /\ / (_) | | | | ( | | | | (_) \ V V /\__ \
17
+ # \/ \/ \___/|_| |_|\_\|_| |_|\___/ \_/\_/ |___/
18
+ #
19
+ #
5
20
  # To update this file, edit the corresponding .md file and run:
6
21
  # gh aw compile
7
22
  # Not all edits will cause changes to this file.
8
23
  #
9
24
  # For more information: https://github.github.com/gh-aw/introduction/overview/
10
25
  #
11
- # Execute only the Lighthouse review stage and return its declared stage result.
26
+ # Assess review with OpenCode and retain a verified delivery record.
12
27
  #
13
28
  # Resolved workflow manifest:
14
29
  # Imports:
15
- # - shared/lighthouse-sdlc-stage.md
30
+ # - shared/lighthouse-opencode.md
16
31
  #
17
32
  # Frontmatter env variables:
18
- # - LIGHTHOUSE_SKILL: (main workflow)
19
33
  # - LIGHTHOUSE_STAGE: (main workflow)
20
34
  #
21
35
  # Secrets used:
@@ -28,19 +42,16 @@
28
42
  #
29
43
  # Custom actions used:
30
44
  # - actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
45
+ # - actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5
31
46
  # - actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
32
47
  # - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
33
48
  # - actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
49
+ # - actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5
34
50
  # - actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
35
51
  # - github/gh-aw-actions/setup@d9128eb3ea40c18b77c76184eda03c0ff2608d79 # v0.93.2
36
52
  #
37
53
  # Container images used:
38
- # - ghcr.io/github/gh-aw-firewall/agent:0.28.70@sha256:b15ab48cbbab02904eb9bbd359a398db59690eebbea1e6934d47ed2bb407dd34
39
- # - ghcr.io/github/gh-aw-firewall/api-proxy:0.28.70@sha256:9ac8f9c7294e892c916de3da9d2588dfd8cd4931e5c39b00143266d7ed9fd52a
40
- # - ghcr.io/github/gh-aw-firewall/squid:0.28.70@sha256:b5bc53f4becfd96e926e63c83831f1b3c9512f713c83161d2b8c9b7204b3e917
41
- # - ghcr.io/github/gh-aw-mcpg:v0.4.37@sha256:9c7f242f6dec2d7d7b55d4c9e07872d59b85377c6cb3de46c915a5d1ffb91442
42
54
  # - ghcr.io/github/gh-aw-node@sha256:41835613992df88f51e923bad486f96dfb2e6cda29f13e217df41833284ae382
43
- # - ghcr.io/github/github-mcp-server:v2.0.2@sha256:ffced0d76e77428532a2ced185516992d77fd146d69eec2f244e6237d1a97796
44
55
 
45
56
  name: "Lighthouse SDLC review"
46
57
  on:
@@ -51,22 +62,7 @@ on:
51
62
  description: "Agent caller context (Reserved for Agentic Workflows)."
52
63
  required: false
53
64
  type: string
54
- input:
55
- default: "{}"
56
- description: Compact JSON input for this stage.
57
- required: false
58
- type: string
59
- previous-stage:
60
- default: integrate
61
- description: Previous stage artifact name.
62
- required: false
63
- type: string
64
- route:
65
- description: Lighthouse route selected by the host.
66
- required: true
67
- type: string
68
- run-id:
69
- description: Stable Lighthouse run identifier.
65
+ issue:
70
66
  required: true
71
67
  type: string
72
68
  secrets:
@@ -91,11 +87,10 @@ concurrency:
91
87
  run-name: "Lighthouse SDLC review"
92
88
 
93
89
  env:
94
- LIGHTHOUSE_SKILL: node_modules/@juangcarmona/lighthouse-sdlc/skills/review/SKILL.md
95
90
  LIGHTHOUSE_STAGE: review
96
91
  OTEL_EXPORTER_OTLP_ENDPOINT: ${{ secrets.GH_AW_DEFAULT_OTLP_ENDPOINT || vars.GH_AW_DEFAULT_OTLP_ENDPOINT }}
97
92
  OTEL_SERVICE_NAME: gh-aw.lighthouse-sdlc-review
98
- OTEL_RESOURCE_ATTRIBUTES: 'gh-aw.workflow.name=Lighthouse%20SDLC%20review,gh-aw.repository=${{ github.repository }},gh-aw.run.id=${{ github.run_id }},github.run_id=${{ github.run_id }},gh-aw.engine.id=copilot'
93
+ OTEL_RESOURCE_ATTRIBUTES: 'gh-aw.workflow.name=Lighthouse%20SDLC%20review,gh-aw.repository=${{ github.repository }},gh-aw.run.id=${{ github.run_id }},github.run_id=${{ github.run_id }},gh-aw.engine.id=opencode'
99
94
  OTEL_EXPORTER_OTLP_HEADERS: ${{ secrets.GH_AW_DEFAULT_OTLP_HEADERS }}
100
95
  GH_AW_OTLP_ENDPOINTS: '[{"url":"${{ secrets.GH_AW_DEFAULT_OTLP_ENDPOINT || vars.GH_AW_DEFAULT_OTLP_ENDPOINT }}","headers":"${{ secrets.GH_AW_DEFAULT_OTLP_HEADERS }}"}]'
101
96
  GH_AW_OTLP_IF_MISSING: ignore
@@ -103,7 +98,9 @@ env:
103
98
  jobs:
104
99
  activation:
105
100
  name: activation
106
- needs: pre_activation
101
+ needs:
102
+ - pre_activation
103
+ - prepare
107
104
  if: needs.pre_activation.outputs.activated == 'true'
108
105
  runs-on: ubuntu-24.04
109
106
  # Permissions for the activation job (workflow permissions default to none).
@@ -128,7 +125,6 @@ jobs:
128
125
  lockdown_check_failed: ${{ steps.generate_aw_info.outputs.lockdown_check_failed == 'true' }}
129
126
  model: ${{ steps.generate_aw_info.outputs.model }}
130
127
  oauth_token_check_failed: ${{ steps.check-oauth-tokens.outputs.oauth_token_check_failed == 'true' }}
131
- secret_verification_result: ${{ steps.validate-secret.outputs.verification_result }}
132
128
  setup-parent-span-id: ${{ steps.setup.outputs.parent-span-id || steps.setup.outputs.span-id }}
133
129
  setup-span-id: ${{ steps.setup.outputs.span-id }}
134
130
  setup-trace-id: ${{ steps.setup.outputs.trace-id }}
@@ -150,9 +146,8 @@ jobs:
150
146
  env:
151
147
  GH_AW_SETUP_WORKFLOW_NAME: "Lighthouse SDLC review"
152
148
  GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/lighthouse-sdlc-review.lock.yml@${{ github.ref }}
153
- GH_AW_INFO_VERSION: "1.0.101"
154
- GH_AW_INFO_AWF_VERSION: "v0.28.70"
155
- GH_AW_INFO_ENGINE_ID: "copilot"
149
+ GH_AW_INFO_VERSION: "2.1.0"
150
+ GH_AW_INFO_ENGINE_ID: "opencode"
156
151
  GH_AW_SETUP_AW_CONTEXT: ${{ inputs.aw_context }}
157
152
  - name: Mask OTLP telemetry headers
158
153
  run: bash "${RUNNER_TEMP}/gh-aw/actions/mask_otlp_headers.sh"
@@ -180,28 +175,27 @@ jobs:
180
175
  - name: Generate agentic run info
181
176
  id: generate_aw_info
182
177
  env:
183
- GH_AW_INFO_ENGINE_ID: "copilot"
184
- GH_AW_INFO_ENGINE_NAME: "GitHub Copilot CLI"
185
- GH_AW_INFO_MODEL: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || vars.GH_AW_DEFAULT_MODEL_COPILOT || 'auto' }}
186
- GH_AW_INFO_VERSION: "1.0.101"
187
- GH_AW_INFO_AGENT_VERSION: "1.0.101"
178
+ GH_AW_INFO_ENGINE_ID: "opencode"
179
+ GH_AW_INFO_ENGINE_NAME: "OpenCode"
180
+ GH_AW_INFO_MODEL: ${{ vars.GH_AW_MODEL_AGENT_CUSTOM || '' }}
181
+ GH_AW_INFO_VERSION: "2.1.0"
182
+ GH_AW_INFO_AGENT_VERSION: "2.1.0"
188
183
  GH_AW_INFO_CLI_VERSION: "v0.93.2"
189
184
  GH_AW_INFO_WORKFLOW_NAME: "Lighthouse SDLC review"
190
185
  GH_AW_INFO_WORKFLOW_ID: ${{ job.workflow_ref }}
191
186
  GH_AW_INFO_EXPERIMENTAL: "false"
192
187
  GH_AW_INFO_SUPPORTS_TOOLS_ALLOWLIST: "true"
193
188
  GH_AW_INFO_STAGED: "false"
194
- GH_AW_INFO_ALLOWED_DOMAINS: '["defaults"]'
195
- GH_AW_INFO_FIREWALL_ENABLED: "true"
196
- GH_AW_INFO_AWF_VERSION: "v0.28.70"
189
+ GH_AW_INFO_ALLOWED_DOMAINS: '[]'
190
+ GH_AW_INFO_FIREWALL_ENABLED: "false"
191
+ GH_AW_INFO_AWF_VERSION: ""
197
192
  GH_AW_INFO_AWMG_VERSION: ""
198
- GH_AW_INFO_FIREWALL_TYPE: "squid"
193
+ GH_AW_INFO_FIREWALL_TYPE: ""
199
194
  GH_AW_INFO_AGENT_RUNTIME: ""
200
- GH_AW_INFO_ENGINE_HARNESS: "copilot-cli"
201
- GH_AW_INFO_MODEL_CONFIG: '{"routing":{"enabled":false},"models":{"allowed":[],"blocked":[]},"max_ai_credits_source":"default"}'
202
- GH_AW_INFO_MAX_AI_CREDITS: ${{ vars.GH_AW_DEFAULT_MAX_AI_CREDITS || '1000' }}
203
- GH_AW_COMPILED_STRICT: "true"
195
+ GH_AW_INFO_MODEL_CONFIG: '{"routing":{"enabled":false}}'
196
+ GH_AW_COMPILED_STRICT: "false"
204
197
  GH_AW_INFO_TARGET_REPO: ${{ steps.resolve-host-repo.outputs.target_repo }}
198
+ GH_AW_INFO_FEATURES: '{"dangerously-disable-sandbox-agent":true}'
205
199
  uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
206
200
  with:
207
201
  script: |
@@ -211,6 +205,11 @@ jobs:
211
205
  setupGlobals(core, github, context, exec, io, getOctokit);
212
206
  const { main } = require(path.join(actionsDir, 'generate_aw_info.cjs'));
213
207
  await main(core, context);
208
+ - name: Enforce strict mode policy
209
+ if: ${{ vars.GH_AW_POLICY_STRICT == 'true' }}
210
+ run: |
211
+ echo "::error::GH_AW_POLICY_STRICT=true but this workflow was not compiled in strict mode. Recompile with --strict or strict: true."
212
+ exit 1
214
213
  - name: Restore daily AIC scan observations
215
214
  id: restore-daily-aic-cache-fallback
216
215
  if: ${{ env.GH_AW_ADMISSION_RESULT != 'admitted' && env.GH_AW_MAX_DAILY_AI_CREDITS != '' }}
@@ -260,11 +259,6 @@ jobs:
260
259
  overwrite: true
261
260
  if-no-files-found: ignore
262
261
  retention-days: ${{ vars.GH_AW_DEFAULT_ARTIFACT_RETENTION_DAYS || '3' }}
263
- - name: Validate COPILOT_GITHUB_TOKEN secret
264
- id: validate-secret
265
- 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
266
- env:
267
- COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
268
262
  - name: Check for OAuth tokens
269
263
  id: check-oauth-tokens
270
264
  run: bash "${RUNNER_TEMP}/gh-aw/actions/check_oauth_tokens.sh"
@@ -338,24 +332,13 @@ jobs:
338
332
  GH_AW_ACTIONS_DIR: ${{ runner.temp }}/gh-aw/actions
339
333
  GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt
340
334
  GH_AW_SAFE_OUTPUTS: ${{ runner.temp }}/gh-aw/safeoutputs/outputs.jsonl
341
- GH_AW_PROMPT_CONFIG: "{\"items\":[{\"content_env\":\"GH_AW_PROMPT_CONTENT_0000\"},{\"file\":\"xpia.md\"},{\"file\":\"temp_folder_prompt.md\"},{\"file\":\"markdown.md\"},{\"file\":\"safe_outputs_mcp_transport_prompt.md\"},{\"file\":\"safe_outputs_prompt.md\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0001\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0002\"},{\"file\":\"mcp_cli_tools_with_safeoutputs_prompt.md\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0003\"},{\"file\":\"github_mcp_tools_with_safeoutputs_prompt.md\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0004\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0005\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0006\"}],\"system_item_count\":12}"
342
- GH_AW_ENV_LIGHTHOUSE_SKILL: ${{ env.LIGHTHOUSE_SKILL }}
343
- GH_AW_EXPR_76DF9333: ${{ github.event.pull_request.number || (fromJSON(steps.generate_aw_info.outputs.aw_context || '{}').item_type == 'pull_request' && fromJSON(steps.generate_aw_info.outputs.aw_context || '{}').item_number) }}
344
- GH_AW_EXPR_77C1A4D2: ${{ github.event.comment.id || fromJSON(steps.generate_aw_info.outputs.aw_context || '{}').comment_id }}
345
- GH_AW_EXPR_79DC8BAA: ${{ inputs.run-id }}
346
- GH_AW_EXPR_7C248226: ${{ github.event.issue.number || (fromJSON(steps.generate_aw_info.outputs.aw_context || '{}').item_type == 'issue' && fromJSON(steps.generate_aw_info.outputs.aw_context || '{}').item_number) }}
347
- GH_AW_EXPR_C19C384F: ${{ github.event.discussion.number || (fromJSON(steps.generate_aw_info.outputs.aw_context || '{}').item_type == 'discussion' && fromJSON(steps.generate_aw_info.outputs.aw_context || '{}').item_number) }}
348
- GH_AW_GITHUB_ACTOR: ${{ github.actor }}
349
- GH_AW_GITHUB_REPOSITORY: ${{ github.repository }}
350
- GH_AW_GITHUB_RUN_ID: ${{ github.run_id }}
351
- GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }}
335
+ GH_AW_PROMPT_CONFIG: "{\"items\":[{\"content_env\":\"GH_AW_PROMPT_CONTENT_0000\"},{\"file\":\"xpia.md\"},{\"file\":\"temp_folder_prompt.md\"},{\"file\":\"markdown.md\"},{\"file\":\"safe_outputs_mcp_transport_prompt.md\"},{\"file\":\"safe_outputs_prompt.md\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0001\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0002\"},{\"file\":\"mcp_cli_tools_with_safeoutputs_prompt.md\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0003\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0004\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0005\"}],\"system_item_count\":10}"
352
336
  GH_AW_PROMPT_CONTENT_0000: "<system>\n"
353
- GH_AW_PROMPT_CONTENT_0001: "<safe-output-tools>\nTools: report_missing_tool, report_missing_data, noop\n"
337
+ GH_AW_PROMPT_CONTENT_0001: "<safe-output-tools>\nTools: noop(max:2)\n"
354
338
  GH_AW_PROMPT_CONTENT_0002: "</safe-output-tools>\n"
355
- GH_AW_PROMPT_CONTENT_0003: "<github-context>\nThe following GitHub context information is available for this workflow:\n{{#if github.actor}}\n- **actor**: __GH_AW_GITHUB_ACTOR__\n{{/if}}\n{{#if github.repository}}\n- **repository**: __GH_AW_GITHUB_REPOSITORY__\n{{/if}}\n{{#if github.workspace}}\n- **workspace**: __GH_AW_GITHUB_WORKSPACE__\n{{/if}}\n{{#if github.event.issue.number || (github.aw.context.item_type == 'issue' && github.aw.context.item_number)}}\n- **issue-number**: #__GH_AW_EXPR_7C248226__\n{{/if}}\n{{#if github.event.discussion.number || (github.aw.context.item_type == 'discussion' && github.aw.context.item_number)}}\n- **discussion-number**: #__GH_AW_EXPR_C19C384F__\n{{/if}}\n{{#if github.event.pull_request.number || (github.aw.context.item_type == 'pull_request' && github.aw.context.item_number)}}\n- **pull-request-number**: #__GH_AW_EXPR_76DF9333__\n{{/if}}\n{{#if github.event.comment.id || github.aw.context.comment_id}}\n- **comment-id**: __GH_AW_EXPR_77C1A4D2__\n{{/if}}\n{{#if github.run_id}}\n- **workflow-run-id**: __GH_AW_GITHUB_RUN_ID__\n{{/if}}\n- **checkouts**: The following repositories have been checked out and are available in the workspace:\n - repo `__GH_AW_GITHUB_REPOSITORY__` → `__GH_AW_GITHUB_WORKSPACE__` (cwd) [full history, all branches available as remote-tracking refs]\n - **Note**: The workspace path reported above may contain a separate shallow, credential-free checkout of the host repository. Use the exact checkout path shown for the repository you need. Before concluding that a branch is unavailable, confirm your working directory matches that path and inspect refs there. If the branch is not present in that checkout and is not listed as an additional fetched ref, it has NOT been checked out. For private repositories you cannot fetch it. If the branch is required and not available, exit with an error and ask the user to add it to the `fetch:` option of the `checkout:` configuration (e.g., `fetch: [\"refs/pulls/open/*\"]` for all open PR refs, or `fetch: [\"main\", \"feature/my-branch\"]` for specific branches).\n - **Warning: No git credentials are available to the agent.** Credentials are\n intentionally removed after the checkout step for security. This means any git\n operation that needs to authenticate to the remote will fail. In private repositories, that includes:\n - `git fetch`, `git pull`, `git clone`, and `git push` (direct push, not via safe-output tools)\n - Checking out or switching to a remote branch that is not already fetched\n - Deepening a shallow clone (`git fetch --unshallow`)\n - On-demand blob fetches in partial/blobless clones (operations on files not in the initial checkout)\n Do NOT attempt to configure credentials, run `git credential fill`, or modify `.gitconfig` —\n authentication will not succeed. If you encounter credential prompts or authentication errors,\n stop immediately and report the limitation rather than spending turns trying to work around it.\n</github-context>\n\n"
356
- GH_AW_PROMPT_CONTENT_0004: "</system>\n"
357
- GH_AW_PROMPT_CONTENT_0005: "{{#runtime-import .github/workflows/shared/lighthouse-sdlc-stage.md}}\n"
358
- GH_AW_PROMPT_CONTENT_0006: "{{#runtime-import .github/workflows/lighthouse-sdlc-review.md}}\n"
339
+ GH_AW_PROMPT_CONTENT_0003: "</system>\n"
340
+ GH_AW_PROMPT_CONTENT_0004: "{{#runtime-import .github/workflows/shared/lighthouse-opencode.md}}\n"
341
+ GH_AW_PROMPT_CONTENT_0005: "{{#runtime-import .github/workflows/lighthouse-sdlc-review.md}}\n"
359
342
  with:
360
343
  script: |
361
344
  const { setupGlobals } = require(process.env.GH_AW_ACTIONS_DIR + '/setup_globals.cjs');
@@ -366,13 +349,11 @@ jobs:
366
349
  uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
367
350
  env:
368
351
  GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt
369
- GH_AW_ENGINE_ID: "copilot"
352
+ GH_AW_ENGINE_ID: "opencode"
370
353
  GH_AW_SUB_AGENT_DIR: ".github/agents"
371
354
  GH_AW_SUB_AGENT_EXT: ".agent.md"
372
355
  GH_AW_SKILL_DIR: ".github/skills"
373
356
  GH_AW_SKILL_EXT: "/SKILL.md"
374
- GH_AW_ENV_LIGHTHOUSE_SKILL: ${{ env.LIGHTHOUSE_SKILL }}
375
- GH_AW_EXPR_79DC8BAA: ${{ inputs.run-id }}
376
357
  with:
377
358
  script: |
378
359
  const path = require('path');
@@ -385,17 +366,7 @@ jobs:
385
366
  uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
386
367
  env:
387
368
  GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt
388
- GH_AW_ENV_LIGHTHOUSE_SKILL: ${{ env.LIGHTHOUSE_SKILL }}
389
- GH_AW_EXPR_76DF9333: ${{ github.event.pull_request.number || (fromJSON(steps.generate_aw_info.outputs.aw_context || '{}').item_type == 'pull_request' && fromJSON(steps.generate_aw_info.outputs.aw_context || '{}').item_number) }}
390
- GH_AW_EXPR_77C1A4D2: ${{ github.event.comment.id || fromJSON(steps.generate_aw_info.outputs.aw_context || '{}').comment_id }}
391
- GH_AW_EXPR_79DC8BAA: ${{ inputs.run-id }}
392
- GH_AW_EXPR_7C248226: ${{ github.event.issue.number || (fromJSON(steps.generate_aw_info.outputs.aw_context || '{}').item_type == 'issue' && fromJSON(steps.generate_aw_info.outputs.aw_context || '{}').item_number) }}
393
- GH_AW_EXPR_C19C384F: ${{ github.event.discussion.number || (fromJSON(steps.generate_aw_info.outputs.aw_context || '{}').item_type == 'discussion' && fromJSON(steps.generate_aw_info.outputs.aw_context || '{}').item_number) }}
394
- GH_AW_GITHUB_ACTOR: ${{ github.actor }}
395
- GH_AW_GITHUB_REPOSITORY: ${{ github.repository }}
396
- GH_AW_GITHUB_RUN_ID: ${{ github.run_id }}
397
- GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }}
398
- GH_AW_MCP_CLI_SERVERS_LIST: "- `github` — run `github --help` to see available tools\n- `safeoutputs` — run `safeoutputs --help` to see available tools"
369
+ GH_AW_MCP_CLI_SERVERS_LIST: '- `safeoutputs` — run `safeoutputs --help` to see available tools'
399
370
  GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED: ${{ needs.pre_activation.outputs.activated }}
400
371
  with:
401
372
  script: |
@@ -410,16 +381,6 @@ jobs:
410
381
  return await substitutePlaceholders({
411
382
  file: process.env.GH_AW_PROMPT,
412
383
  substitutions: {
413
- GH_AW_ENV_LIGHTHOUSE_SKILL: process.env.GH_AW_ENV_LIGHTHOUSE_SKILL,
414
- GH_AW_EXPR_76DF9333: process.env.GH_AW_EXPR_76DF9333,
415
- GH_AW_EXPR_77C1A4D2: process.env.GH_AW_EXPR_77C1A4D2,
416
- GH_AW_EXPR_79DC8BAA: process.env.GH_AW_EXPR_79DC8BAA,
417
- GH_AW_EXPR_7C248226: process.env.GH_AW_EXPR_7C248226,
418
- GH_AW_EXPR_C19C384F: process.env.GH_AW_EXPR_C19C384F,
419
- GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR,
420
- GH_AW_GITHUB_REPOSITORY: process.env.GH_AW_GITHUB_REPOSITORY,
421
- GH_AW_GITHUB_RUN_ID: process.env.GH_AW_GITHUB_RUN_ID,
422
- GH_AW_GITHUB_WORKSPACE: process.env.GH_AW_GITHUB_WORKSPACE,
423
384
  GH_AW_MCP_CLI_SERVERS_LIST: process.env.GH_AW_MCP_CLI_SERVERS_LIST,
424
385
  GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED: process.env.GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED
425
386
  }
@@ -483,17 +444,19 @@ jobs:
483
444
 
484
445
  agent:
485
446
  name: agent
486
- needs: activation
447
+ needs:
448
+ - activation
449
+ - prepare
487
450
  if: needs.activation.outputs.daily_ai_credits_exceeded != 'true'
488
451
  runs-on:
489
452
  - self-hosted
490
453
  - linux
491
- - lighthouse-sdlc
454
+ - lighthouse-workflow
492
455
  # Permissions for the agent job (workflow permissions default to none).
493
456
  permissions:
494
457
  contents: read
495
458
  concurrency:
496
- group: "gh-aw-copilot-lighthouse-sdlc-review"
459
+ group: "gh-aw-opencode-lighthouse-sdlc-review"
497
460
  queue: max
498
461
  timeout-minutes: 60
499
462
  env:
@@ -501,6 +464,7 @@ jobs:
501
464
  GH_AW_ASSETS_ALLOWED_EXTS: ""
502
465
  GH_AW_ASSETS_BRANCH: ""
503
466
  GH_AW_ASSETS_MAX_SIZE_KB: 0
467
+ GH_AW_ENGINE_VERSION: "2.1.0"
504
468
  GH_AW_MCP_LOG_DIR: /tmp/gh-aw/mcp-logs/safeoutputs
505
469
  GH_AW_PR_HEAD_BASE_BRANCH: ""
506
470
  GH_AW_PR_HEAD_BASE_PR_NUMBER: ""
@@ -512,30 +476,17 @@ jobs:
512
476
  GH_AW_TARGET_REPO_SLUG: ""
513
477
  GH_AW_WORKFLOW_ID_SANITIZED: lighthousesdlcreview
514
478
  outputs:
515
- agentic_engine_timeout: ${{ steps.detect-agent-errors.outputs.agentic_engine_timeout || 'false' }}
516
479
  ai_credits_rate_limit_error: ${{ steps.parse-mcp-gateway.outputs.ai_credits_rate_limit_error || 'false' }}
517
- aic: ${{ steps.parse-token-usage.outputs.aic }}
518
- ambient_context: ${{ steps.parse-token-usage.outputs.ambient_context }}
480
+ aic: ${{ steps.parse-mcp-gateway.outputs.aic }}
481
+ ambient_context: ${{ steps.parse-mcp-gateway.outputs.ambient_context }}
519
482
  artifact_prefix: ${{ needs.activation.outputs.artifact_prefix }}
520
- checkout_pr_invalidated: ${{ steps.checkout-pr.outputs.checkout_pr_invalidated || 'false' }}
521
- checkout_pr_success: ${{ steps.checkout-pr.outputs.checkout_pr_success || 'true' }}
522
483
  has_patch: ${{ steps.collect_output.outputs.has_patch }}
523
- http_400_response_error: ${{ steps.detect-agent-errors.outputs.http_400_response_error || 'false' }}
524
- inference_access_error: ${{ steps.detect-agent-errors.outputs.inference_access_error || 'false' }}
525
- invocation_cap_exceeded: ${{ steps.detect-agent-errors.outputs.invocation_cap_exceeded || 'false' }}
526
- max_cache_misses_exceeded: ${{ steps.detect-agent-errors.outputs.max_cache_misses_exceeded || 'false' }}
527
- mcp_policy_error: ${{ steps.detect-agent-errors.outputs.mcp_policy_error || 'false' }}
528
- missing_model_pricing_error: ${{ steps.detect-agent-errors.outputs.missing_model_pricing_error || 'false' }}
529
- missing_model_pricing_model_name: ${{ steps.detect-agent-errors.outputs.missing_model_pricing_model_name || '' }}
530
484
  model: ${{ needs.activation.outputs.model }}
531
- model_endpoint_mismatch_error: ${{ steps.detect-agent-errors.outputs.model_endpoint_mismatch_error || 'false' }}
532
- model_not_supported_error: ${{ steps.detect-agent-errors.outputs.model_not_supported_error || 'false' }}
533
485
  output: ${{ steps.collect_output.outputs.output }}
534
486
  output_types: ${{ steps.collect_output.outputs.output_types }}
535
487
  setup-parent-span-id: ${{ steps.setup.outputs.parent-span-id || steps.setup.outputs.span-id }}
536
488
  setup-span-id: ${{ steps.setup.outputs.span-id }}
537
489
  setup-trace-id: ${{ steps.setup.outputs.trace-id }}
538
- shell_expansion_guard_rejected: ${{ steps.detect-agent-errors.outputs.shell_expansion_guard_rejected || 'false' }}
539
490
  unknown_model_ai_credits: ${{ steps.parse-mcp-gateway.outputs.unknown_model_ai_credits || 'false' }}
540
491
  steps:
541
492
  - name: Setup Scripts
@@ -549,9 +500,8 @@ jobs:
549
500
  env:
550
501
  GH_AW_SETUP_WORKFLOW_NAME: "Lighthouse SDLC review"
551
502
  GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/lighthouse-sdlc-review.lock.yml@${{ github.ref }}
552
- GH_AW_INFO_VERSION: "1.0.101"
553
- GH_AW_INFO_AWF_VERSION: "v0.28.70"
554
- GH_AW_INFO_ENGINE_ID: "copilot"
503
+ GH_AW_INFO_VERSION: "2.1.0"
504
+ GH_AW_INFO_ENGINE_ID: "opencode"
555
505
  GH_AW_SETUP_AW_CONTEXT: ${{ inputs.aw_context }}
556
506
  - name: Set runtime paths
557
507
  id: set-runtime-paths
@@ -570,22 +520,12 @@ jobs:
570
520
  run: bash "${RUNNER_TEMP}/gh-aw/actions/mask_otlp_headers.sh"
571
521
  - name: Check OTLP telemetry configuration
572
522
  run: bash "${RUNNER_TEMP}/gh-aw/actions/check_otlp_default_credentials.sh"
573
- - name: Checkout repository (gh-aw default)
574
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
575
- with:
576
- persist-credentials: false
577
- fetch-depth: 0
578
523
  - name: Initialize agent execution evidence
579
524
  run: |
580
525
  mkdir -p "/tmp/gh-aw"
581
526
  evidence_tmp="/tmp/gh-aw/agent_execution.json.tmp"
582
527
  printf '{"version":1,"component":"agent","run_id":%s,"run_attempt":%s,"state":"not_started"}\n' "$GITHUB_RUN_ID" "$GITHUB_RUN_ATTEMPT" > "$evidence_tmp"
583
528
  mv "$evidence_tmp" "/tmp/gh-aw/agent_execution.json"
584
- - name: Setup Node.js
585
- uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
586
- with:
587
- node-version: '24'
588
- package-manager-cache: false
589
529
  - name: Create gh-aw temp directory
590
530
  run: bash "${RUNNER_TEMP}/gh-aw/actions/create_gh_aw_tmp_dir.sh"
591
531
  - name: Configure gh CLI for GitHub Enterprise
@@ -597,21 +537,28 @@ jobs:
597
537
  with:
598
538
  name: ${{ needs.activation.outputs.artifact_prefix }}activation
599
539
  path: /tmp/gh-aw
600
- - name: Install the locked consumer packages
601
- run: npm ci --ignore-scripts
602
- - name: Check the installed SDLC version
603
- run: node node_modules/@juangcarmona/lighthouse-sdlc/src/installation.mjs
604
- - env:
605
- STAGE_INPUT: ${{ inputs.input }}
606
- name: Materialize the host input
607
- run: "set -euo pipefail\nmkdir -p /tmp/gh-aw/agent\nprintf '%s\\n' \"${STAGE_INPUT:-\"{}\"}\" > /tmp/gh-aw/agent/input.json\n"
608
- shell: bash
609
- - if: inputs.previous-stage != ''
610
- name: Load the previous stage result
540
+ - name: Check out the authorized product revision
541
+ uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5
542
+ with:
543
+ persist-credentials: false
544
+ ref: ${{ needs.prepare.outputs.revision }}
545
+ - name: Setup Node.js
546
+ uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
547
+ with:
548
+ node-version: '24'
549
+ package-manager-cache: false
550
+ - name: Load the pinned harness package
551
+ uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5
552
+ with:
553
+ path: tools
554
+ persist-credentials: false
555
+ ref: __LIGHTHOUSE_REF__
556
+ repository: juangcarmona/lighthouse
557
+ - name: Load the authorized issue context
611
558
  uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
612
559
  with:
613
- name: lighthouse-sdlc-${{ inputs.run-id }}-${{ inputs.previous-stage }}
614
- path: /tmp/gh-aw/agent/previous
560
+ name: lighthouse-input-${{ inputs.issue }}-${{ github.run_attempt }}
561
+ path: ${{ runner.temp }}/lighthouse-${{ github.run_id }}-${{ github.run_attempt }}
615
562
 
616
563
  - name: Configure Git credentials
617
564
  env:
@@ -619,47 +566,6 @@ jobs:
619
566
  GITHUB_SERVER_URL: ${{ github.server_url }}
620
567
  GITHUB_TOKEN: ${{ github.token }}
621
568
  run: bash "${RUNNER_TEMP}/gh-aw/actions/configure_git_credentials.sh"
622
- - name: Checkout PR branch
623
- id: checkout-pr
624
- if: |
625
- github.event.pull_request || github.event.issue.pull_request || github.event_name == 'workflow_dispatch'
626
- uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
627
- env:
628
- GH_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
629
- with:
630
- github-token: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
631
- script: |
632
- const path = require('path');
633
- const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
634
- const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs'));
635
- setupGlobals(core, github, context, exec, io, getOctokit);
636
- const { main } = require(path.join(actionsDir, 'checkout_pr_branch.cjs'));
637
- await main();
638
- - name: Install GitHub Copilot CLI
639
- run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.101 --checksums-sha256 018625eac68670d66ede904b9b82cdcd6ab8f87ba20e6e1fbdf0b62c8295d5be --prefer-toolcache
640
- env:
641
- GH_HOST: github.com
642
- GH_AW_COPILOT_MIN_VERSION: 1.0.35
643
- - name: Install AWF binary
644
- run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.28.70 --rootless
645
- - name: Determine automatic lockdown mode for GitHub MCP Server
646
- id: determine-automatic-lockdown
647
- uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
648
- env:
649
- GH_AW_GITHUB_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN }}
650
- GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }}
651
- with:
652
- script: |
653
- const path = require('path');
654
- const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
655
- const determineAutomaticLockdown = require(path.join(actionsDir, 'determine_automatic_lockdown.cjs'));
656
- await determineAutomaticLockdown(github, context, core);
657
- - name: Restore agent config folders from base branch
658
- if: steps.checkout-pr.outcome == 'success'
659
- env:
660
- GH_AW_AGENT_FOLDERS: ".agents .github"
661
- GH_AW_AGENT_FILES: "AGENTS.md"
662
- run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_base_github_folders.sh"
663
569
  - name: Restore inline sub-agents from activation artifact
664
570
  env:
665
571
  GH_AW_SUB_AGENT_DIR: ".github/agents"
@@ -670,7 +576,7 @@ jobs:
670
576
  GH_AW_SKILL_DIR: ".github/skills"
671
577
  run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_inline_skills.sh"
672
578
  - name: Download container images
673
- run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.28.70@sha256:b15ab48cbbab02904eb9bbd359a398db59690eebbea1e6934d47ed2bb407dd34 ghcr.io/github/gh-aw-firewall/api-proxy:0.28.70@sha256:9ac8f9c7294e892c916de3da9d2588dfd8cd4931e5c39b00143266d7ed9fd52a ghcr.io/github/gh-aw-firewall/squid:0.28.70@sha256:b5bc53f4becfd96e926e63c83831f1b3c9512f713c83161d2b8c9b7204b3e917 ghcr.io/github/gh-aw-mcpg:v0.4.37@sha256:9c7f242f6dec2d7d7b55d4c9e07872d59b85377c6cb3de46c915a5d1ffb91442 ghcr.io/github/gh-aw-node@sha256:41835613992df88f51e923bad486f96dfb2e6cda29f13e217df41833284ae382 ghcr.io/github/github-mcp-server:v2.0.2@sha256:ffced0d76e77428532a2ced185516992d77fd146d69eec2f244e6237d1a97796
579
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-node@sha256:41835613992df88f51e923bad486f96dfb2e6cda29f13e217df41833284ae382
674
580
  - name: Prepare Safe Outputs Directories
675
581
  run: |
676
582
  mkdir -p "${RUNNER_TEMP}/gh-aw/safeoutputs"
@@ -681,7 +587,7 @@ jobs:
681
587
  env:
682
588
  GH_AW_FILE_ROOT: "${{ runner.temp }}/gh-aw"
683
589
  GH_AW_FILE_CONFIG: "{\"files\":[{\"path\":\"safeoutputs/config.json\",\"content_env\":\"GH_AW_SAFE_OUTPUTS_CONFIG\"}]}"
684
- GH_AW_SAFE_OUTPUTS_CONFIG: "{\"create_report_incomplete_issue\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"false\"},\"report_incomplete\":{},\"report_missing_data\":{},\"report_missing_tool\":{}}"
590
+ GH_AW_SAFE_OUTPUTS_CONFIG: "{\"noop\":{\"max\":2,\"report-as-issue\":\"false\"}}"
685
591
  with:
686
592
  script: |
687
593
  const path = require('path');
@@ -710,68 +616,6 @@ jobs:
710
616
  "maxLength": 65000
711
617
  }
712
618
  }
713
- },
714
- "report_incomplete": {
715
- "defaultMax": 5,
716
- "fields": {
717
- "details": {
718
- "type": "string",
719
- "sanitize": true,
720
- "maxLength": 65000
721
- },
722
- "reason": {
723
- "required": true,
724
- "type": "string",
725
- "sanitize": true,
726
- "maxLength": 1024
727
- }
728
- }
729
- },
730
- "report_missing_data": {
731
- "defaultMax": 20,
732
- "fields": {
733
- "alternatives": {
734
- "type": "string",
735
- "sanitize": true,
736
- "maxLength": 256
737
- },
738
- "context": {
739
- "type": "string",
740
- "sanitize": true,
741
- "maxLength": 256
742
- },
743
- "data_type": {
744
- "type": "string",
745
- "sanitize": true,
746
- "maxLength": 128
747
- },
748
- "reason": {
749
- "type": "string",
750
- "sanitize": true,
751
- "maxLength": 256
752
- }
753
- }
754
- },
755
- "report_missing_tool": {
756
- "defaultMax": 20,
757
- "fields": {
758
- "alternatives": {
759
- "type": "string",
760
- "sanitize": true,
761
- "maxLength": 512
762
- },
763
- "reason": {
764
- "required": true,
765
- "type": "string",
766
- "sanitize": true,
767
- "maxLength": 256
768
- },
769
- "tool": {
770
- "type": "string",
771
- "sanitize": true,
772
- "maxLength": 128
773
- }
774
- }
775
619
  }
776
620
  }
777
621
  uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
@@ -791,10 +635,6 @@ jobs:
791
635
  GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
792
636
  GH_AW_SAFE_OUTPUTS_CONFIG_PATH: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS_CONFIG_PATH }}
793
637
  GH_AW_SAFE_OUTPUTS_TOOLS_PATH: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS_TOOLS_PATH }}
794
- GH_AW_SINK_VISIBILITY: ${{ steps.determine-automatic-lockdown.outputs.visibility }}
795
- GITHUB_MCP_GUARD_MIN_INTEGRITY: ${{ steps.determine-automatic-lockdown.outputs.min_integrity }}
796
- GITHUB_MCP_GUARD_REPOS: ${{ steps.determine-automatic-lockdown.outputs.repos }}
797
- GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
798
638
  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
799
639
  run: |
800
640
  set -eo pipefail
@@ -807,7 +647,7 @@ jobs:
807
647
 
808
648
  # Export gateway environment variables for MCP config and gateway script
809
649
  export MCP_GATEWAY_PORT="8080"
810
- export MCP_GATEWAY_DOMAIN="awmg-mcpg"
650
+ export MCP_GATEWAY_DOMAIN="localhost"
811
651
  export MCP_GATEWAY_HOST_DOMAIN="localhost"
812
652
  MCP_GATEWAY_AGENT_ID=$(openssl rand -base64 45 | tr -d '/+=')
813
653
  echo "::add-mask::${MCP_GATEWAY_AGENT_ID}"
@@ -823,36 +663,17 @@ jobs:
823
663
  export GH_AW_PR_HEAD_BASE_REF="${GH_AW_PR_HEAD_BASE_REF:-}"
824
664
  export GH_AW_PR_HEAD_REPO="${GH_AW_PR_HEAD_REPO:-}"
825
665
  export GH_AW_TARGET_REPO_SLUG="${GH_AW_TARGET_REPO_SLUG:-}"
826
- export GH_AW_ENGINE="copilot"
666
+ export GH_AW_ENGINE="opencode"
827
667
  MCP_GATEWAY_UID=$(id -u 2>/dev/null || echo '0')
828
668
  MCP_GATEWAY_GID=$(id -g 2>/dev/null || echo '0')
829
669
  source "${RUNNER_TEMP}/gh-aw/actions/resolve_docker_socket_gid.sh"
830
- export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network bridge -p 127.0.0.1:'"${MCP_GATEWAY_PORT}"':'"${MCP_GATEWAY_PORT}"' --name awmg-mcpg --add-host host.docker.internal:host-gateway --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_AGENT_ID -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_TARGET_REPO_SLUG -e GH_AW_PR_HEAD_BASE_BRANCH -e GH_AW_PR_HEAD_BASE_SHA -e GH_AW_PR_HEAD_BASE_REPO -e GH_AW_PR_HEAD_BASE_PR_NUMBER -e GH_AW_PR_HEAD_BASE_REF -e GH_AW_PR_HEAD_REPO -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 GH_AW_SINK_VISIBILITY -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 -e RUNNER_TOOL_CACHE -e MCP_GATEWAY_ALLOWED_MOUNT_ROOTS -e GITHUB_AW_OTEL_TRACE_ID -e GITHUB_AW_OTEL_PARENT_SPAN_ID -e OTEL_EXPORTER_OTLP_HEADERS -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.4.37@sha256:9c7f242f6dec2d7d7b55d4c9e07872d59b85377c6cb3de46c915a5d1ffb91442'
670
+ 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_AGENT_ID -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_TARGET_REPO_SLUG -e GH_AW_PR_HEAD_BASE_BRANCH -e GH_AW_PR_HEAD_BASE_SHA -e GH_AW_PR_HEAD_BASE_REPO -e GH_AW_PR_HEAD_BASE_PR_NUMBER -e GH_AW_PR_HEAD_BASE_REF -e GH_AW_PR_HEAD_REPO -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 GH_AW_SINK_VISIBILITY -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 -e RUNNER_TOOL_CACHE -e MCP_GATEWAY_ALLOWED_MOUNT_ROOTS -e GITHUB_AW_OTEL_TRACE_ID -e GITHUB_AW_OTEL_PARENT_SPAN_ID -e OTEL_EXPORTER_OTLP_HEADERS -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.4.37@sha256:9c7f242f6dec2d7d7b55d4c9e07872d59b85377c6cb3de46c915a5d1ffb91442'
831
671
 
832
- mkdir -p "$HOME/.copilot"
833
672
  GH_AW_NODE=$(which node 2>/dev/null || command -v node 2>/dev/null || echo node)
834
- cat << GH_AW_MCP_CONFIG_3db6aaf67c51d953_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs"
673
+ cat << GH_AW_MCP_CONFIG_6001799711bbe943_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs"
835
674
  {
836
675
  "mcpServers": {
837
- "github": {
838
- "type": "stdio",
839
- "container": "ghcr.io/github/github-mcp-server:v2.0.2",
840
- "env": {
841
- "GITHUB_FEATURES": "fields_param",
842
- "GITHUB_HOST": "${GITHUB_SERVER_URL}",
843
- "GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_MCP_SERVER_TOKEN}",
844
- "GITHUB_READ_ONLY": "1",
845
- "GITHUB_TOOLSETS": "repos,issues,pull_requests"
846
- },
847
- "guard-policies": {
848
- "allow-only": {
849
- "min-integrity": "$GITHUB_MCP_GUARD_MIN_INTEGRITY",
850
- "repos": "$GITHUB_MCP_GUARD_REPOS"
851
- }
852
- }
853
- },
854
676
  "safeoutputs": {
855
- "type": "stdio",
856
677
  "container": "ghcr.io/github/gh-aw-node@sha256:41835613992df88f51e923bad486f96dfb2e6cda29f13e217df41833284ae382",
857
678
  "mounts": ["\${GITHUB_WORKSPACE}:\${GITHUB_WORKSPACE}:rw", "${RUNNER_TEMP}/gh-aw/safeoutputs:${RUNNER_TEMP}/gh-aw/safeoutputs:rw", "/tmp/gh-aw:/tmp/gh-aw:rw"],
858
679
  "args": ["-w", "\${GITHUB_WORKSPACE}"],
@@ -883,14 +704,6 @@ jobs:
883
704
  "GITHUB_TOKEN": "\${GITHUB_TOKEN}",
884
705
  "GITHUB_WORKSPACE": "\${GITHUB_WORKSPACE}",
885
706
  "RUNNER_TEMP": "\${RUNNER_TEMP}"
886
- },
887
- "guard-policies": {
888
- "write-sink": {
889
- "accept": [
890
- "*"
891
- ],
892
- "sink-visibility": "${GH_AW_SINK_VISIBILITY}"
893
- }
894
707
  }
895
708
  }
896
709
  },
@@ -907,7 +720,7 @@ jobs:
907
720
  }
908
721
  }
909
722
  }
910
- GH_AW_MCP_CONFIG_3db6aaf67c51d953_EOF
723
+ GH_AW_MCP_CONFIG_6001799711bbe943_EOF
911
724
  - name: Mount MCP servers as CLIs
912
725
  id: mount-mcp-clis
913
726
  continue-on-error: true
@@ -932,195 +745,69 @@ jobs:
932
745
  id: pre_agent_audit
933
746
  continue-on-error: true
934
747
  run: bash "${RUNNER_TEMP}/gh-aw/actions/audit_pre_agent_workspace.sh"
935
- - name: Log GitHub rate limits at agent start
936
- continue-on-error: true
937
- uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
938
- with:
939
- github-token: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
940
- script: |
941
- const path = require('path');
942
- const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
943
- const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs'));
944
- setupGlobals(core, github, context, exec, io, getOctokit);
945
- const { fetchAndLogRateLimit } = require(path.join(actionsDir, 'github_rate_limit_logger.cjs'));
946
- await fetchAndLogRateLimit(github, 'agent_start', true);
947
- - name: Execute GitHub Copilot CLI
748
+ - name: Write OpenCode log parser script
749
+ if: always()
750
+ run: |
751
+ mkdir -p "${RUNNER_TEMP}/gh-aw/actions"
752
+ cat <<'GHAW_LOG_PARSER_SCRIPT_5d2e8b3f_EOF' > "${RUNNER_TEMP}/gh-aw/actions/opencode_log_parser.cjs"
753
+ // @ts-check
754
+ // Auto-generated log parser for behavior-defined engine "OpenCode".
755
+ const { createEngineLogParser } = require("./log_parser_shared.cjs");
756
+
757
+ // --- begin engine-provided parse function ---
758
+ function parseLog(logContent) {
759
+ const fs = require("fs");
760
+ const events = require("path").join(process.env.RUNNER_TEMP, "gh-aw", `opencode-events-${process.env.GITHUB_RUN_ID}-${process.env.GITHUB_RUN_ATTEMPT}.jsonl`);
761
+ return require("./parse_opencode_log.cjs").parseOpenCodeLog(fs.existsSync(events) ? fs.readFileSync(events, "utf8") : logContent);
762
+ }
763
+
764
+ // --- end engine-provided parse function ---
765
+
766
+ const main = createEngineLogParser({
767
+ parserName: "OpenCode",
768
+ parseFunction: parseLog,
769
+ supportsDirectories: false,
770
+ });
771
+
772
+ if (typeof module !== "undefined" && module.exports) {
773
+ module.exports = { main, parseLog };
774
+ }
775
+ GHAW_LOG_PARSER_SCRIPT_5d2e8b3f_EOF
776
+ chmod 755 "${RUNNER_TEMP}/gh-aw/actions/opencode_log_parser.cjs"
777
+ - name: OpenCode progress and result
948
778
  id: agentic_execution
949
- # Copilot CLI tool arguments (sorted):
950
- # --allow-tool github
951
- # --allow-tool safeoutputs
952
- # --allow-tool shell(cat)
953
- # --allow-tool shell(date)
954
- # --allow-tool shell(echo)
955
- # --allow-tool shell(find)
956
- # --allow-tool shell(git:*)
957
- # --allow-tool shell(github:*)
958
- # --allow-tool shell(grep)
959
- # --allow-tool shell(head)
960
- # --allow-tool shell(ls)
961
- # --allow-tool shell(node)
962
- # --allow-tool shell(npm:*)
963
- # --allow-tool shell(npx:*)
964
- # --allow-tool shell(printf)
965
- # --allow-tool shell(pwd)
966
- # --allow-tool shell(rg)
967
- # --allow-tool shell(safeoutputs:*)
968
- # --allow-tool shell(sort)
969
- # --allow-tool shell(tail)
970
- # --allow-tool shell(uniq)
971
- # --allow-tool shell(wc)
972
- # --allow-tool shell(yq)
973
- # --allow-tool write
974
- timeout-minutes: ${{ fromJSON(vars.GH_AW_DEFAULT_TIMEOUT_MINUTES || '20') }}
779
+ timeout-minutes: 15
975
780
  run: |
976
781
  set -o pipefail
977
- printf '%s' "$(date +%s%3N)" > /tmp/gh-aw/agent_cli_start_ms.txt
978
782
  gh_aw_exit_code=0
979
- trap 'gh_aw_exit_code=$?; mkdir -p /tmp/gh-aw >/dev/null 2>&1 || true; printf "%s" "$gh_aw_exit_code" > /tmp/gh-aw/agent_execution_exit_code.txt || true; rm -f "$HOME/.copilot/settings.json"; if [ "$gh_aw_exit_code" -ne 0 ]; then echo "::error::Agent execution exited with code $gh_aw_exit_code"; fi' EXIT
980
- mkdir -p "$HOME/.copilot"
981
- printf '%s' '{"builtInAgents":{"rubberDuck":false},"enabledFeatureFlags":{"EXTENSIONS":false}}' > "$HOME/.copilot/settings.json"
982
- export XDG_CONFIG_HOME="$HOME"
983
- export GH_AW_MCP_CONFIG="$HOME/.copilot/mcp-config.json"
984
- GH_AW_COPILOT_SRC="$(command -v copilot 2>/dev/null || true)"
985
- if [ -z "$GH_AW_COPILOT_SRC" ] || [ ! -x "$GH_AW_COPILOT_SRC" ]; then
986
- echo "GitHub Copilot CLI executable not found on PATH after installation" >&2
987
- exit 127
988
- fi
989
- GH_AW_COPILOT_BIN="${RUNNER_TEMP}/gh-aw/bin/copilot"
990
- mkdir -p "${RUNNER_TEMP}/gh-aw/bin"
991
- if [ "$GH_AW_COPILOT_SRC" != "$GH_AW_COPILOT_BIN" ]; then
992
- cp "$GH_AW_COPILOT_SRC" "$GH_AW_COPILOT_BIN"
993
- fi
994
- chmod 755 "$GH_AW_COPILOT_BIN"
995
-
996
- touch /tmp/gh-aw/agent-step-summary.md
997
- GH_AW_NODE_BIN=$(command -v node 2>/dev/null || true)
998
- export GH_AW_NODE_BIN
999
- export COPILOT_API_KEY="$COPILOT_DUMMY_BYOK"
1000
- (umask 177 && touch /tmp/gh-aw/agent-stdio.log)
1001
- GH_AW_MAX_AI_CREDITS="${GH_AW_MAX_AI_CREDITS:-1000}"
1002
- if [[ ! "$GH_AW_MAX_AI_CREDITS" =~ ^[0-9]+$ ]]; then
1003
- GH_AW_MAX_AI_CREDITS="1000"
1004
- fi
1005
- if [[ "${GH_AW_ADMISSION_RESULT:-}" == "admitted" && -z "${GH_AW_ADMISSION_MAX_AI_CREDITS:-}" ]]; then
1006
- echo "ERR_ADMISSION: Missing required runtime admission allowance." >&2
1007
- exit 1
1008
- fi
1009
-
1010
- if [[ "${GH_AW_ADMISSION_RESULT:-}" == "admitted" && -n "${GH_AW_ADMISSION_MAX_AI_CREDITS:-}" ]]; then
1011
- if [[ ! "$GH_AW_ADMISSION_MAX_AI_CREDITS" =~ ^[1-9][0-9]{0,9}$ ]] || (( GH_AW_ADMISSION_MAX_AI_CREDITS > 2147483647 )); then
1012
- echo "ERR_ADMISSION: Invalid runtime admission allowance." >&2
1013
- exit 1
1014
- fi
1015
- GH_AW_MAX_AI_CREDITS="$GH_AW_ADMISSION_MAX_AI_CREDITS"
1016
- echo "Admission allowance applied (value withheld)."
1017
- else
1018
- echo "No component admission allowance; retaining existing budget policy (value withheld)."
1019
- fi
1020
- unset GH_AW_ADMISSION_RESULT GH_AW_ADMISSION_MAX_AI_CREDITS
1021
- printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.28.70/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"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\",\"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\",\"s.symcb.com\",\"s.symcd.com\",\"security.ubuntu.com\",\"ts-crl.ws.symantec.com\",\"ts-ocsp.ws.symantec.com\",\"www.googleapis.com\"],\"isolation\":true,\"topologyAttach\":[\"awmg-mcpg\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS},\"maxCacheMisses\":5,\"models\":{\"agent\":[\"sonnet-6x\",\"gpt-6\",\"gpt-5.4\",\"gpt-5.5\",\"gpt-5.6\",\"gpt-5.3\",\"gemini-pro\",\"any\"],\"antigravity\":[\"copilot/antigravity*\",\"google/antigravity*\",\"gemini/antigravity*\"],\"any\":[\"copilot/*\",\"anthropic/*\",\"openai/*\",\"google/*\",\"gemini/*\"],\"auto\":[\"copilot/auto\",\"large\"],\"claude\":[\"agent\"],\"codex\":[\"agent\"],\"coding\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\",\"gpt-5-codex\",\"kimi\"],\"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*\"],\"detection\":[\"small\"],\"evals\":[\"small\"],\"fable\":[\"copilot/*fable*\",\"anthropic/*fable*\"],\"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-3.6-flash\":[\"copilot/gemini-3.6*flash*\",\"google/gemini-3.6*flash*\",\"gemini/gemini-3.6*flash*\"],\"gemini-3.7-flash\":[\"copilot/gemini-3.7*flash*\",\"google/gemini-3.7*flash*\",\"gemini/gemini-3.7*flash*\"],\"gemini-3.8-flash\":[\"copilot/gemini-3.8*flash*\",\"google/gemini-3.8*flash*\",\"gemini/gemini-3.8*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-omni\":[\"copilot/gemini-omni*\",\"google/gemini-omni*\",\"gemini/gemini-omni*\"],\"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*\"],\"gpt-5.6\":[\"copilot/gpt-5.6*\",\"openai/gpt-5.6*\"],\"gpt-6\":[\"copilot/gpt-6*\",\"openai/gpt-6*\"],\"grok\":[\"copilot/*grok*\",\"openai/*grok*\"],\"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*\"],\"kimi\":[\"copilot/kimi*\",\"openai/kimi*\"],\"kiwi\":[\"copilot/kiwi*\",\"openai/kiwi*\"],\"large\":[\"sonnet\",\"gpt-6\",\"gpt-5-pro\",\"gpt-5\",\"gemini-pro\"],\"lyria\":[\"google/lyria*\",\"gemini/lyria*\",\"copilot/lyria*\"],\"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\"],\"raptor-mini\":[\"copilot/raptor*\",\"openai/raptor*\"],\"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-5*\",\"copilot/*sonnet-4-5-*\",\"anthropic/*sonnet-4-5-*\",\"copilot/*sonnet-4-6*\",\"anthropic/*sonnet-4-6*\",\"anthropic/*sonnet-5*\"],\"summarization\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash-lite\",\"mini\"],\"veo\":[\"google/veo*\",\"gemini/veo*\"],\"vision\":[\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"]}},\"container\":{\"imageTag\":\"0.28.70,squid=sha256:b5bc53f4becfd96e926e63c83831f1b3c9512f713c83161d2b8c9b7204b3e917,agent=sha256:b15ab48cbbab02904eb9bbd359a398db59690eebbea1e6934d47ed2bb407dd34,api-proxy=sha256:9ac8f9c7294e892c916de3da9d2588dfd8cd4931e5c39b00143266d7ed9fd52a,cli-proxy=sha256:372ac51a5cccffdfe484f3f7be427d2d1c566e8ae550d55bd45d9fd166a154b4\"},\"logging\":{\"proxyLogsDir\":\"/tmp/gh-aw/sandbox/firewall/logs\",\"auditDir\":\"/tmp/gh-aw/sandbox/firewall/audit\"}}" > "${RUNNER_TEMP}/gh-aw/awf-config.json"
1022
- cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json
1023
- export GH_AW_MODELS_JSON_PATH="/tmp/gh-aw/models.json"
1024
- GH_AW_DOCKER_HOST=""
1025
- if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then
1026
- GH_AW_DOCKER_HOST="${DOCKER_HOST}"
1027
- fi
1028
- if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then
1029
- GH_AW_CHROOT_BINARIES_SOURCE_PATH="${RUNNER_TEMP}/gh-aw" GH_AW_CHROOT_IDENTITY_HOME="${RUNNER_TEMP}/gh-aw/home" node "${RUNNER_TEMP}/gh-aw/actions/patch_awf_chroot_config.cjs"
1030
- fi
1031
- GH_AW_TOOL_CACHE_MOUNT=""
1032
- GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"
1033
- if [ -d "$GH_AW_TOOL_CACHE" ]; then
1034
- if [[ "$GH_AW_TOOL_CACHE" != /opt/* ]]; then
1035
- GH_AW_TOOL_CACHE_MOUNT="$GH_AW_TOOL_CACHE:$GH_AW_TOOL_CACHE:ro"
1036
- fi
1037
- fi
1038
- # shellcheck disable=SC1003,SC2016,SC2086
783
+ trap 'gh_aw_exit_code=$?; mkdir -p /tmp/gh-aw >/dev/null 2>&1 || true; printf "%s" "$gh_aw_exit_code" > /tmp/gh-aw/agent_execution_exit_code.txt || true; if [ "$gh_aw_exit_code" -ne 0 ]; then echo "::error::Agent execution exited with code $gh_aw_exit_code"; fi' EXIT
1039
784
  mkdir -p "/tmp/gh-aw"
1040
785
  evidence_tmp="/tmp/gh-aw/agent_execution.json.tmp"
1041
786
  printf '{"version":1,"component":"agent","run_id":%s,"run_attempt":%s,"state":"started"}\n' "$GITHUB_RUN_ID" "$GITHUB_RUN_ATTEMPT" > "$evidence_tmp"
1042
787
  mv "$evidence_tmp" "/tmp/gh-aw/agent_execution.json"
1043
788
  export GH_AW_AWF_EXECUTION_COMPONENT="agent"
1044
789
  export GH_AW_AWF_EXECUTION_EVIDENCE_FILE="/tmp/gh-aw/agent_execution.json"
1045
- GH_AW_AWF_ENGINE_NAME=copilot \
1046
- GH_AW_AWF_HARNESS_MARKER='[copilot-harness]' \
1047
- GH_AW_AWF_LOG_FILE=/tmp/gh-aw/agent-stdio.log \
1048
- GH_AW_AWF_ATTEMPT_LOG_NAME=copilot \
1049
- bash "${RUNNER_TEMP}/gh-aw/actions/run_awf_with_startup_retries.sh" -- \
1050
- 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_ENGINE_STEP_TIMEOUT_MINUTES:+--agent-timeout "$GH_AW_ENGINE_STEP_TIMEOUT_MINUTES"} ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} --env-all --exclude-env ACTIONS_ID_TOKEN_REQUEST_TOKEN --exclude-env ACTIONS_ID_TOKEN_REQUEST_URL --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GH_AW_OTLP_ALL_HEADERS --exclude-env GH_AW_OTLP_ENDPOINTS --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_AGENT_ID --exclude-env OTEL_EXPORTER_OTLP_ENDPOINT --exclude-env OTEL_EXPORTER_OTLP_HEADERS --mount /tmp/gh-aw:/tmp/gh-aw:rw --log-level info --session-state-dir /tmp/gh-aw/sandbox/agent/session-state --skip-pull \
1051
- -- /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"; GH_AW_TOOL_BINS="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr "\n" ":")"; GH_AW_TOOL_BINS="${GH_AW_TOOL_BINS%:}"; export PATH="$PATH${GH_AW_TOOL_BINS:+:}$GH_AW_TOOL_BINS"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/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" "${RUNNER_TEMP}/gh-aw/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-tool github --allow-tool safeoutputs --allow-tool '\''shell(cat)'\'' --allow-tool '\''shell(date)'\'' --allow-tool '\''shell(echo)'\'' --allow-tool '\''shell(find)'\'' --allow-tool '\''shell(git:*)'\'' --allow-tool '\''shell(github:*)'\'' --allow-tool '\''shell(grep)'\'' --allow-tool '\''shell(head)'\'' --allow-tool '\''shell(ls)'\'' --allow-tool '\''shell(node)'\'' --allow-tool '\''shell(npm:*)'\'' --allow-tool '\''shell(npx:*)'\'' --allow-tool '\''shell(printf)'\'' --allow-tool '\''shell(pwd)'\'' --allow-tool '\''shell(rg)'\'' --allow-tool '\''shell(safeoutputs:*)'\'' --allow-tool '\''shell(sort)'\'' --allow-tool '\''shell(tail)'\'' --allow-tool '\''shell(uniq)'\'' --allow-tool '\''shell(wc)'\'' --allow-tool '\''shell(yq)'\'' --allow-tool write --deny-tool workflow --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt'
790
+ export no_proxy="${NO_PROXY:-}"
791
+ printf '%s' "$(date +%s%3N)" > /tmp/gh-aw/agent_cli_start_ms.txt
792
+ cd "${GITHUB_WORKSPACE}" && node tools/src/packages/sdlc/src/opencode-execute.mjs "$(cat /tmp/gh-aw/aw-prompts/prompt.txt)" 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log
1052
793
  env:
1053
- AWF_REFLECT_ENABLED: 1
1054
- COPILOT_AGENT_RUNNER_TYPE: STANDALONE
1055
- COPILOT_DUMMY_BYOK: dummy-byok-key-for-offline-mode
1056
- COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
1057
- COPILOT_MODEL: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || vars.GH_AW_DEFAULT_MODEL_COPILOT || 'auto' }}
1058
794
  GH_AW_ADMISSION_MAX_AI_CREDITS: ${{ needs.activation.outputs.admission-max-ai-credits }}
1059
795
  GH_AW_ADMISSION_RESULT: ${{ needs.activation.outputs.admission-result }}
1060
- GH_AW_ENGINE_STEP_TIMEOUT_MINUTES: ${{ fromJSON(vars.GH_AW_DEFAULT_TIMEOUT_MINUTES || '20') }}
1061
- GH_AW_LLM_PROVIDER: github
796
+ GH_AW_ENGINE_VERSION: 2.1.0
1062
797
  GH_AW_MAX_AI_CREDITS: ${{ vars.GH_AW_DEFAULT_MAX_AI_CREDITS || '1000' }}
1063
798
  GH_AW_MAX_TURNS: ${{ vars.GH_AW_DEFAULT_MAX_TURNS || '' }}
1064
- GH_AW_PHASE: agent
1065
799
  GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
1066
800
  GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
1067
- GH_AW_TIMEOUT_MINUTES: ${{ fromJSON(vars.GH_AW_DEFAULT_TIMEOUT_MINUTES || '20') }}
1068
- GH_AW_VERSION: v0.93.2
1069
- GITHUB_API_URL: ${{ github.api_url }}
1070
- GITHUB_AW: true
1071
- GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows
1072
- GITHUB_COPILOT_PROMPT_MODE_EXTENSIONS: false
1073
- GITHUB_HEAD_REF: ${{ github.head_ref }}
1074
- GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
1075
- GITHUB_REF_NAME: ${{ github.ref_name }}
1076
- GITHUB_SERVER_URL: ${{ github.server_url }}
1077
- GITHUB_STEP_SUMMARY: /tmp/gh-aw/agent-step-summary.md
1078
801
  GITHUB_WORKSPACE: ${{ github.workspace }}
1079
- GIT_AUTHOR_EMAIL: github-actions[bot]@users.noreply.github.com
1080
- GIT_AUTHOR_NAME: github-actions[bot]
1081
- GIT_COMMITTER_EMAIL: github-actions[bot]@users.noreply.github.com
1082
- GIT_COMMITTER_NAME: github-actions[bot]
802
+ NO_PROXY: localhost,127.0.0.1,host.docker.internal,host.docker.internal:10000,host.docker.internal:10001,host.docker.internal:10002,host.docker.internal:10003,172.30.0.30,172.30.0.30:10000,172.30.0.30:10001,172.30.0.30:10002,172.30.0.30:10003
1083
803
  RUNNER_TEMP: ${{ runner.temp }}
1084
804
  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) || '' }}
1085
- - name: Log GitHub rate limits at agent end
1086
- if: always()
1087
- continue-on-error: true
1088
- uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
1089
- with:
1090
- github-token: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
1091
- script: |
1092
- const path = require('path');
1093
- const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
1094
- const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs'));
1095
- setupGlobals(core, github, context, exec, io, getOctokit);
1096
- const { fetchAndLogRateLimit } = require(path.join(actionsDir, 'github_rate_limit_logger.cjs'));
1097
- await fetchAndLogRateLimit(github, 'agent_end', true);
1098
- - name: Detect agent errors
1099
- if: always()
1100
- id: detect-agent-errors
1101
- continue-on-error: true
1102
- env:
1103
- GH_AW_AGENTIC_EXECUTION_OUTCOME: ${{ steps.agentic_execution.outcome }}
1104
- GH_AW_ENGINE_STEP_TIMEOUT_MINUTES: ${{ fromJSON(vars.GH_AW_DEFAULT_TIMEOUT_MINUTES || '20') }}
1105
- uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
1106
- with:
1107
- script: |
1108
- const path = require('path');
1109
- const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
1110
- const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs'));
1111
- setupGlobals(core, github, context, exec, io, getOctokit);
1112
- const { main } = require(path.join(actionsDir, 'detect_agent_errors.cjs'));
1113
- await main();
1114
805
  - name: Configure Git credentials
1115
806
  env:
1116
807
  GITHUB_REPOSITORY: ${{ github.repository }}
1117
808
  GITHUB_SERVER_URL: ${{ github.server_url }}
1118
809
  GITHUB_TOKEN: ${{ github.token }}
1119
810
  run: bash "${RUNNER_TEMP}/gh-aw/actions/configure_git_credentials.sh"
1120
- - name: Copy Copilot session state files to logs
1121
- if: always()
1122
- continue-on-error: true
1123
- run: bash "${RUNNER_TEMP}/gh-aw/actions/copy_copilot_session_state.sh"
1124
811
  - name: Stop MCP Gateway
1125
812
  if: always()
1126
813
  continue-on-error: true
@@ -1143,10 +830,7 @@ jobs:
1143
830
  const { main } = require(path.join(actionsDir, 'redact_secrets.cjs'));
1144
831
  await main();
1145
832
  env:
1146
- GH_AW_SECRET_NAMES: 'COPILOT_GITHUB_TOKEN,GH_AW_GITHUB_MCP_SERVER_TOKEN,GH_AW_GITHUB_TOKEN,GITHUB_TOKEN'
1147
- SECRET_COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
1148
- SECRET_GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }}
1149
- SECRET_GH_AW_GITHUB_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN }}
833
+ GH_AW_SECRET_NAMES: 'GITHUB_TOKEN'
1150
834
  SECRET_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
1151
835
  - name: Append agent step summary
1152
836
  if: always()
@@ -1164,7 +848,6 @@ jobs:
1164
848
  uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
1165
849
  env:
1166
850
  GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
1167
- GH_AW_ALLOWED_DOMAINS: "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,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,s.symcb.com,s.symcd.com,security.ubuntu.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.googleapis.com"
1168
851
  GITHUB_SERVER_URL: ${{ github.server_url }}
1169
852
  GITHUB_API_URL: ${{ github.api_url }}
1170
853
  with:
@@ -1179,7 +862,7 @@ jobs:
1179
862
  if: always()
1180
863
  uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
1181
864
  env:
1182
- GH_AW_AGENT_OUTPUT: /tmp/gh-aw/sandbox/agent/logs/
865
+ GH_AW_AGENT_OUTPUT: /tmp/gh-aw/agent-stdio.log
1183
866
  GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
1184
867
  with:
1185
868
  script: |
@@ -1187,7 +870,7 @@ jobs:
1187
870
  const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
1188
871
  const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs'));
1189
872
  setupGlobals(core, github, context, exec, io, getOctokit);
1190
- const { main } = require(path.join(actionsDir, 'parse_copilot_log.cjs'));
873
+ const { main } = require(path.join(actionsDir, 'opencode_log_parser.cjs'));
1191
874
  await main();
1192
875
  - name: Parse MCP Gateway logs for step summary
1193
876
  if: always()
@@ -1201,37 +884,6 @@ jobs:
1201
884
  setupGlobals(core, github, context, exec, io, getOctokit);
1202
885
  const { main } = require(path.join(actionsDir, 'parse_mcp_gateway_log.cjs'));
1203
886
  await main();
1204
- - name: Print firewall logs
1205
- if: always()
1206
- continue-on-error: true
1207
- env:
1208
- AWF_LOGS_DIR: /tmp/gh-aw/sandbox/firewall/logs
1209
- run: bash "${RUNNER_TEMP}/gh-aw/actions/print_firewall_logs.sh" --rootless
1210
- - name: Parse token usage for step summary
1211
- if: always()
1212
- id: parse-token-usage
1213
- continue-on-error: true
1214
- uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
1215
- with:
1216
- script: |
1217
- const path = require('path');
1218
- const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
1219
- const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs'));
1220
- setupGlobals(core, github, context, exec, io, getOctokit);
1221
- const { main } = require(path.join(actionsDir, 'parse_token_usage.cjs'));
1222
- await main();
1223
- - name: Print AWF reflect summary
1224
- if: always()
1225
- continue-on-error: true
1226
- uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
1227
- with:
1228
- script: |
1229
- const path = require('path');
1230
- const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
1231
- const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs'));
1232
- setupGlobals(core, github, context, exec, io, getOctokit);
1233
- const { main } = require(path.join(actionsDir, 'awf_reflect_summary.cjs'));
1234
- await main();
1235
887
  - name: Generate observability summary
1236
888
  if: always()
1237
889
  uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
@@ -1249,34 +901,25 @@ jobs:
1249
901
  if [ ! -f /tmp/gh-aw/agent_output.json ]; then
1250
902
  echo '{"items":[]}' > /tmp/gh-aw/agent_output.json
1251
903
  fi
904
+ - name: Validate the Lighthouse result
905
+ run: node tools/src/packages/sdlc/src/completion-actions.mjs validate
1252
906
  - if: always()
1253
- name: Preserve the stage result
1254
- run: |
1255
- set -euo pipefail
1256
- mkdir -p "$GITHUB_WORKSPACE/.lighthouse/gh-aw"
1257
- result=/tmp/gh-aw/agent/stage-result.json
1258
- if [ -f "$result" ]; then
1259
- cp "$result" "$GITHUB_WORKSPACE/.lighthouse/gh-aw/stage-result.json"
1260
- else
1261
- echo "::error::The worker did not produce /tmp/gh-aw/agent/stage-result.json"
1262
- exit 1
1263
- fi
1264
- shell: bash
1265
- - env:
1266
- EXPECTED_RUN_ID: ${{ inputs.run-id }}
1267
- EXPECTED_STAGE: ${{ env.LIGHTHOUSE_STAGE }}
1268
- RESULT_FILE: /tmp/gh-aw/agent/stage-result.json
1269
- if: always()
1270
- name: Require completion of the dispatched stage
1271
- run: "set -euo pipefail\nnode node_modules/@juangcarmona/lighthouse-sdlc/src/sdlc.mjs stage-result --input \"$RESULT_FILE\" \\\n --require-complete --stage \"$EXPECTED_STAGE\" --run-id \"$EXPECTED_RUN_ID\" --format json\n"
1272
- shell: bash
907
+ name: Preserve the result and runtime receipt
908
+ uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
909
+ with:
910
+ if-no-files-found: error
911
+ name: lighthouse-result-${{ inputs.issue }}-${{ github.run_attempt }}
912
+ path: |
913
+ ${{ runner.temp }}/lighthouse-${{ github.run_id }}-${{ github.run_attempt }}/envelope.json
914
+ ${{ runner.temp }}/lighthouse-${{ github.run_id }}-${{ github.run_attempt }}/runtime.json
915
+ retention-days: ${{ vars.GH_AW_DEFAULT_ARTIFACT_RETENTION_DAYS || '14' }}
1273
916
  - if: always()
1274
- name: Upload stage evidence
917
+ name: Preserve OpenCode diagnostic events
1275
918
  uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
1276
919
  with:
1277
- if-no-files-found: warn
1278
- name: lighthouse-sdlc-${{ inputs.run-id }}-${{ env.LIGHTHOUSE_STAGE }}
1279
- path: ${{ github.workspace }}/.lighthouse/gh-aw/stage-result.json
920
+ if-no-files-found: ignore
921
+ name: opencode-events-${{ inputs.issue }}-${{ github.run_attempt }}
922
+ path: ${{ runner.temp }}/gh-aw/opencode-events-${{ github.run_id }}-${{ github.run_attempt }}.jsonl
1280
923
  retention-days: ${{ vars.GH_AW_DEFAULT_ARTIFACT_RETENTION_DAYS || '14' }}
1281
924
 
1282
925
  # Small dedicated copy of the agent output so safe-output processing
@@ -1301,7 +944,6 @@ jobs:
1301
944
  /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/model-routing.jsonl
1302
945
  /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl
1303
946
  /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/model-routing.jsonl
1304
- /tmp/gh-aw/awf-resolved-config.json
1305
947
  if-no-files-found: ignore
1306
948
  retention-days: ${{ vars.GH_AW_DEFAULT_ARTIFACT_RETENTION_DAYS || '0' }}
1307
949
  - name: Upload agent artifacts
@@ -1319,14 +961,7 @@ jobs:
1319
961
  /tmp/gh-aw/aw-prompts/user.txt
1320
962
  /tmp/gh-aw/aw-prompts/system.txt
1321
963
  /tmp/gh-aw/skill_inventory.json
1322
- /tmp/gh-aw/sandbox/agent/logs/
1323
- /tmp/gh-aw/redacted-urls.log
1324
964
  /tmp/gh-aw/mcp-logs/
1325
- /tmp/gh-aw/agent_usage.json
1326
- /tmp/gh-aw/runtime/aw_info.json
1327
- /tmp/gh-aw/agent_usage.jsonl
1328
- /tmp/gh-aw/agent/model-endpoint-mismatch.json
1329
- /tmp/gh-aw/agent/model-resolution.json
1330
965
  /tmp/gh-aw/agent-stdio.log
1331
966
  /tmp/gh-aw/pre-agent-audit.txt
1332
967
  /tmp/gh-aw/github_rate_limits.jsonl
@@ -1334,13 +969,6 @@ jobs:
1334
969
  /tmp/gh-aw/otlp-export-errors.jsonl
1335
970
  /tmp/gh-aw/safeoutputs.jsonl
1336
971
  /tmp/gh-aw/agent_output.json
1337
- /tmp/gh-aw/aw-*.patch
1338
- /tmp/gh-aw/aw-*.bundle
1339
- /tmp/gh-aw/awf-config.json
1340
- /tmp/gh-aw/awf-resolved-config.json
1341
- /tmp/gh-aw/sandbox/firewall/logs/
1342
- /tmp/gh-aw/sandbox/firewall/audit/
1343
- /tmp/gh-aw/sandbox/firewall/awf-reflect.json
1344
972
  if-no-files-found: ignore
1345
973
  retention-days: ${{ vars.GH_AW_DEFAULT_ARTIFACT_RETENTION_DAYS || '0' }}
1346
974
 
@@ -1349,13 +977,13 @@ jobs:
1349
977
  needs:
1350
978
  - activation
1351
979
  - agent
1352
- - detection
1353
- - safe_outputs
980
+ - prepare
981
+ - publish
1354
982
  if: >
1355
983
  always() && (needs.agent.result != 'skipped' || needs.activation.outputs.lockdown_check_failed == 'true' ||
1356
984
  needs.activation.outputs.oauth_token_check_failed == 'true' || needs.activation.outputs.stale_lock_file_failed == 'true' ||
1357
- needs.activation.outputs.secret_verification_result == 'failed' || needs.activation.outputs.daily_ai_credits_exceeded == 'true' ||
1358
- needs.activation.outputs.daily_ai_credits_guardrail_status == 'structural_error' || needs.activation.outputs.daily_ai_credits_guardrail_status == 'transient_error')
985
+ needs.activation.outputs.daily_ai_credits_exceeded == 'true' || needs.activation.outputs.daily_ai_credits_guardrail_status == 'structural_error' ||
986
+ needs.activation.outputs.daily_ai_credits_guardrail_status == 'transient_error')
1359
987
  runs-on: ubuntu-24.04
1360
988
  # Permissions for the conclusion job (workflow permissions default to none).
1361
989
  permissions:
@@ -1366,16 +994,13 @@ jobs:
1366
994
  cancel-in-progress: false
1367
995
  queue: max
1368
996
  env:
1369
- GH_AW_JOB_DISPLAY_NAMES: "{\"activation\":\"activation\",\"agent\":\"agent\",\"conclusion\":\"conclusion\",\"detection\":\"detection\",\"pre_activation\":\"pre_activation\",\"safe_outputs\":\"safe_outputs\"}"
1370
- GH_AW_JOB_RESULTS: "{\"activation\":{\"result\":\"${{ needs.activation.result }}\"},\"agent\":{\"result\":\"${{ needs.agent.result }}\"},\"detection\":{\"result\":\"${{ needs.detection.result }}\"},\"safe_outputs\":{\"result\":\"${{ needs.safe_outputs.result }}\"}}"
1371
- GH_AW_JOB_TIMING_ELIGIBLE: "{\"activation\":true,\"agent\":true,\"conclusion\":true,\"detection\":true,\"pre_activation\":true,\"safe_outputs\":true}"
997
+ GH_AW_JOB_DISPLAY_NAMES: "{\"activation\":\"activation\",\"agent\":\"agent\",\"conclusion\":\"conclusion\",\"pre_activation\":\"pre_activation\",\"prepare\":\"Verify accepted commit, checks and evidence protection\",\"publish\":\"Validate, publish and release\"}"
998
+ GH_AW_JOB_RESULTS: "{\"activation\":{\"result\":\"${{ needs.activation.result }}\"},\"agent\":{\"result\":\"${{ needs.agent.result }}\"},\"prepare\":{\"result\":\"${{ needs.prepare.result }}\"},\"publish\":{\"result\":\"${{ needs.publish.result }}\"}}"
999
+ GH_AW_JOB_TIMING_ELIGIBLE: "{\"activation\":true,\"agent\":true,\"conclusion\":true,\"pre_activation\":true,\"prepare\":true,\"publish\":true}"
1372
1000
  GH_AW_RUNTIME_FEATURES: ${{ vars.GH_AW_RUNTIME_FEATURES }}
1373
1001
  outputs:
1374
- incomplete_count: ${{ steps.report_incomplete.outputs.incomplete_count }}
1375
1002
  noop_comment_body: ${{ steps.noop.outputs.noop_comment_body }}
1376
1003
  noop_message: ${{ steps.noop.outputs.noop_message }}
1377
- tools_reported: ${{ steps.missing_tool.outputs.tools_reported }}
1378
- total_count: ${{ steps.missing_tool.outputs.total_count }}
1379
1004
  steps:
1380
1005
  - name: Setup Scripts
1381
1006
  id: setup
@@ -1388,9 +1013,8 @@ jobs:
1388
1013
  env:
1389
1014
  GH_AW_SETUP_WORKFLOW_NAME: "Lighthouse SDLC review"
1390
1015
  GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/lighthouse-sdlc-review.lock.yml@${{ github.ref }}
1391
- GH_AW_INFO_VERSION: "1.0.101"
1392
- GH_AW_INFO_AWF_VERSION: "v0.28.70"
1393
- GH_AW_INFO_ENGINE_ID: "copilot"
1016
+ GH_AW_INFO_VERSION: "2.1.0"
1017
+ GH_AW_INFO_ENGINE_ID: "opencode"
1394
1018
  GH_AW_SETUP_AW_CONTEXT: ${{ inputs.aw_context }}
1395
1019
  - name: Download agent output artifact
1396
1020
  id: download-agent-output
@@ -1409,20 +1033,6 @@ jobs:
1409
1033
  if [ -f "/tmp/gh-aw/agent_output.json" ]; then
1410
1034
  echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT"
1411
1035
  fi
1412
- - name: Restore runtime model metadata
1413
- if: always()
1414
- run: |
1415
- if [ -f /tmp/gh-aw/runtime/aw_info.json ]; then cp /tmp/gh-aw/runtime/aw_info.json /tmp/gh-aw/aw_info.json; fi
1416
- - name: Warn if threat detection produced no verdict
1417
- if: always() && needs.detection.result != 'skipped' && (needs.detection.outputs.detection_reason == 'agent_failure' || needs.detection.outputs.detection_reason == 'parse_error' || needs.detection.outputs.detection_conclusion == '')
1418
- run: echo "::warning::Threat detection produced no security verdict. Review the detection job logs before trusting the agent outputs."
1419
- - name: Download detection artifact
1420
- id: download-detection-artifact
1421
- continue-on-error: true
1422
- uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
1423
- with:
1424
- name: ${{ needs.activation.outputs.artifact_prefix }}detection
1425
- path: /tmp/gh-aw/threat-detection/
1426
1036
  - name: Download Safe Outputs Items Manifest
1427
1037
  id: download-safe-outputs-manifest
1428
1038
  if: always()
@@ -1437,16 +1047,16 @@ jobs:
1437
1047
  uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
1438
1048
  env:
1439
1049
  GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
1440
- GH_AW_NOOP_MAX: "1"
1050
+ GH_AW_NOOP_MAX: "2"
1441
1051
  GH_AW_WORKFLOW_NAME: "Lighthouse SDLC review"
1442
1052
  GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/lighthouse-sdlc-review.md"
1443
- GH_AW_ENGINE_ID: "copilot"
1053
+ GH_AW_ENGINE_ID: "opencode"
1054
+ GH_AW_ENGINE_VERSION: "2.1.0"
1444
1055
  GH_AW_ENGINE_MODEL: ${{ needs.agent.outputs.model }}
1445
1056
  GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
1446
1057
  GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }}
1447
1058
  GH_AW_NOOP_REPORT_AS_ISSUE: "false"
1448
1059
  GH_AW_AIC: ${{ needs.agent.outputs.aic }}
1449
- GH_AW_THREAT_DETECTION_AIC: ${{ needs.detection.outputs.aic }}
1450
1060
  GH_AW_AMBIENT_CONTEXT: ${{ needs.agent.outputs.ambient_context }}
1451
1061
  GH_AW_WORKFLOW_ID: "lighthouse-sdlc-review"
1452
1062
  with:
@@ -1458,63 +1068,6 @@ jobs:
1458
1068
  setupGlobals(core, github, context, exec, io, getOctokit);
1459
1069
  const { main } = require(path.join(actionsDir, 'handle_noop_message.cjs'));
1460
1070
  await main();
1461
- - name: Log detection run
1462
- id: detection_runs
1463
- uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
1464
- env:
1465
- GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
1466
- GH_AW_WORKFLOW_NAME: "Lighthouse SDLC review"
1467
- GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/lighthouse-sdlc-review.md"
1468
- GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
1469
- GH_AW_DETECTION_CONCLUSION: ${{ needs.detection.outputs.detection_conclusion }}
1470
- GH_AW_DETECTION_REASON: ${{ needs.detection.outputs.detection_reason }}
1471
- with:
1472
- github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
1473
- script: |
1474
- const path = require('path');
1475
- const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
1476
- const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs'));
1477
- setupGlobals(core, github, context, exec, io, getOctokit);
1478
- const { main } = require(path.join(actionsDir, 'handle_detection_runs.cjs'));
1479
- await main();
1480
- - name: Record missing tool
1481
- id: missing_tool
1482
- uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
1483
- env:
1484
- GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
1485
- GH_AW_MISSING_TOOL_CREATE_ISSUE: "true"
1486
- GH_AW_WORKFLOW_NAME: "Lighthouse SDLC review"
1487
- GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/lighthouse-sdlc-review.md"
1488
- GH_AW_ENGINE_ID: "copilot"
1489
- GH_AW_ENGINE_MODEL: ${{ needs.agent.outputs.model }}
1490
- with:
1491
- github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
1492
- script: |
1493
- const path = require('path');
1494
- const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
1495
- const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs'));
1496
- setupGlobals(core, github, context, exec, io, getOctokit);
1497
- const { main } = require(path.join(actionsDir, 'missing_tool.cjs'));
1498
- await main();
1499
- - name: Record incomplete
1500
- id: report_incomplete
1501
- uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
1502
- env:
1503
- GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
1504
- GH_AW_REPORT_INCOMPLETE_CREATE_ISSUE: "true"
1505
- GH_AW_WORKFLOW_NAME: "Lighthouse SDLC review"
1506
- GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/lighthouse-sdlc-review.md"
1507
- GH_AW_ENGINE_ID: "copilot"
1508
- GH_AW_ENGINE_MODEL: ${{ needs.agent.outputs.model }}
1509
- with:
1510
- github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
1511
- script: |
1512
- const path = require('path');
1513
- const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
1514
- const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs'));
1515
- setupGlobals(core, github, context, exec, io, getOctokit);
1516
- const { main } = require(path.join(actionsDir, 'report_incomplete_handler.cjs'));
1517
- await main();
1518
1071
  - name: Handle agent failure
1519
1072
  id: handle_agent_failure
1520
1073
  if: always()
@@ -1527,29 +1080,12 @@ jobs:
1527
1080
  GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }}
1528
1081
  GH_AW_WORKFLOW_ID: "lighthouse-sdlc-review"
1529
1082
  GH_AW_ACTION_FAILURE_ISSUE_EXPIRES_HOURS: "0"
1530
- GH_AW_ENGINE_ID: "copilot"
1531
- GH_AW_SECRET_VERIFICATION_RESULT: ${{ needs.activation.outputs.secret_verification_result }}
1532
- GH_AW_ENGINE_SECRET_FAILURE_MESSAGE: "**Alternative**: If your organization has a Copilot subscription, you can avoid the need for a personal access token by adding a top-level `permissions` block to your workflow file. This enables Copilot inference through the org using the built-in GitHub Actions token.\n\n```yaml\npermissions:\n copilot-requests: write\n```\n\nSee: https://github.github.com/gh-aw/reference/engines/#github-copilot-default"
1533
- GH_AW_CHECKOUT_PR_SUCCESS: ${{ needs.agent.outputs.checkout_pr_success }}
1534
- GH_AW_CHECKOUT_PR_INVALIDATED: ${{ needs.agent.outputs.checkout_pr_invalidated }}
1083
+ GH_AW_ENGINE_ID: "opencode"
1535
1084
  GH_AW_AI_CREDITS_RATE_LIMIT_ERROR: ${{ needs.agent.outputs.ai_credits_rate_limit_error || 'false' }}
1536
1085
  GH_AW_UNKNOWN_MODEL_AI_CREDITS: ${{ needs.agent.outputs.unknown_model_ai_credits || 'false' }}
1537
1086
  GH_AW_AIC: ${{ needs.agent.outputs.aic }}
1538
- GH_AW_THREAT_DETECTION_AIC: ${{ needs.detection.outputs.aic }}
1539
- GH_AW_DETECTION_JOB_RESULT: ${{ needs.detection.result }}
1540
1087
  GH_AW_MAX_AI_CREDITS: ${{ vars.GH_AW_DEFAULT_MAX_AI_CREDITS || '1000' }}
1541
- GH_AW_DEFAULT_CHECKOUT_USES_TRIGGER_REF: "true"
1542
- GH_AW_INFERENCE_ACCESS_ERROR: ${{ needs.agent.outputs.inference_access_error }}
1543
- GH_AW_MCP_POLICY_ERROR: ${{ needs.agent.outputs.mcp_policy_error }}
1544
- GH_AW_AGENTIC_ENGINE_TIMEOUT: ${{ needs.agent.outputs.agentic_engine_timeout }}
1545
- GH_AW_MODEL_NOT_SUPPORTED_ERROR: ${{ needs.agent.outputs.model_not_supported_error }}
1546
- GH_AW_MODEL_ENDPOINT_MISMATCH_ERROR: ${{ needs.agent.outputs.model_endpoint_mismatch_error }}
1547
- GH_AW_HTTP_400_RESPONSE_ERROR: ${{ needs.agent.outputs.http_400_response_error }}
1548
- GH_AW_MAX_CACHE_MISSES_EXCEEDED: ${{ needs.agent.outputs.max_cache_misses_exceeded }}
1549
- GH_AW_MISSING_MODEL_PRICING_ERROR: ${{ needs.agent.outputs.missing_model_pricing_error }}
1550
- GH_AW_MISSING_MODEL_PRICING_MODEL_NAME: ${{ needs.agent.outputs.missing_model_pricing_model_name }}
1551
- GH_AW_SHELL_EXPANSION_GUARD_REJECTED: ${{ needs.agent.outputs.shell_expansion_guard_rejected }}
1552
- GH_AW_ENGINE_API_HOSTS: "api.enterprise.githubcopilot.com,api.githubcopilot.com,api.business.githubcopilot.com,api.individual.githubcopilot.com"
1088
+ GH_AW_DEFAULT_CHECKOUT_USES_TRIGGER_REF: "false"
1553
1089
  GH_AW_LOCKDOWN_CHECK_FAILED: ${{ needs.activation.outputs.lockdown_check_failed }}
1554
1090
  GH_AW_OAUTH_TOKEN_CHECK_FAILED: ${{ needs.activation.outputs.oauth_token_check_failed }}
1555
1091
  GH_AW_STALE_LOCK_FILE_FAILED: ${{ needs.activation.outputs.stale_lock_file_failed }}
@@ -1564,7 +1100,7 @@ jobs:
1564
1100
  GH_AW_FAILURE_REPORT_AS_ISSUE: "false"
1565
1101
  GH_AW_MISSING_TOOL_REPORT_AS_FAILURE: "true"
1566
1102
  GH_AW_MISSING_DATA_REPORT_AS_FAILURE: "true"
1567
- GH_AW_TIMEOUT_MINUTES: "${{ fromJSON(vars.GH_AW_DEFAULT_TIMEOUT_MINUTES || '20') }}"
1103
+ GH_AW_TIMEOUT_MINUTES: "15"
1568
1104
  with:
1569
1105
  github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
1570
1106
  script: |
@@ -1596,10 +1132,6 @@ jobs:
1596
1132
  - name: Collect usage artifact files
1597
1133
  if: always()
1598
1134
  continue-on-error: true
1599
- env:
1600
- GH_AW_DETECTION_JOB_RESULT: ${{ needs.detection.result }}
1601
- GH_AW_DETECTION_CONCLUSION: ${{ needs.detection.outputs.detection_conclusion }}
1602
- GH_AW_DETECTION_REASON: ${{ needs.detection.outputs.detection_reason }}
1603
1135
  run: bash "${RUNNER_TEMP}/gh-aw/actions/collect_usage_artifact_files.sh"
1604
1136
  - name: Generate usage activity summary and unified session
1605
1137
  if: always()
@@ -1695,359 +1227,9 @@ jobs:
1695
1227
  overwrite: true
1696
1228
  retention-days: ${{ vars.GH_AW_DEFAULT_ARTIFACT_RETENTION_DAYS || '0' }}
1697
1229
 
1698
- detection:
1699
- name: detection
1700
- needs:
1701
- - activation
1702
- - agent
1703
- if: always() && needs.agent.result != 'skipped'
1704
- runs-on: ubuntu-latest
1705
- # Permissions for the detection job (workflow permissions default to none).
1706
- permissions:
1707
- contents: read
1708
- timeout-minutes: 10
1709
- env:
1710
- GH_AW_RUNTIME_FEATURES: ${{ vars.GH_AW_RUNTIME_FEATURES }}
1711
- outputs:
1712
- aic: ${{ steps.parse_detection_token_usage.outputs.aic }}
1713
- detection_conclusion: ${{ steps.detection_conclusion.outputs.conclusion }}
1714
- detection_reason: ${{ steps.detection_conclusion.outputs.reason }}
1715
- detection_success: ${{ steps.detection_conclusion.outputs.success }}
1716
- run_detection: ${{ steps.detection_guard.outputs.run_detection }}
1717
- steps:
1718
- - name: Setup Scripts
1719
- id: setup
1720
- uses: github/gh-aw-actions/setup@d9128eb3ea40c18b77c76184eda03c0ff2608d79 # v0.93.2
1721
- with:
1722
- destination: ${{ runner.temp }}/gh-aw/actions
1723
- job-name: ${{ github.job }}
1724
- trace-id: ${{ needs.activation.outputs.setup-trace-id }}
1725
- parent-span-id: ${{ needs.activation.outputs.setup-parent-span-id || needs.activation.outputs.setup-span-id }}
1726
- env:
1727
- GH_AW_SETUP_WORKFLOW_NAME: "Lighthouse SDLC review"
1728
- GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/lighthouse-sdlc-review.lock.yml@${{ github.ref }}
1729
- GH_AW_INFO_VERSION: "1.0.101"
1730
- GH_AW_INFO_AWF_VERSION: "v0.28.70"
1731
- GH_AW_INFO_ENGINE_ID: "copilot"
1732
- GH_AW_SETUP_AW_CONTEXT: ${{ inputs.aw_context }}
1733
- - name: Download activation artifact
1734
- continue-on-error: true
1735
- uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
1736
- with:
1737
- name: ${{ needs.activation.outputs.artifact_prefix }}activation
1738
- path: /tmp/gh-aw
1739
- - name: Download agent output artifact
1740
- id: download-agent-output
1741
- continue-on-error: true
1742
- uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
1743
- with:
1744
- pattern: "{${{ needs.agent.outputs.artifact_prefix }}agent,${{ needs.agent.outputs.artifact_prefix }}agent-output-fallback}"
1745
- merge-multiple: true
1746
- path: /tmp/gh-aw/
1747
- - name: Setup agent output environment variable
1748
- id: setup-agent-output-env
1749
- if: steps.download-agent-output.outcome == 'success'
1750
- run: |
1751
- mkdir -p /tmp/gh-aw/
1752
- find "/tmp/gh-aw/" -type f -print
1753
- if [ -f "/tmp/gh-aw/agent_output.json" ]; then
1754
- echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT"
1755
- fi
1756
- - name: Checkout repository for patch context
1757
- if: needs.agent.outputs.has_patch == 'true'
1758
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
1759
- with:
1760
- persist-credentials: false
1761
- # --- Threat Detection ---
1762
- - name: Initialize detection execution evidence
1763
- run: |
1764
- mkdir -p "/tmp/gh-aw/threat-detection"
1765
- evidence_tmp="/tmp/gh-aw/threat-detection/execution.json.tmp"
1766
- printf '{"version":1,"component":"detection","run_id":%s,"run_attempt":%s,"state":"not_started"}\n' "$GITHUB_RUN_ID" "$GITHUB_RUN_ATTEMPT" > "$evidence_tmp"
1767
- mv "$evidence_tmp" "/tmp/gh-aw/threat-detection/execution.json"
1768
- - name: Clear inherited Copilot session state
1769
- run: rm -rf /tmp/gh-aw/sandbox/agent/logs/copilot-session-state
1770
- - name: Clean stale firewall files from agent artifact
1771
- run: |
1772
- rm -rf /tmp/gh-aw/sandbox/firewall/logs
1773
- rm -rf /tmp/gh-aw/sandbox/firewall/audit
1774
- - name: Download container images
1775
- run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.28.70@sha256:b15ab48cbbab02904eb9bbd359a398db59690eebbea1e6934d47ed2bb407dd34 ghcr.io/github/gh-aw-firewall/api-proxy:0.28.70@sha256:9ac8f9c7294e892c916de3da9d2588dfd8cd4931e5c39b00143266d7ed9fd52a ghcr.io/github/gh-aw-firewall/squid:0.28.70@sha256:b5bc53f4becfd96e926e63c83831f1b3c9512f713c83161d2b8c9b7204b3e917
1776
- - name: Check if detection needed
1777
- id: detection_guard
1778
- if: always()
1779
- env:
1780
- OUTPUT_TYPES: ${{ needs.agent.outputs.output_types }}
1781
- HAS_PATCH: ${{ needs.agent.outputs.has_patch }}
1782
- run: |
1783
- if [[ -n "$OUTPUT_TYPES" || "$HAS_PATCH" == "true" ]]; then
1784
- echo "run_detection=true" >> "$GITHUB_OUTPUT"
1785
- echo "Detection will run: output_types=$OUTPUT_TYPES, has_patch=$HAS_PATCH"
1786
- else
1787
- echo "run_detection=false" >> "$GITHUB_OUTPUT"
1788
- echo "Detection skipped: no agent outputs or patches to analyze"
1789
- fi
1790
- - name: Clear MCP Config for detection
1791
- if: always() && steps.detection_guard.outputs.run_detection == 'true'
1792
- run: |
1793
- rm -f "${RUNNER_TEMP}/gh-aw/mcp-config/mcp-servers.json"
1794
- rm -f "$HOME/.copilot/mcp-config.json"
1795
- rm -f "$GITHUB_WORKSPACE/.gemini/settings.json"
1796
- - name: Prepare threat detection files
1797
- if: always() && steps.detection_guard.outputs.run_detection == 'true'
1798
- run: |
1799
- bash "${RUNNER_TEMP}/gh-aw/actions/prepare_threat_detection_files.sh"
1800
- - name: Setup threat detection
1801
- id: detection_setup
1802
- if: always() && steps.detection_guard.outputs.run_detection == 'true'
1803
- uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
1804
- env:
1805
- WORKFLOW_NAME: "Lighthouse SDLC review"
1806
- WORKFLOW_DESCRIPTION: "Execute only the Lighthouse review stage and return its declared stage result."
1807
- HAS_PATCH: ${{ needs.agent.outputs.has_patch }}
1808
- GH_AW_DETECTION_CONTINUE_ON_ERROR: "true"
1809
- GH_AW_DETECTION_SKIP_PROMPT_SUMMARY: "true"
1810
- with:
1811
- script: |
1812
- const path = require('path');
1813
- const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
1814
- const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs'));
1815
- setupGlobals(core, github, context, exec, io, getOctokit);
1816
- const { main } = require(path.join(actionsDir, 'setup_threat_detection.cjs'));
1817
- await main();
1818
- - name: Ensure threat-detection directory and log
1819
- if: always() && steps.detection_guard.outputs.run_detection == 'true'
1820
- run: |
1821
- mkdir -p /tmp/gh-aw/threat-detection
1822
- touch /tmp/gh-aw/threat-detection/detection.log
1823
- - name: Install AWF binary
1824
- run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.28.70 --rootless
1825
- - name: Setup Node.js
1826
- uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
1827
- with:
1828
- node-version: '24'
1829
- package-manager-cache: false
1830
- - name: Install GitHub Copilot CLI
1831
- run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.101 --checksums-sha256 018625eac68670d66ede904b9b82cdcd6ab8f87ba20e6e1fbdf0b62c8295d5be --prefer-toolcache
1832
- env:
1833
- GH_HOST: github.com
1834
- GH_AW_COPILOT_MIN_VERSION: 1.0.35
1835
- - name: Install threat-detect binary
1836
- id: threat_detect_install
1837
- if: always() && steps.detection_guard.outputs.run_detection == 'true'
1838
- continue-on-error: true
1839
- run: |
1840
- bash "${RUNNER_TEMP}/gh-aw/actions/install_threat_detect_binary.sh" v0.5.2 --artifact-base-url https://github.com/github/gh-aw-threat-detection/releases/download --sha256-amd64 b4ecda6a8f1ee09913c40b58e5e9d3337d2173618d41b1bfdef9207e4e7959b9 --sha256-arm64 f6260a0f9ad72bcb67c7af19c4ce262ca34e2c3d5ccbf912832a8bd277200904
1841
- - name: Execute threat detection with AWF
1842
- id: detection_agentic_execution
1843
- if: always() && steps.detection_guard.outputs.run_detection == 'true' && steps.detection_setup.outcome == 'success' && steps.detection_setup.outputs.ready == 'true' && steps.threat_detect_install.outcome == 'success'
1844
- continue-on-error: true
1845
- timeout-minutes: 10
1846
- env:
1847
- AWF_REFLECT_ENABLED: 1
1848
- COPILOT_AGENT_RUNNER_TYPE: STANDALONE
1849
- COPILOT_DUMMY_BYOK: dummy-byok-key-for-offline-mode
1850
- COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
1851
- COPILOT_MODEL: ${{ vars.GH_AW_MODEL_DETECTION_COPILOT || vars.GH_AW_DEFAULT_MODEL_COPILOT || 'detection' }}
1852
- GH_AW_ADMISSION_MAX_AI_CREDITS: ${{ needs.activation.outputs.admission-max-ai-credits-threat-detection }}
1853
- GH_AW_ADMISSION_RESULT: ${{ needs.activation.outputs.admission-result }}
1854
- GH_AW_HARNESS_MAX_RETRIES: 0
1855
- GH_AW_LLM_PROVIDER: github
1856
- GH_AW_MAX_AI_CREDITS: ${{ vars.GH_AW_DEFAULT_DETECTION_MAX_AI_CREDITS || '400' }}
1857
- GH_AW_MAX_TURNS: ${{ vars.GH_AW_DEFAULT_MAX_TURNS || '' }}
1858
- GH_AW_MODEL_FALLBACK: ${{ vars.GH_AW_MODEL_DETECTION_COPILOT || vars.GH_AW_DEFAULT_MODEL_COPILOT || 'auto' }}
1859
- GH_AW_PHASE: detection
1860
- GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
1861
- GH_AW_TIMEOUT_MINUTES: 10
1862
- GH_AW_VERSION: v0.93.2
1863
- GITHUB_API_URL: ${{ github.api_url }}
1864
- GITHUB_AW: true
1865
- GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows
1866
- GITHUB_COPILOT_PROMPT_MODE_EXTENSIONS: false
1867
- GITHUB_HEAD_REF: ${{ github.head_ref }}
1868
- GITHUB_REF_NAME: ${{ github.ref_name }}
1869
- GITHUB_SERVER_URL: ${{ github.server_url }}
1870
- GITHUB_STEP_SUMMARY: /tmp/gh-aw/agent-step-summary.md
1871
- GITHUB_WORKSPACE: ${{ github.workspace }}
1872
- GIT_AUTHOR_EMAIL: github-actions[bot]@users.noreply.github.com
1873
- GIT_AUTHOR_NAME: github-actions[bot]
1874
- GIT_COMMITTER_EMAIL: github-actions[bot]@users.noreply.github.com
1875
- GIT_COMMITTER_NAME: github-actions[bot]
1876
- RUNNER_TEMP: ${{ runner.temp }}
1877
- 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) || '' }}
1878
- WORKFLOW_NAME: "Lighthouse SDLC review"
1879
- WORKFLOW_DESCRIPTION: "Execute only the Lighthouse review stage and return its declared stage result."
1880
- HAS_PATCH: ${{ needs.agent.outputs.has_patch }}
1881
- GH_AW_DETECTION_CONTINUE_ON_ERROR: "true"
1882
- run: |
1883
- mkdir -p "/tmp/gh-aw/threat-detection"
1884
- evidence_tmp="/tmp/gh-aw/threat-detection/execution.json.tmp"
1885
- printf '{"version":1,"component":"detection","run_id":%s,"run_attempt":%s,"state":"started"}\n' "$GITHUB_RUN_ID" "$GITHUB_RUN_ATTEMPT" > "$evidence_tmp"
1886
- mv "$evidence_tmp" "/tmp/gh-aw/threat-detection/execution.json"
1887
- export GH_AW_AWF_EXECUTION_COMPONENT="detection"
1888
- export GH_AW_AWF_EXECUTION_EVIDENCE_FILE="/tmp/gh-aw/threat-detection/execution.json"
1889
- set -o pipefail
1890
- printf '%s' "$(date +%s%3N)" > /tmp/gh-aw/agent_cli_start_ms.txt
1891
- GH_AW_COPILOT_SRC="$(command -v copilot 2>/dev/null || true)"
1892
- if [ -z "$GH_AW_COPILOT_SRC" ] || [ ! -x "$GH_AW_COPILOT_SRC" ]; then
1893
- echo "GitHub Copilot CLI executable not found on PATH after installation" >&2
1894
- exit 127
1895
- fi
1896
- GH_AW_COPILOT_BIN="${RUNNER_TEMP}/gh-aw/bin/copilot"
1897
- mkdir -p "${RUNNER_TEMP}/gh-aw/bin"
1898
- if [ "$GH_AW_COPILOT_SRC" != "$GH_AW_COPILOT_BIN" ]; then
1899
- cp "$GH_AW_COPILOT_SRC" "$GH_AW_COPILOT_BIN"
1900
- fi
1901
- chmod 755 "$GH_AW_COPILOT_BIN"
1902
-
1903
- (umask 177 && touch /tmp/gh-aw/threat-detection/detection.log)
1904
- GH_AW_MAX_AI_CREDITS="${GH_AW_MAX_AI_CREDITS:-400}"
1905
- if [[ ! "$GH_AW_MAX_AI_CREDITS" =~ ^[0-9]+$ ]]; then
1906
- GH_AW_MAX_AI_CREDITS="400"
1907
- fi
1908
-
1909
- if [[ "${GH_AW_ADMISSION_RESULT:-}" == "admitted" && -n "${GH_AW_ADMISSION_MAX_AI_CREDITS:-}" ]]; then
1910
- if [[ ! "$GH_AW_ADMISSION_MAX_AI_CREDITS" =~ ^[1-9][0-9]{0,9}$ ]] || (( GH_AW_ADMISSION_MAX_AI_CREDITS > 2147483647 )); then
1911
- echo "ERR_ADMISSION: Invalid runtime admission allowance." >&2
1912
- exit 1
1913
- fi
1914
- GH_AW_MAX_AI_CREDITS="$GH_AW_ADMISSION_MAX_AI_CREDITS"
1915
- echo "Admission allowance applied (value withheld)."
1916
- else
1917
- echo "No component admission allowance; retaining existing budget policy (value withheld)."
1918
- fi
1919
- unset GH_AW_ADMISSION_RESULT GH_AW_ADMISSION_MAX_AI_CREDITS
1920
- printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.28.70/awf-config.schema.json\",\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS},\"maxCacheMisses\":5,\"models\":{\"agent\":[\"sonnet-6x\",\"gpt-6\",\"gpt-5.4\",\"gpt-5.5\",\"gpt-5.6\",\"gpt-5.3\",\"gemini-pro\",\"any\"],\"antigravity\":[\"copilot/antigravity*\",\"google/antigravity*\",\"gemini/antigravity*\"],\"any\":[\"copilot/*\",\"anthropic/*\",\"openai/*\",\"google/*\",\"gemini/*\"],\"auto\":[\"copilot/auto\",\"large\"],\"claude\":[\"agent\"],\"codex\":[\"agent\"],\"coding\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\",\"gpt-5-codex\",\"kimi\"],\"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*\"],\"detection\":[\"small\"],\"evals\":[\"small\"],\"fable\":[\"copilot/*fable*\",\"anthropic/*fable*\"],\"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-3.6-flash\":[\"copilot/gemini-3.6*flash*\",\"google/gemini-3.6*flash*\",\"gemini/gemini-3.6*flash*\"],\"gemini-3.7-flash\":[\"copilot/gemini-3.7*flash*\",\"google/gemini-3.7*flash*\",\"gemini/gemini-3.7*flash*\"],\"gemini-3.8-flash\":[\"copilot/gemini-3.8*flash*\",\"google/gemini-3.8*flash*\",\"gemini/gemini-3.8*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-omni\":[\"copilot/gemini-omni*\",\"google/gemini-omni*\",\"gemini/gemini-omni*\"],\"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*\"],\"gpt-5.6\":[\"copilot/gpt-5.6*\",\"openai/gpt-5.6*\"],\"gpt-6\":[\"copilot/gpt-6*\",\"openai/gpt-6*\"],\"grok\":[\"copilot/*grok*\",\"openai/*grok*\"],\"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*\"],\"kimi\":[\"copilot/kimi*\",\"openai/kimi*\"],\"kiwi\":[\"copilot/kiwi*\",\"openai/kiwi*\"],\"large\":[\"sonnet\",\"gpt-6\",\"gpt-5-pro\",\"gpt-5\",\"gemini-pro\"],\"lyria\":[\"google/lyria*\",\"gemini/lyria*\",\"copilot/lyria*\"],\"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\"],\"raptor-mini\":[\"copilot/raptor*\",\"openai/raptor*\"],\"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-5*\",\"copilot/*sonnet-4-5-*\",\"anthropic/*sonnet-4-5-*\",\"copilot/*sonnet-4-6*\",\"anthropic/*sonnet-4-6*\",\"anthropic/*sonnet-5*\"],\"summarization\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash-lite\",\"mini\"],\"veo\":[\"google/veo*\",\"gemini/veo*\"],\"vision\":[\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"]}},\"container\":{\"imageTag\":\"0.28.70,squid=sha256:b5bc53f4becfd96e926e63c83831f1b3c9512f713c83161d2b8c9b7204b3e917,agent=sha256:b15ab48cbbab02904eb9bbd359a398db59690eebbea1e6934d47ed2bb407dd34,api-proxy=sha256:9ac8f9c7294e892c916de3da9d2588dfd8cd4931e5c39b00143266d7ed9fd52a,cli-proxy=sha256:372ac51a5cccffdfe484f3f7be427d2d1c566e8ae550d55bd45d9fd166a154b4\",\"agentTimeout\":10},\"logging\":{\"proxyLogsDir\":\"/tmp/gh-aw/sandbox/firewall/logs\",\"auditDir\":\"/tmp/gh-aw/sandbox/firewall/audit\"}}" > "${RUNNER_TEMP}/gh-aw/awf-config.json"
1921
- cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json
1922
- export GH_AW_MODELS_JSON_PATH="/tmp/gh-aw/models.json"
1923
- GH_AW_DOCKER_HOST=""
1924
- if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then
1925
- GH_AW_DOCKER_HOST="${DOCKER_HOST}"
1926
- fi
1927
- if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then
1928
- _GH_AW_CHROOT_JSON=$(jq -c --arg src "${RUNNER_TEMP}/gh-aw" --arg user "$(id -un)" --argjson uid "$(id -u)" --argjson gid "$(id -g)" --arg home "${RUNNER_TEMP}/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; }
1929
- printf '%s\n' "$_GH_AW_CHROOT_JSON" > "${RUNNER_TEMP}/gh-aw/awf-config.json"
1930
- fi
1931
- GH_AW_TOOL_CACHE_MOUNT=""
1932
- GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"
1933
- if [ -d "$GH_AW_TOOL_CACHE" ]; then
1934
- if [[ "$GH_AW_TOOL_CACHE" != /opt/* ]]; then
1935
- GH_AW_TOOL_CACHE_MOUNT="$GH_AW_TOOL_CACHE:$GH_AW_TOOL_CACHE:ro"
1936
- fi
1937
- fi
1938
- # shellcheck disable=SC1003,SC2016,SC2086
1939
- 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"} --env-all --exclude-env ACTIONS_ID_TOKEN_REQUEST_TOKEN --exclude-env ACTIONS_ID_TOKEN_REQUEST_URL --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GH_AW_OTLP_ALL_HEADERS --exclude-env GH_AW_OTLP_ENDPOINTS --exclude-env OTEL_EXPORTER_OTLP_ENDPOINT --exclude-env OTEL_EXPORTER_OTLP_HEADERS --mount /tmp/gh-aw:/tmp/gh-aw:rw --mount /tmp/gh-aw/threat-detection:/tmp/gh-aw/threat-detection:rw --log-level info --session-state-dir /tmp/gh-aw/sandbox/agent/session-state --skip-pull \
1940
- -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/bin:$PATH" && : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; GH_AW_TOOL_BINS="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr "\n" ":")"; GH_AW_TOOL_BINS="${GH_AW_TOOL_BINS%:}"; export PATH="$PATH${GH_AW_TOOL_BINS:+:}$GH_AW_TOOL_BINS"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/bin:$PATH" || true && threat-detect --engine copilot --output /tmp/gh-aw/threat-detection/detection_result.json /tmp/gh-aw/threat-detection' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log
1941
- - name: Copy detection firewall logs
1942
- if: always() && steps.detection_guard.outputs.run_detection == 'true'
1943
- continue-on-error: true
1944
- run: |
1945
- mkdir -p /tmp/gh-aw/threat-detection/sandbox/firewall
1946
- if [ -d /tmp/gh-aw/sandbox/firewall/logs ]; then mkdir -p /tmp/gh-aw/threat-detection/sandbox/firewall/logs && cp -r /tmp/gh-aw/sandbox/firewall/logs/. /tmp/gh-aw/threat-detection/sandbox/firewall/logs/; fi
1947
- if [ -d /tmp/gh-aw/sandbox/firewall/audit ]; then mkdir -p /tmp/gh-aw/threat-detection/sandbox/firewall/audit && cp -r /tmp/gh-aw/sandbox/firewall/audit/. /tmp/gh-aw/threat-detection/sandbox/firewall/audit/; fi
1948
- - name: Redact secrets in detection logs
1949
- id: redact_detection_logs
1950
- if: always() && steps.detection_guard.outputs.run_detection == 'true'
1951
- uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
1952
- env:
1953
- GH_AW_SECRET_NAMES: 'COPILOT_GITHUB_TOKEN,GH_AW_DEFAULT_OTLP_ENDPOINT,GH_AW_DEFAULT_OTLP_HEADERS'
1954
- SECRET_COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
1955
- SECRET_GH_AW_DEFAULT_OTLP_ENDPOINT: ${{ secrets.GH_AW_DEFAULT_OTLP_ENDPOINT }}
1956
- SECRET_GH_AW_DEFAULT_OTLP_HEADERS: ${{ secrets.GH_AW_DEFAULT_OTLP_HEADERS }}
1957
- with:
1958
- script: |
1959
- const path = require('path');
1960
- const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
1961
- const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs'));
1962
- setupGlobals(core, github, context, exec, io, getOctokit);
1963
- const { main } = require(path.join(actionsDir, 'redact_secrets.cjs'));
1964
- const { persistDetectionMasks } = require(path.join(actionsDir, 'detection_mask_state.cjs'));
1965
- await main({ additionalDirectories: ["/tmp/gh-aw/threat-detection/sandbox/firewall"], persistDetectionMasks });
1966
- - name: Parse threat detection token usage for step summary
1967
- id: parse_detection_token_usage
1968
- if: always() && steps.detection_guard.outputs.run_detection == 'true' && steps.redact_detection_logs.outcome == 'success'
1969
- continue-on-error: true
1970
- uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
1971
- env:
1972
- GH_AW_TOKEN_USAGE_SUMMARY_TITLE: Threat Detection Token Usage
1973
- GH_AW_PHASE: detection
1974
- GH_AW_AGENT_USAGE_PATH: /tmp/gh-aw/threat-detection/detection_usage.json
1975
- GH_AW_AGENT_USAGE_JSONL_PATH: /tmp/gh-aw/threat-detection/detection_usage.jsonl
1976
- GH_AW_WRITE_EMPTY_USAGE: "true"
1977
- with:
1978
- script: |
1979
- const path = require('path');
1980
- const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
1981
- const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs'));
1982
- setupGlobals(core, github, context, exec, io, getOctokit);
1983
- const { main } = require(path.join(actionsDir, 'parse_token_usage.cjs'));
1984
- await main();
1985
- - name: Redact secrets in detection artifacts
1986
- id: redact_detection_artifacts
1987
- if: always() && steps.detection_guard.outputs.run_detection == 'true'
1988
- uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
1989
- env:
1990
- GH_AW_SECRET_NAMES: 'COPILOT_GITHUB_TOKEN,GH_AW_DEFAULT_OTLP_ENDPOINT,GH_AW_DEFAULT_OTLP_HEADERS'
1991
- SECRET_COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
1992
- SECRET_GH_AW_DEFAULT_OTLP_ENDPOINT: ${{ secrets.GH_AW_DEFAULT_OTLP_ENDPOINT }}
1993
- SECRET_GH_AW_DEFAULT_OTLP_HEADERS: ${{ secrets.GH_AW_DEFAULT_OTLP_HEADERS }}
1994
- with:
1995
- script: |
1996
- const path = require('path');
1997
- const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
1998
- const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs'));
1999
- setupGlobals(core, github, context, exec, io, getOctokit);
2000
- const { main } = require(path.join(actionsDir, 'redact_secrets.cjs'));
2001
- const { persistDetectionMasks } = require(path.join(actionsDir, 'detection_mask_state.cjs'));
2002
- await main({ additionalDirectories: ["/tmp/gh-aw/threat-detection/sandbox/firewall"], persistDetectionMasks });
2003
- - name: Render detection log
2004
- if: always() && steps.detection_guard.outputs.run_detection == 'true' && steps.redact_detection_logs.outcome == 'success' && steps.redact_detection_artifacts.outcome == 'success'
2005
- continue-on-error: true
2006
- uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
2007
- with:
2008
- script: |
2009
- const path = require('path');
2010
- const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
2011
- const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs'));
2012
- setupGlobals(core, github, context, exec, io, getOctokit);
2013
- const { main } = require(path.join(actionsDir, 'render_detection_log.cjs'));
2014
- await main();
2015
- - name: Upload threat detection artifact
2016
- if: always() && steps.detection_guard.outputs.run_detection == 'true' && steps.redact_detection_logs.outcome == 'success' && steps.redact_detection_artifacts.outcome == 'success'
2017
- uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
2018
- with:
2019
- name: ${{ needs.agent.outputs.artifact_prefix }}detection
2020
- path: |
2021
- /tmp/gh-aw/threat-detection/detection_result.json
2022
- /tmp/gh-aw/threat-detection/execution.json
2023
- /tmp/gh-aw/threat-detection/detection_usage.json
2024
- /tmp/gh-aw/threat-detection/detection_usage.jsonl
2025
- /tmp/gh-aw/threat-detection/sandbox/firewall/logs/
2026
- /tmp/gh-aw/threat-detection/sandbox/firewall/audit/
2027
- if-no-files-found: ignore
2028
- retention-days: ${{ vars.GH_AW_DEFAULT_ARTIFACT_RETENTION_DAYS || '0' }}
2029
- - name: Conclude threat detection
2030
- id: detection_conclusion
2031
- if: always() && steps.detection_guard.outputs.run_detection == 'false' || (always() && steps.detection_guard.outputs.run_detection == 'true' && steps.redact_detection_logs.outcome == 'success' && steps.redact_detection_artifacts.outcome == 'success')
2032
- continue-on-error: true
2033
- env:
2034
- RUN_DETECTION: ${{ steps.detection_guard.outputs.run_detection }}
2035
- DETECTION_AGENTIC_EXECUTION_OUTCOME: ${{ steps.detection_agentic_execution.outcome }}
2036
- THREAT_DETECT_INSTALL_OUTCOME: ${{ steps.threat_detect_install.outcome }}
2037
- GH_AW_DETECTION_CONTINUE_ON_ERROR: "true"
2038
- run: |
2039
- bash "${RUNNER_TEMP}/gh-aw/actions/conclude_threat_detection.sh" /tmp/gh-aw/threat-detection/detection_result.json
2040
- - name: Upload skipped detection execution evidence
2041
- if: always() && steps.detection_guard.outputs.run_detection == 'false'
2042
- uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
2043
- with:
2044
- name: ${{ needs.agent.outputs.artifact_prefix }}detection
2045
- path: /tmp/gh-aw/threat-detection/execution.json
2046
- if-no-files-found: ignore
2047
- retention-days: ${{ vars.GH_AW_DEFAULT_ARTIFACT_RETENTION_DAYS || '0' }}
2048
-
2049
1230
  pre_activation:
2050
1231
  name: pre_activation
1232
+ needs: prepare
2051
1233
  runs-on: ubuntu-24.04
2052
1234
  env:
2053
1235
  GH_AW_RUNTIME_FEATURES: ${{ vars.GH_AW_RUNTIME_FEATURES }}
@@ -2067,9 +1249,8 @@ jobs:
2067
1249
  env:
2068
1250
  GH_AW_SETUP_WORKFLOW_NAME: "Lighthouse SDLC review"
2069
1251
  GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/lighthouse-sdlc-review.lock.yml@${{ github.ref }}
2070
- GH_AW_INFO_VERSION: "1.0.101"
2071
- GH_AW_INFO_AWF_VERSION: "v0.28.70"
2072
- GH_AW_INFO_ENGINE_ID: "copilot"
1252
+ GH_AW_INFO_VERSION: "2.1.0"
1253
+ GH_AW_INFO_ENGINE_ID: "opencode"
2073
1254
  GH_AW_SETUP_AW_CONTEXT: ${{ inputs.aw_context }}
2074
1255
  - name: Check team membership for workflow
2075
1256
  id: check_membership
@@ -2086,83 +1267,77 @@ jobs:
2086
1267
  const { main } = require(path.join(actionsDir, 'check_membership.cjs'));
2087
1268
  await main();
2088
1269
 
2089
- safe_outputs:
2090
- name: safe_outputs
2091
- needs:
2092
- - activation
2093
- - agent
2094
- - detection
2095
- if: (!cancelled()) && needs.agent.result != 'skipped' && needs.detection.result == 'success'
1270
+ prepare:
1271
+ name: Verify accepted commit, checks and evidence protection
2096
1272
  runs-on: ubuntu-24.04
2097
- # Permissions for the safe_outputs job (workflow permissions default to none).
1273
+ # Permissions for the prepare job (workflow permissions default to none).
2098
1274
  permissions:
1275
+ actions: read
1276
+ checks: read
1277
+ contents: read
2099
1278
  issues: write
2100
1279
  pull-requests: read
2101
- timeout-minutes: 45
2102
1280
  env:
2103
- GH_AW_AGENT_AIC: ${{ needs.agent.outputs.aic }}
2104
- GH_AW_AIC: ${{ needs.agent.outputs.aic }}
2105
- GH_AW_AMBIENT_CONTEXT: ${{ needs.agent.outputs.ambient_context }}
2106
- GH_AW_CALLER_WORKFLOW_ID: "${{ github.repository }}/lighthouse-sdlc-review"
2107
- GH_AW_DETECTION_CONCLUSION: ${{ needs.detection.outputs.detection_conclusion }}
2108
- GH_AW_DETECTION_REASON: ${{ needs.detection.outputs.detection_reason }}
2109
- GH_AW_ENGINE_ID: "copilot"
2110
- GH_AW_ENGINE_MODEL: ${{ needs.agent.outputs.model }}
2111
- GH_AW_RUNTIME_FEATURES: ${{ vars.GH_AW_RUNTIME_FEATURES }}
2112
- GH_AW_RUN_DETECTION: ${{ needs.detection.outputs.run_detection }}
2113
- GH_AW_THREAT_DETECTION_AIC: ${{ needs.detection.outputs.aic }}
2114
- GH_AW_WORKFLOW_ID: "lighthouse-sdlc-review"
2115
- GH_AW_WORKFLOW_NAME: "Lighthouse SDLC review"
2116
- GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/lighthouse-sdlc-review.md"
1281
+ LIGHTHOUSE_ISSUE: ${{ inputs.issue }}
2117
1282
  outputs:
2118
- code_push_failure_count: ${{ steps.process_safe_outputs.outputs.code_push_failure_count }}
2119
- code_push_failure_errors: ${{ steps.process_safe_outputs.outputs.code_push_failure_errors }}
2120
- create_discussion_error_count: ${{ steps.process_safe_outputs.outputs.create_discussion_error_count }}
2121
- create_discussion_errors: ${{ steps.process_safe_outputs.outputs.create_discussion_errors }}
2122
- process_safe_outputs_items_applied: ${{ steps.process_safe_outputs.outputs.items_applied }}
2123
- process_safe_outputs_items_cancelled: ${{ steps.process_safe_outputs.outputs.items_cancelled }}
2124
- process_safe_outputs_items_deferred: ${{ steps.process_safe_outputs.outputs.items_deferred }}
2125
- process_safe_outputs_items_failed: ${{ steps.process_safe_outputs.outputs.items_failed }}
2126
- process_safe_outputs_items_skipped: ${{ steps.process_safe_outputs.outputs.items_skipped }}
2127
- process_safe_outputs_items_succeeded: ${{ steps.process_safe_outputs.outputs.items_succeeded }}
2128
- process_safe_outputs_items_warnings: ${{ steps.process_safe_outputs.outputs.items_warnings }}
2129
- process_safe_outputs_processed_count: ${{ steps.process_safe_outputs.outputs.processed_count }}
2130
- process_safe_outputs_status: ${{ steps.process_safe_outputs.outputs.status }}
1283
+ revision: ${{ steps.prepare.outputs.revision }}
2131
1284
  steps:
2132
- - name: Setup Scripts
2133
- id: setup
2134
- uses: github/gh-aw-actions/setup@d9128eb3ea40c18b77c76184eda03c0ff2608d79 # v0.93.2
1285
+ - name: Configure GH_HOST for enterprise compatibility
1286
+ id: ghes-host-config
1287
+ shell: bash
1288
+ run: | # zizmor: ignore[github-env] - GITHUB_SERVER_URL is set by GitHub Actions, not user input.
1289
+ # Derive GH_HOST from GITHUB_SERVER_URL so the gh CLI targets the correct
1290
+ # GitHub instance (GHES/GHEC). On github.com this is a harmless no-op.
1291
+ GH_HOST="${GITHUB_SERVER_URL#https://}"
1292
+ GH_HOST="${GH_HOST#http://}"
1293
+ echo "GH_HOST=${GH_HOST}" >> "$GITHUB_ENV"
1294
+ - uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5
2135
1295
  with:
2136
- destination: ${{ runner.temp }}/gh-aw/actions
2137
- job-name: ${{ github.job }}
2138
- trace-id: ${{ needs.activation.outputs.setup-trace-id }}
2139
- parent-span-id: ${{ needs.activation.outputs.setup-parent-span-id || needs.activation.outputs.setup-span-id }}
1296
+ persist-credentials: false
1297
+ ref: __LIGHTHOUSE_REF__
1298
+ repository: juangcarmona/lighthouse
1299
+ - uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5
1300
+ with:
1301
+ node-version: 24
1302
+ - name: Collect verified owner intent and reserve the issue
1303
+ id: prepare
1304
+ run: node src/packages/sdlc/src/completion-actions.mjs prepare
2140
1305
  env:
2141
- GH_AW_SETUP_WORKFLOW_NAME: "Lighthouse SDLC review"
2142
- GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/lighthouse-sdlc-review.lock.yml@${{ github.ref }}
2143
- GH_AW_INFO_VERSION: "1.0.101"
2144
- GH_AW_INFO_AWF_VERSION: "v0.28.70"
2145
- GH_AW_INFO_ENGINE_ID: "copilot"
2146
- GH_AW_SETUP_AW_CONTEXT: ${{ inputs.aw_context }}
2147
- - name: Mask OTLP telemetry headers
2148
- run: bash "${RUNNER_TEMP}/gh-aw/actions/mask_otlp_headers.sh"
2149
- - name: Download agent output artifact
2150
- id: download-agent-output
2151
- continue-on-error: true
2152
- uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
1306
+ GH_TOKEN: ${{ github.token }}
1307
+ - name: Preserve the execution request
1308
+ uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
2153
1309
  with:
2154
- pattern: "{${{ needs.activation.outputs.artifact_prefix }}agent,${{ needs.activation.outputs.artifact_prefix }}agent-output-fallback}"
2155
- merge-multiple: true
2156
- path: /tmp/gh-aw/
2157
- - name: Setup agent output environment variable
2158
- id: setup-agent-output-env
2159
- if: steps.download-agent-output.outcome == 'success'
2160
- run: |
2161
- mkdir -p /tmp/gh-aw/
2162
- find "/tmp/gh-aw/" -type f -print
2163
- if [ -f "/tmp/gh-aw/agent_output.json" ]; then
2164
- echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT"
2165
- fi
1310
+ if-no-files-found: error
1311
+ name: lighthouse-input-${{ inputs.issue }}-${{ github.run_attempt }}
1312
+ path: ${{ runner.temp }}/lighthouse-${{ github.run_id }}-${{ github.run_attempt }}/
1313
+ retention-days: ${{ vars.GH_AW_DEFAULT_ARTIFACT_RETENTION_DAYS || '14' }}
1314
+ - name: Release reservation if preparation failed
1315
+ if: failure()
1316
+ run: node src/packages/sdlc/src/completion-actions.mjs cleanup
1317
+ env:
1318
+ GH_TOKEN: ${{ github.token }}
1319
+
1320
+ publish:
1321
+ name: Validate, publish and release
1322
+ needs:
1323
+ - agent
1324
+ - prepare
1325
+ if: always() && needs.prepare.result == 'success'
1326
+ runs-on: ubuntu-24.04
1327
+ # Permissions for the publish job (workflow permissions default to none).
1328
+ permissions:
1329
+ actions: write
1330
+ checks: read
1331
+ contents: write
1332
+ issues: write
1333
+ pull-requests: write
1334
+ concurrency:
1335
+ cancel-in-progress: false
1336
+ group: lighthouse-process-publication
1337
+
1338
+ env:
1339
+ LIGHTHOUSE_ISSUE: ${{ inputs.issue }}
1340
+ steps:
2166
1341
  - name: Configure GH_HOST for enterprise compatibility
2167
1342
  id: ghes-host-config
2168
1343
  shell: bash
@@ -2172,36 +1347,42 @@ jobs:
2172
1347
  GH_HOST="${GITHUB_SERVER_URL#https://}"
2173
1348
  GH_HOST="${GH_HOST#http://}"
2174
1349
  echo "GH_HOST=${GH_HOST}" >> "$GITHUB_ENV"
2175
- - name: Process Safe Outputs
2176
- id: process_safe_outputs
2177
- uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
2178
- env:
2179
- GH_AW_JOB_CHECK_RUN_ID: ${{ job.check_run_id }}
2180
- GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
2181
- GH_AW_COMMENT_ID: ${{ needs.activation.outputs.comment_id }}
2182
- GH_AW_MENTIONS_GITHUB_TOKEN: ${{ github.token }}
2183
- GH_AW_ALLOWED_DOMAINS: "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,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,s.symcb.com,s.symcd.com,security.ubuntu.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.googleapis.com"
2184
- GITHUB_SERVER_URL: ${{ github.server_url }}
2185
- GITHUB_API_URL: ${{ github.api_url }}
2186
- GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_report_incomplete_issue\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"false\"},\"report_incomplete\":{},\"report_missing_data\":{},\"report_missing_tool\":{}}"
2187
- GH_AW_GITHUB_TOKEN_SOURCE: ${{ secrets.GH_AW_GITHUB_TOKEN != '' && 'pat' || 'github_actions' }}
1350
+ - uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5
2188
1351
  with:
2189
- github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
2190
- script: |
2191
- const path = require('path');
2192
- const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
2193
- const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs'));
2194
- setupGlobals(core, github, context, exec, io, getOctokit, process.env.GH_AW_GITHUB_TOKEN_SOURCE);
2195
- const { main } = require(path.join(actionsDir, 'process_safe_outputs.cjs'));
2196
- await main();
2197
- - name: Upload Safe Outputs Items
1352
+ persist-credentials: false
1353
+ ref: __LIGHTHOUSE_REF__
1354
+ repository: juangcarmona/lighthouse
1355
+ - uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5
1356
+ with:
1357
+ node-version: 24
1358
+ - name: Load the execution request
1359
+ uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
1360
+ with:
1361
+ name: lighthouse-input-${{ inputs.issue }}-${{ github.run_attempt }}
1362
+ path: ${{ runner.temp }}/lighthouse-${{ github.run_id }}-${{ github.run_attempt }}
1363
+ - name: Load the candidate result
1364
+ if: needs.agent.result == 'success'
1365
+ uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
1366
+ with:
1367
+ name: lighthouse-result-${{ inputs.issue }}-${{ github.run_attempt }}
1368
+ path: ${{ runner.temp }}/lighthouse-${{ github.run_id }}-${{ github.run_attempt }}
1369
+ - name: Recheck authority and publish the validated result
1370
+ if: needs.agent.result == 'success'
1371
+ run: node src/packages/sdlc/src/completion-actions.mjs publish
1372
+ env:
1373
+ GH_TOKEN: ${{ github.token }}
1374
+ - name: Preserve merge and publication receipts
2198
1375
  if: always()
2199
1376
  uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
2200
1377
  with:
2201
- name: ${{ needs.activation.outputs.artifact_prefix }}safe-outputs-items
1378
+ if-no-files-found: warn
1379
+ name: lighthouse-completion-${{ inputs.issue }}-${{ github.run_attempt }}
2202
1380
  path: |
2203
- /tmp/gh-aw/safe-output-items.jsonl
2204
- /tmp/gh-aw/temporary-id-map.json
2205
- /tmp/gh-aw/safe-output-errors.json
2206
- if-no-files-found: ignore
2207
- retention-days: ${{ vars.GH_AW_DEFAULT_ARTIFACT_RETENTION_DAYS || '0' }}
1381
+ ${{ runner.temp }}/lighthouse-${{ github.run_id }}-${{ github.run_attempt }}/integration-receipt.json
1382
+ ${{ runner.temp }}/lighthouse-${{ github.run_id }}-${{ github.run_attempt }}/publication-receipt.json
1383
+ retention-days: ${{ vars.GH_AW_DEFAULT_ARTIFACT_RETENTION_DAYS || '30' }}
1384
+ - name: Release the issue reservation
1385
+ if: always()
1386
+ run: node src/packages/sdlc/src/completion-actions.mjs cleanup
1387
+ env:
1388
+ GH_TOKEN: ${{ github.token }}