@juangcarmona/lighthouse-sdlc 0.15.2 → 0.16.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.
- package/README.md +6 -1
- package/execution-environments.md +2 -0
- package/meta-commands/ff.md +2 -2
- package/meta-commands/hotfix.md +3 -1
- package/package.json +8 -3
- package/schemas/product-change.schema.json +118 -0
- package/skills/independent-review/SKILL.md +13 -0
- package/skills/product-change/SKILL.md +18 -0
- package/src/completion.mjs +5 -3
- package/src/contracts.mjs +2 -0
- package/src/host-contract.mjs +11 -3
- package/src/implementation-runtime.mjs +14 -5
- package/src/implementation.mjs +2 -2
- package/src/install-workflows.mjs +17 -5
- package/src/integration-evidence.mjs +4 -1
- package/src/issue-actions.mjs +124 -17
- package/src/opencode-execute.mjs +7 -7
- package/src/product-change-actions.mjs +308 -0
- package/src/product-change.mjs +277 -0
- package/src/proposal-review.mjs +1 -1
- package/src/proposal.mjs +4 -4
- package/src/sdlc.mjs +1 -1
- package/src/stage-dispatch.mjs +11 -3
- package/src/unattended-actions.mjs +287 -0
- package/src/unattended-runtime.mjs +115 -0
- package/src/unattended.mjs +161 -0
- package/templates/unattended.json +37 -0
- package/unattended.md +40 -0
- package/workflows/lighthouse-sdlc-apply-product-change.lock.yml +1838 -0
- package/workflows/lighthouse-sdlc-apply-product-change.md +183 -0
- package/workflows/lighthouse-sdlc-product-change.lock.yml +1329 -0
- package/workflows/lighthouse-sdlc-product-change.md +195 -0
- package/workflows/lighthouse-sdlc-router.yml +12 -2
- package/workflows/lighthouse-sdlc-unattended.yml +67 -0
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
---
|
|
2
|
+
# Owned by lighthouse-sdlc. Regenerate the lock with gh aw v0.93.2.
|
|
3
|
+
name: product-change
|
|
4
|
+
description: Prepare and publish an authenticated Product Change candidate for an authorized issue idea.
|
|
5
|
+
run-name: "product change #${{ 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 }}
|
|
11
|
+
on:
|
|
12
|
+
roles: all
|
|
13
|
+
workflow_dispatch:
|
|
14
|
+
inputs:
|
|
15
|
+
issue:
|
|
16
|
+
description: Source issue containing the product idea
|
|
17
|
+
required: true
|
|
18
|
+
type: string
|
|
19
|
+
dispatch-request:
|
|
20
|
+
description: Authenticated router receipt comment ID
|
|
21
|
+
required: true
|
|
22
|
+
type: string
|
|
23
|
+
needs: [prepare]
|
|
24
|
+
if: needs.prepare.outputs.eligible == 'true'
|
|
25
|
+
runs-on: [self-hosted, linux, lighthouse-workflow]
|
|
26
|
+
runs-on-slim: ubuntu-24.04
|
|
27
|
+
timeout-minutes: 30
|
|
28
|
+
env:
|
|
29
|
+
LIGHTHOUSE_STAGE: propose
|
|
30
|
+
LIGHTHOUSE_WORKER: product-change
|
|
31
|
+
LIGHTHOUSE_DISPATCH_REQUIRED: "true"
|
|
32
|
+
LIGHTHOUSE_PRODUCT_CHANGE_ENABLED: "true"
|
|
33
|
+
permissions:
|
|
34
|
+
contents: read
|
|
35
|
+
engine:
|
|
36
|
+
id: opencode
|
|
37
|
+
command: node
|
|
38
|
+
imports:
|
|
39
|
+
- shared/lighthouse-opencode.md
|
|
40
|
+
strict: false
|
|
41
|
+
features:
|
|
42
|
+
dangerously-disable-sandbox-agent: true
|
|
43
|
+
sandbox:
|
|
44
|
+
agent: false
|
|
45
|
+
tools:
|
|
46
|
+
github: false
|
|
47
|
+
safe-outputs:
|
|
48
|
+
create-issue: false
|
|
49
|
+
report-incomplete: false
|
|
50
|
+
threat-detection: false
|
|
51
|
+
report-failure-as-issue: false
|
|
52
|
+
report-missing-tool: false
|
|
53
|
+
report-missing-data: false
|
|
54
|
+
noop:
|
|
55
|
+
report-as-issue: false
|
|
56
|
+
network:
|
|
57
|
+
allowed: []
|
|
58
|
+
steps:
|
|
59
|
+
- name: Check out the authorized product revision
|
|
60
|
+
uses: actions/checkout@v5
|
|
61
|
+
with:
|
|
62
|
+
persist-credentials: false
|
|
63
|
+
ref: ${{ needs.prepare.outputs.source_revision }}
|
|
64
|
+
- name: Load the pinned harness package
|
|
65
|
+
uses: actions/checkout@v5
|
|
66
|
+
with:
|
|
67
|
+
repository: juangcarmona/lighthouse
|
|
68
|
+
ref: __LIGHTHOUSE_REF__
|
|
69
|
+
path: tools
|
|
70
|
+
persist-credentials: false
|
|
71
|
+
- name: Load the authorized product request
|
|
72
|
+
uses: actions/download-artifact@v8
|
|
73
|
+
with:
|
|
74
|
+
name: lighthouse-input-${{ inputs.issue }}-${{ github.run_attempt }}
|
|
75
|
+
path: ${{ runner.temp }}/lighthouse-${{ github.run_id }}-${{ github.run_attempt }}
|
|
76
|
+
post-steps:
|
|
77
|
+
- name: Validate the Lighthouse result
|
|
78
|
+
run: node tools/src/packages/sdlc/src/issue-actions.mjs validate
|
|
79
|
+
- name: Preserve the result and runtime receipt
|
|
80
|
+
if: always()
|
|
81
|
+
uses: actions/upload-artifact@v7
|
|
82
|
+
with:
|
|
83
|
+
name: lighthouse-result-${{ inputs.issue }}-${{ github.run_attempt }}
|
|
84
|
+
path: |
|
|
85
|
+
${{ runner.temp }}/lighthouse-${{ github.run_id }}-${{ github.run_attempt }}/envelope.json
|
|
86
|
+
${{ runner.temp }}/lighthouse-${{ github.run_id }}-${{ github.run_attempt }}/runtime.json
|
|
87
|
+
if-no-files-found: error
|
|
88
|
+
retention-days: 14
|
|
89
|
+
jobs:
|
|
90
|
+
prepare:
|
|
91
|
+
outputs:
|
|
92
|
+
eligible: ${{ steps.prepare.outputs.eligible }}
|
|
93
|
+
source_revision: ${{ steps.prepare.outputs.source_revision }}
|
|
94
|
+
name: Authenticate and checkpoint the idea
|
|
95
|
+
runs-on: ubuntu-24.04
|
|
96
|
+
permissions:
|
|
97
|
+
actions: read
|
|
98
|
+
contents: read
|
|
99
|
+
issues: write
|
|
100
|
+
env:
|
|
101
|
+
LIGHTHOUSE_ISSUE: ${{ inputs.issue }}
|
|
102
|
+
LIGHTHOUSE_PRODUCT_CHANGE_ENABLED: "true"
|
|
103
|
+
steps:
|
|
104
|
+
- uses: actions/checkout@v5
|
|
105
|
+
with:
|
|
106
|
+
repository: juangcarmona/lighthouse
|
|
107
|
+
ref: __LIGHTHOUSE_REF__
|
|
108
|
+
persist-credentials: false
|
|
109
|
+
- uses: actions/setup-node@v5
|
|
110
|
+
with:
|
|
111
|
+
node-version: 24
|
|
112
|
+
- name: Install provider integration when the adopter configured it
|
|
113
|
+
run: |
|
|
114
|
+
npm ci --ignore-scripts
|
|
115
|
+
npm install --no-save --package-lock=false --ignore-scripts @prodshape/integration-openspec@0.6.6
|
|
116
|
+
- name: Collect verified intent and reserve the issue
|
|
117
|
+
id: prepare
|
|
118
|
+
env:
|
|
119
|
+
GH_TOKEN: ${{ github.token }}
|
|
120
|
+
run: node src/packages/sdlc/src/issue-actions.mjs prepare
|
|
121
|
+
- name: Preserve the execution request
|
|
122
|
+
if: steps.prepare.outputs.eligible == 'true'
|
|
123
|
+
uses: actions/upload-artifact@v7
|
|
124
|
+
with:
|
|
125
|
+
name: lighthouse-input-${{ inputs.issue }}-${{ github.run_attempt }}
|
|
126
|
+
path: ${{ runner.temp }}/lighthouse-${{ github.run_id }}-${{ github.run_attempt }}/
|
|
127
|
+
if-no-files-found: error
|
|
128
|
+
retention-days: 14
|
|
129
|
+
- name: Release reservation if preparation failed
|
|
130
|
+
if: failure()
|
|
131
|
+
env:
|
|
132
|
+
GH_TOKEN: ${{ github.token }}
|
|
133
|
+
run: node src/packages/sdlc/src/issue-actions.mjs cleanup
|
|
134
|
+
publish:
|
|
135
|
+
name: Validate and publish the product candidate
|
|
136
|
+
needs: [prepare, agent]
|
|
137
|
+
if: always() && needs.prepare.result == 'success' && needs.prepare.outputs.eligible == 'true'
|
|
138
|
+
runs-on: ubuntu-24.04
|
|
139
|
+
permissions:
|
|
140
|
+
contents: write
|
|
141
|
+
issues: write
|
|
142
|
+
pull-requests: write
|
|
143
|
+
env:
|
|
144
|
+
LIGHTHOUSE_ISSUE: ${{ inputs.issue }}
|
|
145
|
+
steps:
|
|
146
|
+
- uses: actions/checkout@v5
|
|
147
|
+
with:
|
|
148
|
+
persist-credentials: false
|
|
149
|
+
ref: ${{ needs.prepare.outputs.source_revision }}
|
|
150
|
+
- uses: actions/checkout@v5
|
|
151
|
+
with:
|
|
152
|
+
repository: juangcarmona/lighthouse
|
|
153
|
+
ref: __LIGHTHOUSE_REF__
|
|
154
|
+
path: tools
|
|
155
|
+
persist-credentials: false
|
|
156
|
+
- uses: actions/setup-node@v5
|
|
157
|
+
with:
|
|
158
|
+
node-version: 24
|
|
159
|
+
- name: Install the repository and optional product provider
|
|
160
|
+
run: |
|
|
161
|
+
npm ci --ignore-scripts
|
|
162
|
+
npm install --no-save --package-lock=false --ignore-scripts @prodshape/integration-openspec@0.6.6
|
|
163
|
+
- name: Load the request and candidate
|
|
164
|
+
uses: actions/download-artifact@v8
|
|
165
|
+
with:
|
|
166
|
+
name: lighthouse-input-${{ inputs.issue }}-${{ github.run_attempt }}
|
|
167
|
+
path: ${{ runner.temp }}/lighthouse-${{ github.run_id }}-${{ github.run_attempt }}
|
|
168
|
+
- name: Load the product result
|
|
169
|
+
if: needs.agent.result == 'success'
|
|
170
|
+
uses: actions/download-artifact@v8
|
|
171
|
+
with:
|
|
172
|
+
name: lighthouse-result-${{ inputs.issue }}-${{ github.run_attempt }}
|
|
173
|
+
path: ${{ runner.temp }}/lighthouse-${{ github.run_id }}-${{ github.run_attempt }}
|
|
174
|
+
- name: Require a completed worker
|
|
175
|
+
if: needs.agent.result != 'success'
|
|
176
|
+
run: exit 1
|
|
177
|
+
- name: Recheck authority and publish the candidate
|
|
178
|
+
if: needs.agent.result == 'success'
|
|
179
|
+
env:
|
|
180
|
+
GH_TOKEN: ${{ github.token }}
|
|
181
|
+
run: node tools/src/packages/sdlc/src/issue-actions.mjs publish
|
|
182
|
+
- name: Release the execution reservation
|
|
183
|
+
if: always()
|
|
184
|
+
env:
|
|
185
|
+
GH_TOKEN: ${{ github.token }}
|
|
186
|
+
run: node tools/src/packages/sdlc/src/issue-actions.mjs cleanup
|
|
187
|
+
---
|
|
188
|
+
|
|
189
|
+
# Prepare a product change from an idea
|
|
190
|
+
|
|
191
|
+
Read the authenticated context and follow `/harness/skills/product-change/SKILL.md`. Use the installed ProductShape schema instructions included in `context.productChange`. The issue title and body define the idea and the host's `context.productChange.parent` defines the scope and authorization. Compare it with the accepted product model, then return one of `aligned`, `candidate` or `blocked` in `result.output.productChange`.
|
|
192
|
+
|
|
193
|
+
For a candidate, return the complete provider-owned change files under `context.productChange.root`, the host-assigned `changeName`, CHG ID, proposal digest, baseline digest and successful provider validation summary. Keep the manifest in draft status. Do not approve, apply, alter the accepted model, publish a branch or continue implementation. The trusted publisher rechecks the exact candidate, validates it against the current accepted model, publishes the PR and requests an explicit product decision. Product approval, apply, implementation, merge and release are separate effects.
|
|
194
|
+
|
|
195
|
+
Return the supplied stage result identity and keep the enclosing lifecycle stage as `propose`. A product idea does not grant implementation authority. The host owns all GitHub effects and releases execution resources when the decision request is durable.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Optional GitHub-native stage adapter; source owned by lighthouse-sdlc.
|
|
2
2
|
name: router
|
|
3
|
-
run-name: "${{ (github.event_name == 'workflow_run' && 'Delivery after CI') || inputs.stage || github.event.label.name || ((github.event.pull_request || github.event.issue.pull_request) && 'PR review') || (github.event_name == 'issue_comment' && 'reply') || 'refine' }} #${{ github.event.issue.number || github.event.pull_request.number || inputs.issue }} · ${{ github.actor }}"
|
|
3
|
+
run-name: "${{ (github.event_name == 'workflow_run' && 'Delivery after CI') || inputs.workflow || inputs.stage || github.event.label.name || ((github.event.pull_request || github.event.issue.pull_request) && 'PR review') || (github.event_name == 'issue_comment' && 'reply') || 'refine' }} #${{ github.event.issue.number || github.event.pull_request.number || inputs.issue }} · ${{ github.actor }}"
|
|
4
4
|
on:
|
|
5
5
|
issues:
|
|
6
6
|
types: [labeled, unlabeled]
|
|
@@ -26,9 +26,15 @@ on:
|
|
|
26
26
|
stage:
|
|
27
27
|
description: Authorized lifecycle stage
|
|
28
28
|
required: true
|
|
29
|
-
default:
|
|
29
|
+
default: propose
|
|
30
30
|
type: choice
|
|
31
31
|
options: [triage, refine, propose, implement, integrate, review]
|
|
32
|
+
workflow:
|
|
33
|
+
description: Select the authorized workflow
|
|
34
|
+
required: true
|
|
35
|
+
default: stage
|
|
36
|
+
type: choice
|
|
37
|
+
options: [stage, product-change]
|
|
32
38
|
after_run:
|
|
33
39
|
description: Recheck a completed execution through the same continuation rules
|
|
34
40
|
required: false
|
|
@@ -52,6 +58,7 @@ env:
|
|
|
52
58
|
LIGHTHOUSE_ENABLED_STAGES: triage,refine,propose,implement,integrate,review
|
|
53
59
|
LIGHTHOUSE_AUTO_IMPLEMENT: true
|
|
54
60
|
LIGHTHOUSE_COMPLETION_ENABLED: true
|
|
61
|
+
LIGHTHOUSE_PRODUCT_CHANGE_ENABLED: false
|
|
55
62
|
jobs:
|
|
56
63
|
pr-state:
|
|
57
64
|
if: >-
|
|
@@ -99,6 +106,7 @@ jobs:
|
|
|
99
106
|
run: ${{ steps.route.outputs.run }}
|
|
100
107
|
issue: ${{ steps.route.outputs.issue }}
|
|
101
108
|
stage: ${{ steps.route.outputs.stage }}
|
|
109
|
+
worker: ${{ steps.route.outputs.worker }}
|
|
102
110
|
steps:
|
|
103
111
|
- uses: actions/checkout@v5
|
|
104
112
|
with:
|
|
@@ -113,6 +121,7 @@ jobs:
|
|
|
113
121
|
env:
|
|
114
122
|
GH_TOKEN: ${{ github.token }}
|
|
115
123
|
LIGHTHOUSE_COMPLETION_ENABLED: true
|
|
124
|
+
LIGHTHOUSE_PRODUCT_CHANGE_ENABLED: ${{ env.LIGHTHOUSE_PRODUCT_CHANGE_ENABLED }}
|
|
116
125
|
run: node src/packages/sdlc/src/issue-actions.mjs route
|
|
117
126
|
dispatch:
|
|
118
127
|
name: 📥 Dispatch selected stage
|
|
@@ -131,6 +140,7 @@ jobs:
|
|
|
131
140
|
env:
|
|
132
141
|
LIGHTHOUSE_ISSUE: ${{ needs.route.outputs.issue }}
|
|
133
142
|
LIGHTHOUSE_STAGE: ${{ needs.route.outputs.stage }}
|
|
143
|
+
LIGHTHOUSE_WORKER: ${{ needs.route.outputs.worker }}
|
|
134
144
|
steps:
|
|
135
145
|
- uses: actions/checkout@v5
|
|
136
146
|
with:
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# Owned by lighthouse-sdlc. Both routes reuse canonical lifecycle stages.
|
|
2
|
+
name: unattended
|
|
3
|
+
run-name: "${{ inputs.route }} #${{ inputs.issue }} · ${{ github.actor }}"
|
|
4
|
+
on:
|
|
5
|
+
workflow_dispatch:
|
|
6
|
+
inputs:
|
|
7
|
+
issue:
|
|
8
|
+
description: Owner-authorized issue
|
|
9
|
+
required: true
|
|
10
|
+
type: string
|
|
11
|
+
route:
|
|
12
|
+
description: Bounded delivery route
|
|
13
|
+
required: true
|
|
14
|
+
type: choice
|
|
15
|
+
options: [ff, hotfix]
|
|
16
|
+
permissions: {}
|
|
17
|
+
concurrency:
|
|
18
|
+
group: lighthouse-issue-${{ inputs.issue }}
|
|
19
|
+
cancel-in-progress: false
|
|
20
|
+
queue: max
|
|
21
|
+
jobs:
|
|
22
|
+
deliver:
|
|
23
|
+
if: vars.LIGHTHOUSE_AUTOMATION_ENABLED == 'true' && github.actor == github.repository_owner
|
|
24
|
+
runs-on: [self-hosted, linux, lighthouse-workflow]
|
|
25
|
+
timeout-minutes: 125
|
|
26
|
+
permissions:
|
|
27
|
+
actions: write
|
|
28
|
+
contents: write
|
|
29
|
+
issues: write
|
|
30
|
+
pull-requests: write
|
|
31
|
+
steps:
|
|
32
|
+
- name: Load the pinned trusted harness
|
|
33
|
+
uses: actions/checkout@v5
|
|
34
|
+
with:
|
|
35
|
+
repository: juangcarmona/lighthouse
|
|
36
|
+
ref: __LIGHTHOUSE_REF__
|
|
37
|
+
path: tools
|
|
38
|
+
persist-credentials: false
|
|
39
|
+
- name: Load current product source
|
|
40
|
+
uses: actions/checkout@v5
|
|
41
|
+
with:
|
|
42
|
+
path: product
|
|
43
|
+
persist-credentials: false
|
|
44
|
+
- uses: actions/setup-node@v5
|
|
45
|
+
with:
|
|
46
|
+
node-version: 24
|
|
47
|
+
- name: Execute the authorized bounded composition
|
|
48
|
+
env:
|
|
49
|
+
GH_TOKEN: ${{ github.token }}
|
|
50
|
+
run: node tools/src/packages/sdlc/src/unattended-actions.mjs
|
|
51
|
+
- name: Retain candidate and execution evidence
|
|
52
|
+
if: always()
|
|
53
|
+
uses: actions/upload-artifact@v7
|
|
54
|
+
with:
|
|
55
|
+
name: lighthouse-unattended-${{ github.run_id }}-${{ github.run_attempt }}
|
|
56
|
+
path: |
|
|
57
|
+
${{ runner.temp }}/lighthouse-unattended-${{ github.run_id }}/report.json
|
|
58
|
+
${{ runner.temp }}/lighthouse-unattended-${{ github.run_id }}/candidate.json
|
|
59
|
+
${{ runner.temp }}/lighthouse-unattended-${{ github.run_id }}/**/request.json
|
|
60
|
+
${{ runner.temp }}/lighthouse-unattended-${{ github.run_id }}/**/envelope.json
|
|
61
|
+
${{ runner.temp }}/lighthouse-unattended-${{ github.run_id }}/**/checks.json
|
|
62
|
+
${{ runner.temp }}/lighthouse-unattended-${{ github.run_id }}/**/changes.json
|
|
63
|
+
${{ runner.temp }}/lighthouse-unattended-${{ github.run_id }}/**/runtime.json
|
|
64
|
+
${{ runner.temp }}/lighthouse-unattended-${{ github.run_id }}/**/engine-error.json
|
|
65
|
+
${{ runner.temp }}/lighthouse-unattended-${{ github.run_id }}/**/evidence/**
|
|
66
|
+
if-no-files-found: warn
|
|
67
|
+
retention-days: 14
|