@juangcarmona/lighthouse-sdlc 0.8.0 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- # gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"f456a5fb316ce09d00925b022d29d92ae8ab7391a45df1c31a849a38aac234e9","body_hash":"245a033a9e58c7058cfbdca9fc38fb8ad2b02df0303bc8a4249b20e56030f7c2","compiler_version":"v0.93.2","strict":true,"agent_id":"copilot","engine_versions":{"copilot":"1.0.101"},"agent_image_runner":"[\"self-hosted\",\"linux\",\"lighthouse-sdlc\"]"}
1
+ # gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"b277076b2b12e8e6e244bf9e8732963377792859fff2efc91b19776b00a566ec","body_hash":"b6a565e439e84fe26c90f7e33b734b85f344741c514a388f06a7b7d676729ecf","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
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}
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
  #
@@ -91,7 +91,7 @@ concurrency:
91
91
  run-name: "Lighthouse SDLC integrate"
92
92
 
93
93
  env:
94
- LIGHTHOUSE_SKILL: src/packages/sdlc/skills/integrate/SKILL.md
94
+ LIGHTHOUSE_SKILL: node_modules/@juangcarmona/lighthouse-sdlc/skills/integrate/SKILL.md
95
95
  LIGHTHOUSE_STAGE: integrate
96
96
  OTEL_EXPORTER_OTLP_ENDPOINT: ${{ secrets.GH_AW_DEFAULT_OTLP_ENDPOINT || vars.GH_AW_DEFAULT_OTLP_ENDPOINT }}
97
97
  OTEL_SERVICE_NAME: gh-aw.lighthouse-sdlc-integrate
@@ -342,6 +342,7 @@ jobs:
342
342
  GH_AW_ENV_LIGHTHOUSE_SKILL: ${{ env.LIGHTHOUSE_SKILL }}
343
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
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 }}
345
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) }}
346
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) }}
347
348
  GH_AW_GITHUB_ACTOR: ${{ github.actor }}
@@ -371,6 +372,7 @@ jobs:
371
372
  GH_AW_SKILL_DIR: ".github/skills"
372
373
  GH_AW_SKILL_EXT: "/SKILL.md"
373
374
  GH_AW_ENV_LIGHTHOUSE_SKILL: ${{ env.LIGHTHOUSE_SKILL }}
375
+ GH_AW_EXPR_79DC8BAA: ${{ inputs.run-id }}
374
376
  with:
375
377
  script: |
376
378
  const path = require('path');
@@ -386,6 +388,7 @@ jobs:
386
388
  GH_AW_ENV_LIGHTHOUSE_SKILL: ${{ env.LIGHTHOUSE_SKILL }}
387
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) }}
388
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 }}
389
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) }}
390
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) }}
391
394
  GH_AW_GITHUB_ACTOR: ${{ github.actor }}
@@ -410,6 +413,7 @@ jobs:
410
413
  GH_AW_ENV_LIGHTHOUSE_SKILL: process.env.GH_AW_ENV_LIGHTHOUSE_SKILL,
411
414
  GH_AW_EXPR_76DF9333: process.env.GH_AW_EXPR_76DF9333,
412
415
  GH_AW_EXPR_77C1A4D2: process.env.GH_AW_EXPR_77C1A4D2,
416
+ GH_AW_EXPR_79DC8BAA: process.env.GH_AW_EXPR_79DC8BAA,
413
417
  GH_AW_EXPR_7C248226: process.env.GH_AW_EXPR_7C248226,
414
418
  GH_AW_EXPR_C19C384F: process.env.GH_AW_EXPR_C19C384F,
415
419
  GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR,
@@ -593,10 +597,14 @@ jobs:
593
597
  with:
594
598
  name: ${{ needs.activation.outputs.artifact_prefix }}activation
595
599
  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
596
604
  - env:
597
605
  STAGE_INPUT: ${{ inputs.input }}
598
606
  name: Materialize the host input
599
- run: "set -euo pipefail\nmkdir -p /tmp/gh-aw/agent\nprintf '%s\\n' \"${STAGE_INPUT:-{}}\" > /tmp/gh-aw/agent/input.json\n"
607
+ run: "set -euo pipefail\nmkdir -p /tmp/gh-aw/agent\nprintf '%s\\n' \"${STAGE_INPUT:-\"{}\"}\" > /tmp/gh-aw/agent/input.json\n"
600
608
  shell: bash
601
609
  - if: inputs.previous-stage != ''
602
610
  name: Load the previous stage result
@@ -1255,25 +1263,12 @@ jobs:
1255
1263
  fi
