Skip to content

fix(ci): governance-enforce gate can pass having scanned nothing - #35

Open
yakimoto wants to merge 1 commit into
mainfrom
fix/1747-enforce-diff-base-fail-open
Open

fix(ci): governance-enforce gate can pass having scanned nothing#35
yakimoto wants to merge 1 commit into
mainfrom
fix/1747-enforce-diff-base-fail-open

Conversation

@yakimoto

@yakimoto yakimoto commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Defect

.github/workflows/governance-enforce.yml resolved its diff base to HEAD~1, which scans only
ONE commit of a multi-commit push and reports every earlier commit as passing. On an initial push,
force-push, or shallow clone this degrades further: HEAD~1 fails to resolve and falls back to
BASE=HEAD, diffing HEAD against itself — an empty diff, zero lines scanned, job green. A gate
that passes without reading any line is worse than no gate.

Changes (targeted, .github/workflows/governance-enforce.yml only)

  1. Add a merge_group: trigger alongside pull_request: / push: — also clears a latent
    merge-queue deadlock (the gate previously never ran in the merge queue).
  2. Add MERGE_BASE_SHA: ${{ github.event.merge_group.base_sha }} to the env of the step that
    computes BASE.
  3. Replace the base resolution: BASE="${PR_BASE_SHA:-$PUSH_BEFORE_SHA}" becomes
    BASE="${PR_BASE_SHA:-${MERGE_BASE_SHA:-$PUSH_BEFORE_SHA}}", and the indeterminate-base
    fallback (previously git rev-parse HEAD~1 2>/dev/null || git rev-parse HEAD) now diffs against
    git's empty-tree object (git hash-object -t tree /dev/null) so the full tree is scanned —
    loud (::warning::) and never a silent empty/partial pass.

wave-av/wave-conferencing-bridge, wave-monitor, wave-desktop, and wave-multiviewer already
carry the correct form of this file; this brings the same fix to this repo.

Out of scope (tracked separately, claude-workstation#1747)

This repo's gate still has three OTHER open defects tracked in #1747 which are deliberately NOT
addressed here: fail-open token scope, unpinned install scripts, and a caret (^) version range
on the @wave-av/governance dependency.

Refs claude-workstation#1747.


Open in Devin Review

View with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is enabled.


Note

Cursor Bugbot is generating a summary for commit e7004e5. Configure here.

Review in cubic

Note

Fix governance-enforce gate to scan full tree when diff base is indeterminate

  • Adds merge_group as a workflow trigger in governance-enforce.yml and uses merge_group.base_sha as the diff base when present.
  • Fixes a bug where the gate could pass having scanned nothing: when the diff base is all-zero or indeterminate, the script now diffs the full tree against Git's empty-tree object instead of falling back to HEAD~1 or HEAD.
  • Emits a GitHub Actions warning when the full-tree fallback is triggered so the scan scope is visible in CI logs.

Macroscope summarized e7004e5.

…ead 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.
@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown

Warning

Review limit reached

You’ve reached a temporary PR review limit under our Fair Usage Limits Policy.

Your recent review volume is higher than typical usage, so adaptive limits are currently applied.

Next review available in: 53 minutes

Your organization has reached its usage spending cap. Adjust your spending cap in the billing tab.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 450f054f-14cd-48a9-87b2-41bd282d82c3

📥 Commits

Reviewing files that changed from the base of the PR and between de34314 and e7004e5.

📒 Files selected for processing (1)
  • .github/workflows/governance-enforce.yml

Comment @coderabbitai help to get the list of available commands.

@cursor

cursor Bot commented Aug 6, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_c20672c7-2700-4b68-954f-74ad0a4928b6)

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Fix governance-enforce diff base to never pass without scanning

🐞 Bug fix ⚙️ Configuration changes 🕐 10-20 Minutes

Grey Divider

AI Description

• Run governance-enforce in merge queue by adding the merge_group trigger.
• Fix diff-base resolution so multi-commit pushes are fully scanned.
• On indeterminate base, diff against empty-tree and emit a warning (never silent no-op).
Diagram

graph TD
  A["GitHub event"] --> B["governance-enforce workflow"] --> C["Resolve diff BASE"] --> D{Base known?}
  D -- "yes" --> E["Run enforce --changed BASE"]
  D -- "no" --> F["Set BASE=empty-tree + warn"] --> E
  E --> G["Gate result"]
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Compute base via git merge-base (after fetching)
  • ➕ More semantically correct base for complex histories (rebases, force-pushes)
  • ➕ Avoids full-tree scan in some indeterminate cases
  • ➖ Requires extra fetch depth/network and careful handling of shallow clones
  • ➖ More moving parts in a critical gate step
