@juangcarmona/lighthouse-sdlc 0.13.0 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/README.md +65 -12
  2. package/capabilities.json +3 -0
  3. package/completion.md +6 -4
  4. package/execution-environments.md +43 -0
  5. package/model-profiles.md +101 -0
  6. package/package.json +9 -1
  7. package/request-triage.md +30 -0
  8. package/schemas/estimate.schema.json +23 -0
  9. package/schemas/execution-environment.schema.json +12 -0
  10. package/schemas/request-analysis.schema.json +37 -0
  11. package/schemas/triage.schema.json +1 -0
  12. package/skills/concise-results/SKILL.md +10 -0
  13. package/skills/implement/SKILL.md +9 -8
  14. package/skills/refine/SKILL.md +1 -1
  15. package/skills/triage/SKILL.md +3 -3
  16. package/src/actions-artifact.mjs +17 -0
  17. package/src/completion-actions.mjs +30 -10
  18. package/src/completion.mjs +20 -1
  19. package/src/delivery-events.mjs +42 -0
  20. package/src/execution-environment.mjs +78 -0
  21. package/src/host-contract.mjs +3 -0
  22. package/src/implementation-runtime.mjs +56 -32
  23. package/src/implementation.mjs +36 -19
  24. package/src/install-workflows.mjs +16 -7
  25. package/src/integration-evidence.mjs +25 -1
  26. package/src/issue-actions.mjs +315 -49
  27. package/src/model-profiles.mjs +58 -0
  28. package/src/opencode-execute.mjs +35 -12
  29. package/src/pr-state-actions.mjs +106 -0
  30. package/src/pr-state.mjs +75 -0
  31. package/src/process-publication.mjs +1 -1
  32. package/src/profile-delegation.mjs +111 -0
  33. package/src/proposal-review.mjs +91 -0
  34. package/src/proposal.mjs +22 -8
  35. package/src/request-triage.mjs +42 -0
  36. package/src/stage-dispatch.mjs +164 -0
  37. package/src/stage-transition.mjs +35 -0
  38. package/src/triage.mjs +4 -0
  39. package/src/worker-maintenance.mjs +83 -0
  40. package/src/worker-recovery.mjs +106 -0
  41. package/src/worker-reports.mjs +150 -0
  42. package/templates/change-request.yml +24 -0
  43. package/workflows/lighthouse-sdlc-apply-review.lock.yml +1335 -0
  44. package/workflows/lighthouse-sdlc-apply-review.md +206 -0
  45. package/workflows/lighthouse-sdlc-implement.lock.yml +51 -90
  46. package/workflows/lighthouse-sdlc-implement.md +40 -11
  47. package/workflows/lighthouse-sdlc-integrate.lock.yml +36 -83
  48. package/workflows/lighthouse-sdlc-integrate.md +25 -2
  49. package/workflows/lighthouse-sdlc-propose.lock.yml +44 -83
  50. package/workflows/lighthouse-sdlc-propose.md +33 -4
  51. package/workflows/lighthouse-sdlc-refine.lock.yml +45 -83
  52. package/workflows/lighthouse-sdlc-refine.md +37 -2
  53. package/workflows/lighthouse-sdlc-review.lock.yml +36 -83
  54. package/workflows/lighthouse-sdlc-review.md +25 -2
  55. package/workflows/lighthouse-sdlc-router.yml +104 -63
  56. package/workflows/lighthouse-sdlc-triage.md +174 -28
  57. package/workflows/lighthouse-worker-maintenance.yml +126 -0
@@ -1,4 +1,4 @@
1
- # gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"09eb09c2dc6239ad8c14f48bf5aaad705b7821b5b6607be4ad2245c9fad409a7","body_hash":"7620b9d532d032c4c46661f502e587429d85d4316e8d327fc3e8db9cb0225569","compiler_version":"v0.93.2","agent_id":"opencode","engine_versions":{"opencode":"2.1.0"},"agent_image_runner":"[\"self-hosted\",\"linux\",\"lighthouse-workflow\"]"}
1
+ # gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"db0c930ff45621fb11e70279823b8fd907ac071c338bb7d4d69701a43830caaa","body_hash":"64c05adc2e6fd3f631b84ea421688ae91dfad6c946b0fb6f8dedf577c8c5bf2a","compiler_version":"v0.93.2","agent_id":"opencode","engine_versions":{"opencode":"2.1.0"},"agent_image_runner":"[\"self-hosted\",\"linux\",\"lighthouse-workflow\"]"}
2
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
  #
