@juangcarmona/lighthouse-sdlc 0.12.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.
@@ -1,22 +1,33 @@
1
- # gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"9b81c0af7913a61b530b2d7fde55c12b1c83c57e34d017783bffc7ae8d8cc8b0","body_hash":"ef7d8c8b6f08305285117fa905a1b73b0da432df2883620ea805d88c52d3a036","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":"09eb09c2dc6239ad8c14f48bf5aaad705b7821b5b6607be4ad2245c9fad409a7","body_hash":"7620b9d532d032c4c46661f502e587429d85d4316e8d327fc3e8db9cb0225569","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 proposal stage and return its declared stage result.
26
+ # Produce a validated OpenSpec proposal PR from an owner-authorized ready issue.
12
27
  #
13
28
  # Resolved workflow manifest:
14
29
  # Imports:
15
- # - shared/lighthouse-sdlc-stage.md
16
- #
17
- # Frontmatter env variables:
18
- # - LIGHTHOUSE_SKILL: (main workflow)
19
- # - LIGHTHOUSE_STAGE: (main workflow)
30
+ # - shared/lighthouse-opencode.md
20
31
  #
21
32
  # Secrets used:
22
33
  # - COPILOT_GITHUB_TOKEN
@@ -28,19 +39,16 @@
28
39
  #
29
40
  # Custom actions used:
30
41
  # - actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
42
+ # - actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5
31
43
  # - actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
32
44
  # - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
33
45
  # - actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
46
+ # - actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5
34
47
  # - actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
35
48
  # - github/gh-aw-actions/setup@d9128eb3ea40c18b77c76184eda03c0ff2608d79 # v0.93.2
36
49
  #
37
50
  # 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
51
  # - ghcr.io/github/gh-aw-node@sha256:41835613992df88f51e923bad486f96dfb2e6cda29f13e217df41833284ae382
43
- # - ghcr.io/github/github-mcp-server:v2.0.2@sha256:ffced0d76e77428532a2ced185516992d77fd146d69eec2f244e6237d1a97796
44
52
 
45
53
  name: "Lighthouse SDLC propose"
46
54
  on:
@@ -51,22 +59,7 @@ on:
51
59
  description: "Agent caller context (Reserved for Agentic Workflows)."
52
60
  required: false
53
61
  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: refine
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.
62
+ issue:
70
63
  required: true
71
64
  type: string
72
65
  secrets:
@@ -91,11 +84,9 @@ concurrency:
91
84
  run-name: "Lighthouse SDLC propose"
92
85
 
93
86
  env:
94
- LIGHTHOUSE_SKILL: node_modules/@juangcarmona/lighthouse-sdlc/skills/propose/SKILL.md
95
- LIGHTHOUSE_STAGE: propose
96
87
  OTEL_EXPORTER_OTLP_ENDPOINT: ${{ secrets.GH_AW_DEFAULT_OTLP_ENDPOINT || vars.GH_AW_DEFAULT_OTLP_ENDPOINT }}
97
88
  OTEL_SERVICE_NAME: gh-aw.lighthouse-sdlc-propose
98
- OTEL_RESOURCE_ATTRIBUTES: 'gh-aw.workflow.name=Lighthouse%20SDLC%20propose,gh-aw.repository=${{ github.repository }},gh-aw.run.id=${{ github.run_id }},github.run_id=${{ github.run_id }},gh-aw.engine.id=copilot'
89
+ OTEL_RESOURCE_ATTRIBUTES: 'gh-aw.workflow.name=Lighthouse%20SDLC%20propose,gh-aw.repository=${{ github.repository }},gh-aw.run.id=${{ github.run_id }},github.run_id=${{ github.run_id }},gh-aw.engine.id=opencode'
99
90
  OTEL_EXPORTER_OTLP_HEADERS: ${{ secrets.GH_AW_DEFAULT_OTLP_HEADERS }}
100
91
  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
92
  GH_AW_OTLP_IF_MISSING: ignore
@@ -103,7 +94,9 @@ env:
103
94
  jobs:
104
95
  activation:
105
96
  name: activation
106
- needs: pre_activation
97
+ needs:
98
+ - pre_activation
99
+ - prepare
107
100
  if: needs.pre_activation.outputs.activated == 'true'
108
101
  runs-on: ubuntu-24.04
109
102
  # Permissions for the activation job (workflow permissions default to none).
@@ -128,7 +121,6 @@ jobs:
128
121
  lockdown_check_failed: ${{ steps.generate_aw_info.outputs.lockdown_check_failed == 'true' }}
129
122
  model: ${{ steps.generate_aw_info.outputs.model }}
130
123
  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
124
  setup-parent-span-id: ${{ steps.setup.outputs.parent-span-id || steps.setup.outputs.span-id }}
133
125
  setup-span-id: ${{ steps.setup.outputs.span-id }}
134
126
  setup-trace-id: ${{ steps.setup.outputs.trace-id }}
@@ -150,9 +142,8 @@ jobs:
150
142
  env:
151
143
  GH_AW_SETUP_WORKFLOW_NAME: "Lighthouse SDLC propose"
152
144
  GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/lighthouse-sdlc-propose.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"
145
+ GH_AW_INFO_VERSION: "2.1.0"
146
+ GH_AW_INFO_ENGINE_ID: "opencode"
156
147
  GH_AW_SETUP_AW_CONTEXT: ${{ inputs.aw_context }}
157
148
  - name: Mask OTLP telemetry headers
158
149
  run: bash "${RUNNER_TEMP}/gh-aw/actions/mask_otlp_headers.sh"
@@ -180,28 +171,27 @@ jobs:
180
171
  - name: Generate agentic run info
181
172
  id: generate_aw_info
182
173
  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"
