@juangcarmona/lighthouse-sdlc 0.17.1 → 0.18.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 (61) hide show
  1. package/README.md +15 -3
  2. package/capabilities.json +2 -1
  3. package/epic-delivery.md +35 -0
  4. package/github-actions.md +19 -3
  5. package/host-contract.md +2 -0
  6. package/package.json +4 -1
  7. package/schemas/product-change.schema.json +23 -4
  8. package/schemas/stage-result.schema.json +23 -1
  9. package/skills/product-change/SKILL.md +3 -3
  10. package/skills/refine/SKILL.md +3 -2
  11. package/src/completion-actions.mjs +49 -12
  12. package/src/completion.mjs +1 -1
  13. package/src/contracts.mjs +10 -0
  14. package/src/decompose.mjs +5 -2
  15. package/src/epic-dispatch.mjs +59 -0
  16. package/src/epic-github.mjs +111 -0
  17. package/src/epic-journal.mjs +104 -0
  18. package/src/epic-merge.mjs +91 -0
  19. package/src/epic-native.mjs +465 -0
  20. package/src/epic.mjs +86 -0
  21. package/src/handoff.mjs +97 -0
  22. package/src/host-contract.mjs +22 -6
  23. package/src/implementation.mjs +33 -5
  24. package/src/install-workflows.mjs +1 -1
  25. package/src/issue-actions.mjs +360 -78
  26. package/src/opencode-execute.mjs +20 -0
  27. package/src/pr-state-actions.mjs +21 -7
  28. package/src/pr-state.mjs +18 -1
  29. package/src/product-change-actions.mjs +158 -46
  30. package/src/product-change.mjs +92 -11
  31. package/src/proposal-review.mjs +16 -6
  32. package/src/proposal.mjs +13 -1
  33. package/src/stacked.mjs +14 -3
  34. package/src/stage-dispatch.mjs +66 -19
  35. package/src/stage-transition.mjs +151 -2
  36. package/src/triage.mjs +4 -2
  37. package/src/unattended-actions.mjs +39 -12
  38. package/src/unattended.mjs +1 -1
  39. package/src/worker-maintenance.mjs +15 -3
  40. package/src/worker-recovery.mjs +204 -6
  41. package/workflows/lighthouse-sdlc-apply-product-change.lock.yml +97 -11
  42. package/workflows/lighthouse-sdlc-apply-product-change.md +75 -6
  43. package/workflows/lighthouse-sdlc-apply-review.lock.yml +33 -2
  44. package/workflows/lighthouse-sdlc-apply-review.md +29 -1
  45. package/workflows/lighthouse-sdlc-epic.yml +79 -0
  46. package/workflows/lighthouse-sdlc-implement.lock.yml +38 -2
  47. package/workflows/lighthouse-sdlc-implement.md +33 -2
  48. package/workflows/lighthouse-sdlc-integrate.lock.yml +4 -1
  49. package/workflows/lighthouse-sdlc-integrate.md +3 -0
  50. package/workflows/lighthouse-sdlc-product-change.lock.yml +39 -4
  51. package/workflows/lighthouse-sdlc-product-change.md +39 -6
  52. package/workflows/lighthouse-sdlc-propose.lock.yml +13 -1
  53. package/workflows/lighthouse-sdlc-propose.md +11 -1
  54. package/workflows/lighthouse-sdlc-refine.lock.yml +29 -2
  55. package/workflows/lighthouse-sdlc-refine.md +25 -2
  56. package/workflows/lighthouse-sdlc-review.lock.yml +4 -1
  57. package/workflows/lighthouse-sdlc-review.md +3 -0
  58. package/workflows/lighthouse-sdlc-router.yml +47 -3
  59. package/workflows/lighthouse-sdlc-triage.lock.yml +30 -3
  60. package/workflows/lighthouse-sdlc-triage.md +26 -3
  61. package/workflows/lighthouse-worker-maintenance.yml +70 -1
@@ -1,4 +1,4 @@
1
- # gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"336bd2322457ccac362ef352c4c943c30fbec9436dc66f6068236e5581def067","body_hash":"8151890e19043f86541decb00d0dc86741daec051c004feb7beab27b025e3621","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":"2e0f36cc4374427b7e70b9fb667e4317a4e885f86a5d3416a8e6a9bdc78ef855","body_hash":"8151890e19043f86541decb00d0dc86741daec051c004feb7beab27b025e3621","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
  #
@@ -31,6 +31,7 @@
31
31
  #
32
32
  # Frontmatter env variables:
33
33
  # - LIGHTHOUSE_DISPATCH_REQUIRED: (main workflow)
34
+ # - LIGHTHOUSE_EPIC_CAPACITY: (main workflow)
34
35
  # - LIGHTHOUSE_RECOVERY_ENABLED: (main workflow)
