@juangcarmona/lighthouse-sdlc 0.15.0 → 0.15.1

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,21 +1,37 @@
1
- # gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"57815f8eaccb278ccbf8d865ad6af7183e778aac49d4d7ecfd4d82332a72accc","body_hash":"00ea52a55baca68b86c1619e0f668596a9f0745bf42ef16348a430a6bdb093af","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":"774a39cc660dd7589cbba460421a95c9fec2bcb21b73471ae90bc9b625eeb767","body_hash":"b6819b09222b408b8140fdc320e7270d45149ccb70442e528ef4f0ffa86e985c","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 triage stage and return its declared stage result.
26
+ # Assess an owner-admitted request without starting refinement.
12
27
  #
13
28
  # Resolved workflow manifest:
14
29
  # Imports:
15
- # - shared/lighthouse-sdlc-stage.md
30
+ # - shared/lighthouse-opencode.md
16
31
  #
17
32
  # Frontmatter env variables:
18
- # - LIGHTHOUSE_SKILL: (main workflow)
33
+ # - LIGHTHOUSE_DISPATCH_REQUIRED: (main workflow)
34
+ # - LIGHTHOUSE_RECOVERY_ENABLED: (main workflow)
19
35
  # - LIGHTHOUSE_STAGE: (main workflow)
20
36
  #
21
37
  # Secrets used:
@@ -28,74 +44,53 @@
28
44
  #
29
45
  # Custom actions used:
30
46
  # - actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
47
+ # - actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5
31
48
  # - actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
32
49
  # - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
33
50
  # - actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
51
+ # - actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5
34
52
  # - actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
35
53
  # - github/gh-aw-actions/setup@d9128eb3ea40c18b77c76184eda03c0ff2608d79 # v0.93.2
36
54
  #
37
55
  # 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
56
  # - ghcr.io/github/gh-aw-node@sha256:41835613992df88f51e923bad486f96dfb2e6cda29f13e217df41833284ae382
43
- # - ghcr.io/github/github-mcp-server:v2.0.2@sha256:ffced0d76e77428532a2ced185516992d77fd146d69eec2f244e6237d1a97796
44
57
 
45
- name: "Lighthouse SDLC triage"
58
+ name: "triage"
46
59
  on:
47
- workflow_call:
60
+ # roles: all # Roles processed as role check in pre-activation job
61
+ workflow_dispatch:
48
62
  inputs:
49
63
  aw_context:
50
64
  default: ""
51
65
  description: "Agent caller context (Reserved for Agentic Workflows)."
52
66
  required: false
53
67
  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: ""
61
- description: Previous stage artifact name; empty for triage.
62
- required: false
63
- type: string
64
- route:
65
- description: Lighthouse route selected by the host.
68
+ dispatch-request:
69
+ description: Authenticated owner admission receipt
66
70
  required: true
67
71
  type: string
68
- run-id:
69
- description: Stable Lighthouse run identifier.
72
+ issue:
73
+ description: Source issue
70
74
  required: true
71
75
  type: string
72
- secrets:
73
- COPILOT_GITHUB_TOKEN:
74
- required: false
75
- GH_AW_DEFAULT_OTLP_ENDPOINT:
76
- required: false
77
- GH_AW_DEFAULT_OTLP_HEADERS:
78
- required: false
79
- GH_AW_GITHUB_MCP_SERVER_TOKEN:
80
- required: false
81
- GH_AW_GITHUB_TOKEN:
82
- required: false
83
76
 
84
77
  # Jobs receive only their explicitly declared permissions.
85
78
  permissions: {}
86
79
 
87
80
  concurrency:
88
- group: "gh-aw-lighthouse-sdlc-triage-${{ github.run_id }}"
81
+ cancel-in-progress: false
82
+ group: lighthouse-issue-${{ inputs.issue }}
89
83
  queue: max
90
84
 
91
- run-name: "Lighthouse SDLC triage"
85
+ run-name: "triage #${{ inputs.issue }} · request ${{ inputs.dispatch-request }}"
92
86
 
93
87
  env:
94
- LIGHTHOUSE_SKILL: node_modules/@juangcarmona/lighthouse-sdlc/skills/triage/SKILL.md
88
+ LIGHTHOUSE_DISPATCH_REQUIRED: "true"
89
+ LIGHTHOUSE_RECOVERY_ENABLED: ${{ vars.LIGHTHOUSE_RECOVERY_ENABLED }}
95
90
  LIGHTHOUSE_STAGE: triage
96
91
  OTEL_EXPORTER_OTLP_ENDPOINT: ${{ secrets.GH_AW_DEFAULT_OTLP_ENDPOINT || vars.GH_AW_DEFAULT_OTLP_ENDPOINT }}
97
92
  OTEL_SERVICE_NAME: gh-aw.lighthouse-sdlc-triage
98
- OTEL_RESOURCE_ATTRIBUTES: 'gh-aw.workflow.name=Lighthouse%20SDLC%20triage,gh-aw.repository=${{ github.repository }},gh-aw.run.id=${{ github.run_id }},github.run_id=${{ github.run_id }},gh-aw.engine.id=copilot'
93
+ OTEL_RESOURCE_ATTRIBUTES: 'gh-aw.workflow.name=triage,gh-aw.repository=${{ github.repository }},gh-aw.run.id=${{ github.run_id }},github.run_id=${{ github.run_id }},gh-aw.engine.id=opencode'
99
94
  OTEL_EXPORTER_OTLP_HEADERS: ${{ secrets.GH_AW_DEFAULT_OTLP_HEADERS }}
100
95
  GH_AW_OTLP_ENDPOINTS: '[{"url":"${{ secrets.GH_AW_DEFAULT_OTLP_ENDPOINT || vars.GH_AW_DEFAULT_OTLP_ENDPOINT }}","headers":"${{ secrets.GH_AW_DEFAULT_OTLP_HEADERS }}"}]'
101
96
  GH_AW_OTLP_IF_MISSING: ignore
@@ -103,8 +98,10 @@ env:
103
98
  jobs:
104
99
  activation:
105
100
  name: activation
106
- needs: pre_activation
107
- if: needs.pre_activation.outputs.activated == 'true'
101
+ needs:
102
+ - pre_activation
103
+ - prepare
104
+ if: needs.pre_activation.outputs.activated == 'true' && (needs.prepare.outputs.eligible == 'true')
108
105
  runs-on: ubuntu-24.04
109
106
  # Permissions for the activation job (workflow permissions default to none).
110
107
  permissions:
@@ -114,7 +111,6 @@ jobs:
114
111
  GH_AW_MAX_DAILY_AI_CREDITS: ${{ vars.GH_AW_DEFAULT_MAX_DAILY_AI_CREDITS || '5000' }}
115
112
  GH_AW_RUNTIME_FEATURES: ${{ vars.GH_AW_RUNTIME_FEATURES }}
116
113
  outputs:
117
- artifact_prefix: ${{ steps.artifact-prefix.outputs.prefix }}
118
114
  aw_context: ${{ steps.generate_aw_info.outputs.aw_context }}
119
115
  comment_id: ""
120
116
  comment_repo: ""
@@ -128,15 +124,10 @@ jobs:
128
124
  lockdown_check_failed: ${{ steps.generate_aw_info.outputs.lockdown_check_failed == 'true' }}