174
+ GH_AW_INFO_ENGINE_ID: "opencode"
175
+ GH_AW_INFO_ENGINE_NAME: "OpenCode"
176
+ GH_AW_INFO_MODEL: ${{ vars.GH_AW_MODEL_AGENT_CUSTOM || '' }}
177
+ GH_AW_INFO_VERSION: "2.1.0"
178
+ GH_AW_INFO_AGENT_VERSION: "2.1.0"
188
179
  GH_AW_INFO_CLI_VERSION: "v0.93.2"
189
180
  GH_AW_INFO_WORKFLOW_NAME: "Lighthouse SDLC propose"
190
181
  GH_AW_INFO_WORKFLOW_ID: ${{ job.workflow_ref }}
191
182
  GH_AW_INFO_EXPERIMENTAL: "false"
192
183
  GH_AW_INFO_SUPPORTS_TOOLS_ALLOWLIST: "true"
193
184
  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"
185
+ GH_AW_INFO_ALLOWED_DOMAINS: '[]'
186
+ GH_AW_INFO_FIREWALL_ENABLED: "false"
187
+ GH_AW_INFO_AWF_VERSION: ""
197
188
  GH_AW_INFO_AWMG_VERSION: ""
198
- GH_AW_INFO_FIREWALL_TYPE: "squid"
189
+ GH_AW_INFO_FIREWALL_TYPE: ""
199
190
  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"
191
+ GH_AW_INFO_MODEL_CONFIG: '{"routing":{"enabled":false}}'
192
+ GH_AW_COMPILED_STRICT: "false"
204
193
  GH_AW_INFO_TARGET_REPO: ${{ steps.resolve-host-repo.outputs.target_repo }}
194
+ GH_AW_INFO_FEATURES: '{"dangerously-disable-sandbox-agent":true}'
205
195
  uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
206
196
  with:
207
197
  script: |
@@ -211,6 +201,11 @@ jobs:
211
201
  setupGlobals(core, github, context, exec, io, getOctokit);
212
202
  const { main } = require(path.join(actionsDir, 'generate_aw_info.cjs'));
213
203
  await main(core, context);
204
+ - name: Enforce strict mode policy
205
+ if: ${{ vars.GH_AW_POLICY_STRICT == 'true' }}
206
+ run: |
207
+ echo "::error::GH_AW_POLICY_STRICT=true but this workflow was not compiled in strict mode. Recompile with --strict or strict: true."
208
+ exit 1
214
209
  - name: Restore daily AIC scan observations
215
210
  id: restore-daily-aic-cache-fallback
216
211
  if: ${{ env.GH_AW_ADMISSION_RESULT != 'admitted' && env.GH_AW_MAX_DAILY_AI_CREDITS != '' }}
@@ -260,11 +255,6 @@ jobs:
260
255
  overwrite: true
261
256
  if-no-files-found: ignore
262
257
  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
258
  - name: Check for OAuth tokens
269
259
  id: check-oauth-tokens
270
260
  run: bash "${RUNNER_TEMP}/gh-aw/actions/check_oauth_tokens.sh"
@@ -338,24 +328,13 @@ jobs:
338
328
  GH_AW_ACTIONS_DIR: ${{ runner.temp }}/gh-aw/actions
339
329
  GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt
340
330
  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 }}
331
+ 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
332
  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"
333
+ GH_AW_PROMPT_CONTENT_0001: "<safe-output-tools>\nTools: noop(max:2)\n"
354
334
  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-propose.md}}\n"
335
+ GH_AW_PROMPT_CONTENT_0003: "</system>\n"
336
+ GH_AW_PROMPT_CONTENT_0004: "{{#runtime-import .github/workflows/shared/lighthouse-opencode.md}}\n"
337
+ GH_AW_PROMPT_CONTENT_0005: "{{#runtime-import .github/workflows/lighthouse-sdlc-propose.md}}\n"
359
338
  with:
360
339
  script: |
361
340
  const { setupGlobals } = require(process.env.GH_AW_ACTIONS_DIR + '/setup_globals.cjs');
@@ -366,13 +345,11 @@ jobs:
366
345
  uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
367
346
  env:
368
347
  GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt
369
- GH_AW_ENGINE_ID: "copilot"
348
+ GH_AW_ENGINE_ID: "opencode"
370
349
  GH_AW_SUB_AGENT_DIR: ".github/agents"
371
350
  GH_AW_SUB_AGENT_EXT: ".agent.md"
372
351
  GH_AW_SKILL_DIR: ".github/skills"
373
352
  GH_AW_SKILL_EXT: "/SKILL.md"
374
- GH_AW_ENV_LIGHTHOUSE_SKILL: ${{ env.LIGHTHOUSE_SKILL }}
375
- GH_AW_EXPR_79DC8BAA: ${{ inputs.run-id }}
376
353
  with:
377
354
  script: |
378
355
  const path = require('path');
@@ -385,17 +362,7 @@ jobs:
385
362
  uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
386
363
  env:
387
364
  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"
365
+ GH_AW_MCP_CLI_SERVERS_LIST: '- `safeoutputs` — run `safeoutputs --help` to see available tools'
399
366
  GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED: ${{ needs.pre_activation.outputs.activated }}
400
367
  with:
401
368
  script: |