35
36
  # - LIGHTHOUSE_WORKER: (main workflow)
36
37
  #
@@ -69,6 +70,10 @@ on:
69
70
  description: Authenticated router receipt comment ID
70
71
  required: true
71
72
  type: string
73
+ epic-parent:
74
+ description: Authenticated parent issue for shared epic serialization
75
+ required: false
76
+ type: string
72
77
  issue:
73
78
  description: Source issue
74
79
  required: true
@@ -79,13 +84,14 @@ permissions: {}
79
84
 
80
85
  concurrency:
81
86
  cancel-in-progress: false
82
- group: lighthouse-issue-${{ inputs.issue }}
87
+ group: ${{ inputs.epic-parent && format('lighthouse-epic-child-{0}', inputs.issue) || format('lighthouse-issue-{0}', inputs.issue) }}
83
88
  queue: max
84
89
 
85
90
  run-name: "apply-review #${{ inputs.issue }} · request ${{ inputs.dispatch-request }}"
86
91
 
87
92
  env:
88
93
  LIGHTHOUSE_DISPATCH_REQUIRED: "true"
94
+ LIGHTHOUSE_EPIC_CAPACITY: ${{ vars.LIGHTHOUSE_EPIC_CAPACITY }}
89
95
  LIGHTHOUSE_RECOVERY_ENABLED: ${{ vars.LIGHTHOUSE_RECOVERY_ENABLED }}
90
96
  LIGHTHOUSE_WORKER: apply-review
91
97
  OTEL_EXPORTER_OTLP_ENDPOINT: ${{ secrets.GH_AW_DEFAULT_OTLP_ENDPOINT || vars.GH_AW_DEFAULT_OTLP_ENDPOINT }}
@@ -1232,6 +1238,11 @@ jobs:
1232
1238
  contents: read
1233
1239
  issues: write
1234
1240
  pull-requests: write
1241
+ concurrency:
1242
+ cancel-in-progress: false
1243
+ group: ${{ inputs.epic-parent && format('lighthouse-issue-{0}', inputs.epic-parent) || format('lighthouse-prepare-{0}', github.run_id) }}
1244
+ queue: max
1245
+
1235
1246
  env:
1236
1247
  LIGHTHOUSE_ISSUE: ${{ inputs.issue }}
1237
1248
  outputs:
@@ -1274,6 +1285,7 @@ jobs:
1274
1285
  run: node src/packages/sdlc/src/issue-actions.mjs cleanup
1275
1286
  env:
1276
1287
  GH_TOKEN: ${{ github.token }}
1288
+ LIGHTHOUSE_PREPARE_FAILED: "true"
1277
1289
 
1278
1290
  publish:
1279
1291
  name: Validate, publish and release
@@ -1288,6 +1300,11 @@ jobs:
1288
1300
  contents: write
1289
1301
  issues: write
1290
1302
  pull-requests: write
1303
+ concurrency:
1304
+ cancel-in-progress: false
1305
+ group: ${{ inputs.epic-parent && format('lighthouse-issue-{0}', inputs.epic-parent) || format('lighthouse-publish-{0}', github.run_id) }}
1306
+ queue: max
1307
+
1291
1308
  env:
1292
1309
  LIGHTHOUSE_ISSUE: ${{ inputs.issue }}
1293
1310
  steps:
@@ -1329,8 +1346,22 @@ jobs:
1329
1346
  run: node src/packages/sdlc/src/issue-actions.mjs publish
1330
1347
  env:
1331
1348
  GH_TOKEN: ${{ github.token }}
1349
+ - name: Preserve the publication receipt
1350
+ if: always()
1351
+ uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
1352
+ with:
1353
+ if-no-files-found: ignore
1354
+ name: lighthouse-implement-publication-${{ inputs.issue }}-${{ github.run_attempt }}
1355
+ path: ${{ runner.temp }}/lighthouse-${{ github.run_id }}-${{ github.run_attempt }}/published-pr.json
1356
+ retention-days: ${{ vars.GH_AW_DEFAULT_ARTIFACT_RETENTION_DAYS || '14' }}
1332
1357
  - name: Release the issue reservation
1333
1358
  if: always()
1334
1359
  run: node src/packages/sdlc/src/issue-actions.mjs cleanup
1335
1360
  env:
1336
1361
  GH_TOKEN: ${{ github.token }}
1362
+ LIGHTHOUSE_AGENT_RESULT: ${{ needs.agent.result }}
1363
+ LIGHTHOUSE_PUBLISH_STATUS: ${{ job.status }}
1364
+ - name: Request the verified product prerequisite
1365
+ run: node src/packages/sdlc/src/issue-actions.mjs continue-product-gap
1366
+ env:
1367
+ GH_TOKEN: ${{ github.token }}
@@ -4,7 +4,7 @@ name: apply review
4
4
  description: Apply authorized feedback to the existing proposal or implementation PR.