1256
1264
  shell: bash
1257
1265
  - env:
1266
+ EXPECTED_RUN_ID: ${{ inputs.run-id }}
1258
1267
  EXPECTED_STAGE: ${{ env.LIGHTHOUSE_STAGE }}
1259
1268
  RESULT_FILE: /tmp/gh-aw/agent/stage-result.json
1260
1269
  if: always()
1261
- name: Validate the stage result and declared gate
1262
- run: |
1263
- set -euo pipefail
1264
- node src/packages/sdlc/src/sdlc.mjs stage-result --input "$RESULT_FILE" --format json
1265
- EXPECTED_STAGE="$EXPECTED_STAGE" RESULT_FILE="$RESULT_FILE" node --input-type=module <<'NODE'
1266
- import { readFileSync } from 'node:fs';
1267
-
1268
- const stage = process.env.EXPECTED_STAGE;
1269
- const result = JSON.parse(readFileSync(process.env.RESULT_FILE, 'utf8'));
1270
- const contract = JSON.parse(readFileSync('src/packages/sdlc/stages.json', 'utf8'));
1271
- const expected = contract.stages.find((item) => item.id === stage);
1272
- if (!expected || result.stage !== stage || result.gate !== expected.gate) {
1273
- console.error(`stage-result does not match stages.json for ${stage}`);
1274
- process.exit(1);
1275
- }
1276
- NODE
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"
1277
1272
  shell: bash
1278
1273
  - if: always()
1279
1274
  name: Upload stage evidence
@@ -8,7 +8,7 @@ runs-on-slim: ubuntu-24.04
8
8
  strict: true
9
9
  env:
10
10
  LIGHTHOUSE_STAGE: integrate
11
- LIGHTHOUSE_SKILL: src/packages/sdlc/skills/integrate/SKILL.md
11
+ LIGHTHOUSE_SKILL: node_modules/@juangcarmona/lighthouse-sdlc/skills/integrate/SKILL.md
12
12
  on:
13
13
  workflow_call:
14
14
  inputs:
@@ -1,4 +1,4 @@
1
- # gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"ebf6e1746c34ac9b555946c99cbb391cf1f1cbd464bf3e459e9f081dccf778b3","body_hash":"52399d69df09f53ba53f4c53ddfc65aa785cad513a6215f4440cd16c6f013c5f","compiler_version":"v0.93.2","strict":true,"agent_id":"copilot","engine_versions":{"copilot":"1.0.101"},"agent_image_runner":"[\"self-hosted\",\"linux\",\"lighthouse-sdlc\"]"}
1
+ # gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"9b81c0af7913a61b530b2d7fde55c12b1c83c57e34d017783bffc7ae8d8cc8b0","body_hash":"ef7d8c8b6f08305285117fa905a1b73b0da432df2883620ea805d88c52d3a036","compiler_version":"v0.93.2","strict":true,"agent_id":"copilot","engine_versions":{"copilot":"1.0.101"},"agent_image_runner":"[\"self-hosted\",\"linux\",\"lighthouse-sdlc\"]"}
2
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}
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
  #
@@ -91,7 +91,7 @@ concurrency:
91
91
  run-name: "Lighthouse SDLC propose"
92
92
 
93
93
  env:
94
- LIGHTHOUSE_SKILL: src/packages/sdlc/skills/propose/SKILL.md
94
+ LIGHTHOUSE_SKILL: node_modules/@juangcarmona/lighthouse-sdlc/skills/propose/SKILL.md
95
95
  LIGHTHOUSE_STAGE: propose
96
96
  OTEL_EXPORTER_OTLP_ENDPOINT: ${{ secrets.GH_AW_DEFAULT_OTLP_ENDPOINT || vars.GH_AW_DEFAULT_OTLP_ENDPOINT }}
97
97
  OTEL_SERVICE_NAME: gh-aw.lighthouse-sdlc-propose
@@ -342,6 +342,7 @@ jobs:
342
342
  GH_AW_ENV_LIGHTHOUSE_SKILL: ${{ env.LIGHTHOUSE_SKILL }}
343
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
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 }}
345
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) }}
346
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) }}
347
348
  GH_AW_GITHUB_ACTOR: ${{ github.actor }}
@@ -371,6 +372,7 @@ jobs:
371
372
  GH_AW_SKILL_DIR: ".github/skills"
372
373
  GH_AW_SKILL_EXT: "/SKILL.md"
373
374
  GH_AW_ENV_LIGHTHOUSE_SKILL: ${{ env.LIGHTHOUSE_SKILL }}