129
125
  model: ${{ steps.generate_aw_info.outputs.model }}
130
126
  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
127
  setup-parent-span-id: ${{ steps.setup.outputs.parent-span-id || steps.setup.outputs.span-id }}
133
128
  setup-span-id: ${{ steps.setup.outputs.span-id }}
134
129
  setup-trace-id: ${{ steps.setup.outputs.trace-id }}
135
130
  stale_lock_file_failed: ${{ steps.check-lock-file.outputs.stale_lock_file_failed == 'true' }}
136
- target_checkout_ref: ${{ steps.resolve-host-repo.outputs.target_checkout_ref }}
137
- target_ref: ${{ steps.resolve-host-repo.outputs.target_ref }}
138
- target_repo: ${{ steps.resolve-host-repo.outputs.target_repo }}
139
- target_repo_name: ${{ steps.resolve-host-repo.outputs.target_repo_name }}
140
131
  steps:
141
132
  - name: Setup Scripts
142
133
  id: setup
@@ -148,60 +139,36 @@ jobs:
148
139
  parent-span-id: ${{ needs.pre_activation.outputs.setup-parent-span-id || needs.pre_activation.outputs.setup-span-id }}
149
140
  safe-output-artifact-client: ${{ env.GH_AW_MAX_DAILY_AI_CREDITS != '' }}
150
141
  env:
151
- GH_AW_SETUP_WORKFLOW_NAME: "Lighthouse SDLC triage"
142
+ GH_AW_SETUP_WORKFLOW_NAME: "triage"
152
143
  GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/lighthouse-sdlc-triage.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"
144
+ GH_AW_INFO_VERSION: "2.1.0"
145
+ GH_AW_INFO_ENGINE_ID: "opencode"
156
146
  GH_AW_SETUP_AW_CONTEXT: ${{ inputs.aw_context }}
157
147
  - name: Mask OTLP telemetry headers
158
148
  run: bash "${RUNNER_TEMP}/gh-aw/actions/mask_otlp_headers.sh"
159
- - name: Resolve host repo for activation checkout
160
- id: resolve-host-repo
161
- uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
162
- env:
163
- JOB_WORKFLOW_REPOSITORY: ${{ job.workflow_repository }}
164
- JOB_WORKFLOW_SHA: ${{ job.workflow_sha }}
165
- JOB_WORKFLOW_REF: ${{ job.workflow_ref }}
166
- JOB_WORKFLOW_FILE_PATH: ${{ job.workflow_file_path }}
167
- with:
168
- script: |
169
- const path = require('path');
170
- const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
171
- const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs'));
172
- setupGlobals(core, github, context, exec, io, getOctokit);
173
- const { main } = require(path.join(actionsDir, 'resolve_host_repo.cjs'));
174
- await main();
175
- - name: Compute artifact prefix
176
- id: artifact-prefix
177
- env:
178
- INPUTS_JSON: ${{ toJSON(inputs) }}
179
- run: bash "${RUNNER_TEMP}/gh-aw/actions/compute_artifact_prefix.sh"
180
149
  - name: Generate agentic run info
181
150
  id: generate_aw_info
182
151
  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"
152
+ GH_AW_INFO_ENGINE_ID: "opencode"
153
+ GH_AW_INFO_ENGINE_NAME: "OpenCode"
154
+ GH_AW_INFO_MODEL: ${{ vars.GH_AW_MODEL_AGENT_CUSTOM || '' }}
155
+ GH_AW_INFO_VERSION: "2.1.0"
156
+ GH_AW_INFO_AGENT_VERSION: "2.1.0"
188
157
  GH_AW_INFO_CLI_VERSION: "v0.93.2"
189
- GH_AW_INFO_WORKFLOW_NAME: "Lighthouse SDLC triage"
158
+ GH_AW_INFO_WORKFLOW_NAME: "triage"
190
159
  GH_AW_INFO_WORKFLOW_ID: ${{ job.workflow_ref }}
191
160
  GH_AW_INFO_EXPERIMENTAL: "false"
192
161
  GH_AW_INFO_SUPPORTS_TOOLS_ALLOWLIST: "true"
193
162
  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"
163
+ GH_AW_INFO_ALLOWED_DOMAINS: '[]'
164
+ GH_AW_INFO_FIREWALL_ENABLED: "false"
165
+ GH_AW_INFO_AWF_VERSION: ""
197
166
  GH_AW_INFO_AWMG_VERSION: ""
198
- GH_AW_INFO_FIREWALL_TYPE: "squid"
167
+ GH_AW_INFO_FIREWALL_TYPE: ""
199
168
  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"
204
- GH_AW_INFO_TARGET_REPO: ${{ steps.resolve-host-repo.outputs.target_repo }}
169
+ GH_AW_INFO_MODEL_CONFIG: '{"routing":{"enabled":false}}'
170
+ GH_AW_COMPILED_STRICT: "false"
171
+ GH_AW_INFO_FEATURES: '{"dangerously-disable-sandbox-agent":true}'
205
172
  uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
206
173
  with:
207
174
  script: |
@@ -211,6 +178,11 @@ jobs:
211
178
  setupGlobals(core, github, context, exec, io, getOctokit);
212
179
  const { main } = require(path.join(actionsDir, 'generate_aw_info.cjs'));
213
180
  await main(core, context);
181
+ - name: Enforce strict mode policy
182
+ if: ${{ vars.GH_AW_POLICY_STRICT == 'true' }}
183
+ run: |
184
+ echo "::error::GH_AW_POLICY_STRICT=true but this workflow was not compiled in strict mode. Recompile with --strict or strict: true."
185
+ exit 1
214
186
  - name: Restore daily AIC scan observations
215
187
  id: restore-daily-aic-cache-fallback
216
188
  if: ${{ env.GH_AW_ADMISSION_RESULT != 'admitted' && env.GH_AW_MAX_DAILY_AI_CREDITS != '' }}
@@ -232,7 +204,7 @@ jobs:
232
204
  if: ${{ env.GH_AW_ADMISSION_RESULT != 'admitted' && env.GH_AW_MAX_DAILY_AI_CREDITS != '' }}
233
205
  uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
234
206
  env:
235
- GH_AW_WORKFLOW_NAME: "Lighthouse SDLC triage"
207
+ GH_AW_WORKFLOW_NAME: "triage"
236
208
  GH_AW_WORKFLOW_ID: "lighthouse-sdlc-triage"
237
209
  GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
238
210
  GH_AW_WORKFLOW_DISPATCH_AW_CONTEXT: ${{ github.event.inputs.aw_context || '' }}
@@ -260,11 +232,6 @@ jobs:
260
232
  overwrite: true
261
233
  if-no-files-found: ignore
262
234
  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
235
  - name: Check for OAuth tokens
269
236
  id: check-oauth-tokens
270
237
  run: bash "${RUNNER_TEMP}/gh-aw/actions/check_oauth_tokens.sh"
@@ -272,19 +239,10 @@ jobs:
272
239
  COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
273
240
  GH_AW_GITHUB_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN }}
274
241
  GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }}
275
- - name: Print cross-repo setup guidance
276
- if: failure() && steps.resolve-host-repo.outputs.target_repo != github.repository
277
- run: |
278
- echo "::error::COPILOT_GITHUB_TOKEN must be configured in the CALLER repository's secrets."
279
- echo "::error::For cross-repo workflow_call, secrets must be set in the repository that triggers the workflow."
280
- echo "::error::See: https://github.github.com/gh-aw/patterns/central-repo-ops/#cross-repo-setup"
281
242
  - name: Checkout .github and .agents folders