5
5
  run-name: "apply-review #${{ inputs.issue }} · request ${{ inputs.dispatch-request }}"
6
6
  concurrency:
7
- group: lighthouse-issue-${{ inputs.issue }}
7
+ group: ${{ inputs.epic-parent && format('lighthouse-epic-child-{0}', inputs.issue) || format('lighthouse-issue-{0}', inputs.issue) }}
8
8
  cancel-in-progress: false
9
9
  queue: max
10
10
  job-discriminator: ${{ github.run_id }}
@@ -21,6 +21,10 @@ on:
21
21
  description: Authenticated router receipt comment ID
22
22
  required: true
23
23
  type: string
24
+ epic-parent:
25
+ description: Authenticated parent issue for shared epic serialization
26
+ required: false
27
+ type: string
24
28
  needs: [prepare]
25
29
  if: needs.prepare.outputs.eligible == 'true'
26
30
  runs-on: [self-hosted, linux, lighthouse-workflow]
@@ -28,6 +32,7 @@ runs-on-slim: ubuntu-24.04
28
32
  timeout-minutes: 55
29
33
  env:
30
34
  LIGHTHOUSE_RECOVERY_ENABLED: ${{ vars.LIGHTHOUSE_RECOVERY_ENABLED }}
35
+ LIGHTHOUSE_EPIC_CAPACITY: ${{ vars.LIGHTHOUSE_EPIC_CAPACITY }}
31
36
  LIGHTHOUSE_WORKER: apply-review
32
37
  LIGHTHOUSE_DISPATCH_REQUIRED: "true"
33
38
  permissions:
@@ -108,6 +113,10 @@ post-steps:
108
113
  retention-days: 14
109
114
  jobs:
110
115
  prepare:
116
+ concurrency:
117
+ group: ${{ inputs.epic-parent && format('lighthouse-issue-{0}', inputs.epic-parent) || format('lighthouse-prepare-{0}', github.run_id) }}
118
+ cancel-in-progress: false
119
+ queue: max
111
120
  outputs:
112
121
  eligible: ${{ steps.prepare.outputs.eligible }}
113
122
  source_revision: ${{ steps.prepare.outputs.source_revision }}
@@ -147,8 +156,13 @@ jobs:
147
156
  if: failure()
148
157
  env:
149
158
  GH_TOKEN: ${{ github.token }}
159
+ LIGHTHOUSE_PREPARE_FAILED: "true"
150
160
  run: node src/packages/sdlc/src/issue-actions.mjs cleanup
151
161
  publish:
162
+ concurrency:
163
+ group: ${{ inputs.epic-parent && format('lighthouse-issue-{0}', inputs.epic-parent) || format('lighthouse-publish-{0}', github.run_id) }}
164
+ cancel-in-progress: false
165
+ queue: max
152
166
  name: Validate, publish and release
153
167
  needs: [prepare, agent]
154
168
  if: always() && needs.prepare.result == 'success' && needs.prepare.outputs.eligible == 'true'
@@ -190,11 +204,25 @@ jobs:
190
204
  env:
191
205
  GH_TOKEN: ${{ github.token }}
192
206
  run: node src/packages/sdlc/src/issue-actions.mjs publish
207
+ - name: Preserve the publication receipt
208
+ if: always()
209
+ uses: actions/upload-artifact@v7
210
+ with:
211
+ name: lighthouse-implement-publication-${{ inputs.issue }}-${{ github.run_attempt }}
212
+ path: ${{ runner.temp }}/lighthouse-${{ github.run_id }}-${{ github.run_attempt }}/published-pr.json
213
+ if-no-files-found: ignore
214
+ retention-days: 14
193
215
  - name: Release the issue reservation
194
216
  if: always()
195
217
  env:
196
218
  GH_TOKEN: ${{ github.token }}
219
+ LIGHTHOUSE_AGENT_RESULT: ${{ needs.agent.result }}
220
+ LIGHTHOUSE_PUBLISH_STATUS: ${{ job.status }}
197
221
  run: node src/packages/sdlc/src/issue-actions.mjs cleanup
222
+ - name: Request the verified product prerequisite
223
+ env:
224
+ GH_TOKEN: ${{ github.token }}
225
+ run: node src/packages/sdlc/src/issue-actions.mjs continue-product-gap
198
226
  ---
199
227
 
200
228
  # Apply the owner feedback