@@ -410,16 +377,6 @@ jobs:
410
377
  return await substitutePlaceholders({
411
378
  file: process.env.GH_AW_PROMPT,
412
379
  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
380
  GH_AW_MCP_CLI_SERVERS_LIST: process.env.GH_AW_MCP_CLI_SERVERS_LIST,
424
381
  GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED: process.env.GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED
425
382
  }
@@ -483,17 +440,19 @@ jobs:
483
440
 
484
441
  agent:
485
442
  name: agent
486
- needs: activation
443
+ needs:
444
+ - activation
445
+ - prepare
487
446
  if: needs.activation.outputs.daily_ai_credits_exceeded != 'true'
488
447
  runs-on:
489
448
  - self-hosted
490
449
  - linux
491
- - lighthouse-sdlc
450
+ - lighthouse-workflow
492
451
  # Permissions for the agent job (workflow permissions default to none).
493
452
  permissions:
494
453
  contents: read
495
454
  concurrency:
496
- group: "gh-aw-copilot-lighthouse-sdlc-propose"
455
+ group: "gh-aw-opencode-lighthouse-sdlc-propose"
497
456
  queue: max
498
457
  timeout-minutes: 60
499
458
  env:
@@ -501,6 +460,7 @@ jobs:
501
460
  GH_AW_ASSETS_ALLOWED_EXTS: ""
502
461
  GH_AW_ASSETS_BRANCH: ""
503
462
  GH_AW_ASSETS_MAX_SIZE_KB: 0
463
+ GH_AW_ENGINE_VERSION: "2.1.0"
504
464
  GH_AW_MCP_LOG_DIR: /tmp/gh-aw/mcp-logs/safeoutputs
505
465
  GH_AW_PR_HEAD_BASE_BRANCH: ""
506
466
  GH_AW_PR_HEAD_BASE_PR_NUMBER: ""
@@ -512,30 +472,17 @@ jobs:
512
472
  GH_AW_TARGET_REPO_SLUG: ""
513
473
  GH_AW_WORKFLOW_ID_SANITIZED: lighthousesdlcpropose
514
474
  outputs:
515
- agentic_engine_timeout: ${{ steps.detect-agent-errors.outputs.agentic_engine_timeout || 'false' }}
516
475
  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 }}
476
+ aic: ${{ steps.parse-mcp-gateway.outputs.aic }}
477
+ ambient_context: ${{ steps.parse-mcp-gateway.outputs.ambient_context }}
519
478
  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
479
  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
480
  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
481
  output: ${{ steps.collect_output.outputs.output }}
534
482
  output_types: ${{ steps.collect_output.outputs.output_types }}
535
483
  setup-parent-span-id: ${{ steps.setup.outputs.parent-span-id || steps.setup.outputs.span-id }}
536
484
  setup-span-id: ${{ steps.setup.outputs.span-id }}
537
485
  setup-trace-id: ${{ steps.setup.outputs.trace-id }}
538
- shell_expansion_guard_rejected: ${{ steps.detect-agent-errors.outputs.shell_expansion_guard_rejected || 'false' }}
539
486
  unknown_model_ai_credits: ${{ steps.parse-mcp-gateway.outputs.unknown_model_ai_credits || 'false' }}
540
487
  steps:
541
488
  - name: Setup Scripts
@@ -549,9 +496,8 @@ jobs:
549
496
  env:
550
497
  GH_AW_SETUP_WORKFLOW_NAME: "Lighthouse SDLC propose"
551
498
  GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/lighthouse-sdlc-propose.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"
499
+ GH_AW_INFO_VERSION: "2.1.0"
500
+ GH_AW_INFO_ENGINE_ID: "opencode"
555
501
  GH_AW_SETUP_AW_CONTEXT: ${{ inputs.aw_context }}
556
502
  - name: Set runtime paths
557
503
  id: set-runtime-paths
@@ -570,22 +516,12 @@ jobs:
570
516
  run: bash "${RUNNER_TEMP}/gh-aw/actions/mask_otlp_headers.sh"
571
517
  - name: Check OTLP telemetry configuration
572
518
  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
519
  - name: Initialize agent execution evidence
579
520
  run: |
580
521
  mkdir -p "/tmp/gh-aw"
581
522
  evidence_tmp="/tmp/gh-aw/agent_execution.json.tmp"
582
523
  printf '{"version":1,"component":"agent","run_id":%s,"run_attempt":%s,"state":"not_started"}\n' "$GITHUB_RUN_ID" "$GITHUB_RUN_ATTEMPT" > "$evidence_tmp"
583
524
  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
525
  - name: Create gh-aw temp directory
590
526
  run: bash "${RUNNER_TEMP}/gh-aw/actions/create_gh_aw_tmp_dir.sh"
591
527
  - name: Configure gh CLI for GitHub Enterprise
@@ -597,21 +533,27 @@ jobs:
597
533
  with:
598
534
  name: ${{ needs.activation.outputs.artifact_prefix }}activation
599
535
  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
536
+ - name: Check out the authorized product revision
537
+ uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5
538
+ with:
539
+ persist-credentials: false
540
+ - name: Setup Node.js
541
+ uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
542
+ with:
543
+ node-version: '24'
544
+ package-manager-cache: false
545
+ - name: Load the pinned harness package
546
+ uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5
547
+ with:
548
+ path: tools
549
+ persist-credentials: false
550
+ ref: __LIGHTHOUSE_REF__
551
+ repository: juangcarmona/lighthouse
552
+ - name: Load the authorized issue context
611
553
  uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
612
554
  with:
613
- name: lighthouse-sdlc-${{ inputs.run-id }}-${{ inputs.previous-stage }}
614
- path: /tmp/gh-aw/agent/previous
555
+ name: lighthouse-input-${{ inputs.issue }}-${{ github.run_attempt }}
556
+ path: ${{ runner.temp }}/lighthouse-${{ github.run_id }}-${{ github.run_attempt }}
615
557
 
616
558
  - name: Configure Git credentials
617
559
  env:
@@ -619,47 +561,6 @@ jobs:
619
561
  GITHUB_SERVER_URL: ${{ github.server_url }}
620
562
  GITHUB_TOKEN: ${{ github.token }}
