@juangcarmona/lighthouse-sdlc 0.12.0 → 0.13.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,41 +1,167 @@
1
1
  ---
2
- # Owned by @juangcarmona/lighthouse-sdlc. Compile with `gh aw compile`; do not edit the lock file.
2
+ # Owned by lighthouse-sdlc. Regenerate the lock with gh aw v0.93.2.
3
3
  name: Lighthouse SDLC propose
4
- description: Execute only the Lighthouse proposal stage and return its declared stage result.
5
- private: true
6
- runs-on: [self-hosted, linux, lighthouse-sdlc]
7
- runs-on-slim: ubuntu-24.04
8
- strict: true
9
- env:
10
- LIGHTHOUSE_STAGE: propose
11
- LIGHTHOUSE_SKILL: node_modules/@juangcarmona/lighthouse-sdlc/skills/propose/SKILL.md
4
+ description: Produce a validated OpenSpec proposal PR from an owner-authorized ready issue.
12
5
  on:
13
6
  workflow_call:
14
7
  inputs:
15
- route:
16
- description: Lighthouse route selected by the host.
17
- required: true
18
- type: string
19
- run-id:
20
- description: Stable Lighthouse run identifier.
8
+ issue:
21
9
  required: true
22
10
  type: string
23
- input:
24
- description: Compact JSON input for this stage.
25
- required: false
26
- type: string
27
- default: '{}'
28
- previous-stage:
29
- description: Previous stage artifact name.
30
- required: false
31
- type: string
32
- default: refine
11
+ needs: [prepare]
12
+ runs-on: [self-hosted, linux, lighthouse-workflow]
13
+ runs-on-slim: ubuntu-24.04
14
+ timeout-minutes: 15
15
+ permissions:
16
+ contents: read
17
+ engine:
18
+ id: opencode
19
+ command: node
33
20
  imports:
34
- - shared/lighthouse-sdlc-stage.md
21
+ - shared/lighthouse-opencode.md
22
+ # Subscription authentication runs inside the operator's Docker engine sandbox.
23
+ # This profile does not claim AWF network isolation or API-proxy credential isolation.
24
+ strict: false
25
+ features:
26
+ dangerously-disable-sandbox-agent: true
27
+ sandbox:
28
+ agent: false
29
+ tools:
30
+ github: false
31
+ safe-outputs:
32
+ create-issue: false
33
+ report-incomplete: false
34
+ threat-detection: false
35
+ report-failure-as-issue: false
36
+ report-missing-tool: false
37
+ report-missing-data: false
38
+ noop:
39
+ report-as-issue: false
40
+ network:
41
+ allowed: []
42
+ steps:
43
+ - name: Check out the authorized product revision
44
+ uses: actions/checkout@v5
45
+ with:
46
+ persist-credentials: false
47
+ - name: Load the pinned harness package
48
+ uses: actions/checkout@v5
49
+ with:
50
+ repository: juangcarmona/lighthouse
51
+ ref: __LIGHTHOUSE_REF__
52
+ path: tools
53
+ persist-credentials: false
54
+ - name: Load the authorized issue context
55
+ uses: actions/download-artifact@v8
56
+ with:
57
+ name: lighthouse-input-${{ inputs.issue }}-${{ github.run_attempt }}
58
+ path: ${{ runner.temp }}/lighthouse-${{ github.run_id }}-${{ github.run_attempt }}
59
+ post-steps:
60
+ - name: Validate the Lighthouse result
61
+ run: node tools/src/packages/sdlc/src/issue-actions.mjs validate
62
+ - name: Preserve the result and runtime receipt
63
+ if: always()
64
+ uses: actions/upload-artifact@v7
65
+ with:
66
+ name: lighthouse-result-${{ inputs.issue }}-${{ github.run_attempt }}
67
+ path: |
68
+ ${{ runner.temp }}/lighthouse-${{ github.run_id }}-${{ github.run_attempt }}/envelope.json
69
+ ${{ runner.temp }}/lighthouse-${{ github.run_id }}-${{ github.run_attempt }}/runtime.json
70
+ if-no-files-found: error
71
+ retention-days: 14
72
+ - name: Preserve OpenCode diagnostic events
73
+ if: always()
74
+ uses: actions/upload-artifact@v7
75
+ with:
76
+ name: opencode-events-${{ inputs.issue }}-${{ github.run_attempt }}
77
+ path: ${{ runner.temp }}/gh-aw/opencode-events-${{ github.run_id }}-${{ github.run_attempt }}.jsonl
78
+ if-no-files-found: ignore
79
+ retention-days: 14
80
+ jobs:
81
+ prepare:
82
+ name: Authorize and reserve issue
83
+ runs-on: ubuntu-24.04
84
+ permissions:
85
+ actions: read
86
+ contents: read
87
+ issues: write
88
+ env:
89
+ LIGHTHOUSE_ISSUE: ${{ inputs.issue }}
90
+ steps:
91
+ - uses: actions/checkout@v5
92
+ with:
93
+ repository: juangcarmona/lighthouse
94
+ ref: __LIGHTHOUSE_REF__
95
+ persist-credentials: false
96
+ - uses: actions/setup-node@v5
97
+ with:
98
+ node-version: 24
99
+ - name: Collect verified owner intent and reserve the issue
100
+ id: prepare
101
+ env:
102
+ GH_TOKEN: ${{ github.token }}
103
+ run: node src/packages/sdlc/src/issue-actions.mjs prepare
104
+ - name: Preserve the execution request
105
+ uses: actions/upload-artifact@v7
106
+ with:
107
+ name: lighthouse-input-${{ inputs.issue }}-${{ github.run_attempt }}
108
+ path: ${{ runner.temp }}/lighthouse-${{ github.run_id }}-${{ github.run_attempt }}/
109
+ if-no-files-found: error
110
+ retention-days: 14
111
+ - name: Release reservation if preparation failed
112
+ if: failure()
113
+ env:
114
+ GH_TOKEN: ${{ github.token }}
115
+ run: node src/packages/sdlc/src/issue-actions.mjs cleanup
116
+ publish:
117
+ name: Validate, publish and release
118
+ needs: [prepare, agent]
119
+ if: always() && needs.prepare.result == 'success'
120
+ runs-on: ubuntu-24.04
121
+ permissions:
122
+ contents: write
123
+ issues: write
124
+ pull-requests: write
125
+ env:
126
+ LIGHTHOUSE_ISSUE: ${{ inputs.issue }}
127
+ steps:
128
+ - uses: actions/checkout@v5
129
+ with:
130
+ repository: juangcarmona/lighthouse
131
+ ref: __LIGHTHOUSE_REF__
132
+ persist-credentials: false
133
+ - uses: actions/setup-node@v5
134
+ with:
135
+ node-version: 24
136
+ - name: Load the execution request
137
+ uses: actions/download-artifact@v8
138
+ with:
139
+ name: lighthouse-input-${{ inputs.issue }}-${{ github.run_attempt }}
140
+ path: ${{ runner.temp }}/lighthouse-${{ github.run_id }}-${{ github.run_attempt }}
141
+ - name: Load the candidate result
142
+ if: needs.agent.result == 'success'
143
+ uses: actions/download-artifact@v8
144
+ with:
145
+ name: lighthouse-result-${{ inputs.issue }}-${{ github.run_attempt }}
146
+ path: ${{ runner.temp }}/lighthouse-${{ github.run_id }}-${{ github.run_attempt }}
147
+ - name: Recheck authority and publish the validated result
148
+ if: needs.agent.result == 'success'
149
+ env:
150
+ GH_TOKEN: ${{ github.token }}
151
+ run: node src/packages/sdlc/src/issue-actions.mjs publish
152
+ - name: Release the issue reservation
153
+ if: always()
154
+ env:
155
+ GH_TOKEN: ${{ github.token }}
156
+ run: node src/packages/sdlc/src/issue-actions.mjs cleanup
35
157
  ---