@@ -0,0 +1,79 @@
1
+ # Not installed until child delivery and aggregate publication are connected.
2
+ name: Lighthouse epic reconciliation
3
+ on:
4
+ workflow_dispatch:
5
+ inputs:
6
+ issue:
7
+ description: Parent issue with an authenticated decomposition plan
8
+ required: true
9
+ type: string
10
+ action:
11
+ description: Reconcile children, register or review a child PR, or publish the aggregate
12
+ required: true
13
+ default: reconcile
14
+ type: choice
15
+ options: [reconcile, register-pr, ready-child, accept-child, publish-aggregate, ready-aggregate]
16
+ child:
17
+ description: Child issue number for PR registration or acceptance
18
+ required: false
19
+ type: string
20
+ run:
21
+ description: Child implementation run ID for PR registration
22
+ required: false
23
+ type: string
24
+ pull-request:
25
+ description: Child PR number for acceptance
26
+ required: false
27
+ type: string
28
+ review:
29
+ description: Owner approval review ID for acceptance
30
+ required: false
31
+ type: string
32
+ head:
33
+ description: Approved child PR head SHA
34
+ required: false
35
+ type: string
36
+ base:
37
+ description: Approved current epic branch SHA
38
+ required: false
39
+ type: string
40
+ concurrency:
41
+ group: lighthouse-issue-${{ inputs.issue }}
42
+ cancel-in-progress: false
43
+ queue: max
44
+ permissions:
45
+ contents: write
46
+ actions: read
47
+ issues: write
48
+ pull-requests: write
49
+ checks: read
50
+ statuses: read
51
+ jobs:
52
+ reconcile:
53
+ if: vars.LIGHTHOUSE_AUTOMATION_ENABLED == 'true' && vars.LIGHTHOUSE_EPIC_ENABLED == 'true' && github.actor == github.repository_owner
54
+ runs-on: ubuntu-24.04
55
+ env:
56
+ LIGHTHOUSE_ISSUE: ${{ inputs.issue }}
57
+ steps:
58
+ - uses: actions/checkout@v5
59
+ with:
60
+ repository: juangcarmona/lighthouse
61
+ ref: __LIGHTHOUSE_REF__
62
+ persist-credentials: false
63
+ - uses: actions/setup-node@v5
64
+ with:
65
+ node-version: 24
66
+ - name: Install the pinned harness
67
+ run: npm ci --ignore-scripts
68
+ - name: Reconcile native child issues
69
+ env:
70
+ GH_TOKEN: ${{ github.token }}
71
+ run: node src/packages/sdlc/src/epic-native.mjs
72
+ - name: Preserve the epic journal
73
+ if: always()
74
+ uses: actions/upload-artifact@v7
75
+ with:
76
+ name: lighthouse-epic-journal-${{ inputs.issue }}-${{ github.run_attempt }}
77
+ path: ${{ runner.temp }}/lighthouse-epic-${{ github.run_id }}-${{ inputs.issue }}/journal.json
78
+ if-no-files-found: error
79
+ retention-days: 14
@@ -1,4 +1,4 @@
1
- # gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"82e278c98bc5542041f7a212403e06f63f11ee41ed07f4bd7a8a08695b1e7255","body_hash":"260db41beef59e0a150c7e0ed9fed84f0f724b5aeba94e5d2576d4b203a9d663","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":"ff6e07d7f4c98ca08ec7640d649089b6061e48826d943401058a4403bd94dd0d","body_hash":"260db41beef59e0a150c7e0ed9fed84f0f724b5aeba94e5d2576d4b203a9d663","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
  #
@@ -31,6 +31,7 @@
31
31
  #
32
32
  # Frontmatter env variables:
33
33
  # - LIGHTHOUSE_DISPATCH_REQUIRED: (main workflow)
34
+ # - LIGHTHOUSE_EPIC_CAPACITY: (main workflow)
34
35
  # - LIGHTHOUSE_RECOVERY_ENABLED: (main workflow)
35
36
  # - LIGHTHOUSE_STAGE: (main workflow)
36
37
  #
@@ -69,6 +70,10 @@ on:
69
70
  description: Authenticated router receipt comment ID
70
71
  required: true
71
72
  type: string
73
+ epic-parent:
74
+ description: Authenticated parent issue for shared epic serialization
75
+ required: false
76
+ type: string
72
77
  issue:
73
78
  description: Source issue
74
79
  required: true
@@ -79,13 +84,14 @@ permissions: {}
79
84
 
80
85
  concurrency:
81
86
  cancel-in-progress: false
82
- group: lighthouse-issue-${{ inputs.issue }}
87
+ group: ${{ inputs.epic-parent && format('lighthouse-epic-child-{0}', inputs.issue) || format('lighthouse-issue-{0}', inputs.issue) }}
83
88
  queue: max
84
89
 
85
90
  run-name: "implement #${{ inputs.issue }} · request ${{ inputs.dispatch-request }}"