282
- if: steps.resolve-host-repo.outputs.target_repo == github.repository
283
243
  uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
284
244
  with:
285
245
  persist-credentials: false
286
- repository: ${{ steps.resolve-host-repo.outputs.target_repo }}
287
- ref: ${{ steps.resolve-host-repo.outputs.target_checkout_ref }}
288
246
  sparse-checkout: |
289
247
  .github
290
248
  .agents
@@ -320,7 +278,7 @@ jobs:
320
278
  GH_AW_COMPILED_VERSION: "v0.93.2"
321
279
  GH_AW_HAS_SAFE_OUTPUTS: "true"
322
280
  GH_AW_BLOCKED_VERSION_REPORT_AS_ISSUE: "false"
323
- GH_AW_WORKFLOW_NAME: "Lighthouse SDLC triage"
281
+ GH_AW_WORKFLOW_NAME: "triage"
324
282
  with:
325
283
  script: |
326
284
  const path = require('path');
@@ -338,24 +296,13 @@ jobs:
338
296
  GH_AW_ACTIONS_DIR: ${{ runner.temp }}/gh-aw/actions
339
297
  GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt
340
298
  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 }}
299
+ 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
300
  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"
301
+ GH_AW_PROMPT_CONTENT_0001: "<safe-output-tools>\nTools: noop(max:2)\n"
354
302
  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-triage.md}}\n"
303
+ GH_AW_PROMPT_CONTENT_0003: "</system>\n"
304
+ GH_AW_PROMPT_CONTENT_0004: "{{#runtime-import .github/workflows/shared/lighthouse-opencode.md}}\n"
305
+ GH_AW_PROMPT_CONTENT_0005: "{{#runtime-import .github/workflows/lighthouse-sdlc-triage.md}}\n"
359
306
  with:
360
307
  script: |
361
308
  const { setupGlobals } = require(process.env.GH_AW_ACTIONS_DIR + '/setup_globals.cjs');
@@ -366,13 +313,11 @@ jobs:
366
313
  uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
367
314
  env:
368
315
  GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt
369
- GH_AW_ENGINE_ID: "copilot"
316
+ GH_AW_ENGINE_ID: "opencode"
370
317
  GH_AW_SUB_AGENT_DIR: ".github/agents"
371
318
  GH_AW_SUB_AGENT_EXT: ".agent.md"
372
319
  GH_AW_SKILL_DIR: ".github/skills"
373
320
  GH_AW_SKILL_EXT: "/SKILL.md"
374
- GH_AW_ENV_LIGHTHOUSE_SKILL: ${{ env.LIGHTHOUSE_SKILL }}
375
- GH_AW_EXPR_79DC8BAA: ${{ inputs.run-id }}
376
321
  with:
377
322
  script: |
378
323
  const path = require('path');
@@ -385,17 +330,7 @@ jobs:
385
330
  uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
386
331
  env:
387
332
  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"
333
+ GH_AW_MCP_CLI_SERVERS_LIST: '- `safeoutputs` — run `safeoutputs --help` to see available tools'
399
334
  GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED: ${{ needs.pre_activation.outputs.activated }}
400
335
  with:
401
336
  script: |
@@ -410,16 +345,6 @@ jobs:
410
345
  return await substitutePlaceholders({
411
346
  file: process.env.GH_AW_PROMPT,
412
347
  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
348
  GH_AW_MCP_CLI_SERVERS_LIST: process.env.GH_AW_MCP_CLI_SERVERS_LIST,
424
349
  GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED: process.env.GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED
425
350
  }
@@ -451,7 +376,7 @@ jobs:
451
376
  if: success() || failure()
452
377
  uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
453
378
  with:
454
- name: ${{ steps.artifact-prefix.outputs.prefix }}info
379
+ name: info
455
380
  path: /tmp/gh-aw/aw_info.json
456
381
  if-no-files-found: ignore
457
382
  retention-days: ${{ vars.GH_AW_DEFAULT_ARTIFACT_RETENTION_DAYS || '0' }}
@@ -463,7 +388,7 @@ jobs:
463
388
  if: success() || failure()
464
389
  uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
465
390
  with:
466
- name: ${{ steps.artifact-prefix.outputs.prefix }}activation
391
+ name: activation
467
392
  include-hidden-files: true
468
393
  path: |
469
394
  /tmp/gh-aw/aw_info.json
@@ -483,24 +408,24 @@ jobs:
483
408
 
484
409
  agent:
485
410
  name: agent
486
- needs: activation
487
- if: needs.activation.outputs.daily_ai_credits_exceeded != 'true'
411
+ needs:
412
+ - activation
413
+ - prepare
414
+ if: (needs.prepare.outputs.eligible == 'true') && (needs.activation.outputs.daily_ai_credits_exceeded != 'true')
488
415
  runs-on:
489
416
  - self-hosted
490
417
  - linux
491
- - lighthouse-sdlc
418
+ - lighthouse-workflow
492
419
  # Permissions for the agent job (workflow permissions default to none).
493
420
  permissions:
494
421
  contents: read
495
- concurrency:
496
- group: "gh-aw-copilot-lighthouse-sdlc-triage"
497
- queue: max
498
422
  timeout-minutes: 60
499
423
  env:
500
424
  DEFAULT_BRANCH: ${{ github.event.repository.default_branch }}
501
425
  GH_AW_ASSETS_ALLOWED_EXTS: ""
502
426
  GH_AW_ASSETS_BRANCH: ""
503
427
  GH_AW_ASSETS_MAX_SIZE_KB: 0
428
+ GH_AW_ENGINE_VERSION: "2.1.0"
504
429
  GH_AW_MCP_LOG_DIR: /tmp/gh-aw/mcp-logs/safeoutputs
505
430
  GH_AW_PR_HEAD_BASE_BRANCH: ""
506
431
  GH_AW_PR_HEAD_BASE_PR_NUMBER: ""
@@ -512,30 +437,16 @@ jobs:
512
437
  GH_AW_TARGET_REPO_SLUG: ""
513
438
  GH_AW_WORKFLOW_ID_SANITIZED: lighthousesdlctriage
514
439
  outputs:
515
- agentic_engine_timeout: ${{ steps.detect-agent-errors.outputs.agentic_engine_timeout || 'false' }}
516
440
  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 }}
519
- 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' }}
441
+ aic: ${{ steps.parse-mcp-gateway.outputs.aic }}
442
+ ambient_context: ${{ steps.parse-mcp-gateway.outputs.ambient_context }}
522
443
  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
444
  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
445
  output: ${{ steps.collect_output.outputs.output }}
534
446
  output_types: ${{ steps.collect_output.outputs.output_types }}
535
447
  setup-parent-span-id: ${{ steps.setup.outputs.parent-span-id || steps.setup.outputs.span-id }}
536
448
  setup-span-id: ${{ steps.setup.outputs.span-id }}
537
449
  setup-trace-id: ${{ steps.setup.outputs.trace-id }}