36
158
 
37
- # Lighthouse SDLC propose worker
159
+ # Propose the authorized change
160
+
161
+ Execute only `propose` using the trusted context in `/input/context.json` and the packaged `/harness/skills/propose/SKILL.md`. The host has authenticated the passed refinement and the owner's explicit request. Inspect the current read-only source under `/workspace`, including product and architecture policy, relevant existing specifications and active changes.
162
+
163
+ Write brief public progress before source inspection and when you choose an approach or find a blocker. Explain the decision and supporting evidence. Keep tool payloads out of progress messages.
38
164
 
39
- Execute only `propose` by following `${{ env.LIGHTHOUSE_SKILL }}` and reading the refine result from `/tmp/gh-aw/agent/previous/stage-result.json` when present; for a supervised run, use the predecessor context in `/tmp/gh-aw/agent/input.json`. ProductShape, ArcShape and OpenSpec remain their own authorities; preserve their citations and artifact references in evidence.
165
+ Follow `context.proposal.instructions` from the pinned OpenSpec provider, in order: proposal, specifications and design, then tasks. Return the actual Markdown files in `result.output.files`, each with `path` and `content`, under the authorized `context.proposal.root`. Include a concise proposal, design alternatives and trade-offs, testable specification scenarios, dependency-ordered unchecked tasks, validation and visual evidence plans where applicable. Every refined acceptance criterion needs a corresponding task or specification. Preserve existing product authority. Keep unresolved product decisions explicit rather than inventing approval.
40
166
 