@@ -29,6 +29,11 @@
29
29
  # Imports:
30
30
  # - shared/lighthouse-opencode.md
31
31
  #
32
+ # Frontmatter env variables:
33
+ # - LIGHTHOUSE_DISPATCH_REQUIRED: (main workflow)
34
+ # - LIGHTHOUSE_RECOVERY_ENABLED: (main workflow)
35
+ # - LIGHTHOUSE_STAGE: (main workflow)
36
+ #
32
37
  # Secrets used:
33
38
  # - COPILOT_GITHUB_TOKEN
34
39
  # - GH_AW_DEFAULT_OTLP_ENDPOINT
@@ -52,38 +57,37 @@
52
57
 
53
58
  name: "Lighthouse SDLC propose"
54
59
  on:
55
- workflow_call:
60
+ # roles: all # Roles processed as role check in pre-activation job
61
+ workflow_dispatch:
56
62
  inputs:
57
63
  aw_context:
58
64
  default: ""
59
65
  description: "Agent caller context (Reserved for Agentic Workflows)."
60
66
  required: false
61
67
  type: string
68
+ dispatch-request:
69
+ description: Authenticated router receipt comment ID
70
+ required: true
71
+ type: string
62
72
  issue:
73
+ description: Source issue
63
74
  required: true
64
75
  type: string
65
- secrets:
66
- COPILOT_GITHUB_TOKEN:
67
- required: false
68
- GH_AW_DEFAULT_OTLP_ENDPOINT:
69
- required: false
70
- GH_AW_DEFAULT_OTLP_HEADERS:
71
- required: false
72
- GH_AW_GITHUB_MCP_SERVER_TOKEN:
73
- required: false
74
- GH_AW_GITHUB_TOKEN:
75
- required: false
76
76
 
77
77
  # Jobs receive only their explicitly declared permissions.
78
78
  permissions: {}
79
79
 
80
80
  concurrency:
81
- group: "gh-aw-lighthouse-sdlc-propose-${{ github.run_id }}"
81
+ cancel-in-progress: false
82
+ group: lighthouse-issue-${{ inputs.issue }}
82
83
  queue: max
83
84
 
84
- run-name: "Lighthouse SDLC propose"
85
+ run-name: "propose #${{ inputs.issue }} · request ${{ inputs.dispatch-request }}"
85
86
 
86
87
  env:
88
+ LIGHTHOUSE_DISPATCH_REQUIRED: "true"
89
+ LIGHTHOUSE_RECOVERY_ENABLED: ${{ vars.LIGHTHOUSE_RECOVERY_ENABLED }}
90
+ LIGHTHOUSE_STAGE: propose
87
91
  OTEL_EXPORTER_OTLP_ENDPOINT: ${{ secrets.GH_AW_DEFAULT_OTLP_ENDPOINT || vars.GH_AW_DEFAULT_OTLP_ENDPOINT }}
88
92
  OTEL_SERVICE_NAME: gh-aw.lighthouse-sdlc-propose
89
93
  OTEL_RESOURCE_ATTRIBUTES: 'gh-aw.workflow.name=Lighthouse%20SDLC%20propose,gh-aw.repository=${{ github.repository }},gh-aw.run.id=${{ github.run_id }},github.run_id=${{ github.run_id }},gh-aw.engine.id=opencode'
@@ -97,7 +101,7 @@ jobs:
97
101
  needs:
98
102
  - pre_activation
99
103
  - prepare
100
- if: needs.pre_activation.outputs.activated == 'true'
104
+ if: needs.pre_activation.outputs.activated == 'true' && (needs.prepare.outputs.eligible == 'true')
101
105
  runs-on: ubuntu-24.04
102
106
  # Permissions for the activation job (workflow permissions default to none).
103
107
  permissions:
@@ -107,7 +111,6 @@ jobs:
107
111
  GH_AW_MAX_DAILY_AI_CREDITS: ${{ vars.GH_AW_DEFAULT_MAX_DAILY_AI_CREDITS || '5000' }}
108
112
  GH_AW_RUNTIME_FEATURES: ${{ vars.GH_AW_RUNTIME_FEATURES }}
109
113
  outputs:
110
- artifact_prefix: ${{ steps.artifact-prefix.outputs.prefix }}
111
114
  aw_context: ${{ steps.generate_aw_info.outputs.aw_context }}
112
115
  comment_id: ""
113
116
  comment_repo: ""
@@ -125,10 +128,6 @@ jobs:
125
128
  setup-span-id: ${{ steps.setup.outputs.span-id }}
126
129
  setup-trace-id: ${{ steps.setup.outputs.trace-id }}
127
130
  stale_lock_file_failed: ${{ steps.check-lock-file.outputs.stale_lock_file_failed == 'true' }}
128
- target_checkout_ref: ${{ steps.resolve-host-repo.outputs.target_checkout_ref }}
129
- target_ref: ${{ steps.resolve-host-repo.outputs.target_ref }}
130
- target_repo: ${{ steps.resolve-host-repo.outputs.target_repo }}
131
- target_repo_name: ${{ steps.resolve-host-repo.outputs.target_repo_name }}
132
131
  steps:
133
132
  - name: Setup Scripts
134
133
  id: setup
@@ -147,27 +146,6 @@ jobs:
147
146
  GH_AW_SETUP_AW_CONTEXT: ${{ inputs.aw_context }}
148
147
  - name: Mask OTLP telemetry headers
149
148
  run: bash "${RUNNER_TEMP}/gh-aw/actions/mask_otlp_headers.sh"
150
- - name: Resolve host repo for activation checkout
151
- id: resolve-host-repo
152
- uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
153
- env:
154
- JOB_WORKFLOW_REPOSITORY: ${{ job.workflow_repository }}
155
- JOB_WORKFLOW_SHA: ${{ job.workflow_sha }}
156
- JOB_WORKFLOW_REF: ${{ job.workflow_ref }}
157
- JOB_WORKFLOW_FILE_PATH: ${{ job.workflow_file_path }}
158
- with:
159
- script: |
160
- const path = require('path');
161
- const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
162
- const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs'));
163
- setupGlobals(core, github, context, exec, io, getOctokit);
164
- const { main } = require(path.join(actionsDir, 'resolve_host_repo.cjs'));
165
- await main();
166
- - name: Compute artifact prefix
167
- id: artifact-prefix
168
- env:
169
- INPUTS_JSON: ${{ toJSON(inputs) }}
170
- run: bash "${RUNNER_TEMP}/gh-aw/actions/compute_artifact_prefix.sh"
171
149
  - name: Generate agentic run info
172
150
  id: generate_aw_info
173
151
  env:
@@ -190,7 +168,6 @@ jobs:
190
168
  GH_AW_INFO_AGENT_RUNTIME: ""
191
169
  GH_AW_INFO_MODEL_CONFIG: '{"routing":{"enabled":false}}'
192
170
  GH_AW_COMPILED_STRICT: "false"
193
- GH_AW_INFO_TARGET_REPO: ${{ steps.resolve-host-repo.outputs.target_repo }}
194
171
  GH_AW_INFO_FEATURES: '{"dangerously-disable-sandbox-agent":true}'
195
172
  uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
196
173
  with:
@@ -262,19 +239,10 @@ jobs:
262
239
  COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
263
240
  GH_AW_GITHUB_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN }}
264
241
  GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }}
265
- - name: Print cross-repo setup guidance
266
- if: failure() && steps.resolve-host-repo.outputs.target_repo != github.repository
267
- run: |
268
- echo "::error::COPILOT_GITHUB_TOKEN must be configured in the CALLER repository's secrets."
269
- echo "::error::For cross-repo workflow_call, secrets must be set in the repository that triggers the workflow."
270
- echo "::error::See: https://github.github.com/gh-aw/patterns/central-repo-ops/#cross-repo-setup"
271
242
  - name: Checkout .github and .agents folders
272
- if: steps.resolve-host-repo.outputs.target_repo == github.repository
273
243
  uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
274
244
  with:
275
245
  persist-credentials: false
276
- repository: ${{ steps.resolve-host-repo.outputs.target_repo }}
277
- ref: ${{ steps.resolve-host-repo.outputs.target_checkout_ref }}
278
246
  sparse-checkout: |
279
247
  .github
280
248
  .agents
@@ -408,7 +376,7 @@ jobs:
408
376
  if: success() || failure()
409
377
  uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
410
378
  with:
411
- name: ${{ steps.artifact-prefix.outputs.prefix }}info
379
+ name: info
412
380
  path: /tmp/gh-aw/aw_info.json
413
381
  if-no-files-found: ignore
414
382
  retention-days: ${{ vars.GH_AW_DEFAULT_ARTIFACT_RETENTION_DAYS || '0' }}
@@ -420,7 +388,7 @@ jobs:
420
388
  if: success() || failure()
421
389
  uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
422
390
  with:
423
- name: ${{ steps.artifact-prefix.outputs.prefix }}activation
391
+ name: activation
424
392
  include-hidden-files: true
425
393
  path: |
426
394
  /tmp/gh-aw/aw_info.json
@@ -443,7 +411,7 @@ jobs:
443
411
  needs:
444
412
  - activation
445
413
  - prepare
446
- if: needs.activation.outputs.daily_ai_credits_exceeded != 'true'
414
+ if: (needs.prepare.outputs.eligible == 'true') && (needs.activation.outputs.daily_ai_credits_exceeded != 'true')
447
415
  runs-on:
448
416
  - self-hosted
449
417
  - linux
@@ -451,9 +419,6 @@ jobs:
451
419
  # Permissions for the agent job (workflow permissions default to none).
452
420
  permissions:
453
421
  contents: read
454
- concurrency:
455
- group: "gh-aw-opencode-lighthouse-sdlc-propose"
456
- queue: max
457
422
  timeout-minutes: 60
458
423
  env:
459
424
  DEFAULT_BRANCH: ${{ github.event.repository.default_branch }}
@@ -475,7 +440,6 @@ jobs:
475
440
  ai_credits_rate_limit_error: ${{ steps.parse-mcp-gateway.outputs.ai_credits_rate_limit_error || 'false' }}
476
441
  aic: ${{ steps.parse-mcp-gateway.outputs.aic }}
477
442
  ambient_context: ${{ steps.parse-mcp-gateway.outputs.ambient_context }}
478
- artifact_prefix: ${{ needs.activation.outputs.artifact_prefix }}
479
443
  has_patch: ${{ steps.collect_output.outputs.has_patch }}
480
444
  model: ${{ needs.activation.outputs.model }}
481
445
  output: ${{ steps.collect_output.outputs.output }}
@@ -531,12 +495,13 @@ jobs:
531
495
  - name: Download activation artifact
532
496
  uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
533
497
  with:
534
- name: ${{ needs.activation.outputs.artifact_prefix }}activation
498
+ name: activation
535
499
  path: /tmp/gh-aw
536
500
  - name: Check out the authorized product revision
537
501
  uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5
538
502
  with:
539
503
  persist-credentials: false
504
+ ref: ${{ needs.prepare.outputs.source_revision }}
540
505
  - name: Setup Node.js
541
506
  uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
542
507
  with:
@@ -924,7 +889,7 @@ jobs:
924
889
  continue-on-error: true
925
890
  uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
926
891
  with:
927
- name: ${{ needs.activation.outputs.artifact_prefix }}agent-output-fallback
892
+ name: agent-output-fallback
928
893
  path: |
929
894
  /tmp/gh-aw/agent_output.json
930
895
  /tmp/gh-aw/safeoutputs.jsonl
@@ -946,7 +911,7 @@ jobs:
946
911
  continue-on-error: true
947
912
  uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
948
913
  with:
949
- name: ${{ needs.activation.outputs.artifact_prefix }}agent
914
+ name: agent
950
915
  path: |
951
916
  /tmp/gh-aw/aw-prompts/prompt.txt
952
917
  /tmp/gh-aw/agent_execution.json
@@ -985,7 +950,7 @@ jobs:
985
950
  actions: read
986
951
  issues: write
987
952
  concurrency:
988
- group: "gh-aw-conclusion-lighthouse-sdlc-propose"
953
+ group: "gh-aw-conclusion-lighthouse-sdlc-propose-${{ github.run_id }}"
989
954
  cancel-in-progress: false
990
955
  queue: max
991
956
  env:
@@ -1016,7 +981,7 @@ jobs:
1016
981
  continue-on-error: true
1017
982
  uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
1018
983
  with:
1019
- pattern: "{${{ needs.activation.outputs.artifact_prefix }}agent,${{ needs.activation.outputs.artifact_prefix }}agent-output-fallback}"
984
+ pattern: "{agent,agent-output-fallback}"
1020
985
  merge-multiple: true
1021
986
  path: /tmp/gh-aw/
1022
987
  - name: Setup agent output environment variable
@@ -1034,7 +999,7 @@ jobs:
1034
999
  continue-on-error: true
1035
1000
  uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
1036
1001
  with:
1037
- pattern: ${{ needs.activation.outputs.artifact_prefix }}safe-outputs-items
1002
+ pattern: safe-outputs-items
1038
1003
  merge-multiple: true
1039
1004
  path: /tmp/gh-aw/
1040
1005
  - name: Process no-op messages
@@ -1159,7 +1124,7 @@ jobs:
1159
1124
  continue-on-error: true
1160
1125
  uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
1161
1126
  with:
1162
- name: ${{ needs.activation.outputs.artifact_prefix }}usage
1127
+ name: usage
1163
1128
  path: |
1164
1129
  /tmp/gh-aw/usage/aw_session.jsonl
1165
1130
  /tmp/gh-aw/usage/aw_info.json
@@ -1194,7 +1159,7 @@ jobs:
1194
1159
  continue-on-error: true
1195
1160
  uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
1196
1161
  with:
1197
- name: ${{ needs.activation.outputs.artifact_prefix }}usage
1162
+ name: usage
1198
1163
  path: |
1199
1164
  /tmp/gh-aw/usage/aw_session.jsonl
1200
1165
  /tmp/gh-aw/usage/aw_info.json
@@ -1229,7 +1194,7 @@ jobs:
1229
1194
  env:
1230
1195
  GH_AW_RUNTIME_FEATURES: ${{ vars.GH_AW_RUNTIME_FEATURES }}
1231
1196
  outputs:
1232
- activated: ${{ steps.check_membership.outputs.is_team_member == 'true' }}
1197
+ activated: ${{ 'true' }}
1233
1198
  matched_command: ''
1234
1199
  setup-parent-span-id: ${{ steps.setup.outputs.parent-span-id || steps.setup.outputs.span-id }}
1235
1200
  setup-span-id: ${{ steps.setup.outputs.span-id }}
@@ -1247,20 +1212,6 @@ jobs:
1247
1212
  GH_AW_INFO_VERSION: "2.1.0"
1248
1213
  GH_AW_INFO_ENGINE_ID: "opencode"
1249
1214
  GH_AW_SETUP_AW_CONTEXT: ${{ inputs.aw_context }}
1250
- - name: Check team membership for workflow
1251
- id: check_membership
1252
- uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
1253
- env:
1254
- GH_AW_REQUIRED_ROLES: "admin,maintainer,write"
1255
- with:
1256
- github-token: ${{ secrets.GITHUB_TOKEN }}
1257
- script: |
1258
- const path = require('path');
1259
- const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
1260
- const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs'));
1261
- setupGlobals(core, github, context, exec, io, getOctokit);
1262
- const { main } = require(path.join(actionsDir, 'check_membership.cjs'));
1263
- await main();
1264
1215
 
1265
1216
  prepare:
1266
1217
  name: Authorize and reserve issue
@@ -1270,8 +1221,12 @@ jobs:
1270
1221
  actions: read
1271
1222
  contents: read
1272
1223
  issues: write
1224
+ pull-requests: read
1273
1225
  env:
1274
1226
  LIGHTHOUSE_ISSUE: ${{ inputs.issue }}
1227
+ outputs:
1228
+ eligible: ${{ steps.prepare.outputs.eligible }}
1229
+ source_revision: ${{ steps.prepare.outputs.source_revision }}
1275
1230
  steps:
1276
1231
  - name: Configure GH_HOST for enterprise compatibility
1277
1232
  id: ghes-host-config
@@ -1296,6 +1251,7 @@ jobs:
1296
1251
  env:
1297
1252
  GH_TOKEN: ${{ github.token }}
1298
1253
  - name: Preserve the execution request
1254
+ if: steps.prepare.outputs.eligible == 'true'
1299
1255
  uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
1300
1256
  with:
1301
1257
  if-no-files-found: error
@@ -1313,7 +1269,7 @@ jobs:
1313
1269
  needs:
1314
1270
  - agent
1315
1271
  - prepare
1316
- if: always() && needs.prepare.result == 'success'
1272
+ if: always() && needs.prepare.result == 'success' && needs.prepare.outputs.eligible == 'true'
1317
1273
  runs-on: ubuntu-24.04
1318
1274
  # Permissions for the publish job (workflow permissions default to none).
1319
1275
  permissions:
@@ -1351,6 +1307,11 @@ jobs:
1351
1307
  with:
1352
1308
  name: lighthouse-result-${{ inputs.issue }}-${{ github.run_attempt }}
1353
1309
  path: ${{ runner.temp }}/lighthouse-${{ github.run_id }}-${{ github.run_attempt }}
1310
+ - name: Require an executed agent
1311
+ if: needs.agent.result != 'success'
1312
+ run: |
1313
+ echo 'The authorized agent did not complete successfully; inspect its execution.' >&2
1314
+ exit 1
1354
1315
  - name: Recheck authority and publish the validated result
1355
1316
  if: needs.agent.result == 'success'
1356
1317
  run: node src/packages/sdlc/src/issue-actions.mjs publish
@@ -2,16 +2,34 @@
2
2
  # Owned by lighthouse-sdlc. Regenerate the lock with gh aw v0.93.2.
3
3
  name: Lighthouse SDLC propose
4
4
  description: Produce a validated OpenSpec proposal PR from an owner-authorized ready issue.
5
+ run-name: "propose #${{ inputs.issue }} · request ${{ inputs.dispatch-request }}"
6
+ concurrency:
7
+ group: lighthouse-issue-${{ inputs.issue }}
8
+ cancel-in-progress: false
9
+ queue: max
10
+ job-discriminator: ${{ github.run_id }}
5
11
  on:
6
- workflow_call:
12
+ # The required preparation job authenticates the originating owner request.
13
+ roles: all
14
+ workflow_dispatch:
7
15
  inputs:
8
16
  issue:
17
+ description: Source issue
18
+ required: true
19
+ type: string
20
+ dispatch-request:
21
+ description: Authenticated router receipt comment ID
9
22
  required: true
10
23
  type: string
11
24
  needs: [prepare]
25
+ if: needs.prepare.outputs.eligible == 'true'
12
26
  runs-on: [self-hosted, linux, lighthouse-workflow]
13
27
  runs-on-slim: ubuntu-24.04
14
28
  timeout-minutes: 15
29
+ env:
30
+ LIGHTHOUSE_RECOVERY_ENABLED: ${{ vars.LIGHTHOUSE_RECOVERY_ENABLED }}
31
+ LIGHTHOUSE_STAGE: propose
32
+ LIGHTHOUSE_DISPATCH_REQUIRED: "true"
15
33
  permissions:
16
34
  contents: read
17
35
  engine:
@@ -44,6 +62,7 @@ steps:
44
62
  uses: actions/checkout@v5
45
63
  with:
46
64
  persist-credentials: false
65
+ ref: ${{ needs.prepare.outputs.source_revision }}
47
66
  - name: Load the pinned harness package
48
67
  uses: actions/checkout@v5
49
68
  with:
@@ -79,12 +98,16 @@ post-steps:
79
98
  retention-days: 14
80
99
  jobs:
81
100
  prepare:
101
+ outputs:
102
+ eligible: ${{ steps.prepare.outputs.eligible }}
103
+ source_revision: ${{ steps.prepare.outputs.source_revision }}
82
104
  name: Authorize and reserve issue
83
105
  runs-on: ubuntu-24.04
84
106
  permissions:
85
107
  actions: read
86
108
  contents: read
87
109
  issues: write