538
- shell_expansion_guard_rejected: ${{ steps.detect-agent-errors.outputs.shell_expansion_guard_rejected || 'false' }}
539
450
  unknown_model_ai_credits: ${{ steps.parse-mcp-gateway.outputs.unknown_model_ai_credits || 'false' }}
540
451
  steps:
541
452
  - name: Setup Scripts
@@ -547,11 +458,10 @@ jobs:
547
458
  trace-id: ${{ needs.activation.outputs.setup-trace-id }}
548
459
  parent-span-id: ${{ needs.activation.outputs.setup-parent-span-id || needs.activation.outputs.setup-span-id }}
549
460
  env:
550
- GH_AW_SETUP_WORKFLOW_NAME: "Lighthouse SDLC triage"
461
+ GH_AW_SETUP_WORKFLOW_NAME: "triage"
551
462
  GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/lighthouse-sdlc-triage.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"
463
+ GH_AW_INFO_VERSION: "2.1.0"
464
+ GH_AW_INFO_ENGINE_ID: "opencode"
555
465
  GH_AW_SETUP_AW_CONTEXT: ${{ inputs.aw_context }}
556
466
  - name: Set runtime paths
557
467
  id: set-runtime-paths
@@ -570,22 +480,12 @@ jobs:
570
480
  run: bash "${RUNNER_TEMP}/gh-aw/actions/mask_otlp_headers.sh"
571
481
  - name: Check OTLP telemetry configuration
572
482
  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
483
  - name: Initialize agent execution evidence
579
484
  run: |
580
485
  mkdir -p "/tmp/gh-aw"
581
486
  evidence_tmp="/tmp/gh-aw/agent_execution.json.tmp"
582
487
  printf '{"version":1,"component":"agent","run_id":%s,"run_attempt":%s,"state":"not_started"}\n' "$GITHUB_RUN_ID" "$GITHUB_RUN_ATTEMPT" > "$evidence_tmp"
583
488
  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
489
  - name: Create gh-aw temp directory
590
490
  run: bash "${RUNNER_TEMP}/gh-aw/actions/create_gh_aw_tmp_dir.sh"
591
491
  - name: Configure gh CLI for GitHub Enterprise
@@ -595,23 +495,30 @@ jobs:
595
495
  - name: Download activation artifact
596
496
  uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
597
497
  with:
598
- name: ${{ needs.activation.outputs.artifact_prefix }}activation
498
+ name: activation
599
499
  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
500
+ - name: Check out the authorized product revision
501
+ uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5
502
+ with:
503
+ persist-credentials: false
504
+ ref: ${{ needs.prepare.outputs.source_revision }}
505
+ - name: Setup Node.js
506
+ uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
507
+ with:
508
+ node-version: '24'
509
+ package-manager-cache: false
510
+ - name: Load the pinned harness package
511
+ uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5
512
+ with:
513
+ path: tools
514
+ persist-credentials: false
515
+ ref: __LIGHTHOUSE_REF__
516
+ repository: juangcarmona/lighthouse
517
+ - name: Load the authorized issue context
611
518
  uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
612
519
  with:
613
- name: lighthouse-sdlc-${{ inputs.run-id }}-${{ inputs.previous-stage }}
614
- path: /tmp/gh-aw/agent/previous
520
+ name: lighthouse-input-${{ inputs.issue }}-${{ github.run_attempt }}
521
+ path: ${{ runner.temp }}/lighthouse-${{ github.run_id }}-${{ github.run_attempt }}
615
522
 
616
523
  - name: Configure Git credentials
617
524
  env:
@@ -619,47 +526,6 @@ jobs:
619
526
  GITHUB_SERVER_URL: ${{ github.server_url }}
620
527
  GITHUB_TOKEN: ${{ github.token }}
621
528
  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
529
  - name: Restore inline sub-agents from activation artifact
664
530
  env:
665
531
  GH_AW_SUB_AGENT_DIR: ".github/agents"
@@ -670,7 +536,7 @@ jobs:
670
536
  GH_AW_SKILL_DIR: ".github/skills"
671
537
  run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_inline_skills.sh"
672
538
  - 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
539
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-node@sha256:41835613992df88f51e923bad486f96dfb2e6cda29f13e217df41833284ae382
674
540
  - name: Prepare Safe Outputs Directories
675
541
  run: |
676
542
  mkdir -p "${RUNNER_TEMP}/gh-aw/safeoutputs"
@@ -681,7 +547,7 @@ jobs:
681
547
  env:
682
548
  GH_AW_FILE_ROOT: "${{ runner.temp }}/gh-aw"
683
549
  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\":{}}"
550
+ GH_AW_SAFE_OUTPUTS_CONFIG: "{\"noop\":{\"max\":2,\"report-as-issue\":\"false\"}}"
685
551
  with:
686
552
  script: |
687
553
  const path = require('path');
@@ -710,68 +576,6 @@ jobs:
710
576
  "maxLength": 65000
711
577
  }
712
578
  }
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
579
  }
776
580
  }
777
581
  uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
@@ -791,10 +595,6 @@ jobs:
791
595
  GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
792
596
  GH_AW_SAFE_OUTPUTS_CONFIG_PATH: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS_CONFIG_PATH }}
793
597
  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
598
  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
799
599
  run: |
800
600
  set -eo pipefail
@@ -807,7 +607,7 @@ jobs:
807
607
 
808
608
  # Export gateway environment variables for MCP config and gateway script
809
609
  export MCP_GATEWAY_PORT="8080"
810
- export MCP_GATEWAY_DOMAIN="awmg-mcpg"
610
+ export MCP_GATEWAY_DOMAIN="localhost"
811
611
  export MCP_GATEWAY_HOST_DOMAIN="localhost"
812
612
  MCP_GATEWAY_AGENT_ID=$(openssl rand -base64 45 | tr -d '/+=')
813
613
  echo "::add-mask::${MCP_GATEWAY_AGENT_ID}"
@@ -823,36 +623,17 @@ jobs:
823
623
  export GH_AW_PR_HEAD_BASE_REF="${GH_AW_PR_HEAD_BASE_REF:-}"
824
624
  export GH_AW_PR_HEAD_REPO="${GH_AW_PR_HEAD_REPO:-}"
825
625
  export GH_AW_TARGET_REPO_SLUG="${GH_AW_TARGET_REPO_SLUG:-}"
826
- export GH_AW_ENGINE="copilot"
626
+ export GH_AW_ENGINE="opencode"
827
627
  MCP_GATEWAY_UID=$(id -u 2>/dev/null || echo '0')
828
628
  MCP_GATEWAY_GID=$(id -g 2>/dev/null || echo '0')
829
629
  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'
630
+ 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
631
 
832
- mkdir -p "$HOME/.copilot"
833
632
  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"
633
+ cat << GH_AW_MCP_CONFIG_6001799711bbe943_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs"
835
634
  {
836
635
  "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
636
  "safeoutputs": {
855
- "type": "stdio",
856
637
  "container": "ghcr.io/github/gh-aw-node@sha256:41835613992df88f51e923bad486f96dfb2e6cda29f13e217df41833284ae382",
857
638
  "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
639
  "args": ["-w", "\${GITHUB_WORKSPACE}"],
@@ -883,14 +664,6 @@ jobs:
883
664
  "GITHUB_TOKEN": "\${GITHUB_TOKEN}",
884
665
  "GITHUB_WORKSPACE": "\${GITHUB_WORKSPACE}",
885
666
  "RUNNER_TEMP": "\${RUNNER_TEMP}"
886
- },
887
- "guard-policies": {
888
- "write-sink": {
889
- "accept": [
890
- "*"
891
- ],
892
- "sink-visibility": "${GH_AW_SINK_VISIBILITY}"
893
- }
894
667
  }
895
668
  }