41
- Do not invoke `implement` or any later stage. Return one valid result in `/tmp/gh-aw/agent/stage-result.json` with `stage: propose`, `gate: planned`, the change artifacts in `output`, and separate evidence arrays. Stop at the planned gate, then call `noop` exactly once. If a prerequisite or check fails, return the declared failure or blocked status with the evidence preserved.
167
+ Write `/output/envelope.json` using the supplied schema and identity. A complete proposal returns `passed` with gate `planned`; it is a candidate for owner review, not approved implementation. Return `blocked` with the precise missing decision when the proposal cannot be completed. The separate publisher checks the file boundary, runs OpenSpec strict validation and opens a proposal PR. The engine writes no repository files and has no GitHub credentials. End after the envelope; the trusted adapter records gh-aw completion.
@@ -1,5 +1,5 @@
1
- # gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"c2d46a609abe68ae8883e069cd886268717d2b691c2e9d5111f49b35a47ac98b","body_hash":"75843d473d92221a1696d21424dad22c79a230f0395722f7957b30fc24ffad58","compiler_version":"v0.93.2","agent_id":"opencode","engine_versions":{"opencode":"2.1.0"},"agent_image_runner":"[\"self-hosted\",\"linux\",\"lighthouse-workflow\"]"}
2
- # gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_DEFAULT_OTLP_ENDPOINT","GH_AW_DEFAULT_OTLP_HEADERS","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN"],"actions":[{"repo":"actions/checkout","sha":"3d3c42e5aac5ba805825da76410c181273ba90b1","version":"v7.0.1"},{"repo":"actions/checkout","sha":"fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09","version":"v5"},{"repo":"actions/download-artifact","sha":"9000827ccba6bdab643e8b6fd33ac0654aef8333","version":"v8.0.2"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"949feb2413d6458794dcd2491c4babbbce0c15c1","version":"v7.1.0"},{"repo":"actions/setup-node","sha":"a0853c24544627f65ddf259abe73b1d18a591444","version":"v5"},{"repo":"actions/upload-artifact","sha":"cf430e030ddbb5b0abf93d22962f4752f3646cd9","version":"v7.0.2"},{"repo":"github/gh-aw-actions/setup","sha":"d9128eb3ea40c18b77c76184eda03c0ff2608d79","version":"v0.93.2"}],"mcp_servers":[],"threat_detection":{"mode":"disabled"},"admission":false}
1
+ # gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"8406b6ec905e9f6e43a42fdae02a5ef0c00e10db92322b65c8d9fcbe84e3e762","body_hash":"00aaac0798637a281758028c249e7c1086c7ca9e32ea9cb2ef51af769c3e2586","compiler_version":"v0.93.2","agent_id":"opencode","engine_versions":{"opencode":"2.1.0"},"agent_image_runner":"[\"self-hosted\",\"linux\",\"lighthouse-workflow\"]"}
2
+ # gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_DEFAULT_OTLP_ENDPOINT","GH_AW_DEFAULT_OTLP_HEADERS","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN"],"actions":[{"repo":"actions/checkout","sha":"3d3c42e5aac5ba805825da76410c181273ba90b1","version":"v7.0.1"},{"repo":"actions/checkout","sha":"fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09","version":"v5"},{"repo":"actions/download-artifact","sha":"9000827ccba6bdab643e8b6fd33ac0654aef8333","version":"v8.0.2"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"949feb2413d6458794dcd2491c4babbbce0c15c1","version":"v7.1.0"},{"repo":"actions/setup-node","sha":"a0853c24544627f65ddf259abe73b1d18a591444","version":"v5"},{"repo":"actions/upload-artifact","sha":"cf430e030ddbb5b0abf93d22962f4752f3646cd9","version":"v7.0.2"},{"repo":"github/gh-aw-actions/setup","sha":"d9128eb3ea40c18b77c76184eda03c0ff2608d79","version":"v0.93.2"}],"containers":[{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:41835613992df88f51e923bad486f96dfb2e6cda29f13e217df41833284ae382","pinned_image":"ghcr.io/github/gh-aw-node@sha256:41835613992df88f51e923bad486f96dfb2e6cda29f13e217df41833284ae382"}],"mcp_servers":[{"name":"safeoutputs","tools":["noop"]}],"threat_detection":{"mode":"disabled"},"admission":false}
3
3
  # This file was automatically generated by gh-aw (v0.93.2). DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md
4
4
  #
5
5
  # ___ _ _
@@ -46,6 +46,9 @@
46
46
  # - actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5
47
47
  # - actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
48
48
  # - github/gh-aw-actions/setup@d9128eb3ea40c18b77c76184eda03c0ff2608d79 # v0.93.2
49
+ #
50
+ # Container images used:
51
+ # - ghcr.io/github/gh-aw-node@sha256:41835613992df88f51e923bad486f96dfb2e6cda29f13e217df41833284ae382
49
52
 
50
53
  name: "Lighthouse SDLC refine"
51
54
  on:
@@ -325,11 +328,13 @@ jobs:
325
328
  GH_AW_ACTIONS_DIR: ${{ runner.temp }}/gh-aw/actions
326
329
  GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt
327
330
  GH_AW_SAFE_OUTPUTS: ${{ runner.temp }}/gh-aw/safeoutputs/outputs.jsonl
328
- GH_AW_PROMPT_CONFIG: "{\"items\":[{\"content_env\":\"GH_AW_PROMPT_CONTENT_0000\"},{\"file\":\"xpia.md\"},{\"file\":\"temp_folder_prompt.md\"},{\"file\":\"markdown.md\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0001\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0002\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0003\"}],\"system_item_count\":5}"
331
+ GH_AW_PROMPT_CONFIG: "{\"items\":[{\"content_env\":\"GH_AW_PROMPT_CONTENT_0000\"},{\"file\":\"xpia.md\"},{\"file\":\"temp_folder_prompt.md\"},{\"file\":\"markdown.md\"},{\"file\":\"safe_outputs_mcp_transport_prompt.md\"},{\"file\":\"safe_outputs_prompt.md\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0001\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0002\"},{\"file\":\"mcp_cli_tools_with_safeoutputs_prompt.md\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0003\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0004\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0005\"}],\"system_item_count\":10}"
329
332
  GH_AW_PROMPT_CONTENT_0000: "<system>\n"
330
- GH_AW_PROMPT_CONTENT_0001: "</system>\n"
331
- GH_AW_PROMPT_CONTENT_0002: "{{#runtime-import .github/workflows/shared/lighthouse-opencode.md}}\n"
332
- GH_AW_PROMPT_CONTENT_0003: "{{#runtime-import .github/workflows/lighthouse-sdlc-refine.md}}\n"
333
+ GH_AW_PROMPT_CONTENT_0001: "<safe-output-tools>\nTools: noop(max:2)\n"
334
+ GH_AW_PROMPT_CONTENT_0002: "</safe-output-tools>\n"
335
+ GH_AW_PROMPT_CONTENT_0003: "</system>\n"
336
+ GH_AW_PROMPT_CONTENT_0004: "{{#runtime-import .github/workflows/shared/lighthouse-opencode.md}}\n"
337
+ GH_AW_PROMPT_CONTENT_0005: "{{#runtime-import .github/workflows/lighthouse-sdlc-refine.md}}\n"
333
338
  with:
334
339
  script: |
335
340
  const { setupGlobals } = require(process.env.GH_AW_ACTIONS_DIR + '/setup_globals.cjs');
@@ -357,6 +362,7 @@ jobs:
357
362
  uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
358
363
  env:
359
364
  GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt
365
+ GH_AW_MCP_CLI_SERVERS_LIST: '- `safeoutputs` — run `safeoutputs --help` to see available tools'
360
366
  GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED: ${{ needs.pre_activation.outputs.activated }}
361
367
  with:
362
368
  script: |
@@ -371,6 +377,7 @@ jobs:
371
377
  return await substitutePlaceholders({
372
378
  file: process.env.GH_AW_PROMPT,
373
379
  substitutions: {
380
+ GH_AW_MCP_CLI_SERVERS_LIST: process.env.GH_AW_MCP_CLI_SERVERS_LIST,
374
381
  GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED: process.env.GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED
375
382
  }
376
383
  });
@@ -563,6 +570,168 @@ jobs:
563
570
  env:
564
571
  GH_AW_SKILL_DIR: ".github/skills"
565
572
  run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_inline_skills.sh"
573
+ - name: Download container images
574
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-node@sha256:41835613992df88f51e923bad486f96dfb2e6cda29f13e217df41833284ae382
575
+ - name: Prepare Safe Outputs Directories
576
+ run: |
577
+ mkdir -p "${RUNNER_TEMP}/gh-aw/safeoutputs"
578
+ mkdir -p /tmp/gh-aw/safeoutputs
579
+ mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs
580
+ - name: Generate Safe Outputs Config
581
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
582
+ env:
583
+ GH_AW_FILE_ROOT: "${{ runner.temp }}/gh-aw"
584
+ GH_AW_FILE_CONFIG: "{\"files\":[{\"path\":\"safeoutputs/config.json\",\"content_env\":\"GH_AW_SAFE_OUTPUTS_CONFIG\"}]}"
585
+ GH_AW_SAFE_OUTPUTS_CONFIG: "{\"noop\":{\"max\":2,\"report-as-issue\":\"false\"}}"
586
+ with:
587
+ script: |
588
+ const path = require('path');
589
+ const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
590
+ const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs'));
591
+ setupGlobals(core, github, context, exec, io, getOctokit);
592
+ const { main } = require(path.join(actionsDir, 'create_files.cjs'));
593
+ await main();
594
+ - name: Generate Safe Outputs Tools
595
+ env:
596
+ GH_AW_TOOLS_META_JSON: |
597
+ {
598
+ "description_suffixes": {},
599
+ "repo_params": {},
600
+ "dynamic_tools": []
601
+ }
602
+ GH_AW_VALIDATION_JSON: |
603
+ {
604
+ "noop": {
605
+ "defaultMax": 2,
606
+ "fields": {
607
+ "message": {
608
+ "required": true,
609
+ "type": "string",
610
+ "sanitize": true,
611
+ "maxLength": 65000
612
+ }
613
+ }
614
+ }
615
+ }
616
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
617
+ with:
618
+ script: |
619
+ const path = require('path');
620
+ const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
621
+ const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs'));
622
+ setupGlobals(core, github, context, exec, io, getOctokit);
623
+ const { main } = require(path.join(actionsDir, 'generate_safe_outputs_tools.cjs'));
624
+ await main();
625
+ - name: Start MCP Gateway
626
+ id: start-mcp-gateway
627
+ env:
628
+ DEBUG: ${{ env.DEBUG || runner.debug == '1' && '*' || '' }}
629
+ GH_AW_POLICY_ALLOW_CREATE_PULL_REQUEST: ${{ vars.GH_AW_POLICY_ALLOW_CREATE_PULL_REQUEST || 'true' }}
630
+ GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
631
+ GH_AW_SAFE_OUTPUTS_CONFIG_PATH: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS_CONFIG_PATH }}
632
+ GH_AW_SAFE_OUTPUTS_TOOLS_PATH: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS_TOOLS_PATH }}
633
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
634
+ run: |
635
+ set -eo pipefail
636
+ mkdir -p "${RUNNER_TEMP}/gh-aw/mcp-config"
637
+ if [ -n "${GITHUB_EVENT_PATH:-}" ] && [ -r "${GITHUB_EVENT_PATH}" ]; then
638
+ GH_AW_SAFEOUTPUTS_EVENT_PATH="${RUNNER_TEMP}/gh-aw/safeoutputs/github_event.json"
639
+ cp "${GITHUB_EVENT_PATH}" "${GH_AW_SAFEOUTPUTS_EVENT_PATH}"
640
+ export GITHUB_EVENT_PATH="${GH_AW_SAFEOUTPUTS_EVENT_PATH}"
641
+ fi
642
+
643
+ # Export gateway environment variables for MCP config and gateway script
644
+ export MCP_GATEWAY_PORT="8080"
645
+ export MCP_GATEWAY_DOMAIN="localhost"
646
+ export MCP_GATEWAY_HOST_DOMAIN="localhost"
647
+ MCP_GATEWAY_AGENT_ID=$(openssl rand -base64 45 | tr -d '/+=')
648
+ echo "::add-mask::${MCP_GATEWAY_AGENT_ID}"
649
+ export MCP_GATEWAY_AGENT_ID
650
+ export MCP_GATEWAY_PAYLOAD_DIR="/tmp/gh-aw/mcp-payloads"
651
+ mkdir -p "${MCP_GATEWAY_PAYLOAD_DIR}"
652
+ export MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD="524288"
653
+ export MCP_GATEWAY_ALLOWED_MOUNT_ROOTS="${GITHUB_WORKSPACE}:rw,${RUNNER_TEMP}/gh-aw:ro,${RUNNER_TEMP}/gh-aw/safeoutputs:rw,/opt:ro,/tmp:rw,/usr/bin/gh:ro"
654
+ export GH_AW_PR_HEAD_BASE_BRANCH="${GH_AW_PR_HEAD_BASE_BRANCH:-}"
655
+ export GH_AW_PR_HEAD_BASE_SHA="${GH_AW_PR_HEAD_BASE_SHA:-}"
656
+ export GH_AW_PR_HEAD_BASE_REPO="${GH_AW_PR_HEAD_BASE_REPO:-}"
657
+ export GH_AW_PR_HEAD_BASE_PR_NUMBER="${GH_AW_PR_HEAD_BASE_PR_NUMBER:-}"
658
+ export GH_AW_PR_HEAD_BASE_REF="${GH_AW_PR_HEAD_BASE_REF:-}"
659
+ export GH_AW_PR_HEAD_REPO="${GH_AW_PR_HEAD_REPO:-}"
660
+ export GH_AW_TARGET_REPO_SLUG="${GH_AW_TARGET_REPO_SLUG:-}"
661
+ export GH_AW_ENGINE="opencode"
662
+ MCP_GATEWAY_UID=$(id -u 2>/dev/null || echo '0')
663
+ MCP_GATEWAY_GID=$(id -g 2>/dev/null || echo '0')
664
+ source "${RUNNER_TEMP}/gh-aw/actions/resolve_docker_socket_gid.sh"
665
+ export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host --name awmg-mcpg --add-host host.docker.internal:127.0.0.1 --user '"${MCP_GATEWAY_UID}"':'"${MCP_GATEWAY_GID}"' --group-add '"${DOCKER_SOCK_GID}"' -v '"${DOCKER_SOCK_PATH}"':/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_AGENT_ID -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DOCKER_HOST=unix:///var/run/docker.sock -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_TARGET_REPO_SLUG -e GH_AW_PR_HEAD_BASE_BRANCH -e GH_AW_PR_HEAD_BASE_SHA -e GH_AW_PR_HEAD_BASE_REPO -e GH_AW_PR_HEAD_BASE_PR_NUMBER -e GH_AW_PR_HEAD_BASE_REF -e GH_AW_PR_HEAD_REPO -e GH_AW_POLICY_ALLOW_CREATE_PULL_REQUEST -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GH_AW_SINK_VISIBILITY -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e RUNNER_TEMP -e RUNNER_TOOL_CACHE -e MCP_GATEWAY_ALLOWED_MOUNT_ROOTS -e GITHUB_AW_OTEL_TRACE_ID -e GITHUB_AW_OTEL_PARENT_SPAN_ID -e OTEL_EXPORTER_OTLP_HEADERS -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw -v '"${RUNNER_TEMP}"'/gh-aw/safeoutputs:'"${RUNNER_TEMP}"'/gh-aw/safeoutputs:rw ghcr.io/github/gh-aw-mcpg:v0.4.37@sha256:9c7f242f6dec2d7d7b55d4c9e07872d59b85377c6cb3de46c915a5d1ffb91442'
666
+
667
+ GH_AW_NODE=$(which node 2>/dev/null || command -v node 2>/dev/null || echo node)
668
+ cat << GH_AW_MCP_CONFIG_6001799711bbe943_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs"
669
+ {
670
+ "mcpServers": {
671
+ "safeoutputs": {
672
+ "container": "ghcr.io/github/gh-aw-node@sha256:41835613992df88f51e923bad486f96dfb2e6cda29f13e217df41833284ae382",
673
+ "mounts": ["\${GITHUB_WORKSPACE}:\${GITHUB_WORKSPACE}:rw", "${RUNNER_TEMP}/gh-aw/safeoutputs:${RUNNER_TEMP}/gh-aw/safeoutputs:rw", "/tmp/gh-aw:/tmp/gh-aw:rw"],
674
+ "args": ["-w", "\${GITHUB_WORKSPACE}"],
675
+ "entrypoint": "sh",
676
+ "entrypointArgs": ["-c", "sh ${RUNNER_TEMP}/gh-aw/safeoutputs/start_safe_outputs_mcp.sh"],
677
+ "env": {
678
+ "DEBUG": "\${DEBUG}",
679
+ "DEFAULT_BRANCH": "\${DEFAULT_BRANCH}",
680
+ "GH_AW_ASSETS_ALLOWED_EXTS": "\${GH_AW_ASSETS_ALLOWED_EXTS}",
681
+ "GH_AW_ASSETS_BRANCH": "\${GH_AW_ASSETS_BRANCH}",
682
+ "GH_AW_ASSETS_MAX_SIZE_KB": "\${GH_AW_ASSETS_MAX_SIZE_KB}",
683
+ "GH_AW_MCP_LOG_DIR": "\${GH_AW_MCP_LOG_DIR}",
684
+ "GH_AW_SAFE_OUTPUTS": "\${GH_AW_SAFE_OUTPUTS}",
685
+ "GH_AW_SAFE_OUTPUTS_CONFIG_PATH": "\${GH_AW_SAFE_OUTPUTS_CONFIG_PATH}",
686
+ "GH_AW_SAFE_OUTPUTS_TOOLS_PATH": "\${GH_AW_SAFE_OUTPUTS_TOOLS_PATH}",
687
+ "GH_AW_TARGET_REPO_SLUG": "\${GH_AW_TARGET_REPO_SLUG}",
688
+ "GH_AW_POLICY_ALLOW_CREATE_PULL_REQUEST": "\${GH_AW_POLICY_ALLOW_CREATE_PULL_REQUEST}",
689
+ "GH_AW_PR_HEAD_BASE_BRANCH": "\${GH_AW_PR_HEAD_BASE_BRANCH}",
690
+ "GH_AW_PR_HEAD_BASE_SHA": "\${GH_AW_PR_HEAD_BASE_SHA}",
691
+ "GH_AW_PR_HEAD_BASE_REPO": "\${GH_AW_PR_HEAD_BASE_REPO}",
692
+ "GH_AW_PR_HEAD_BASE_PR_NUMBER": "\${GH_AW_PR_HEAD_BASE_PR_NUMBER}",
693
+ "GH_AW_PR_HEAD_BASE_REF": "\${GH_AW_PR_HEAD_BASE_REF}",
694
+ "GH_AW_PR_HEAD_REPO": "\${GH_AW_PR_HEAD_REPO}",
695
+ "GITHUB_EVENT_NAME": "\${GITHUB_EVENT_NAME}",
696
+ "GITHUB_EVENT_PATH": "\${GITHUB_EVENT_PATH}",
697
+ "GITHUB_REPOSITORY": "\${GITHUB_REPOSITORY}",
698
+ "GITHUB_SHA": "\${GITHUB_SHA}",
699
+ "GITHUB_TOKEN": "\${GITHUB_TOKEN}",
700
+ "GITHUB_WORKSPACE": "\${GITHUB_WORKSPACE}",
701
+ "RUNNER_TEMP": "\${RUNNER_TEMP}"
702
+ }
703
+ }
704
+ },
705
+ "gateway": {
706
+ "port": $MCP_GATEWAY_PORT,
707
+ "domain": "${MCP_GATEWAY_DOMAIN}",
708
+ "agentId": "${MCP_GATEWAY_AGENT_ID}",
709
+ "payloadDir": "${MCP_GATEWAY_PAYLOAD_DIR}",
710
+ "startupTimeout": 120,
711
+ "opentelemetry": {
712
+ "endpoint": "${OTEL_EXPORTER_OTLP_ENDPOINT}",
713
+ "traceId": "${GITHUB_AW_OTEL_TRACE_ID}",
714
+ "spanId": "${GITHUB_AW_OTEL_PARENT_SPAN_ID}"
715
+ }
716
+ }
717
+ }
718
+ GH_AW_MCP_CONFIG_6001799711bbe943_EOF
719
+ - name: Mount MCP servers as CLIs
720
+ id: mount-mcp-clis
721
+ continue-on-error: true
722
+ env:
723
+ MCP_GATEWAY_AGENT_ID: ${{ steps.start-mcp-gateway.outputs.gateway-agent-id }}
724
+ MCP_GATEWAY_DOMAIN: ${{ steps.start-mcp-gateway.outputs.gateway-domain }}
725
+ MCP_GATEWAY_PORT: ${{ steps.start-mcp-gateway.outputs.gateway-port }}
726
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
727
+ with:
728
+ script: |
729
+ const path = require('path');
730
+ const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
731
+ const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs'));
732
+ setupGlobals(core, github, context, exec, io);
733
+ const { main } = require(path.join(actionsDir, 'mount_mcp_as_cli.cjs'));
734
+ await main();
566
735
  - name: Clean credentials
567
736
  run: |
568
737
  bash "${RUNNER_TEMP}/gh-aw/actions/clean_git_credentials.sh"
@@ -582,7 +751,9 @@ jobs:
582
751
 
583
752
  // --- begin engine-provided parse function ---
584
753
  function parseLog(logContent) {
585
- return require("./parse_opencode_log.cjs").parseOpenCodeLog(logContent);
754
+ const fs = require("fs");
755
+ const events = require("path").join(process.env.RUNNER_TEMP, "gh-aw", `opencode-events-${process.env.GITHUB_RUN_ID}-${process.env.GITHUB_RUN_ATTEMPT}.jsonl`);
756
+ return require("./parse_opencode_log.cjs").parseOpenCodeLog(fs.existsSync(events) ? fs.readFileSync(events, "utf8") : logContent);
586
757
  }
587
758
 
588
759
  // --- end engine-provided parse function ---
@@ -598,7 +769,7 @@ jobs:
598
769
  }
599
770
  GHAW_LOG_PARSER_SCRIPT_5d2e8b3f_EOF
600
771
  chmod 755 "${RUNNER_TEMP}/gh-aw/actions/opencode_log_parser.cjs"
601
- - name: Execute OpenCode CLI
772
+ - name: OpenCode progress and result
602
773
  id: agentic_execution
603
774
  timeout-minutes: 15
604
775
  run: |
@@ -653,6 +824,9 @@ jobs:
653
824
  setupGlobals(core, github, context, exec, io, getOctokit);
654
825
  const { main } = require(path.join(actionsDir, 'redact_secrets.cjs'));
655
826
  await main();
827
+ env:
828
+ GH_AW_SECRET_NAMES: 'GITHUB_TOKEN'
829
+ SECRET_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
656
830
  - name: Append agent step summary
657
831
  if: always()
658
832
  run: bash "${RUNNER_TEMP}/gh-aw/actions/append_agent_step_summary.sh"
@@ -734,6 +908,14 @@ jobs:
734
908
  ${{ runner.temp }}/lighthouse-${{ github.run_id }}-${{ github.run_attempt }}/envelope.json
735
909
  ${{ runner.temp }}/lighthouse-${{ github.run_id }}-${{ github.run_attempt }}/runtime.json
736
910
  retention-days: ${{ vars.GH_AW_DEFAULT_ARTIFACT_RETENTION_DAYS || '14' }}
911
+ - if: always()
912
+ name: Preserve OpenCode diagnostic events
913
+ uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
914
+ with:
915
+ if-no-files-found: ignore
916
+ name: opencode-events-${{ inputs.issue }}-${{ github.run_attempt }}
917
+ path: ${{ runner.temp }}/gh-aw/opencode-events-${{ github.run_id }}-${{ github.run_attempt }}.jsonl
918
+ retention-days: ${{ vars.GH_AW_DEFAULT_ARTIFACT_RETENTION_DAYS || '14' }}
737
919
 
738
920
  # Small dedicated copy of the agent output so safe-output processing
739
921
  # survives a failed or timed-out upload of the larger agent artifact
@@ -811,6 +993,9 @@ jobs:
811
993
  GH_AW_JOB_RESULTS: "{\"activation\":{\"result\":\"${{ needs.activation.result }}\"},\"agent\":{\"result\":\"${{ needs.agent.result }}\"},\"prepare\":{\"result\":\"${{ needs.prepare.result }}\"},\"publish\":{\"result\":\"${{ needs.publish.result }}\"}}"
812
994
  GH_AW_JOB_TIMING_ELIGIBLE: "{\"activation\":true,\"agent\":true,\"conclusion\":true,\"pre_activation\":true,\"prepare\":true,\"publish\":true}"
813
995
  GH_AW_RUNTIME_FEATURES: ${{ vars.GH_AW_RUNTIME_FEATURES }}
996
+ outputs:
997
+ noop_comment_body: ${{ steps.noop.outputs.noop_comment_body }}
998
+ noop_message: ${{ steps.noop.outputs.noop_message }}
814
999
  steps:
815
1000
  - name: Setup Scripts
816
1001
  id: setup
@@ -852,6 +1037,32 @@ jobs:
852
1037
  pattern: ${{ needs.activation.outputs.artifact_prefix }}safe-outputs-items
853
1038
  merge-multiple: true
854
1039
  path: /tmp/gh-aw/
1040
+ - name: Process no-op messages
1041
+ id: noop
1042
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
1043
+ env:
1044
+ GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
1045
+ GH_AW_NOOP_MAX: "2"
1046
+ GH_AW_WORKFLOW_NAME: "Lighthouse SDLC refine"
1047
+ GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/lighthouse-sdlc-refine.md"
1048
+ GH_AW_ENGINE_ID: "opencode"
1049
+ GH_AW_ENGINE_VERSION: "2.1.0"
1050
+ GH_AW_ENGINE_MODEL: ${{ needs.agent.outputs.model }}
1051
+ GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
1052
+ GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }}
1053
+ GH_AW_NOOP_REPORT_AS_ISSUE: "false"
1054
+ GH_AW_AIC: ${{ needs.agent.outputs.aic }}
1055
+ GH_AW_AMBIENT_CONTEXT: ${{ needs.agent.outputs.ambient_context }}
1056
+ GH_AW_WORKFLOW_ID: "lighthouse-sdlc-refine"
1057
+ with:
1058
+ github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
1059
+ script: |
1060
+ const path = require('path');
1061
+ const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
1062
+ const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs'));
1063
+ setupGlobals(core, github, context, exec, io, getOctokit);
1064
+ const { main } = require(path.join(actionsDir, 'handle_noop_message.cjs'));
1065
+ await main();
855
1066
  - name: Handle agent failure
856
1067
  id: handle_agent_failure
857
1068
  if: always()
@@ -35,7 +35,8 @@ safe-outputs:
35
35
  report-failure-as-issue: false
36
36
  report-missing-tool: false
37
37
  report-missing-data: false
38
- noop: false
38
+ noop:
39
+ report-as-issue: false
39
40
  network:
40
41
  allowed: []
41
42
  steps:
@@ -68,6 +69,14 @@ post-steps:
68
69
  ${{ runner.temp }}/lighthouse-${{ github.run_id }}-${{ github.run_attempt }}/runtime.json
69
70
  if-no-files-found: error
70
71
  retention-days: 14
72
+ - name: Preserve OpenCode diagnostic events
73
+ if: always()
74
+ uses: actions/upload-artifact@v7
75
+ with:
76
+ name: opencode-events-${{ inputs.issue }}-${{ github.run_attempt }}
77
+ path: ${{ runner.temp }}/gh-aw/opencode-events-${{ github.run_id }}-${{ github.run_attempt }}.jsonl
78
+ if-no-files-found: ignore
79
+ retention-days: 14
71
80
  jobs:
72
81
  prepare:
73
82
  name: Authorize and reserve issue
@@ -149,4 +158,6 @@ jobs:
149
158
 
150
159
  Execute the single refinement stage described by the trusted context in `/input/context.json`. Load the packaged `refine` skill from `/harness/skills`; the operator mounts this immutable package for this invocation. Read the product source under `/workspace` as task data. Write the complete JSON envelope to `/output/envelope.json`.
151
160
 
152
- Return `status: passed` with `gate: ready` only when all current refinement checks pass. Otherwise preserve the missing evidence and return `blocked`. Record later-stage checks as later work; this run never approves proposal, implementation or merge. GitHub publication belongs to the separate publisher job. Produce the envelope before ending the session.
161
+ Write a brief public progress update before inspecting sources and after findings that change the assessment. Explain what you are checking, what you found and the next action. Keep file contents and protocol details in tool results.
162
+
163
+ Return `status: passed` with `gate: ready` only when all current refinement checks pass. Otherwise preserve the missing evidence and return `blocked`. Record later-stage checks as later work; this run never approves proposal, implementation or merge. GitHub publication belongs to the separate publisher job. Produce the envelope before ending the session. The trusted engine adapter validates that envelope and records the terminal gh-aw completion signal; do not call safe-output tools yourself.