86
91
 
87
92
  env:
88
93
  LIGHTHOUSE_DISPATCH_REQUIRED: "true"
94
+ LIGHTHOUSE_EPIC_CAPACITY: ${{ vars.LIGHTHOUSE_EPIC_CAPACITY }}
89
95
  LIGHTHOUSE_RECOVERY_ENABLED: ${{ vars.LIGHTHOUSE_RECOVERY_ENABLED }}
90
96
  LIGHTHOUSE_STAGE: implement
91
97
  OTEL_EXPORTER_OTLP_ENDPOINT: ${{ secrets.GH_AW_DEFAULT_OTLP_ENDPOINT || vars.GH_AW_DEFAULT_OTLP_ENDPOINT }}
@@ -1231,6 +1237,12 @@ jobs:
1231
1237
  actions: read
1232
1238
  contents: read
1233
1239
  issues: write
1240
+ pull-requests: read
1241
+ concurrency:
1242
+ cancel-in-progress: false
1243
+ group: ${{ inputs.epic-parent && format('lighthouse-issue-{0}', inputs.epic-parent) || format('lighthouse-prepare-{0}', github.run_id) }}
1244
+ queue: max
1245
+
1234
1246
  env:
1235
1247
  LIGHTHOUSE_ISSUE: ${{ inputs.issue }}
1236
1248
  outputs:
@@ -1272,11 +1284,14 @@ jobs:
1272
1284
  run: node src/packages/sdlc/src/issue-actions.mjs cleanup
1273
1285
  env:
1274
1286
  GH_TOKEN: ${{ github.token }}
1287
+ LIGHTHOUSE_PREPARE_FAILED: "true"
1275
1288
 
1276
1289
  publish:
1277
1290
  name: Validate, publish and release
1278
1291
  needs:
1292
+ - activation
1279
1293
  - agent
1294
+ - pre_activation
1280
1295
  - prepare
1281
1296
  if: always() && needs.prepare.result == 'success' && needs.prepare.outputs.eligible == 'true'
1282
1297
  runs-on: ubuntu-24.04
@@ -1286,6 +1301,11 @@ jobs:
1286
1301
  contents: write
1287
1302
  issues: write
1288
1303
  pull-requests: write
1304
+ concurrency:
1305
+ cancel-in-progress: false
1306
+ group: ${{ inputs.epic-parent && format('lighthouse-issue-{0}', inputs.epic-parent) || format('lighthouse-publish-{0}', github.run_id) }}
1307
+ queue: max
1308
+
1289
1309
  env:
1290
1310
  LIGHTHOUSE_ISSUE: ${{ inputs.issue }}
1291
1311
  steps:
@@ -1327,8 +1347,24 @@ jobs:
1327
1347
  run: node src/packages/sdlc/src/issue-actions.mjs publish
1328
1348
  env:
1329
1349
  GH_TOKEN: ${{ github.token }}
1350
+ - name: Preserve the publication receipt
1351
+ if: always()
1352
+ uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
1353
+ with:
1354
+ if-no-files-found: ignore
1355
+ name: lighthouse-implement-publication-${{ inputs.issue }}-${{ github.run_attempt }}
1356
+ path: ${{ runner.temp }}/lighthouse-${{ github.run_id }}-${{ github.run_attempt }}/published-pr.json
1357
+ retention-days: ${{ vars.GH_AW_DEFAULT_ARTIFACT_RETENTION_DAYS || '14' }}
1330
1358
  - name: Release the issue reservation
1331
1359
  if: always()
1332
1360
  run: node src/packages/sdlc/src/issue-actions.mjs cleanup
1333
1361
  env:
1334
1362
  GH_TOKEN: ${{ github.token }}
1363
+ LIGHTHOUSE_ACTIVATION_RESULT: ${{ needs.activation.result }}
1364
+ LIGHTHOUSE_AGENT_RESULT: ${{ needs.agent.result }}
1365
+ LIGHTHOUSE_PRE_ACTIVATION_RESULT: ${{ needs.pre_activation.result }}
1366
+ LIGHTHOUSE_PUBLISH_STATUS: ${{ job.status }}
1367
+ - name: Request the verified product prerequisite
1368
+ run: node src/packages/sdlc/src/issue-actions.mjs continue-product-gap
1369
+ env:
1370
+ GH_TOKEN: ${{ github.token }}
@@ -4,7 +4,7 @@ name: implement
4
4
  description: Plan and implement an authorized issue in an isolated workspace and deliver a reviewable PR.
5
5
  run-name: "implement #${{ inputs.issue }} · request ${{ inputs.dispatch-request }}"
6
6
  concurrency:
7
- group: lighthouse-issue-${{ inputs.issue }}
7
+ group: ${{ inputs.epic-parent && format('lighthouse-epic-child-{0}', inputs.issue) || format('lighthouse-issue-{0}', inputs.issue) }}
8
8
  cancel-in-progress: false
9
9
  queue: max
10
10
  job-discriminator: ${{ github.run_id }}
@@ -21,6 +21,10 @@ on:
21
21
  description: Authenticated router receipt comment ID
22
22
  required: true
23
23
  type: string
24
+ epic-parent:
25
+ description: Authenticated parent issue for shared epic serialization
26
+ required: false
27
+ type: string
24
28
  needs: [prepare]
25
29
  if: needs.prepare.outputs.eligible == 'true'
26
30
  runs-on: [self-hosted, linux, lighthouse-workflow]
@@ -28,6 +32,7 @@ runs-on-slim: ubuntu-24.04
28
32
  timeout-minutes: 55
29
33
  env:
30
34
  LIGHTHOUSE_RECOVERY_ENABLED: ${{ vars.LIGHTHOUSE_RECOVERY_ENABLED }}
35
+ LIGHTHOUSE_EPIC_CAPACITY: ${{ vars.LIGHTHOUSE_EPIC_CAPACITY }}
31
36
  LIGHTHOUSE_STAGE: implement
32
37
  LIGHTHOUSE_DISPATCH_REQUIRED: "true"
33
38
  permissions:
@@ -108,6 +113,10 @@ post-steps:
108
113
  retention-days: 14
109
114
  jobs:
110
115
  prepare:
116
+ concurrency:
117
+ group: ${{ inputs.epic-parent && format('lighthouse-issue-{0}', inputs.epic-parent) || format('lighthouse-prepare-{0}', github.run_id) }}
118
+ cancel-in-progress: false
119
+ queue: max
111
120
  outputs:
112
121
  eligible: ${{ steps.prepare.outputs.eligible }}
113
122
  source_revision: ${{ steps.prepare.outputs.source_revision }}
@@ -117,6 +126,7 @@ jobs:
117
126
  actions: read
118
127
  contents: read
119
128
  issues: write
129
+ pull-requests: read
120
130
  env:
121
131
  LIGHTHOUSE_ISSUE: ${{ inputs.issue }}
122
132
  steps:
@@ -145,10 +155,15 @@ jobs:
145
155
  if: failure()
146
156
  env:
147
157
  GH_TOKEN: ${{ github.token }}
158
+ LIGHTHOUSE_PREPARE_FAILED: "true"
148
159
  run: node src/packages/sdlc/src/issue-actions.mjs cleanup
149
160
  publish:
161
+ concurrency:
162
+ group: ${{ inputs.epic-parent && format('lighthouse-issue-{0}', inputs.epic-parent) || format('lighthouse-publish-{0}', github.run_id) }}
163
+ cancel-in-progress: false
164
+ queue: max
150
165
  name: Validate, publish and release
151
- needs: [prepare, agent]
166
+ needs: [prepare, pre_activation, activation, agent]
152
167
  if: always() && needs.prepare.result == 'success' && needs.prepare.outputs.eligible == 'true'
153
168
  runs-on: ubuntu-24.04
154
169
  permissions:
@@ -188,11 +203,27 @@ jobs:
188
203
  env:
189
204
  GH_TOKEN: ${{ github.token }}
190
205
  run: node src/packages/sdlc/src/issue-actions.mjs publish
206
+ - name: Preserve the publication receipt
207
+ if: always()
208
+ uses: actions/upload-artifact@v7
209
+ with:
210
+ name: lighthouse-implement-publication-${{ inputs.issue }}-${{ github.run_attempt }}
211
+ path: ${{ runner.temp }}/lighthouse-${{ github.run_id }}-${{ github.run_attempt }}/published-pr.json
212
+ if-no-files-found: ignore
213
+ retention-days: 14
191
214
  - name: Release the issue reservation
192
215
  if: always()
193
216
  env:
194
217
  GH_TOKEN: ${{ github.token }}
218
+ LIGHTHOUSE_PRE_ACTIVATION_RESULT: ${{ needs.pre_activation.result }}
219
+ LIGHTHOUSE_ACTIVATION_RESULT: ${{ needs.activation.result }}
220
+ LIGHTHOUSE_AGENT_RESULT: ${{ needs.agent.result }}
221
+ LIGHTHOUSE_PUBLISH_STATUS: ${{ job.status }}
195
222
  run: node src/packages/sdlc/src/issue-actions.mjs cleanup
223
+ - name: Request the verified product prerequisite
224
+ env:
225
+ GH_TOKEN: ${{ github.token }}
226
+ run: node src/packages/sdlc/src/issue-actions.mjs continue-product-gap
196
227
  ---
197
228
 