621
563
  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
564
  - name: Restore inline sub-agents from activation artifact
664
565
  env:
665
566
  GH_AW_SUB_AGENT_DIR: ".github/agents"
@@ -670,7 +571,7 @@ jobs:
670
571
  GH_AW_SKILL_DIR: ".github/skills"
671
572
  run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_inline_skills.sh"
672
573
  - 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
574
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-node@sha256:41835613992df88f51e923bad486f96dfb2e6cda29f13e217df41833284ae382
674
575
  - name: Prepare Safe Outputs Directories
675
576
  run: |
676
577
  mkdir -p "${RUNNER_TEMP}/gh-aw/safeoutputs"
@@ -681,7 +582,7 @@ jobs:
681
582
  env:
682
583
  GH_AW_FILE_ROOT: "${{ runner.temp }}/gh-aw"
683
584
  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\":{}}"
585
+ GH_AW_SAFE_OUTPUTS_CONFIG: "{\"noop\":{\"max\":2,\"report-as-issue\":\"false\"}}"
685
586
  with:
686
587
  script: |
687
588
  const path = require('path');
@@ -710,68 +611,6 @@ jobs:
710
611
  "maxLength": 65000
711
612
  }
712
613
  }
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
614
  }
776
615
  }
777
616
  uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
@@ -791,10 +630,6 @@ jobs:
791
630
  GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
792
631
  GH_AW_SAFE_OUTPUTS_CONFIG_PATH: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS_CONFIG_PATH }}
793
632
  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
633
  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
799
634
  run: |
800
635
  set -eo pipefail
@@ -807,7 +642,7 @@ jobs:
807
642
 
808
643
  # Export gateway environment variables for MCP config and gateway script
809
644
  export MCP_GATEWAY_PORT="8080"
810
- export MCP_GATEWAY_DOMAIN="awmg-mcpg"
645
+ export MCP_GATEWAY_DOMAIN="localhost"
811
646
  export MCP_GATEWAY_HOST_DOMAIN="localhost"
812
647
  MCP_GATEWAY_AGENT_ID=$(openssl rand -base64 45 | tr -d '/+=')
813
648
  echo "::add-mask::${MCP_GATEWAY_AGENT_ID}"
@@ -823,36 +658,17 @@ jobs:
823
658
  export GH_AW_PR_HEAD_BASE_REF="${GH_AW_PR_HEAD_BASE_REF:-}"
824
659
  export GH_AW_PR_HEAD_REPO="${GH_AW_PR_HEAD_REPO:-}"
825
660
  export GH_AW_TARGET_REPO_SLUG="${GH_AW_TARGET_REPO_SLUG:-}"
826
- export GH_AW_ENGINE="copilot"
661
+ export GH_AW_ENGINE="opencode"
827
662
  MCP_GATEWAY_UID=$(id -u 2>/dev/null || echo '0')
828
663
  MCP_GATEWAY_GID=$(id -g 2>/dev/null || echo '0')
829
664
  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'
665
+ 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
666
 
832
- mkdir -p "$HOME/.copilot"
833
667
  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"
668
+ cat << GH_AW_MCP_CONFIG_6001799711bbe943_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs"
835
669
  {
836
670
  "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
671
  "safeoutputs": {
855
- "type": "stdio",
856
672
  "container": "ghcr.io/github/gh-aw-node@sha256:41835613992df88f51e923bad486f96dfb2e6cda29f13e217df41833284ae382",
857
673
  "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
674
  "args": ["-w", "\${GITHUB_WORKSPACE}"],
@@ -883,14 +699,6 @@ jobs:
883
699
  "GITHUB_TOKEN": "\${GITHUB_TOKEN}",
884
700
  "GITHUB_WORKSPACE": "\${GITHUB_WORKSPACE}",
885
701
  "RUNNER_TEMP": "\${RUNNER_TEMP}"
886
- },
887
- "guard-policies": {
888
- "write-sink": {
889
- "accept": [
890
- "*"
891
- ],
892
- "sink-visibility": "${GH_AW_SINK_VISIBILITY}"
893
- }
894
702
  }
895
703
  }
896
704
  },
@@ -907,7 +715,7 @@ jobs:
907
715
  }
908
716
  }
909
717
  }
910
- GH_AW_MCP_CONFIG_3db6aaf67c51d953_EOF
718
+ GH_AW_MCP_CONFIG_6001799711bbe943_EOF
911
719
  - name: Mount MCP servers as CLIs
912
720
  id: mount-mcp-clis
913
721
  continue-on-error: true
@@ -932,195 +740,69 @@ jobs:
932
740
  id: pre_agent_audit
933
741
  continue-on-error: true
934
742
  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
743
+ - name: Write OpenCode log parser script
744
+ if: always()
745
+ run: |
746
+ mkdir -p "${RUNNER_TEMP}/gh-aw/actions"
747
+ cat <<'GHAW_LOG_PARSER_SCRIPT_5d2e8b3f_EOF' > "${RUNNER_TEMP}/gh-aw/actions/opencode_log_parser.cjs"
748
+ // @ts-check
749
+ // Auto-generated log parser for behavior-defined engine "OpenCode".
750
+ const { createEngineLogParser } = require("./log_parser_shared.cjs");
751
+
752
+ // --- begin engine-provided parse function ---
753
+ function parseLog(logContent) {
754
+ const fs = require("fs");
755
+ const events = require("path").join(process.env.RUNNER_TEMP, "gh-aw", `opencode-events-${process.env.GITHUB_RUN_ID}-${process.env.GITHUB_RUN_ATTEMPT}.jsonl`);
756
+ return require("./parse_opencode_log.cjs").parseOpenCodeLog(fs.existsSync(events) ? fs.readFileSync(events, "utf8") : logContent);
757
+ }
758
+
759
+ // --- end engine-provided parse function ---
760
+
761
+ const main = createEngineLogParser({
762
+ parserName: "OpenCode",
763
+ parseFunction: parseLog,
764
+ supportsDirectories: false,
765
+ });
766
+
767
+ if (typeof module !== "undefined" && module.exports) {
768
+ module.exports = { main, parseLog };
769
+ }
770
+ GHAW_LOG_PARSER_SCRIPT_5d2e8b3f_EOF
771
+ chmod 755 "${RUNNER_TEMP}/gh-aw/actions/opencode_log_parser.cjs"
772
+ - name: OpenCode progress and result
948
773
  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') }}