896
669
  },
@@ -907,7 +680,7 @@ jobs:
907
680
  }
908
681
  }
909
682
  }
910
- GH_AW_MCP_CONFIG_3db6aaf67c51d953_EOF
683
+ GH_AW_MCP_CONFIG_6001799711bbe943_EOF
911
684
  - name: Mount MCP servers as CLIs
912
685
  id: mount-mcp-clis
913
686
  continue-on-error: true
@@ -932,195 +705,69 @@ jobs:
932
705
  id: pre_agent_audit
933
706
  continue-on-error: true
934
707
  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
708
+ - name: Write OpenCode log parser script
709
+ if: always()
710
+ run: |
711
+ mkdir -p "${RUNNER_TEMP}/gh-aw/actions"
712
+ cat <<'GHAW_LOG_PARSER_SCRIPT_5d2e8b3f_EOF' > "${RUNNER_TEMP}/gh-aw/actions/opencode_log_parser.cjs"
713
+ // @ts-check
714
+ // Auto-generated log parser for behavior-defined engine "OpenCode".
715
+ const { createEngineLogParser } = require("./log_parser_shared.cjs");
716
+
717
+ // --- begin engine-provided parse function ---
718
+ function parseLog(logContent) {
719
+ const fs = require("fs");
720
+ const events = require("path").join(process.env.RUNNER_TEMP, "gh-aw", `opencode-events-${process.env.GITHUB_RUN_ID}-${process.env.GITHUB_RUN_ATTEMPT}.jsonl`);
721
+ return require("./parse_opencode_log.cjs").parseOpenCodeLog(fs.existsSync(events) ? fs.readFileSync(events, "utf8") : logContent);
722
+ }
723
+
724
+ // --- end engine-provided parse function ---
725
+
726
+ const main = createEngineLogParser({
727
+ parserName: "OpenCode",
728
+ parseFunction: parseLog,
729
+ supportsDirectories: false,
730
+ });
731
+
732
+ if (typeof module !== "undefined" && module.exports) {
733
+ module.exports = { main, parseLog };
734
+ }
735
+ GHAW_LOG_PARSER_SCRIPT_5d2e8b3f_EOF
736
+ chmod 755 "${RUNNER_TEMP}/gh-aw/actions/opencode_log_parser.cjs"
737
+ - name: OpenCode progress and result
948
738
  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') }}
739
+ timeout-minutes: 15
975
740
  run: |
976
741
  set -o pipefail
977
- printf '%s' "$(date +%s%3N)" > /tmp/gh-aw/agent_cli_start_ms.txt
978
742
  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
743
+ 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
744
  mkdir -p "/tmp/gh-aw"
1040
745
  evidence_tmp="/tmp/gh-aw/agent_execution.json.tmp"
1041
746
  printf '{"version":1,"component":"agent","run_id":%s,"run_attempt":%s,"state":"started"}\n' "$GITHUB_RUN_ID" "$GITHUB_RUN_ATTEMPT" > "$evidence_tmp"
1042
747
  mv "$evidence_tmp" "/tmp/gh-aw/agent_execution.json"
1043
748
  export GH_AW_AWF_EXECUTION_COMPONENT="agent"
1044
749
  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'
750
+ export no_proxy="${NO_PROXY:-}"
751
+ printf '%s' "$(date +%s%3N)" > /tmp/gh-aw/agent_cli_start_ms.txt
752
+ 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
753
  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
754
  GH_AW_ADMISSION_MAX_AI_CREDITS: ${{ needs.activation.outputs.admission-max-ai-credits }}
1059
755
  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
756
+ GH_AW_ENGINE_VERSION: 2.1.0
1062
757
  GH_AW_MAX_AI_CREDITS: ${{ vars.GH_AW_DEFAULT_MAX_AI_CREDITS || '1000' }}
1063
758
  GH_AW_MAX_TURNS: ${{ vars.GH_AW_DEFAULT_MAX_TURNS || '' }}
1064
- GH_AW_PHASE: agent
1065
759
  GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
1066
760
  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
761
  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]
762
+ 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
763
  RUNNER_TEMP: ${{ runner.temp }}
1084
764
  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
765
  - name: Configure Git credentials
1115
766
  env:
1116
767
  GITHUB_REPOSITORY: ${{ github.repository }}
1117
768
  GITHUB_SERVER_URL: ${{ github.server_url }}
1118
769
  GITHUB_TOKEN: ${{ github.token }}
1119
770
  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
771
  - name: Stop MCP Gateway
1125
772
  if: always()
1126
773
  continue-on-error: true
@@ -1143,10 +790,7 @@ jobs:
1143
790
  const { main } = require(path.join(actionsDir, 'redact_secrets.cjs'));
1144
791
  await main();
1145
792
  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 }}
793
+ GH_AW_SECRET_NAMES: 'GITHUB_TOKEN'
1150
794
  SECRET_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
1151
795
  - name: Append agent step summary
1152
796
  if: always()
@@ -1164,7 +808,6 @@ jobs:
1164
808
  uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
1165
809
  env:
1166
810
  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
811
  GITHUB_SERVER_URL: ${{ github.server_url }}
1169
812
  GITHUB_API_URL: ${{ github.api_url }}
1170
813
  with:
@@ -1179,7 +822,7 @@ jobs:
1179
822
  if: always()
1180
823
  uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
1181
824
  env:
1182
- GH_AW_AGENT_OUTPUT: /tmp/gh-aw/sandbox/agent/logs/
825
+ GH_AW_AGENT_OUTPUT: /tmp/gh-aw/agent-stdio.log
1183
826
  GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
1184
827
  with:
1185
828
  script: |
@@ -1187,7 +830,7 @@ jobs:
1187
830
  const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
1188
831
  const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs'));
1189
832
  setupGlobals(core, github, context, exec, io, getOctokit);
1190
- const { main } = require(path.join(actionsDir, 'parse_copilot_log.cjs'));
833
+ const { main } = require(path.join(actionsDir, 'opencode_log_parser.cjs'));
1191
834
  await main();
1192
835
  - name: Parse MCP Gateway logs for step summary
1193
836
  if: always()
@@ -1201,37 +844,6 @@ jobs:
1201
844
  setupGlobals(core, github, context, exec, io, getOctokit);
1202
845
  const { main } = require(path.join(actionsDir, 'parse_mcp_gateway_log.cjs'));
1203
846
  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
847
  - name: Generate observability summary
1236
848
  if: always()
1237
849
  uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
@@ -1249,34 +861,25 @@ jobs:
1249
861
  if [ ! -f /tmp/gh-aw/agent_output.json ]; then
1250
862
  echo '{"items":[]}' > /tmp/gh-aw/agent_output.json
1251
863
  fi
864
+ - name: Validate the Lighthouse result
865
+ run: node tools/src/packages/sdlc/src/issue-actions.mjs validate
1252
866
  - 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