198
229
  # Plan and implement the issue
@@ -1,4 +1,4 @@
1
- # gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"7f49111df8257bd180f3ea15a29176a41b68e160acd597a331c8e32a80f0c5cc","body_hash":"71107231af6c0ea2e2f2880e7bfcf90d02e031b1db4c95a2d5b456e934f6f1ed","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":"a16ef770ce94e692e43480d8f233a7739697a914dc73b618265e41059d7b5f2b","body_hash":"71107231af6c0ea2e2f2880e7bfcf90d02e031b1db4c95a2d5b456e934f6f1ed","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
  #
@@ -1264,6 +1264,7 @@ jobs:
1264
1264
  run: node src/packages/sdlc/src/completion-actions.mjs cleanup
1265
1265
  env:
1266
1266
  GH_TOKEN: ${{ github.token }}
1267
+ LIGHTHOUSE_PREPARE_FAILED: "true"
1267
1268
 
1268
1269
  publish:
1269
1270
  name: Validate, publish and release
@@ -1339,3 +1340,5 @@ jobs:
1339
1340
  run: node src/packages/sdlc/src/completion-actions.mjs cleanup
1340
1341
  env:
1341
1342
  GH_TOKEN: ${{ github.token }}
1343
+ LIGHTHOUSE_AGENT_RESULT: ${{ needs.agent.result }}
1344
+ LIGHTHOUSE_PUBLISH_STATUS: ${{ job.status }}
@@ -137,6 +137,7 @@ jobs:
137
137
  if: failure()
138
138
  env:
139
139
  GH_TOKEN: ${{ github.token }}
140
+ LIGHTHOUSE_PREPARE_FAILED: "true"
140
141
  run: node src/packages/sdlc/src/completion-actions.mjs cleanup
141
142
  publish:
142
143
  concurrency:
@@ -198,6 +199,8 @@ jobs:
198
199
  if: always()
199
200
  env:
200
201
  GH_TOKEN: ${{ github.token }}
202
+ LIGHTHOUSE_AGENT_RESULT: ${{ needs.agent.result }}
203
+ LIGHTHOUSE_PUBLISH_STATUS: ${{ job.status }}
201
204
  run: node src/packages/sdlc/src/completion-actions.mjs cleanup
202
205
  ---
203
206
 
@@ -1,4 +1,4 @@
1
- # gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"d9bc6f2a17df20e9429be94ac79f84cf1bce20368f3d85d9ae7348fdd9e91288","body_hash":"e2b54676d59603e04f18e85816981a5c5c714022973e553e0b8f460306bfa099","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":"a7ed9b2d7b90453caab6233d54bd2cd8b6a38a0a42ac3b956a33ab9cb379b708","body_hash":"5269ffd1955c7c2f756025111209f18fd1d97a635086c7d29d7a24d1b8a9b09d","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
  #
@@ -23,7 +23,7 @@
23
23
  #
24
24
  # For more information: https://github.github.com/gh-aw/introduction/overview/
25
25
  #
26
- # Prepare and publish an authenticated Product Change candidate for an authorized issue idea.
26
+ # Prepare and publish an authenticated Product Change candidate for an idea or issue prerequisite.
27
27
  #
28
28
  # Resolved workflow manifest:
29
29
  # Imports:
@@ -521,6 +521,11 @@ jobs:
521
521
  with:
522
522
  name: lighthouse-input-${{ inputs.issue }}-${{ github.run_attempt }}
523
523
  path: ${{ runner.temp }}/lighthouse-${{ github.run_id }}-${{ github.run_attempt }}
524
+ - name: Load ProductShape inspection evidence
525
+ uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
526
+ with:
527
+ name: lighthouse-product-evidence-${{ inputs.issue }}-${{ github.run_attempt }}
528
+ path: ${{ runner.temp }}/lighthouse-${{ github.run_id }}-${{ github.run_attempt }}/product-evidence
524
529
 
525
530
  - name: Configure Git credentials
526
531
  env:
@@ -1215,6 +1220,7 @@ jobs:
1215
1220
  actions: read
1216
1221
  contents: read
1217
1222
  issues: write
1223
+ pull-requests: read
1218
1224
  env:
1219
1225
  LIGHTHOUSE_ISSUE: ${{ inputs.issue }}
1220
1226
  LIGHTHOUSE_PRODUCT_CHANGE_ENABLED: true
@@ -1236,6 +1242,12 @@ jobs:
1236
1242
  persist-credentials: false
1237
1243
  ref: __LIGHTHOUSE_REF__
1238
1244
  repository: juangcarmona/lighthouse
1245
+ - name: Check out the adopter's current product source
1246
+ uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5
1247
+ with:
1248
+ path: .lighthouse-product-source
1249
+ persist-credentials: false
1250
+ ref: ${{ github.event.repository.default_branch }}
1239
1251
  - uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5