774
+ timeout-minutes: 15
975
775
  run: |
976
776
  set -o pipefail
977
- printf '%s' "$(date +%s%3N)" > /tmp/gh-aw/agent_cli_start_ms.txt
978
777
  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
778
+ 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
779
  mkdir -p "/tmp/gh-aw"
1040
780
  evidence_tmp="/tmp/gh-aw/agent_execution.json.tmp"
1041
781
  printf '{"version":1,"component":"agent","run_id":%s,"run_attempt":%s,"state":"started"}\n' "$GITHUB_RUN_ID" "$GITHUB_RUN_ATTEMPT" > "$evidence_tmp"
1042
782
  mv "$evidence_tmp" "/tmp/gh-aw/agent_execution.json"
1043
783
  export GH_AW_AWF_EXECUTION_COMPONENT="agent"
1044
784
  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'
785
+ export no_proxy="${NO_PROXY:-}"
786
+ printf '%s' "$(date +%s%3N)" > /tmp/gh-aw/agent_cli_start_ms.txt
787
+ 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
788
  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
789
  GH_AW_ADMISSION_MAX_AI_CREDITS: ${{ needs.activation.outputs.admission-max-ai-credits }}
1059
790
  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
791
+ GH_AW_ENGINE_VERSION: 2.1.0
1062
792
  GH_AW_MAX_AI_CREDITS: ${{ vars.GH_AW_DEFAULT_MAX_AI_CREDITS || '1000' }}
1063
793
  GH_AW_MAX_TURNS: ${{ vars.GH_AW_DEFAULT_MAX_TURNS || '' }}
1064
- GH_AW_PHASE: agent
1065
794
  GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
1066
795
  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
796
  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]
797
+ 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
798
  RUNNER_TEMP: ${{ runner.temp }}
1084
799
  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
800
  - name: Configure Git credentials
1115
801
  env:
1116
802
  GITHUB_REPOSITORY: ${{ github.repository }}
1117
803
  GITHUB_SERVER_URL: ${{ github.server_url }}
1118
804
  GITHUB_TOKEN: ${{ github.token }}
1119
805
  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
806
  - name: Stop MCP Gateway
1125
807
  if: always()
1126
808
  continue-on-error: true
@@ -1143,10 +825,7 @@ jobs:
1143
825
  const { main } = require(path.join(actionsDir, 'redact_secrets.cjs'));
1144
826
  await main();
1145
827
  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 }}
828
+ GH_AW_SECRET_NAMES: 'GITHUB_TOKEN'
1150
829
  SECRET_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
1151
830
  - name: Append agent step summary
1152
831
  if: always()
@@ -1164,7 +843,6 @@ jobs:
1164
843
  uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
1165
844
  env:
1166
845
  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
846
  GITHUB_SERVER_URL: ${{ github.server_url }}
1169
847
  GITHUB_API_URL: ${{ github.api_url }}
1170
848
  with:
@@ -1179,7 +857,7 @@ jobs:
1179
857
  if: always()
1180
858
  uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
1181
859
  env:
1182
- GH_AW_AGENT_OUTPUT: /tmp/gh-aw/sandbox/agent/logs/
860
+ GH_AW_AGENT_OUTPUT: /tmp/gh-aw/agent-stdio.log
1183
861
  GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
1184
862
  with:
1185
863
  script: |
@@ -1187,7 +865,7 @@ jobs:
1187
865
  const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
1188
866
  const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs'));
1189
867
  setupGlobals(core, github, context, exec, io, getOctokit);
1190
- const { main } = require(path.join(actionsDir, 'parse_copilot_log.cjs'));
868
+ const { main } = require(path.join(actionsDir, 'opencode_log_parser.cjs'));
1191
869
  await main();
1192
870
  - name: Parse MCP Gateway logs for step summary
1193
871
  if: always()
@@ -1201,37 +879,6 @@ jobs:
1201
879
  setupGlobals(core, github, context, exec, io, getOctokit);
1202
880
  const { main } = require(path.join(actionsDir, 'parse_mcp_gateway_log.cjs'));
1203
881
  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
882
  - name: Generate observability summary
1236
883
  if: always()
1237
884
  uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
@@ -1249,34 +896,25 @@ jobs:
1249
896
  if [ ! -f /tmp/gh-aw/agent_output.json ]; then
1250
897
  echo '{"items":[]}' > /tmp/gh-aw/agent_output.json
1251
898
  fi
899
+ - name: Validate the Lighthouse result
900
+ run: node tools/src/packages/sdlc/src/issue-actions.mjs validate
1252
901
  - 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
902
+ name: Preserve the result and runtime receipt
903
+ uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
904
+ with:
905
+ if-no-files-found: error
906
+ name: lighthouse-result-${{ inputs.issue }}-${{ github.run_attempt }}
907
+ path: |
908
+ ${{ runner.temp }}/lighthouse-${{ github.run_id }}-${{ github.run_attempt }}/envelope.json
909
+ ${{ runner.temp }}/lighthouse-${{ github.run_id }}-${{ github.run_attempt }}/runtime.json
910
+ retention-days: ${{ vars.GH_AW_DEFAULT_ARTIFACT_RETENTION_DAYS || '14' }}
1273
911
  - if: always()
