From b1958cfda3439f90a048d3c85cd097e70b3a57de Mon Sep 17 00:00:00 2001 From: Jake Fineman Date: Thu, 6 Aug 2026 10:48:40 -0400 Subject: [PATCH 1/3] fix(ci): enforce gate scanned a partial range and could pass having read nothing BASE=HEAD~1 scans one commit of a multi-commit push and reports the rest as passing; when HEAD~1 does not resolve it degrades to BASE=HEAD, an empty diff and a green job. Resolve to the empty-tree object so the full tree is scanned, and add merge_group so the gate runs in the merge queue. Refs #1747. --- .github/workflows/governance-enforce.yml | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/.github/workflows/governance-enforce.yml b/.github/workflows/governance-enforce.yml index e68aef6..b8c2d70 100644 --- a/.github/workflows/governance-enforce.yml +++ b/.github/workflows/governance-enforce.yml @@ -7,6 +7,7 @@ name: governance-enforce on: pull_request: + merge_group: push: branches: [main, master] @@ -39,11 +40,17 @@ jobs: - name: A_BLOCK enforce (secrets + hardcoded paths on the diff) env: PR_BASE_SHA: ${{ github.event.pull_request.base.sha }} + MERGE_BASE_SHA: ${{ github.event.merge_group.base_sha }} PUSH_BEFORE_SHA: ${{ github.event.before }} run: | - BASE="${PR_BASE_SHA:-$PUSH_BEFORE_SHA}" + BASE="${PR_BASE_SHA:-${MERGE_BASE_SHA:-$PUSH_BEFORE_SHA}}" if [ -z "$BASE" ] || [ "$BASE" = "0000000000000000000000000000000000000000" ]; then - BASE=$(git rev-parse HEAD~1 2>/dev/null || git rev-parse HEAD) + # Indeterminate base (first push / force-push). Do NOT silently scan a partial range — + # HEAD~1 would skip earlier commits in a multi-commit push and let a violation through + # (a config-no-silent-noop hole). Diff the full tree against git's empty-tree object so + # every introduced file is scanned; loud, never a silent empty/partial pass. + BASE=$(git hash-object -t tree /dev/null) + echo "::warning::indeterminate diff base; scanning full tree (empty-tree base) so no commit is skipped" fi echo "diffing against $BASE" node "$RUNNER_TEMP/gov/node_modules/@wave-av/governance/bin/enforce.mjs" --changed "$BASE" From aac2627f6d7dc7513a64cf9ff90550d01ddc7bee Mon Sep 17 00:00:00 2001 From: yakimoto Date: Thu, 6 Aug 2026 14:53:27 +0000 Subject: [PATCH 2/3] fix(ci): floor governance enforcer at 0.4.6 so the empty-tree base cannot silently pass Co-authored-by: Codesmith --- .github/workflows/governance-enforce.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/governance-enforce.yml b/.github/workflows/governance-enforce.yml index b8c2d70..31b7275 100644 --- a/.github/workflows/governance-enforce.yml +++ b/.github/workflows/governance-enforce.yml @@ -36,7 +36,11 @@ jobs: run: | mkdir -p "$RUNNER_TEMP/gov" && cd "$RUNNER_TEMP/gov" printf '@wave-av:registry=https://npm.pkg.github.com\n//npm.pkg.github.com/:_authToken=${NODE_AUTH_TOKEN}\n' > .npmrc - npm install @wave-av/governance@^0.4.4 --no-save --no-audit --no-fund + # Floor is 0.4.6, not 0.4.4: the published 0.4.4/0.4.5 diff lister fails OPEN (any git + # error, including a tree-object base, yields "0 changed file(s) scanned" and exit 0). + # 0.4.6 diffs two-dot (`git diff HEAD`, which accepts the empty-tree object the + # indeterminate-base fallback supplies) and fails closed on any git listing error. + npm install @wave-av/governance@^0.4.6 --no-save --no-audit --no-fund - name: A_BLOCK enforce (secrets + hardcoded paths on the diff) env: PR_BASE_SHA: ${{ github.event.pull_request.base.sha }} From defc1a555b38737a0d9658e31dd19b49f5753d84 Mon Sep 17 00:00:00 2001 From: yakimoto Date: Thu, 6 Aug 2026 14:57:03 +0000 Subject: [PATCH 3/3] fix(ci): guard the diff base for resolvability so a force-push falls back loud, not raw-git-error Co-authored-by: Codesmith --- .github/workflows/governance-enforce.yml | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/.github/workflows/governance-enforce.yml b/.github/workflows/governance-enforce.yml index 31b7275..bb54162 100644 --- a/.github/workflows/governance-enforce.yml +++ b/.github/workflows/governance-enforce.yml @@ -48,11 +48,15 @@ jobs: PUSH_BEFORE_SHA: ${{ github.event.before }} run: | BASE="${PR_BASE_SHA:-${MERGE_BASE_SHA:-$PUSH_BEFORE_SHA}}" - if [ -z "$BASE" ] || [ "$BASE" = "0000000000000000000000000000000000000000" ]; then - # Indeterminate base (first push / force-push). Do NOT silently scan a partial range — - # HEAD~1 would skip earlier commits in a multi-commit push and let a violation through - # (a config-no-silent-noop hole). Diff the full tree against git's empty-tree object so - # every introduced file is scanned; loud, never a silent empty/partial pass. + if [ -z "$BASE" ] || [ "$BASE" = "0000000000000000000000000000000000000000" ] \ + || ! git cat-file -e "$BASE^{commit}" 2>/dev/null; then + # Indeterminate base: first push (before-SHA is all zeros) or force-push (before-SHA is + # the orphaned old tip, which the clone cannot resolve — hence the cat-file guard; the + # fail-closed enforcer would otherwise hard-fail on a raw git error). Do NOT silently + # scan a partial range — HEAD~1 would skip earlier commits in a multi-commit push and + # let a violation through (a config-no-silent-noop hole). Diff the full tree against + # git's empty-tree object so every introduced file is scanned; loud, never a silent + # empty/partial pass. BASE=$(git hash-object -t tree /dev/null) echo "::warning::indeterminate diff base; scanning full tree (empty-tree base) so no commit is skipped" fi