1240
1252
  with:
1241
1253
  node-version: 24
@@ -1245,32 +1257,50 @@ jobs:
1245
1257
  npm install --no-save --package-lock=false --ignore-scripts @prodshape/integration-openspec@0.6.6
1246
1258
  - name: Collect verified intent and reserve the issue
1247
1259
  id: prepare
1248
- run: node src/packages/sdlc/src/issue-actions.mjs prepare
1260
+ run: node "$GITHUB_WORKSPACE/src/packages/sdlc/src/issue-actions.mjs" prepare
1249
1261
  env:
1250
1262
  GH_TOKEN: ${{ github.token }}
1263
+ working-directory: .lighthouse-product-source
1251
1264
  - name: Preserve the execution request
1252
1265
  if: steps.prepare.outputs.eligible == 'true'
1253
1266
  uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
1254
1267
  with:
1255
1268
  if-no-files-found: error
1256
1269
  name: lighthouse-input-${{ inputs.issue }}-${{ github.run_attempt }}
1257
- path: ${{ runner.temp }}/lighthouse-${{ github.run_id }}-${{ github.run_attempt }}/
1270
+ path: |
1271
+ ${{ runner.temp }}/lighthouse-${{ github.run_id }}-${{ github.run_attempt }}/admission.json
1272
+ ${{ runner.temp }}/lighthouse-${{ github.run_id }}-${{ github.run_attempt }}/request.json
1273
+ ${{ runner.temp }}/lighthouse-${{ github.run_id }}-${{ github.run_attempt }}/issue.json
1274
+ ${{ runner.temp }}/lighthouse-${{ github.run_id }}-${{ github.run_attempt }}/context.json
1275
+ ${{ runner.temp }}/lighthouse-${{ github.run_id }}-${{ github.run_attempt }}/reserved
1276
+ retention-days: ${{ vars.GH_AW_DEFAULT_ARTIFACT_RETENTION_DAYS || '14' }}
1277
+ - name: Preserve ProductShape inspection evidence
1278
+ if: steps.prepare.outputs.eligible == 'true'
1279
+ uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
1280
+ with:
1281
+ if-no-files-found: error
1282
+ name: lighthouse-product-evidence-${{ inputs.issue }}-${{ github.run_attempt }}
1283
+ path: ${{ runner.temp }}/lighthouse-${{ github.run_id }}-${{ github.run_attempt }}/product-evidence/
1258
1284
  retention-days: ${{ vars.GH_AW_DEFAULT_ARTIFACT_RETENTION_DAYS || '14' }}
1259
1285
  - name: Release reservation if preparation failed
1260
1286
  if: failure()
1261
1287
  run: node src/packages/sdlc/src/issue-actions.mjs cleanup
1262
1288
  env:
1263
1289
  GH_TOKEN: ${{ github.token }}
1290
+ LIGHTHOUSE_PREPARE_FAILED: "true"
1264
1291
 
1265
1292
  publish:
1266
1293
  name: Validate and publish the product candidate
1267
1294
  needs:
1295
+ - activation
1268
1296
  - agent
1297
+ - pre_activation
1269
1298
  - prepare
1270
1299
  if: always() && needs.prepare.result == 'success' && needs.prepare.outputs.eligible == 'true'
1271
1300
  runs-on: ubuntu-24.04
1272
1301
  # Permissions for the publish job (workflow permissions default to none).
1273
1302
  permissions:
1303
+ actions: read
1274
1304
  contents: write
1275
1305
  issues: write
1276
1306
  pull-requests: write
@@ -1303,6 +1333,7 @@ jobs:
1303
1333
  run: |
1304
1334
  npm ci --ignore-scripts
1305
1335
  npm install --no-save --package-lock=false --ignore-scripts @prodshape/integration-openspec@0.6.6
1336
+ working-directory: .lighthouse-harness
1306
1337
  - name: Load the request and candidate
1307
1338
  uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
1308
1339
  with:
@@ -1327,3 +1358,7 @@ jobs:
1327
1358
  run: node .lighthouse-harness/src/packages/sdlc/src/issue-actions.mjs cleanup
1328
1359
  env:
1329
1360
  GH_TOKEN: ${{ github.token }}
1361
+ LIGHTHOUSE_ACTIVATION_RESULT: ${{ needs.activation.result }}
1362
+ LIGHTHOUSE_AGENT_RESULT: ${{ needs.agent.result }}
1363
+ LIGHTHOUSE_PRE_ACTIVATION_RESULT: ${{ needs.pre_activation.result }}
1364
+ LIGHTHOUSE_PUBLISH_STATUS: ${{ job.status }}