867
+ name: Preserve the result and runtime receipt
868
+ uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
869
+ with:
870
+ if-no-files-found: error
871
+ name: lighthouse-result-${{ inputs.issue }}-${{ github.run_attempt }}
872
+ path: |
873
+ ${{ runner.temp }}/lighthouse-${{ github.run_id }}-${{ github.run_attempt }}/envelope.json
874
+ ${{ runner.temp }}/lighthouse-${{ github.run_id }}-${{ github.run_attempt }}/runtime.json
875
+ retention-days: ${{ vars.GH_AW_DEFAULT_ARTIFACT_RETENTION_DAYS || '14' }}
1273
876
  - if: always()
1274
- name: Upload stage evidence
877
+ name: Preserve OpenCode diagnostic events
1275
878
  uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
1276
879
  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
880
+ if-no-files-found: ignore
881
+ name: opencode-events-${{ inputs.issue }}-${{ github.run_attempt }}
882
+ path: ${{ runner.temp }}/gh-aw/opencode-events-${{ github.run_id }}-${{ github.run_attempt }}.jsonl
1280
883
  retention-days: ${{ vars.GH_AW_DEFAULT_ARTIFACT_RETENTION_DAYS || '14' }}
1281
884
 
1282
885
  # Small dedicated copy of the agent output so safe-output processing
@@ -1286,7 +889,7 @@ jobs:
1286
889
  continue-on-error: true
1287
890
  uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
1288
891
  with:
1289
- name: ${{ needs.activation.outputs.artifact_prefix }}agent-output-fallback
892
+ name: agent-output-fallback
1290
893
  path: |
1291
894
  /tmp/gh-aw/agent_output.json
1292
895
  /tmp/gh-aw/safeoutputs.jsonl
@@ -1301,7 +904,6 @@ jobs:
1301
904
  /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/model-routing.jsonl
1302
905
  /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl
1303
906
  /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/model-routing.jsonl
1304
- /tmp/gh-aw/awf-resolved-config.json
1305
907
  if-no-files-found: ignore
1306
908
  retention-days: ${{ vars.GH_AW_DEFAULT_ARTIFACT_RETENTION_DAYS || '0' }}
1307
909
  - name: Upload agent artifacts
@@ -1309,7 +911,7 @@ jobs:
1309
911
  continue-on-error: true
1310
912
  uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
1311
913
  with:
1312
- name: ${{ needs.activation.outputs.artifact_prefix }}agent
914
+ name: agent
1313
915
  path: |
1314
916
  /tmp/gh-aw/aw-prompts/prompt.txt
1315
917
  /tmp/gh-aw/agent_execution.json
@@ -1319,14 +921,7 @@ jobs:
1319
921
  /tmp/gh-aw/aw-prompts/user.txt
1320
922
  /tmp/gh-aw/aw-prompts/system.txt
1321
923
  /tmp/gh-aw/skill_inventory.json
1322
- /tmp/gh-aw/sandbox/agent/logs/
1323
- /tmp/gh-aw/redacted-urls.log
1324
924
  /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
925
  /tmp/gh-aw/agent-stdio.log
1331
926
  /tmp/gh-aw/pre-agent-audit.txt
1332
927
  /tmp/gh-aw/github_rate_limits.jsonl
@@ -1334,13 +929,6 @@ jobs:
1334
929
  /tmp/gh-aw/otlp-export-errors.jsonl
1335
930
  /tmp/gh-aw/safeoutputs.jsonl
1336
931
  /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
932
  if-no-files-found: ignore
1345
933
  retention-days: ${{ vars.GH_AW_DEFAULT_ARTIFACT_RETENTION_DAYS || '0' }}
1346
934
 
@@ -1349,33 +937,30 @@ jobs:
1349
937
  needs:
1350
938
  - activation
1351
939
  - agent
1352
- - detection
1353
- - safe_outputs
940
+ - prepare
941
+ - publish
1354
942
  if: >
1355
943
  always() && (needs.agent.result != 'skipped' || needs.activation.outputs.lockdown_check_failed == 'true' ||
1356
944
  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')
945
+ needs.activation.outputs.daily_ai_credits_exceeded == 'true' || needs.activation.outputs.daily_ai_credits_guardrail_status == 'structural_error' ||
946
+ needs.activation.outputs.daily_ai_credits_guardrail_status == 'transient_error')
1359
947
  runs-on: ubuntu-24.04
1360
948
  # Permissions for the conclusion job (workflow permissions default to none).
1361
949
  permissions:
1362
950
  actions: read
1363
951
  issues: write
1364
952
  concurrency:
1365
- group: "gh-aw-conclusion-lighthouse-sdlc-triage"
953
+ group: "gh-aw-conclusion-lighthouse-sdlc-triage-${{ github.run_id }}"
1366
954
  cancel-in-progress: false
1367
955
  queue: max
1368
956
  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}"
957
+ 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\"}"
958
+ GH_AW_JOB_RESULTS: "{\"activation\":{\"result\":\"${{ needs.activation.result }}\"},\"agent\":{\"result\":\"${{ needs.agent.result }}\"},\"prepare\":{\"result\":\"${{ needs.prepare.result }}\"},\"publish\":{\"result\":\"${{ needs.publish.result }}\"}}"
959
+ GH_AW_JOB_TIMING_ELIGIBLE: "{\"activation\":true,\"agent\":true,\"conclusion\":true,\"pre_activation\":true,\"prepare\":true,\"publish\":true}"
1372
960
  GH_AW_RUNTIME_FEATURES: ${{ vars.GH_AW_RUNTIME_FEATURES }}
1373
961
  outputs:
1374
- incomplete_count: ${{ steps.report_incomplete.outputs.incomplete_count }}
1375
962
  noop_comment_body: ${{ steps.noop.outputs.noop_comment_body }}
1376
963
  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
964
  steps:
1380
965
  - name: Setup Scripts
1381
966
  id: setup
@@ -1386,18 +971,17 @@ jobs:
1386
971
  trace-id: ${{ needs.activation.outputs.setup-trace-id }}
1387
972
  parent-span-id: ${{ needs.activation.outputs.setup-parent-span-id || needs.activation.outputs.setup-span-id }}
1388
973
  env:
1389
- GH_AW_SETUP_WORKFLOW_NAME: "Lighthouse SDLC triage"
974
+ GH_AW_SETUP_WORKFLOW_NAME: "triage"
1390
975
  GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/lighthouse-sdlc-triage.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"
976
+ GH_AW_INFO_VERSION: "2.1.0"
977
+ GH_AW_INFO_ENGINE_ID: "opencode"
1394
978
  GH_AW_SETUP_AW_CONTEXT: ${{ inputs.aw_context }}
1395
979
  - name: Download agent output artifact
1396
980
  id: download-agent-output
1397
981
  continue-on-error: true
1398
982
  uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
1399
983
  with:
1400
- pattern: "{${{ needs.activation.outputs.artifact_prefix }}agent,${{ needs.activation.outputs.artifact_prefix }}agent-output-fallback}"
984
+ pattern: "{agent,agent-output-fallback}"
1401
985
  merge-multiple: true
1402
986
  path: /tmp/gh-aw/
1403
987
  - name: Setup agent output environment variable
@@ -1409,27 +993,13 @@ jobs:
1409
993
  if [ -f "/tmp/gh-aw/agent_output.json" ]; then
1410
994
  echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT"
1411
995
  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
996
  - name: Download Safe Outputs Items Manifest