375
+ GH_AW_EXPR_79DC8BAA: ${{ inputs.run-id }}
374
376
  with:
375
377
  script: |
376
378
  const path = require('path');
@@ -386,6 +388,7 @@ jobs:
386
388
  GH_AW_ENV_LIGHTHOUSE_SKILL: ${{ env.LIGHTHOUSE_SKILL }}
387
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) }}
388
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 }}
389
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) }}
390
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) }}
391
394
  GH_AW_GITHUB_ACTOR: ${{ github.actor }}
@@ -410,6 +413,7 @@ jobs:
410
413
  GH_AW_ENV_LIGHTHOUSE_SKILL: process.env.GH_AW_ENV_LIGHTHOUSE_SKILL,
411
414
  GH_AW_EXPR_76DF9333: process.env.GH_AW_EXPR_76DF9333,
412
415
  GH_AW_EXPR_77C1A4D2: process.env.GH_AW_EXPR_77C1A4D2,
416
+ GH_AW_EXPR_79DC8BAA: process.env.GH_AW_EXPR_79DC8BAA,
413
417
  GH_AW_EXPR_7C248226: process.env.GH_AW_EXPR_7C248226,
414
418
  GH_AW_EXPR_C19C384F: process.env.GH_AW_EXPR_C19C384F,
415
419
  GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR,
@@ -593,10 +597,14 @@ jobs:
593
597
  with:
594
598
  name: ${{ needs.activation.outputs.artifact_prefix }}activation
595
599
  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
596
604
  - env:
597
605
  STAGE_INPUT: ${{ inputs.input }}
598
606
  name: Materialize the host input
599
- run: "set -euo pipefail\nmkdir -p /tmp/gh-aw/agent\nprintf '%s\\n' \"${STAGE_INPUT:-{}}\" > /tmp/gh-aw/agent/input.json\n"
607
+ run: "set -euo pipefail\nmkdir -p /tmp/gh-aw/agent\nprintf '%s\\n' \"${STAGE_INPUT:-\"{}\"}\" > /tmp/gh-aw/agent/input.json\n"
600
608
  shell: bash
601
609
  - if: inputs.previous-stage != ''
602
610
  name: Load the previous stage result
@@ -1255,25 +1263,12 @@ jobs:
1255
1263
  fi
1256
1264
  shell: bash
1257
1265
  - env:
1266
+ EXPECTED_RUN_ID: ${{ inputs.run-id }}
1258
1267
  EXPECTED_STAGE: ${{ env.LIGHTHOUSE_STAGE }}
1259
1268
  RESULT_FILE: /tmp/gh-aw/agent/stage-result.json
1260
1269
  if: always()
1261
- name: Validate the stage result and declared gate
1262
- run: |
1263
- set -euo pipefail
1264
- node src/packages/sdlc/src/sdlc.mjs stage-result --input "$RESULT_FILE" --format json
1265
- EXPECTED_STAGE="$EXPECTED_STAGE" RESULT_FILE="$RESULT_FILE" node --input-type=module <<'NODE'
1266
- import { readFileSync } from 'node:fs';
1267
-
1268
- const stage = process.env.EXPECTED_STAGE;
1269
- const result = JSON.parse(readFileSync(process.env.RESULT_FILE, 'utf8'));
1270
- const contract = JSON.parse(readFileSync('src/packages/sdlc/stages.json', 'utf8'));
1271
- const expected = contract.stages.find((item) => item.id === stage);
1272
- if (!expected || result.stage !== stage || result.gate !== expected.gate) {
1273
- console.error(`stage-result does not match stages.json for ${stage}`);
1274
- process.exit(1);
1275
- }
1276
- NODE
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"
1277
1272
  shell: bash
1278
1273
  - if: always()
1279
1274
  name: Upload stage evidence
@@ -8,7 +8,7 @@ runs-on-slim: ubuntu-24.04
8
8
  strict: true
9
9
  env:
10
10
  LIGHTHOUSE_STAGE: propose
11
- LIGHTHOUSE_SKILL: src/packages/sdlc/skills/propose/SKILL.md
11
+ LIGHTHOUSE_SKILL: node_modules/@juangcarmona/lighthouse-sdlc/skills/propose/SKILL.md
12
12
  on:
13
13
  workflow_call:
14
14
  inputs:
@@ -1,4 +1,4 @@
1
- # gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"562e519e2949405165a4285dd87bc748d1aa89939c5378d34c0109426ee1ff56","body_hash":"bcc6396e51707a5f2c63d1aafc9f00ca01ae0d400713dad6e07c3ab38fc9046c","compiler_version":"v0.93.2","strict":true,"agent_id":"copilot","engine_versions":{"copilot":"1.0.101"},"agent_image_runner":"[\"self-hosted\",\"linux\",\"lighthouse-sdlc\"]"}
1
+ # gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"8eedd2af3fe5e8b1b73b9748ac54248a82a41659066888a6627da9ffde8b6f4d","body_hash":"4a2b7bbbefeddc6efc5a04d245e1ea988469ee076c527417cdb0249f11e554f2","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
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}
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
  #
@@ -91,7 +91,7 @@ concurrency:
91
91
  run-name: "Lighthouse SDLC refine"
92
92
 
93
93
  env:
94
- LIGHTHOUSE_SKILL: src/packages/sdlc/skills/refine/SKILL.md
94
+ LIGHTHOUSE_SKILL: node_modules/@juangcarmona/lighthouse-sdlc/skills/refine/SKILL.md
95
95
  LIGHTHOUSE_STAGE: refine
96
96
  OTEL_EXPORTER_OTLP_ENDPOINT: ${{ secrets.GH_AW_DEFAULT_OTLP_ENDPOINT || vars.GH_AW_DEFAULT_OTLP_ENDPOINT }}
97
97
  OTEL_SERVICE_NAME: gh-aw.lighthouse-sdlc-refine
@@ -342,6 +342,7 @@ jobs:
342
342
  GH_AW_ENV_LIGHTHOUSE_SKILL: ${{ env.LIGHTHOUSE_SKILL }}
343
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
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 }}
345
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) }}
346
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) }}
347
348
  GH_AW_GITHUB_ACTOR: ${{ github.actor }}
@@ -371,6 +372,7 @@ jobs:
371
372
  GH_AW_SKILL_DIR: ".github/skills"
372
373
  GH_AW_SKILL_EXT: "/SKILL.md"
373
374
  GH_AW_ENV_LIGHTHOUSE_SKILL: ${{ env.LIGHTHOUSE_SKILL }}
375
+ GH_AW_EXPR_79DC8BAA: ${{ inputs.run-id }}
374
376
  with:
375
377
  script: |
376
378
  const path = require('path');
@@ -386,6 +388,7 @@ jobs:
386
388
  GH_AW_ENV_LIGHTHOUSE_SKILL: ${{ env.LIGHTHOUSE_SKILL }}
387
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) }}
388
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 }}
389
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) }}
390
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) }}
391
394
  GH_AW_GITHUB_ACTOR: ${{ github.actor }}
@@ -410,6 +413,7 @@ jobs:
410
413
  GH_AW_ENV_LIGHTHOUSE_SKILL: process.env.GH_AW_ENV_LIGHTHOUSE_SKILL,
411
414
  GH_AW_EXPR_76DF9333: process.env.GH_AW_EXPR_76DF9333,
412
415
  GH_AW_EXPR_77C1A4D2: process.env.GH_AW_EXPR_77C1A4D2,
416
+ GH_AW_EXPR_79DC8BAA: process.env.GH_AW_EXPR_79DC8BAA,
413
417
  GH_AW_EXPR_7C248226: process.env.GH_AW_EXPR_7C248226,
414
418
  GH_AW_EXPR_C19C384F: process.env.GH_AW_EXPR_C19C384F,
415
419
  GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR,
@@ -593,10 +597,14 @@ jobs:
593
597
  with:
594
598
  name: ${{ needs.activation.outputs.artifact_prefix }}activation
595
599
  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
596
604
  - env:
597
605
  STAGE_INPUT: ${{ inputs.input }}
598
606
  name: Materialize the host input
599
- run: "set -euo pipefail\nmkdir -p /tmp/gh-aw/agent\nprintf '%s\\n' \"${STAGE_INPUT:-{}}\" > /tmp/gh-aw/agent/input.json\n"
607
+ run: "set -euo pipefail\nmkdir -p /tmp/gh-aw/agent\nprintf '%s\\n' \"${STAGE_INPUT:-\"{}\"}\" > /tmp/gh-aw/agent/input.json\n"
600
608
  shell: bash
601
609
  - if: inputs.previous-stage != ''
602
610
  name: Load the previous stage result
@@ -1255,25 +1263,12 @@ jobs:
1255
1263
  fi
1256
1264
  shell: bash
1257
1265
  - env:
1266
+ EXPECTED_RUN_ID: ${{ inputs.run-id }}
1258
1267
  EXPECTED_STAGE: ${{ env.LIGHTHOUSE_STAGE }}
1259
1268
  RESULT_FILE: /tmp/gh-aw/agent/stage-result.json
1260
1269
  if: always()
1261
- name: Validate the stage result and declared gate
1262
- run: |
1263
- set -euo pipefail
1264
- node src/packages/sdlc/src/sdlc.mjs stage-result --input "$RESULT_FILE" --format json
1265
- EXPECTED_STAGE="$EXPECTED_STAGE" RESULT_FILE="$RESULT_FILE" node --input-type=module <<'NODE'
1266
- import { readFileSync } from 'node:fs';
1267
-
1268
- const stage = process.env.EXPECTED_STAGE;
1269
- const result = JSON.parse(readFileSync(process.env.RESULT_FILE, 'utf8'));
1270
- const contract = JSON.parse(readFileSync('src/packages/sdlc/stages.json', 'utf8'));
1271
- const expected = contract.stages.find((item) => item.id === stage);
1272
- if (!expected || result.stage !== stage || result.gate !== expected.gate) {
1273
- console.error(`stage-result does not match stages.json for ${stage}`);
1274
- process.exit(1);
1275
- }
1276
- NODE
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"
1277
1272
  shell: bash
1278
1273
  - if: always()
1279
1274
  name: Upload stage evidence
@@ -8,7 +8,7 @@ runs-on-slim: ubuntu-24.04
8
8
  strict: true
9
9
  env:
10
10
  LIGHTHOUSE_STAGE: refine
11
- LIGHTHOUSE_SKILL: src/packages/sdlc/skills/refine/SKILL.md
11
+ LIGHTHOUSE_SKILL: node_modules/@juangcarmona/lighthouse-sdlc/skills/refine/SKILL.md
12
12
  on:
13
13
  workflow_call:
14
14
  inputs:
@@ -1,4 +1,4 @@
1
- # gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"bc2cf6c3225681d9eb45d1fd2392f9917ba6e1481955301c5151b7d33a022235","body_hash":"3e49dc1c8aabfe651fa9a195977e54c1ccd2bbaf58c9c2bd21e404d322e684c9","compiler_version":"v0.93.2","strict":true,"agent_id":"copilot","engine_versions":{"copilot":"1.0.101"},"agent_image_runner":"[\"self-hosted\",\"linux\",\"lighthouse-sdlc\"]"}
1
+ # gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"eb70f1d711ea5126bbe478ec05c0e7a68cb4c3bed9d2987449aa740d2c5db7e5","body_hash":"ecf132f588f1691b697be174527c5f7342d2f769678480dec54fd189a3f8d98e","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
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}
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
  #
@@ -91,7 +91,7 @@ concurrency:
91
91
  run-name: "Lighthouse SDLC review"
92
92
 
93
93
  env:
94
- LIGHTHOUSE_SKILL: src/packages/sdlc/skills/review/SKILL.md
94
+ LIGHTHOUSE_SKILL: node_modules/@juangcarmona/lighthouse-sdlc/skills/review/SKILL.md
95
95
  LIGHTHOUSE_STAGE: review
96
96
  OTEL_EXPORTER_OTLP_ENDPOINT: ${{ secrets.GH_AW_DEFAULT_OTLP_ENDPOINT || vars.GH_AW_DEFAULT_OTLP_ENDPOINT }}
97
97
  OTEL_SERVICE_NAME: gh-aw.lighthouse-sdlc-review
@@ -342,6 +342,7 @@ jobs:
342
342
  GH_AW_ENV_LIGHTHOUSE_SKILL: ${{ env.LIGHTHOUSE_SKILL }}
343
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
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 }}
345
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) }}
346
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) }}
347
348
  GH_AW_GITHUB_ACTOR: ${{ github.actor }}
@@ -371,6 +372,7 @@ jobs:
371
372
  GH_AW_SKILL_DIR: ".github/skills"
372
373
  GH_AW_SKILL_EXT: "/SKILL.md"
373
374
  GH_AW_ENV_LIGHTHOUSE_SKILL: ${{ env.LIGHTHOUSE_SKILL }}
375
+ GH_AW_EXPR_79DC8BAA: ${{ inputs.run-id }}
374
376
  with:
375
377
  script: |
376
378
  const path = require('path');
@@ -386,6 +388,7 @@ jobs:
386
388
  GH_AW_ENV_LIGHTHOUSE_SKILL: ${{ env.LIGHTHOUSE_SKILL }}
387
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) }}
388
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 }}
389
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) }}
390
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) }}
391
394
  GH_AW_GITHUB_ACTOR: ${{ github.actor }}
@@ -410,6 +413,7 @@ jobs:
410
413
  GH_AW_ENV_LIGHTHOUSE_SKILL: process.env.GH_AW_ENV_LIGHTHOUSE_SKILL,
411
414
  GH_AW_EXPR_76DF9333: process.env.GH_AW_EXPR_76DF9333,
412
415
  GH_AW_EXPR_77C1A4D2: process.env.GH_AW_EXPR_77C1A4D2,
416
+ GH_AW_EXPR_79DC8BAA: process.env.GH_AW_EXPR_79DC8BAA,
413
417
  GH_AW_EXPR_7C248226: process.env.GH_AW_EXPR_7C248226,
414
418
  GH_AW_EXPR_C19C384F: process.env.GH_AW_EXPR_C19C384F,
415
419
  GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR,
@@ -593,10 +597,14 @@ jobs:
593
597
  with:
594
598
  name: ${{ needs.activation.outputs.artifact_prefix }}activation
595
599
  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
596
604
  - env:
597
605
  STAGE_INPUT: ${{ inputs.input }}
598
606
  name: Materialize the host input
599
- run: "set -euo pipefail\nmkdir -p /tmp/gh-aw/agent\nprintf '%s\\n' \"${STAGE_INPUT:-{}}\" > /tmp/gh-aw/agent/input.json\n"
607
+ run: "set -euo pipefail\nmkdir -p /tmp/gh-aw/agent\nprintf '%s\\n' \"${STAGE_INPUT:-\"{}\"}\" > /tmp/gh-aw/agent/input.json\n"
600
608
  shell: bash
601
609
  - if: inputs.previous-stage != ''
602
610
  name: Load the previous stage result
@@ -1255,25 +1263,12 @@ jobs:
1255
1263
  fi
1256
1264
  shell: bash
1257
1265
  - env:
1266
+ EXPECTED_RUN_ID: ${{ inputs.run-id }}
1258
1267
  EXPECTED_STAGE: ${{ env.LIGHTHOUSE_STAGE }}
1259
1268
  RESULT_FILE: /tmp/gh-aw/agent/stage-result.json
1260
1269
  if: always()
1261
- name: Validate the stage result and declared gate
1262
- run: |
1263
- set -euo pipefail
1264
- node src/packages/sdlc/src/sdlc.mjs stage-result --input "$RESULT_FILE" --format json
1265
- EXPECTED_STAGE="$EXPECTED_STAGE" RESULT_FILE="$RESULT_FILE" node --input-type=module <<'NODE'
1266
- import { readFileSync } from 'node:fs';
1267
-
1268
- const stage = process.env.EXPECTED_STAGE;
1269
- const result = JSON.parse(readFileSync(process.env.RESULT_FILE, 'utf8'));
1270
- const contract = JSON.parse(readFileSync('src/packages/sdlc/stages.json', 'utf8'));
1271
- const expected = contract.stages.find((item) => item.id === stage);
1272
- if (!expected || result.stage !== stage || result.gate !== expected.gate) {
1273
- console.error(`stage-result does not match stages.json for ${stage}`);
1274
- process.exit(1);
1275
- }
1276
- NODE
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"
1277
1272
  shell: bash
1278
1273
  - if: always()
1279
1274
  name: Upload stage evidence
@@ -8,7 +8,7 @@ runs-on-slim: ubuntu-24.04
8
8
  strict: true
9
9
  env:
10
10
  LIGHTHOUSE_STAGE: review
11
- LIGHTHOUSE_SKILL: src/packages/sdlc/skills/review/SKILL.md
11
+ LIGHTHOUSE_SKILL: node_modules/@juangcarmona/lighthouse-sdlc/skills/review/SKILL.md
12
12
  on:
13
13
  workflow_call:
14
14
  inputs:
@@ -1,12 +1,12 @@
1
1
  name: Lighthouse SDLC router
2
2
 
3
3
  # This router owns the only automatic composition boundary. A normal dispatch calls exactly one
4
- # worker. `ff` follows the selected route and stops when a worker fails; it never adds a stage.
4
+ # worker. `ff` is blocked for routes with human gates until approvals can be verified.
5
5
  on:
6
6
  workflow_dispatch:
7
7
  inputs:
8
8
  route:
9
- description: Lighthouse route from src/packages/sdlc/routes.json.
9
+ description: Lighthouse route from the installed SDLC package.
10
10
  required: true
11
11
  type: choice
12
12
  options: [supervised, plan-only, unattended, hotfix, stacked]
@@ -59,6 +59,11 @@ jobs:
59
59
  review: ${{ steps.route.outputs.review }}
60
60
  steps:
61
61
  - uses: actions/checkout@v5
62
+ - uses: actions/setup-node@v5
63
+ with:
64
+ node-version: 24
65
+ - run: npm ci --ignore-scripts
66
+ - run: node node_modules/@juangcarmona/lighthouse-sdlc/src/installation.mjs
62
67
  - name: Validate route, prerequisites and selected composition
63
68
  id: route
64
69
  env:
@@ -68,7 +73,7 @@ jobs:
68
73
  AVAILABLE: ${{ inputs.available }}
69
74
  run: |
70
75
  set -euo pipefail
71
- node src/packages/sdlc/src/sdlc.mjs route --route "$ROUTE" --available "$AVAILABLE" --format json > route.json
76
+ node node_modules/@juangcarmona/lighthouse-sdlc/src/sdlc.mjs route --route "$ROUTE" --available "$AVAILABLE" --composition "$COMPOSITION" --format json > route.json
72
77
  jq -e '.valid == true and .canRun == true' route.json >/dev/null
73
78
  jq -e --arg stage "$STAGE" '.stages | index($stage) != null' route.json >/dev/null
74
79
  if [ "$COMPOSITION" = ff ]; then
@@ -1,4 +1,4 @@
1
- # gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"2c6086ff0b107313a5e4dda6c47cc224aaa5e708b5060e1ec243528fe5ee12cb","body_hash":"80b3474e3d854c1fe1bfa4c9af92b7c0e13f15639578f906f62e32c7a78ef05f","compiler_version":"v0.93.2","strict":true,"agent_id":"copilot","engine_versions":{"copilot":"1.0.101"},"agent_image_runner":"[\"self-hosted\",\"linux\",\"lighthouse-sdlc\"]"}
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
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}
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
  #
@@ -91,7 +91,7 @@ concurrency:
91
91
  run-name: "Lighthouse SDLC triage"
92
92
 
93
93
  env:
94
- LIGHTHOUSE_SKILL: src/packages/sdlc/skills/triage/SKILL.md
94
+ LIGHTHOUSE_SKILL: node_modules/@juangcarmona/lighthouse-sdlc/skills/triage/SKILL.md
95
95
  LIGHTHOUSE_STAGE: triage
96
96
  OTEL_EXPORTER_OTLP_ENDPOINT: ${{ secrets.GH_AW_DEFAULT_OTLP_ENDPOINT || vars.GH_AW_DEFAULT_OTLP_ENDPOINT }}
97
97
  OTEL_SERVICE_NAME: gh-aw.lighthouse-sdlc-triage
@@ -342,6 +342,7 @@ jobs:
342
342
  GH_AW_ENV_LIGHTHOUSE_SKILL: ${{ env.LIGHTHOUSE_SKILL }}
343
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
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 }}
345
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) }}
346
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) }}
347
348
  GH_AW_GITHUB_ACTOR: ${{ github.actor }}
@@ -371,6 +372,7 @@ jobs:
371
372
  GH_AW_SKILL_DIR: ".github/skills"
372
373
  GH_AW_SKILL_EXT: "/SKILL.md"
373
374
  GH_AW_ENV_LIGHTHOUSE_SKILL: ${{ env.LIGHTHOUSE_SKILL }}
375
+ GH_AW_EXPR_79DC8BAA: ${{ inputs.run-id }}
374
376
  with:
375
377
  script: |
376
378
  const path = require('path');
@@ -386,6 +388,7 @@ jobs:
386
388
  GH_AW_ENV_LIGHTHOUSE_SKILL: ${{ env.LIGHTHOUSE_SKILL }}
387
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) }}
388
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 }}
389
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) }}
390
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) }}
391
394
  GH_AW_GITHUB_ACTOR: ${{ github.actor }}
@@ -410,6 +413,7 @@ jobs:
410
413
  GH_AW_ENV_LIGHTHOUSE_SKILL: process.env.GH_AW_ENV_LIGHTHOUSE_SKILL,
411
414
  GH_AW_EXPR_76DF9333: process.env.GH_AW_EXPR_76DF9333,
412
415
  GH_AW_EXPR_77C1A4D2: process.env.GH_AW_EXPR_77C1A4D2,
416
+ GH_AW_EXPR_79DC8BAA: process.env.GH_AW_EXPR_79DC8BAA,
413
417
  GH_AW_EXPR_7C248226: process.env.GH_AW_EXPR_7C248226,
414
418
  GH_AW_EXPR_C19C384F: process.env.GH_AW_EXPR_C19C384F,
415
419
  GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR,
@@ -593,10 +597,14 @@ jobs:
593
597
  with:
594
598
  name: ${{ needs.activation.outputs.artifact_prefix }}activation
595
599
  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
596
604
  - env:
597
605
  STAGE_INPUT: ${{ inputs.input }}
598
606
  name: Materialize the host input
599
- run: "set -euo pipefail\nmkdir -p /tmp/gh-aw/agent\nprintf '%s\\n' \"${STAGE_INPUT:-{}}\" > /tmp/gh-aw/agent/input.json\n"
607
+ run: "set -euo pipefail\nmkdir -p /tmp/gh-aw/agent\nprintf '%s\\n' \"${STAGE_INPUT:-\"{}\"}\" > /tmp/gh-aw/agent/input.json\n"
600
608
  shell: bash
601
609
  - if: inputs.previous-stage != ''
602
610
  name: Load the previous stage result
@@ -1255,25 +1263,12 @@ jobs:
1255
1263
  fi
1256
1264
  shell: bash
1257
1265
  - env:
1266
+ EXPECTED_RUN_ID: ${{ inputs.run-id }}
1258
1267
  EXPECTED_STAGE: ${{ env.LIGHTHOUSE_STAGE }}
1259
1268
  RESULT_FILE: /tmp/gh-aw/agent/stage-result.json
1260
1269
  if: always()
1261
- name: Validate the stage result and declared gate
1262
- run: |
1263
- set -euo pipefail
1264
- node src/packages/sdlc/src/sdlc.mjs stage-result --input "$RESULT_FILE" --format json
1265
- EXPECTED_STAGE="$EXPECTED_STAGE" RESULT_FILE="$RESULT_FILE" node --input-type=module <<'NODE'
1266
- import { readFileSync } from 'node:fs';
1267
-
1268
- const stage = process.env.EXPECTED_STAGE;
1269
- const result = JSON.parse(readFileSync(process.env.RESULT_FILE, 'utf8'));
1270
- const contract = JSON.parse(readFileSync('src/packages/sdlc/stages.json', 'utf8'));
1271
- const expected = contract.stages.find((item) => item.id === stage);
1272
- if (!expected || result.stage !== stage || result.gate !== expected.gate) {
1273
- console.error(`stage-result does not match stages.json for ${stage}`);
1274
- process.exit(1);
1275
- }
1276
- NODE
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"
1277
1272
  shell: bash
1278
1273
  - if: always()
1279
1274
  name: Upload stage evidence
@@ -8,7 +8,7 @@ runs-on-slim: ubuntu-24.04
8
8
  strict: true
9
9
  env:
10
10
  LIGHTHOUSE_STAGE: triage
11
- LIGHTHOUSE_SKILL: src/packages/sdlc/skills/triage/SKILL.md
11
+ LIGHTHOUSE_SKILL: node_modules/@juangcarmona/lighthouse-sdlc/skills/triage/SKILL.md
12
12
  on:
13
13
  workflow_call:
14
14
  inputs:
@@ -36,6 +36,6 @@ imports:
36
36
 
37
37
  # Lighthouse SDLC triage worker
38
38
 
39
- Execute only `triage` by following `${{ env.LIGHTHOUSE_SKILL }}` and the package contracts in `src/packages/sdlc/routes.json`, `src/packages/sdlc/stages.json` and `src/packages/sdlc/schemas/stage-result.schema.json`. Read ProductShape and ArcShape context when the host provides citations, and preserve those citations in evidence.
39
+ Execute only `triage` by following `${{ env.LIGHTHOUSE_SKILL }}` and the package contracts in `node_modules/@juangcarmona/lighthouse-sdlc/routes.json`, `node_modules/@juangcarmona/lighthouse-sdlc/stages.json` and `node_modules/@juangcarmona/lighthouse-sdlc/schemas/stage-result.schema.json`. Read ProductShape and ArcShape context when the host provides citations, and preserve those citations in evidence.
40
40
 
41
41
  Do not invoke `refine` or any later stage. Do not invent route names, labels, gates, statuses or evidence fields. Assess the work item, route, owner and evidence as the skill requires. Write one valid result to `/tmp/gh-aw/agent/stage-result.json` with `stage: triage`, `gate: triaged`, the triage record in `output`, and separate `evidence`, `missingEvidence`, `unavailableChecks` and `pendingReview` arrays. Stop at the triaged gate, then call `noop` exactly once.