From 56a42f378e1d111237ad7a68118eeb14b2ae8186 Mon Sep 17 00:00:00 2001 From: stxkxs <139715017+stxkxs@users.noreply.github.com> Date: Fri, 7 Aug 2026 22:28:48 -0700 Subject: [PATCH 1/2] fix: the merge gate could not block a merge MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `merge-gate` had the right shape — `needs:` on the other jobs — and a condition that made it inert: `if: github.event_name == 'pull_request'` rather than `if: always()`. A job whose dependency fails is skipped, and GitHub counts a skipped check as passing for branch protection, so the gate reported success in exactly the case it exists to catch. It was harmless only because this repository has no branch protection at all and nothing requires the check. Requiring it, which is the point of adding it, would have installed a gate that cannot block. Two more problems in the same job: Its `needs:` list named nine of the eleven other jobs. `build` was covered only transitively, through the four jobs that depend on it. `docs` was not covered at all — it could fail with the gate still green. Its body was fifteen `echo "✅ ..."` lines. Six of them — approval-gate invariant, Slack adapter discipline, HTTP-client discipline, secret inventory agreement, chart secret paths, vendored byte-identity — correspond to nothing in the dependency list, so the job asserted properties it had no way to observe. It verified nothing directly and printed a checklist that read as though it had. Now it depends on all eleven jobs, runs with `if: always()`, and delegates to the shared gate in nanohype/.github, which treats anything other than `success` as a failure, refuses an empty `needs:`, and reads this workflow back to confirm no job in it is unwatched. That last check is what would have caught the missing `docs` dependency on its own. --- .github/workflows/ci.yml | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7856bbd..548194a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -490,6 +490,8 @@ jobs: needs: [ lint, + build, + docs, test-unit, test-integration, security-audit, @@ -499,22 +501,11 @@ jobs: helm-lint, docker-build, ] - if: github.event_name == 'pull_request' + # Load-bearing. Without it a failed dependency SKIPS this job, and GitHub + # counts a skipped check as passing for branch protection — the gate would + # report green exactly when something broke. + if: always() steps: - - name: All gates passed - run: | - echo "✅ Lint" - echo "✅ Unit Tests (100% branch on audit.ts + statuspage-approval-gate.ts)" - echo "✅ Integration Tests (ConsistentRead semantics verified against dynamodb-local)" - echo "✅ Dependency Security Audit (no HIGH/CRITICAL) + typecheck (src + tests)" - echo "✅ Platform CRs valid against the digest-verified eks-agent-platform CRD schemas" - echo "✅ Platform CR gate self-test — every seeded defect rejected" - echo "✅ Vendored CRD schemas match their pin, and the pin is current with upstream" - echo "✅ Helm Lint + Template" - echo "✅ Docker Build" - echo "✅ Approval-gate invariant verified" - echo "✅ Slack adapter discipline verified" - echo "✅ HTTP-client discipline verified" - echo "✅ Secret inventory lists agree" - echo "✅ Every secret path the chart reads is one the seeder creates" - echo "✅ Vendored copies byte-identical to nanohype (chart + runtime + config)" + - uses: nanohype/.github/actions/merge-gate@90a3158c1ef7532a7ab1b1267adc210e145c70d5 # main + with: + needs: ${{ toJSON(needs) }} From 02536a0cdbc4cbbbfa4102e91abfcf2b32745f89 Mon Sep 17 00:00:00 2001 From: stxkxs <139715017+stxkxs@users.noreply.github.com> Date: Fri, 7 Aug 2026 22:36:47 -0700 Subject: [PATCH 2/2] fix: repin the gate past the manifest load failure --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 548194a..0f3413c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -506,6 +506,6 @@ jobs: # report green exactly when something broke. if: always() steps: - - uses: nanohype/.github/actions/merge-gate@90a3158c1ef7532a7ab1b1267adc210e145c70d5 # main + - uses: nanohype/.github/actions/merge-gate@6ec6c5b3e6c4a8b15e12da4afd7ac4870a630092 # main with: needs: ${{ toJSON(needs) }}