110
+ pull-requests: read
88
111
  env:
89
112
  LIGHTHOUSE_ISSUE: ${{ inputs.issue }}
90
113
  steps:
@@ -102,6 +125,7 @@ jobs:
102
125
  GH_TOKEN: ${{ github.token }}
103
126
  run: node src/packages/sdlc/src/issue-actions.mjs prepare
104
127
  - name: Preserve the execution request
128
+ if: steps.prepare.outputs.eligible == 'true'
105
129
  uses: actions/upload-artifact@v7
106
130
  with:
107
131
  name: lighthouse-input-${{ inputs.issue }}-${{ github.run_attempt }}
@@ -116,7 +140,7 @@ jobs:
116
140
  publish:
117
141
  name: Validate, publish and release
118
142
  needs: [prepare, agent]
119
- if: always() && needs.prepare.result == 'success'
143
+ if: always() && needs.prepare.result == 'success' && needs.prepare.outputs.eligible == 'true'
120
144
  runs-on: ubuntu-24.04
121
145
  permissions:
122
146
  contents: write
@@ -144,6 +168,11 @@ jobs:
144
168
  with:
145
169
  name: lighthouse-result-${{ inputs.issue }}-${{ github.run_attempt }}
146
170
  path: ${{ runner.temp }}/lighthouse-${{ github.run_id }}-${{ github.run_attempt }}
171
+ - name: Require an executed agent
172
+ if: needs.agent.result != 'success'
173
+ run: |
174
+ echo 'The authorized agent did not complete successfully; inspect its execution.' >&2
175
+ exit 1
147
176
  - name: Recheck authority and publish the validated result
148
177
  if: needs.agent.result == 'success'
149
178
  env:
@@ -158,10 +187,10 @@ jobs:
158
187
 
159
188
  # Propose the authorized change
160
189
 
161
- Execute only `propose` using the trusted context in `/input/context.json` and the packaged `/harness/skills/propose/SKILL.md`. The host has authenticated the passed refinement and the owner's explicit request. Inspect the current read-only source under `/workspace`, including product and architecture policy, relevant existing specifications and active changes.
190
+ Execute only `propose` using the trusted context in `/input/context.json` and the packaged `/harness/skills/propose/SKILL.md`. For an initial proposal, the host supplies the authenticated passed refinement. When `context.proposalReview` is present, revise its existing files using the verified owner feedback and discussion; the request authorizes revision of that candidate, not acceptance or implementation. Inspect the current read-only source under `/workspace`, including product and architecture policy, relevant existing specifications and active changes.
162
191
 
163
192
  Write brief public progress before source inspection and when you choose an approach or find a blocker. Explain the decision and supporting evidence. Keep tool payloads out of progress messages.
164
193
 
165
194
  Follow `context.proposal.instructions` from the pinned OpenSpec provider, in order: proposal, specifications and design, then tasks. Return the actual Markdown files in `result.output.files`, each with `path` and `content`, under the authorized `context.proposal.root`. Include a concise proposal, design alternatives and trade-offs, testable specification scenarios, dependency-ordered unchecked tasks, validation and visual evidence plans where applicable. Every refined acceptance criterion needs a corresponding task or specification. Preserve existing product authority. Keep unresolved product decisions explicit rather than inventing approval.
166
195
 
167
- Write `/output/envelope.json` using the supplied schema and identity. A complete proposal returns `passed` with gate `planned`; it is a candidate for owner review, not approved implementation. Return `blocked` with the precise missing decision when the proposal cannot be completed. The separate publisher checks the file boundary, runs OpenSpec strict validation and opens a proposal PR. The engine writes no repository files and has no GitHub credentials. End after the envelope; the trusted adapter records gh-aw completion.
196
+ Write `/output/envelope.json` using the supplied schema and identity. A complete proposal returns `passed` with gate `planned`; it is a candidate for owner review, not approved implementation. Return `blocked` with the precise missing decision when the proposal cannot be completed. The separate publisher checks the file boundary, runs OpenSpec strict validation and opens a proposal PR or updates the existing PR identified by `context.proposalReview`. The engine writes no repository files and has no GitHub credentials. End after the envelope; the trusted adapter records gh-aw completion.