2. Add an explicit 'full scan' mode to the governance tool
  • ➕ Moves the edge-case logic into the enforcement tool (single source of truth)
  • ➕ Cleaner workflow scripting
  • ➖ Requires changes/release of @wave-av/governance and coordinated rollout
  • ➖ Still needs a workflow decision to select the mode

Recommendation: The PR’s approach (prefer explicit event-provided base SHAs, and fall back to empty-tree with a visible warning) is the best fit for a workflow-only, targeted fix: it eliminates silent no-op/partial scans without introducing extra network fetch complexity or requiring governance tool changes.

Files changed (1) +9 / -2

Bug fix (1) +9 / -2
governance-enforce.ymlFix diff base resolution and add merge_group trigger +9/-2

Fix diff base resolution and add merge_group trigger

• Adds merge_group to ensure the governance gate runs in merge queue contexts. Updates base-sha selection to prefer PR, then merge_group, then push before-sha; when the base is indeterminate, diffs against git’s empty-tree and emits a warning to prevent silent empty/partial scans.

.github/workflows/governance-enforce.yml

@cubic-dev-ai

cubic-dev-ai Bot commented Aug 6, 2026

Copy link
Copy Markdown

Running ultrareview automatically — This is a security-critical CI gate change: the base-SHA resolution and new merge_group trigger directly control whether the governance scan sees the full diff, so a subtle shell or event-payload bug could let the gate pass without scanning — exactly the failure this PR aims to fix.. I'll post findings when complete.

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 3 potential issues.

Open in Devin Review

Comment on lines +48 to +53
# 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"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Force-pushes and first pushes now fail the required check on pre-existing issues

When the starting point for the comparison cannot be determined, the check now compares against an empty starting point (git hash-object -t tree /dev/null at .github/workflows/governance-enforce.yml:52) instead of a recent commit, so every file in the repository is inspected and any long-standing issue fails the required gate.
Impact: A first push to a branch or a force-push can block merges because of old, unrelated issues that the gate was explicitly designed to tolerate.

Fallback base switches the gate from diff-scoped to whole-repository scope

The workflow header (.github/workflows/governance-enforce.yml:3-6) states the gate is "Diff-scoped: blocks NEW violations without failing on legacy debt", and the org ruleset requires this job's enforce check. Previously the indeterminate-base fallback used HEAD~1 (or HEAD), keeping the scan small. With the empty-tree base, --changed "$BASE" now yields every tracked file, so any legacy violation in capabilities.json, the profile YAMLs, or scripts/ will fail the job. This path triggers on push when github.event.before is all-zeros (new branch / first push) and after force-pushes.

A less disruptive option is to keep a loud warning but resolve a real commit base (e.g. git merge-base origin/main HEAD), or make the full-tree scan report-only / warn-only while still failing on genuinely undeterminable state.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

# 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)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔍 Enforcer may not accept a bare tree object as the diff base

--changed "$BASE" is passed to the external @wave-av/governance enforcer (.github/workflows/governance-enforce.yml:56), which is not vendored in this repo, so its handling of the base argument can't be verified here. Git's empty-tree id works with git diff <tree> HEAD, but not with commit-only forms commonly used by such scripts (git diff BASE...HEAD, git merge-base, git log BASE..HEAD, git rev-parse BASE^{commit}), which would abort with a fatal error. Worth confirming against enforce.mjs v0.4.4 that a tree-ish base is supported before relying on this fallback in a required gate.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.


on:
pull_request:
merge_group:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔍 merge_group only added to this workflow

This is the only workflow in .github/workflows/ with a merge_group trigger (the others — _checks.yml, foundation-gate.yml, public-repo-guard.yml — are PR/push only). If a merge queue is enabled and those checks are also required, they will never report on queue entries and could stall the queue. Confirm the queue's required-check set matches the workflows that actually trigger on merge_group.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

@macroscopeapp

macroscopeapp Bot commented Aug 6, 2026

Copy link
Copy Markdown

Approvability

Verdict: Approved e7004e5

Minor CI workflow fix that makes governance enforcement stricter by ensuring the gate cannot pass with partial/empty scans. Author owns this workflow file. No application runtime impact.

You can customize Macroscope's approvability policy. Learn more.

@qodo-code-review

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0)

Grey Divider

Great, no issues found!

Qodo reviewed your code and found no material issues that require review

Grey Divider

To customize comments, go to the Qodo configuration screen, or learn more in the docs.

Qodo Logo

@qodo-code-review

Copy link
Copy Markdown

Qodo Fixer

No findings are available for this PR yet. Findings appear here once Qodo has reviewed the PR.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ultrareview completed in 4m 10s

No issues found across 1 file

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Re-trigger cubic

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant