From 3de32482a9124eba69d7592108fc586248cdc2ff Mon Sep 17 00:00:00 2001 From: Brad Edwards Date: Tue, 22 Sep 2026 08:25:21 +0200 Subject: [PATCH] ci: install Ground Control Phase E finalization --- .github/workflows/ground-control-phase-e.yml | 67 ++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 .github/workflows/ground-control-phase-e.yml diff --git a/.github/workflows/ground-control-phase-e.yml b/.github/workflows/ground-control-phase-e.yml new file mode 100644 index 000000000..748c8e81b --- /dev/null +++ b/.github/workflows/ground-control-phase-e.yml @@ -0,0 +1,67 @@ +name: Ground Control Phase E +# Carries the pull request into the run record, so a dispatch run — which has no +# `pull_requests` association — is still bound to what it finalized (issue #1671). +run-name: Ground Control Phase E for PR ${{ github.event.pull_request.number || inputs.pr }} + +# A merged Ground Control delivery pull request finishes Phase E here, with no model or +# agent session. The agent records a trusted delivery-readiness handoff at Phase D and may +# then terminate permanently; this job is a trigger and a transport. +# +# It holds no `gh` logic, no marker parser, and no completion reconstruction. It passes the +# event's pull-request number to `grndctl finalize-merged-pr`, which resolves the issue from +# the trusted pointer and replays the recorded payload through the incumbent finalizer — so +# the merge gate, the immutable merged-revision requirement verification, the final-report +# marker, and the idempotent close all still apply, unchanged. +# +# It runs no tests, no policy suite, and no review, and it waits for no other post-merge job. +# +# Written by `grndctl init`. The pinned version below is the grndctl that wrote it; bump it +# deliberately rather than tracking a moving tag. + +on: + pull_request: + types: [closed] + branches: [main, dev] + workflow_dispatch: + inputs: + pr: + description: Pull request number to finalize (maintainer repair path) + required: true + type: string + +concurrency: + # Serialize per pull request so a replay cannot race itself. Never cancel: a cancelled + # finalization leaves neither a final report nor a failure record. + group: gc-phase-e-${{ github.event.pull_request.number || inputs.pr }} + cancel-in-progress: false + +permissions: + contents: read + pull-requests: read + # The close gate verifies this job's own run through the Actions API before it accepts an + # automation-authored final-report marker. + actions: read + # The final report and the issue close. This is the job's only write. + issues: write + +jobs: + finalize: + if: ${{ github.event_name == 'workflow_dispatch' || github.event.pull_request.merged == true }} + runs-on: ubuntu-latest + steps: + # The immutable merge revision, never the pull-request head. Phase E reads requirement + # state from the merged tree and executes none of the delivered code; `fetch-depth: 0` + # brings every branch, so the merge commit is present on the dispatch path too. + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + with: + ref: ${{ github.event.pull_request.merge_commit_sha || github.sha }} + fetch-depth: 0 + persist-credentials: false + - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 + with: + node-version: 22 + - name: Finalize the merged delivery + env: + GH_TOKEN: ${{ github.token }} + PR: ${{ github.event.pull_request.number || inputs.pr }} + run: npx --yes grndctl@1.2.1 finalize-merged-pr --pr "$PR"