1274
- name: Upload stage evidence
912
+ name: Preserve OpenCode diagnostic events
1275
913
  uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
1276
914
  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
915
+ if-no-files-found: ignore
916
+ name: opencode-events-${{ inputs.issue }}-${{ github.run_attempt }}
917
+ path: ${{ runner.temp }}/gh-aw/opencode-events-${{ github.run_id }}-${{ github.run_attempt }}.jsonl
1280
918
  retention-days: ${{ vars.GH_AW_DEFAULT_ARTIFACT_RETENTION_DAYS || '14' }}
1281
919
 
1282
920
  # Small dedicated copy of the agent output so safe-output processing
@@ -1301,7 +939,6 @@ jobs:
1301
939
  /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/model-routing.jsonl
1302
940
  /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl
1303
941
  /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/model-routing.jsonl
1304
- /tmp/gh-aw/awf-resolved-config.json
1305
942
  if-no-files-found: ignore
1306
943
  retention-days: ${{ vars.GH_AW_DEFAULT_ARTIFACT_RETENTION_DAYS || '0' }}
1307
944
  - name: Upload agent artifacts
@@ -1319,14 +956,7 @@ jobs:
1319
956
  /tmp/gh-aw/aw-prompts/user.txt
1320
957
  /tmp/gh-aw/aw-prompts/system.txt
1321
958
  /tmp/gh-aw/skill_inventory.json
1322
- /tmp/gh-aw/sandbox/agent/logs/
1323
- /tmp/gh-aw/redacted-urls.log
1324
959
  /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
960
  /tmp/gh-aw/agent-stdio.log
1331
961
  /tmp/gh-aw/pre-agent-audit.txt
1332
962
  /tmp/gh-aw/github_rate_limits.jsonl
@@ -1334,13 +964,6 @@ jobs:
1334
964
  /tmp/gh-aw/otlp-export-errors.jsonl
1335
965
  /tmp/gh-aw/safeoutputs.jsonl
1336
966
  /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
967
  if-no-files-found: ignore
1345
968
  retention-days: ${{ vars.GH_AW_DEFAULT_ARTIFACT_RETENTION_DAYS || '0' }}
1346
969
 
@@ -1349,13 +972,13 @@ jobs:
1349
972
  needs:
1350
973
  - activation
1351
974
  - agent
1352
- - detection
1353
- - safe_outputs
975
+ - prepare
976
+ - publish
1354
977
  if: >
1355
978
  always() && (needs.agent.result != 'skipped' || needs.activation.outputs.lockdown_check_failed == 'true' ||
1356
979
  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')
980
+ needs.activation.outputs.daily_ai_credits_exceeded == 'true' || needs.activation.outputs.daily_ai_credits_guardrail_status == 'structural_error' ||
981
+ needs.activation.outputs.daily_ai_credits_guardrail_status == 'transient_error')
1359
982
  runs-on: ubuntu-24.04
1360
983
  # Permissions for the conclusion job (workflow permissions default to none).
1361
984
  permissions:
@@ -1366,16 +989,13 @@ jobs:
1366
989
  cancel-in-progress: false
1367
990
  queue: max
1368
991
  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}"
992
+ GH_AW_JOB_DISPLAY_NAMES: "{\"activation\":\"activation\",\"agent\":\"agent\",\"conclusion\":\"conclusion\",\"pre_activation\":\"pre_activation\",\"prepare\":\"Authorize and reserve issue\",\"publish\":\"Validate, publish and release\"}"
993
+ GH_AW_JOB_RESULTS: "{\"activation\":{\"result\":\"${{ needs.activation.result }}\"},\"agent\":{\"result\":\"${{ needs.agent.result }}\"},\"prepare\":{\"result\":\"${{ needs.prepare.result }}\"},\"publish\":{\"result\":\"${{ needs.publish.result }}\"}}"
994
+ GH_AW_JOB_TIMING_ELIGIBLE: "{\"activation\":true,\"agent\":true,\"conclusion\":true,\"pre_activation\":true,\"prepare\":true,\"publish\":true}"
1372
995
  GH_AW_RUNTIME_FEATURES: ${{ vars.GH_AW_RUNTIME_FEATURES }}
1373
996
  outputs:
1374
- incomplete_count: ${{ steps.report_incomplete.outputs.incomplete_count }}
1375
997
  noop_comment_body: ${{ steps.noop.outputs.noop_comment_body }}
1376
998
  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
999
  steps:
1380
1000
  - name: Setup Scripts
1381
1001
  id: setup
@@ -1388,9 +1008,8 @@ jobs:
1388
1008
  env:
1389
1009
  GH_AW_SETUP_WORKFLOW_NAME: "Lighthouse SDLC propose"
1390
1010
  GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/lighthouse-sdlc-propose.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"
1011
+ GH_AW_INFO_VERSION: "2.1.0"
1012
+ GH_AW_INFO_ENGINE_ID: "opencode"
1394
1013
  GH_AW_SETUP_AW_CONTEXT: ${{ inputs.aw_context }}
1395
1014
  - name: Download agent output artifact
1396
1015
  id: download-agent-output
@@ -1409,20 +1028,6 @@ jobs:
1409
1028
  if [ -f "/tmp/gh-aw/agent_output.json" ]; then
1410
1029
  echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT"
1411
1030
  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
1031
  - name: Download Safe Outputs Items Manifest
1427
1032
  id: download-safe-outputs-manifest
1428
1033
  if: always()
@@ -1437,16 +1042,16 @@ jobs:
1437
1042
  uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
1438
1043
  env:
1439
1044
  GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
1440
- GH_AW_NOOP_MAX: "1"
1045
+ GH_AW_NOOP_MAX: "2"
1441
1046
  GH_AW_WORKFLOW_NAME: "Lighthouse SDLC propose"
1442
1047
  GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/lighthouse-sdlc-propose.md"
1443
- GH_AW_ENGINE_ID: "copilot"
1048
+ GH_AW_ENGINE_ID: "opencode"
1049
+ GH_AW_ENGINE_VERSION: "2.1.0"
1444
1050
  GH_AW_ENGINE_MODEL: ${{ needs.agent.outputs.model }}
1445
1051
  GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
1446
1052
  GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }}
1447
1053
  GH_AW_NOOP_REPORT_AS_ISSUE: "false"
1448
1054
  GH_AW_AIC: ${{ needs.agent.outputs.aic }}
1449
- GH_AW_THREAT_DETECTION_AIC: ${{ needs.detection.outputs.aic }}
1450
1055
  GH_AW_AMBIENT_CONTEXT: ${{ needs.agent.outputs.ambient_context }}
1451
1056
  GH_AW_WORKFLOW_ID: "lighthouse-sdlc-propose"
1452
1057
  with:
@@ -1458,63 +1063,6 @@ jobs:
1458
1063
  setupGlobals(core, github, context, exec, io, getOctokit);
1459
1064
  const { main } = require(path.join(actionsDir, 'handle_noop_message.cjs'));
1460
1065
  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 propose"
1467
- GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/lighthouse-sdlc-propose.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 propose"
1487
- GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/lighthouse-sdlc-propose.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 propose"
1506
- GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/lighthouse-sdlc-propose.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
1066
  - name: Handle agent failure
1519
1067
  id: handle_agent_failure
1520
1068
  if: always()
@@ -1527,29 +1075,12 @@ jobs:
1527
1075
  GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }}
1528
1076
  GH_AW_WORKFLOW_ID: "lighthouse-sdlc-propose"
1529
1077
  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 }}
1078
+ GH_AW_ENGINE_ID: "opencode"
1535
1079
  GH_AW_AI_CREDITS_RATE_LIMIT_ERROR: ${{ needs.agent.outputs.ai_credits_rate_limit_error || 'false' }}
1536
1080
  GH_AW_UNKNOWN_MODEL_AI_CREDITS: ${{ needs.agent.outputs.unknown_model_ai_credits || 'false' }}
1537
1081
  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
1082
  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"
1083
+ GH_AW_DEFAULT_CHECKOUT_USES_TRIGGER_REF: "false"
1553
1084
  GH_AW_LOCKDOWN_CHECK_FAILED: ${{ needs.activation.outputs.lockdown_check_failed }}
1554
1085
  GH_AW_OAUTH_TOKEN_CHECK_FAILED: ${{ needs.activation.outputs.oauth_token_check_failed }}
1555
1086
  GH_AW_STALE_LOCK_FILE_FAILED: ${{ needs.activation.outputs.stale_lock_file_failed }}
@@ -1564,7 +1095,7 @@ jobs:
1564
1095
  GH_AW_FAILURE_REPORT_AS_ISSUE: "false"
1565
1096
  GH_AW_MISSING_TOOL_REPORT_AS_FAILURE: "true"
1566
1097
  GH_AW_MISSING_DATA_REPORT_AS_FAILURE: "true"
1567
- GH_AW_TIMEOUT_MINUTES: "${{ fromJSON(vars.GH_AW_DEFAULT_TIMEOUT_MINUTES || '20') }}"
1098
+ GH_AW_TIMEOUT_MINUTES: "15"
1568
1099
  with:
1569
1100
  github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
1570
1101
  script: |
@@ -1596,10 +1127,6 @@ jobs:
1596
1127
  - name: Collect usage artifact files
1597
1128
  if: always()
1598
1129
  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
1130
  run: bash "${RUNNER_TEMP}/gh-aw/actions/collect_usage_artifact_files.sh"
1604
1131
  - name: Generate usage activity summary and unified session
1605
1132
  if: always()
@@ -1695,359 +1222,9 @@ jobs:
1695
1222
  overwrite: true
1696
1223
  retention-days: ${{ vars.GH_AW_DEFAULT_ARTIFACT_RETENTION_DAYS || '0' }}
1697
1224
 
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 propose"
1728
- GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/lighthouse-sdlc-propose.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 propose"
1806
- WORKFLOW_DESCRIPTION: "Execute only the Lighthouse proposal 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 propose"
1879
- WORKFLOW_DESCRIPTION: "Execute only the Lighthouse proposal 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
1225
  pre_activation:
2050
1226
  name: pre_activation
1227
+ needs: prepare
2051
1228
  runs-on: ubuntu-24.04
2052
1229
  env:
2053
1230
  GH_AW_RUNTIME_FEATURES: ${{ vars.GH_AW_RUNTIME_FEATURES }}
@@ -2067,9 +1244,8 @@ jobs:
2067
1244
  env:
2068
1245
  GH_AW_SETUP_WORKFLOW_NAME: "Lighthouse SDLC propose"
2069
1246
  GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/lighthouse-sdlc-propose.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"
1247
+ GH_AW_INFO_VERSION: "2.1.0"
1248
+ GH_AW_INFO_ENGINE_ID: "opencode"
2073
1249
  GH_AW_SETUP_AW_CONTEXT: ${{ inputs.aw_context }}
2074
1250
  - name: Check team membership for workflow
2075
1251
  id: check_membership
@@ -2086,83 +1262,67 @@ jobs:
2086
1262
  const { main } = require(path.join(actionsDir, 'check_membership.cjs'));
2087
1263
  await main();
2088
1264
 
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'
1265
+ prepare:
1266
+ name: Authorize and reserve issue
2096
1267
  runs-on: ubuntu-24.04
2097
- # Permissions for the safe_outputs job (workflow permissions default to none).
1268
+ # Permissions for the prepare job (workflow permissions default to none).
2098
1269
  permissions:
1270
+ actions: read
1271
+ contents: read
2099
1272
  issues: write
2100
- pull-requests: read
2101
- timeout-minutes: 45
2102
1273
  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-propose"
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-propose"
2115
- GH_AW_WORKFLOW_NAME: "Lighthouse SDLC propose"
2116
- GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/lighthouse-sdlc-propose.md"
2117
- 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 }}
1274
+ LIGHTHOUSE_ISSUE: ${{ inputs.issue }}
2131
1275
  steps:
2132
- - name: Setup Scripts
2133
- id: setup
2134
- uses: github/gh-aw-actions/setup@d9128eb3ea40c18b77c76184eda03c0ff2608d79 # v0.93.2
1276
+ - name: Configure GH_HOST for enterprise compatibility
1277
+ id: ghes-host-config
1278
+ shell: bash
1279
+ run: | # zizmor: ignore[github-env] - GITHUB_SERVER_URL is set by GitHub Actions, not user input.
1280
+ # Derive GH_HOST from GITHUB_SERVER_URL so the gh CLI targets the correct
1281
+ # GitHub instance (GHES/GHEC). On github.com this is a harmless no-op.
1282
+ GH_HOST="${GITHUB_SERVER_URL#https://}"
1283
+ GH_HOST="${GH_HOST#http://}"
1284
+ echo "GH_HOST=${GH_HOST}" >> "$GITHUB_ENV"
1285
+ - uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5
2135
1286
  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 }}
1287
+ persist-credentials: false
1288
+ ref: __LIGHTHOUSE_REF__
1289
+ repository: juangcarmona/lighthouse
1290
+ - uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5
1291
+ with:
1292
+ node-version: 24
1293
+ - name: Collect verified owner intent and reserve the issue
1294
+ id: prepare
1295
+ run: node src/packages/sdlc/src/issue-actions.mjs prepare
2140
1296
  env:
2141
- GH_AW_SETUP_WORKFLOW_NAME: "Lighthouse SDLC propose"
2142
- GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/lighthouse-sdlc-propose.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
1297
+ GH_TOKEN: ${{ github.token }}
1298
+ - name: Preserve the execution request
1299
+ uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
2153
1300
  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
1301
+ if-no-files-found: error
1302
+ name: lighthouse-input-${{ inputs.issue }}-${{ github.run_attempt }}
1303
+ path: ${{ runner.temp }}/lighthouse-${{ github.run_id }}-${{ github.run_attempt }}/
1304
+ retention-days: ${{ vars.GH_AW_DEFAULT_ARTIFACT_RETENTION_DAYS || '14' }}
1305
+ - name: Release reservation if preparation failed
1306
+ if: failure()
1307
+ run: node src/packages/sdlc/src/issue-actions.mjs cleanup
1308
+ env:
1309
+ GH_TOKEN: ${{ github.token }}
1310
+
1311
+ publish:
1312
+ name: Validate, publish and release
1313
+ needs:
1314
+ - agent
1315
+ - prepare
1316
+ if: always() && needs.prepare.result == 'success'
1317
+ runs-on: ubuntu-24.04
1318
+ # Permissions for the publish job (workflow permissions default to none).
1319
+ permissions:
1320
+ contents: write
1321
+ issues: write
1322
+ pull-requests: write
1323
+ env:
1324
+ LIGHTHOUSE_ISSUE: ${{ inputs.issue }}
1325
+ steps:
2166
1326
  - name: Configure GH_HOST for enterprise compatibility
2167
1327
  id: ghes-host-config
2168
1328
  shell: bash
@@ -2172,36 +1332,32 @@ jobs:
2172
1332
  GH_HOST="${GITHUB_SERVER_URL#https://}"
2173
1333
  GH_HOST="${GH_HOST#http://}"
2174
1334
  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' }}
1335
+ - uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5
2188
1336
  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
2198
- if: always()
2199
- uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
1337
+ persist-credentials: false
1338
+ ref: __LIGHTHOUSE_REF__
1339
+ repository: juangcarmona/lighthouse
1340
+ - uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5
2200
1341
  with:
2201
- name: ${{ needs.activation.outputs.artifact_prefix }}safe-outputs-items
2202
- 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' }}
1342
+ node-version: 24
1343
+ - name: Load the execution request
1344
+ uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
1345
+ with:
1346
+ name: lighthouse-input-${{ inputs.issue }}-${{ github.run_attempt }}
1347
+ path: ${{ runner.temp }}/lighthouse-${{ github.run_id }}-${{ github.run_attempt }}
1348
+ - name: Load the candidate result
1349
+ if: needs.agent.result == 'success'
1350
+ uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
1351
+ with:
1352
+ name: lighthouse-result-${{ inputs.issue }}-${{ github.run_attempt }}
1353
+ path: ${{ runner.temp }}/lighthouse-${{ github.run_id }}-${{ github.run_attempt }}
1354
+ - name: Recheck authority and publish the validated result
1355
+ if: needs.agent.result == 'success'
1356
+ run: node src/packages/sdlc/src/issue-actions.mjs publish
1357
+ env:
1358
+ GH_TOKEN: ${{ github.token }}
1359
+ - name: Release the issue reservation
1360
+ if: always()
1361
+ run: node src/packages/sdlc/src/issue-actions.mjs cleanup
1362
+ env:
1363
+ GH_TOKEN: ${{ github.token }}