1427
997
  id: download-safe-outputs-manifest
1428
998
  if: always()
1429
999
  continue-on-error: true
1430
1000
  uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
1431
1001
  with:
1432
- pattern: ${{ needs.activation.outputs.artifact_prefix }}safe-outputs-items
1002
+ pattern: safe-outputs-items
1433
1003
  merge-multiple: true
1434
1004
  path: /tmp/gh-aw/
1435
1005
  - name: Process no-op messages
@@ -1437,16 +1007,16 @@ jobs:
1437
1007
  uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
1438
1008
  env:
1439
1009
  GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
1440
- GH_AW_NOOP_MAX: "1"
1441
- GH_AW_WORKFLOW_NAME: "Lighthouse SDLC triage"
1010
+ GH_AW_NOOP_MAX: "2"
1011
+ GH_AW_WORKFLOW_NAME: "triage"
1442
1012
  GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/lighthouse-sdlc-triage.md"
1443
- GH_AW_ENGINE_ID: "copilot"
1013
+ GH_AW_ENGINE_ID: "opencode"
1014
+ GH_AW_ENGINE_VERSION: "2.1.0"
1444
1015
  GH_AW_ENGINE_MODEL: ${{ needs.agent.outputs.model }}
1445
1016
  GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
1446
1017
  GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }}
1447
1018
  GH_AW_NOOP_REPORT_AS_ISSUE: "false"
1448
1019
  GH_AW_AIC: ${{ needs.agent.outputs.aic }}
1449
- GH_AW_THREAT_DETECTION_AIC: ${{ needs.detection.outputs.aic }}
1450
1020
  GH_AW_AMBIENT_CONTEXT: ${{ needs.agent.outputs.ambient_context }}
1451
1021
  GH_AW_WORKFLOW_ID: "lighthouse-sdlc-triage"
1452
1022
  with:
@@ -1458,98 +1028,24 @@ jobs:
1458
1028
  setupGlobals(core, github, context, exec, io, getOctokit);
1459
1029
  const { main } = require(path.join(actionsDir, 'handle_noop_message.cjs'));
1460
1030
  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 triage"
1467
- GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/lighthouse-sdlc-triage.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 triage"
1487
- GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/lighthouse-sdlc-triage.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 triage"
1506
- GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/lighthouse-sdlc-triage.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
1031
  - name: Handle agent failure
1519
1032
  id: handle_agent_failure
1520
1033
  if: always()
1521
1034
  uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
1522
1035
  env:
1523
1036
  GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
1524
- GH_AW_WORKFLOW_NAME: "Lighthouse SDLC triage"
1037
+ GH_AW_WORKFLOW_NAME: "triage"
1525
1038
  GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/lighthouse-sdlc-triage.md"
1526
1039
  GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
1527
1040
  GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }}
1528
1041
  GH_AW_WORKFLOW_ID: "lighthouse-sdlc-triage"
1529
1042
  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 }}
1043
+ GH_AW_ENGINE_ID: "opencode"
1535
1044
  GH_AW_AI_CREDITS_RATE_LIMIT_ERROR: ${{ needs.agent.outputs.ai_credits_rate_limit_error || 'false' }}
1536
1045
  GH_AW_UNKNOWN_MODEL_AI_CREDITS: ${{ needs.agent.outputs.unknown_model_ai_credits || 'false' }}
1537
1046
  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
1047
  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"
1048
+ GH_AW_DEFAULT_CHECKOUT_USES_TRIGGER_REF: "false"
1553
1049
  GH_AW_LOCKDOWN_CHECK_FAILED: ${{ needs.activation.outputs.lockdown_check_failed }}
1554
1050
  GH_AW_OAUTH_TOKEN_CHECK_FAILED: ${{ needs.activation.outputs.oauth_token_check_failed }}
1555
1051
  GH_AW_STALE_LOCK_FILE_FAILED: ${{ needs.activation.outputs.stale_lock_file_failed }}
@@ -1564,7 +1060,7 @@ jobs:
1564
1060
  GH_AW_FAILURE_REPORT_AS_ISSUE: "false"
1565
1061
  GH_AW_MISSING_TOOL_REPORT_AS_FAILURE: "true"
1566
1062
  GH_AW_MISSING_DATA_REPORT_AS_FAILURE: "true"
1567
- GH_AW_TIMEOUT_MINUTES: "${{ fromJSON(vars.GH_AW_DEFAULT_TIMEOUT_MINUTES || '20') }}"
1063
+ GH_AW_TIMEOUT_MINUTES: "15"
1568
1064
  with:
1569
1065
  github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
1570
1066
  script: |
@@ -1580,7 +1076,7 @@ jobs:
1580
1076
  uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
1581
1077
  env:
1582
1078
  GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
1583
- GH_AW_WORKFLOW_NAME: "Lighthouse SDLC triage"
1079
+ GH_AW_WORKFLOW_NAME: "triage"
1584
1080
  GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/lighthouse-sdlc-triage.md"
1585
1081
  GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
1586
1082
  GH_AW_REPORT_FAILED_JOBS: "true"
@@ -1596,10 +1092,6 @@ jobs:
1596
1092
  - name: Collect usage artifact files
1597
1093
  if: always()
1598
1094
  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
1095
  run: bash "${RUNNER_TEMP}/gh-aw/actions/collect_usage_artifact_files.sh"
1604
1096
  - name: Generate usage activity summary and unified session
1605
1097
  if: always()
@@ -1632,7 +1124,7 @@ jobs:
1632
1124
  continue-on-error: true
1633
1125
  uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
1634
1126
  with:
1635
- name: ${{ needs.activation.outputs.artifact_prefix }}usage
1127
+ name: usage
1636
1128
  path: |
1637
1129
  /tmp/gh-aw/usage/aw_session.jsonl
1638
1130
  /tmp/gh-aw/usage/aw_info.json
@@ -1667,7 +1159,7 @@ jobs:
1667
1159
  continue-on-error: true
1668
1160
  uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
1669
1161
  with:
1670
- name: ${{ needs.activation.outputs.artifact_prefix }}usage
1162
+ name: usage
1671
1163
  path: |
1672
1164
  /tmp/gh-aw/usage/aw_session.jsonl
1673
1165
  /tmp/gh-aw/usage/aw_info.json
@@ -1695,364 +1187,14 @@ jobs:
1695
1187
  overwrite: true
1696
1188
  retention-days: ${{ vars.GH_AW_DEFAULT_ARTIFACT_RETENTION_DAYS || '0' }}
1697
1189
 
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 triage"
1728
- GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/lighthouse-sdlc-triage.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 triage"
1806
- WORKFLOW_DESCRIPTION: "Execute only the Lighthouse triage 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 triage"
1879
- WORKFLOW_DESCRIPTION: "Execute only the Lighthouse triage 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
1190
  pre_activation:
2050
1191
  name: pre_activation
1192
+ needs: prepare
2051
1193
  runs-on: ubuntu-24.04
2052
1194
  env:
2053
1195
  GH_AW_RUNTIME_FEATURES: ${{ vars.GH_AW_RUNTIME_FEATURES }}
2054
1196
  outputs:
2055
- activated: ${{ steps.check_membership.outputs.is_team_member == 'true' }}
1197
+ activated: ${{ 'true' }}
2056
1198
  matched_command: ''
2057
1199
  setup-parent-span-id: ${{ steps.setup.outputs.parent-span-id || steps.setup.outputs.span-id }}
2058
1200
  setup-span-id: ${{ steps.setup.outputs.span-id }}
@@ -2065,104 +1207,77 @@ jobs:
2065
1207
  destination: ${{ runner.temp }}/gh-aw/actions
2066
1208
  job-name: ${{ github.job }}
2067
1209
  env:
2068
- GH_AW_SETUP_WORKFLOW_NAME: "Lighthouse SDLC triage"
1210
+ GH_AW_SETUP_WORKFLOW_NAME: "triage"
2069
1211
  GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/lighthouse-sdlc-triage.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"
1212
+ GH_AW_INFO_VERSION: "2.1.0"
1213
+ GH_AW_INFO_ENGINE_ID: "opencode"
2073
1214
  GH_AW_SETUP_AW_CONTEXT: ${{ inputs.aw_context }}
2074
- - name: Check team membership for workflow
2075
- id: check_membership
2076
- uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
2077
- env:
2078
- GH_AW_REQUIRED_ROLES: "admin,maintainer,write"
2079
- with:
2080
- github-token: ${{ secrets.GITHUB_TOKEN }}
2081
- script: |
2082
- const path = require('path');
2083
- const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
2084
- const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs'));
2085
- setupGlobals(core, github, context, exec, io, getOctokit);
2086
- const { main } = require(path.join(actionsDir, 'check_membership.cjs'));
2087
- await main();
2088
1215
 
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'
1216
+ prepare:
1217
+ name: Authorize and reserve issue
2096
1218
  runs-on: ubuntu-24.04
2097
- # Permissions for the safe_outputs job (workflow permissions default to none).
1219
+ # Permissions for the prepare job (workflow permissions default to none).
2098
1220
  permissions:
1221
+ actions: read
1222
+ contents: read
2099
1223
  issues: write
2100
- pull-requests: read
2101
- timeout-minutes: 45
2102
1224
  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-triage"
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-triage"
2115
- GH_AW_WORKFLOW_NAME: "Lighthouse SDLC triage"
2116
- GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/lighthouse-sdlc-triage.md"
1225
+ LIGHTHOUSE_ISSUE: ${{ inputs.issue }}
2117
1226
  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 }}
1227
+ eligible: ${{ steps.prepare.outputs.eligible }}
1228
+ source_revision: ${{ steps.prepare.outputs.source_revision }}
2131
1229
  steps:
2132
- - name: Setup Scripts
2133
- id: setup
2134
- uses: github/gh-aw-actions/setup@d9128eb3ea40c18b77c76184eda03c0ff2608d79 # v0.93.2
1230
+ - name: Configure GH_HOST for enterprise compatibility
1231
+ id: ghes-host-config
1232
+ shell: bash
1233
+ run: | # zizmor: ignore[github-env] - GITHUB_SERVER_URL is set by GitHub Actions, not user input.
1234
+ # Derive GH_HOST from GITHUB_SERVER_URL so the gh CLI targets the correct
1235
+ # GitHub instance (GHES/GHEC). On github.com this is a harmless no-op.
1236
+ GH_HOST="${GITHUB_SERVER_URL#https://}"
1237
+ GH_HOST="${GH_HOST#http://}"
1238
+ echo "GH_HOST=${GH_HOST}" >> "$GITHUB_ENV"
1239
+ - uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5
2135
1240
  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 }}
1241
+ persist-credentials: false
1242
+ ref: __LIGHTHOUSE_REF__
1243
+ repository: juangcarmona/lighthouse
1244
+ - uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5
1245
+ with:
1246
+ node-version: 24
1247
+ - name: Verify admission and reserve issue
1248
+ id: prepare
1249
+ run: node src/packages/sdlc/src/issue-actions.mjs prepare
2140
1250
  env:
2141
- GH_AW_SETUP_WORKFLOW_NAME: "Lighthouse SDLC triage"
2142
- GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/lighthouse-sdlc-triage.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
1251
+ GH_TOKEN: ${{ github.token }}
1252
+ - name: Preserve the execution request
1253
+ if: steps.prepare.outputs.eligible == 'true'
1254
+ uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
2153
1255
  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
1256
+ if-no-files-found: error
1257
+ name: lighthouse-input-${{ inputs.issue }}-${{ github.run_attempt }}
1258
+ path: ${{ runner.temp }}/lighthouse-${{ github.run_id }}-${{ github.run_attempt }}/
1259
+ retention-days: ${{ vars.GH_AW_DEFAULT_ARTIFACT_RETENTION_DAYS || '14' }}
1260
+ - name: Release reservation if preparation failed
1261
+ if: failure()
1262
+ run: node src/packages/sdlc/src/issue-actions.mjs cleanup
1263
+ env:
1264
+ GH_TOKEN: ${{ github.token }}
1265
+
1266
+ publish:
1267
+ name: Validate, publish and release
1268
+ needs:
1269
+ - agent
1270
+ - prepare
1271
+ if: always() && needs.prepare.result == 'success' && needs.prepare.outputs.eligible == 'true'
1272
+ runs-on: ubuntu-24.04
1273
+ # Permissions for the publish job (workflow permissions default to none).
1274
+ permissions:
1275
+ actions: read
1276
+ contents: read
1277
+ issues: write
1278
+ env:
1279
+ LIGHTHOUSE_ISSUE: ${{ inputs.issue }}
1280
+ steps:
2166
1281
  - name: Configure GH_HOST for enterprise compatibility
2167
1282
  id: ghes-host-config
2168
1283
  shell: bash
@@ -2172,36 +1287,35 @@ jobs:
2172
1287
  GH_HOST="${GITHUB_SERVER_URL#https://}"
2173
1288
  GH_HOST="${GH_HOST#http://}"
2174
1289
  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' }}
1290
+ - uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5
2188
1291
  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
1292
+ persist-credentials: false
1293
+ ref: __LIGHTHOUSE_REF__
1294
+ repository: juangcarmona/lighthouse
1295
+ - uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5
2200
1296
  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' }}
1297
+ node-version: 24
1298
+ - name: Load the execution request
1299
+ uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
1300
+ with:
1301
+ name: lighthouse-input-${{ inputs.issue }}-${{ github.run_attempt }}
1302
+ path: ${{ runner.temp }}/lighthouse-${{ github.run_id }}-${{ github.run_attempt }}
1303
+ - name: Load the candidate result
1304
+ if: needs.agent.result == 'success'
1305
+ uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
1306
+ with:
1307
+ name: lighthouse-result-${{ inputs.issue }}-${{ github.run_attempt }}
1308
+ path: ${{ runner.temp }}/lighthouse-${{ github.run_id }}-${{ github.run_attempt }}
1309
+ - name: Require an executed agent
1310
+ if: needs.agent.result != 'success'
1311
+ run: exit 1
1312
+ - name: Recheck authority and publish
1313
+ if: needs.agent.result == 'success'
1314
+ run: node src/packages/sdlc/src/issue-actions.mjs publish
1315
+ env:
1316
+ GH_TOKEN: ${{ github.token }}
1317
+ - name: Release reservation
1318
+ if: always()
1319
+ run: node src/packages/sdlc/src/issue-actions.mjs cleanup
1320
+ env:
1321
+ GH_TOKEN: ${{ github.token }}