Skip to content

ci: vendor governance-enforce — this repo was never in the A_BLOCK ruleset - #42

Open
yakimoto wants to merge 7 commits into
mainfrom
ci/vendor-governance-enforce
Open

ci: vendor governance-enforce — this repo was never in the A_BLOCK ruleset#42
yakimoto wants to merge 7 commits into
mainfrom
ci/vendor-governance-enforce

Conversation

@yakimoto

@yakimoto yakimoto commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Adds the governance-enforce A_BLOCK gate (secrets / hardcoded-paths, diff-scoped) to this repo. Part of claude-workstation#1624 E4 T4.9a, following the wave-av/cli#20 pilot.

Why this repo had no secrets scan

The org ruleset governance-a-block-enforce (17901847) requires an enforce check across the fleet. Its scope is an explicit include list of 112 hand-maintained repository names — and every one of them matches wave-*.

The 16 public repos absent from that list are exactly the 16 not named wave-*: .github, adk, api-spec, cli, companion-module-wave, create-wave-app, crest-console, dispatch-edge, examples, mcp-server, obs-wave-plugin, sdk, sdk-python, sdks, vmix-wave-integration, workflow-sdk.

Read the intersection: the repos that publish our npm packages are precisely the repos running with no A_BLOCK secrets scan. Nobody excluded them. A naming convention silently became a security boundary, and it drew the line in the worst possible place.

Why the workflow lands before the ruleset entry

Adding a repo to a required_status_checks ruleset before it emits that check is a permanent deadlock — a required check that never reports can never go green, and every PR on the repo becomes unmergeable. So the order is: vendor the workflow, observe it green, then extend the list. Doing it the intuitive way round would have bricked all sixteen.

This PR is also its own liveness drill. The workflow triggers on pull_request, so it runs on the PR that adds it. If enforce reports green here, the vendored shape works in this repo. If it does not, nothing was required and nothing is blocked — which is the point of this ordering.

Proven before fan-out, not assumed

@wave-av/governance is an internal-visibility package owned by claude-workstation, so whether a public repo's GITHUB_TOKEN can read it was the one real assumption. Rather than fan out on the inference, it was piloted on a single repo first:

wave-av/cli#20 — workflow run 31011943790, conclusion success.

That is the receipt this PR rides on. The shape is copied verbatim from wave-av/wave-moq-edge (public, 12/12 green), which matters because auto-approve.yml fails silently on every public repo — it calls a reusable workflow in the private wave-foundation, and a public repo cannot do that (parse-time failure, zero jobs, no annotation). This workflow calls nothing cross-repo, so that trap does not apply.

Security properties, unchanged from the source:

  • actions SHA-pinned (actions/checkout@df4cb1c, actions/setup-node@48b55a0)
  • persist-credentials: false on checkout
  • least privilege: contents: read + packages: read
  • isolated install into RUNNER_TEMP, --no-save, so nothing touches this repo's dependency tree
  • the .npmrc is written with a literal ${NODE_AUTH_TOKEN} (single-quoted printf) which npm expands at run time — no secret value is ever written to disk or a log
  • both ${{ }} inputs (base.sha, event.before) are routed through env: and read as "$VAR", never interpolated into the script body

Diff-scoped by design: it blocks new violations without failing on legacy debt.

Refs wave-av/claude-workstation#1624.


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


Note

Low Risk
CI-only addition with read-only permissions and isolated temp install; no application runtime or merge-blocking ruleset change until the workflow is verified green.

Overview
Adds .github/workflows/governance-enforce.yml, bringing this repo into the org A_BLOCK fan-out (secrets-in-git, Doppler expectations, hardcoded paths) via @wave-av/governance@0.4.6. The workflow runs on PRs and pushes to main/master, emits the enforce job check, and is meant to go green here before the repo is added to governance-a-block-enforce (required check with no reporter = deadlock).

The vendored shape is hardened: step-scoped GITHUB_TOKEN for npm, --ignore-scripts on install, exact package pin, push concurrency that does not cancel in-progress push runs (so commits aren’t left un-scanned), and fail-closed diff-base resolution (empty tree vs HEAD self-diff). Enforcement is diff-scoped so new violations block without failing on legacy debt.

Reviewed by Cursor Bugbot for commit 67d046c. Configure here.

Note

Add governance enforcement workflow to scan diffs on PRs and pushes to main

Adds governance-enforce.yml, which runs @wave-av/governance@0.4.6 on pull requests, merge groups, and pushes to main/master. The enforcer scans only changed files using a computed diff base; if no valid base is found, it falls back to the empty tree and scans the full repository. Push and merge group runs are not cancelable to ensure no committed ranges are skipped.

Macroscope summarized 6cf0c37.

@yakimoto yakimoto added the rr:skip-cubic RF.P1 reviewer routing (#1039) label Aug 5, 2026
@cursor

cursor Bot commented Aug 5, 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_b3d25476-41cf-41c6-8a71-ba1dd92af023)

@coderabbitai

coderabbitai Bot commented Aug 5, 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: 44 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 03a01b15-2cfd-458b-b88f-8a39df6ef7c0

📥 Commits

Reviewing files that changed from the base of the PR and between e8228c4 and 6cf0c37.

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

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

macroscopeapp[bot]
macroscopeapp Bot previously approved these changes Aug 5, 2026
@macroscopeapp

macroscopeapp Bot commented Aug 5, 2026

Copy link
Copy Markdown

Approvability

Verdict: Needs human review

Unable to check for correctness in 6cf0c37. New CI workflow adding a secrets/governance scanning gate with non-trivial edge-case handling logic. While the author owns this file, the security implications of correctly handling all push/PR scenarios (force-push, branch creation, unreachable commits) warrant human verification that the fallback behavior is correct.

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

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Add governance-enforce A_BLOCK diff-scoped secrets/path gate to CI

⚙️ Configuration changes ✨ Enhancement 🕐 10-20 Minutes

Grey Divider

AI Description

• Add a required enforce status check that scans PR diffs for new secrets and hardcoded paths.
• Fetch and run @wave-av/governance in an isolated install using least-privilege GitHub token
 access.
• Enable the gate on pull requests and on pushes to main/master with concurrency cancellation.
Diagram

graph TD
  A([PR / Push event]) --> B["GitHub Actions: governance-enforce"] --> C["Job: enforce"] --> D["Checkout (full history)"] --> E["Setup Node 22"] --> F["npm install @wave-av/governance"] --> G["Run enforce.mjs --changed BASE"] --> H(["Status check: enforce"]) 
  subgraph Legend
    direction LR
    _evt([Event]) ~~~ _wf["Workflow/Job"] ~~~ _chk([Status check])
  end
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Reusable workflow (centralized org workflow)
  • ➕ Single source of truth; easier to roll out changes across repos
  • ➕ Consistent permissions and pinning enforced centrally
  • ➖ Not viable if the reusable workflow lives in a private repo (public repos cannot consume it reliably)
  • ➖ Introduces cross-repo dependency that can fail at parse-time and silently skip jobs
2. Publish a dedicated GitHub Action for enforcement
  • ➕ Cleaner workflow YAML (one action step instead of npm install + node command)
  • ➕ Can encapsulate base-SHA selection logic and telemetry
  • ➖ Requires maintaining/versioning another distribution artifact
  • ➖ Still needs access to the enforcer logic; may not reduce trust surface if it wraps the same package
3. Rely on GitHub Advanced Security secret scanning only
  • ➕ Native integration and UI; no custom toolchain
  • ➕ Less CI time and fewer moving parts
  • ➖ May not cover org-specific hardcoded-path rules or Doppler-specific patterns
  • ➖ Harder to make strictly diff-scoped and aligned with existing A_BLOCK policy semantics

Recommendation: The vendored workflow + isolated install is the best fit given public-repo constraints around private reusable workflows and the need for a diff-scoped A_BLOCK gate. Keep this approach, but ensure the package access path (GitHub Packages read via GITHUB_TOKEN) remains stable and consider later extracting a public, SHA-pinned action wrapper once the rollout is complete to simplify future updates.

Files changed (1) +59 / -0

Other (1) +59 / -0
governance-enforce.ymlIntroduce A_BLOCK governance enforcement workflow and required check +59/-0

Introduce A_BLOCK governance enforcement workflow and required check

• Adds a new GitHub Actions workflow that runs on pull requests and pushes to main/master. The job installs '@wave-av/governance' from GitHub Packages in an isolated temp directory and executes diff-scoped enforcement against a computed base SHA, emitting the 'enforce' check expected by the org ruleset.

.github/workflows/governance-enforce.yml

devin-ai-integration[bot]

This comment was marked as resolved.

…push)

Co-authored-by: Codesmith <codesmith-bot@users.noreply.github.com>
@qodo-code-review

qodo-code-review Bot commented Aug 5, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (0) 📜 Skill insights (0)

Grey Divider


Remediation recommended

1. Unpinned enforcer dependency ✓ Resolved 🐞 Bug ⛨ Security
Description
The workflow installs @wave-av/governance using a caret range (^0.4.4) via a runtime `npm
install`, so the required gate’s behavior can change (or break) without any PR in this repo. Because
npm install runs package lifecycle scripts by default, the job is also executing third-party code
in the runner context with its granted permissions (contents: read, packages: read) and the
job’s GITHUB_TOKEN.
Code

.github/workflows/governance-enforce.yml[R45-48]

+        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
Evidence
The new workflow performs a runtime install of @wave-av/governance with a caret range, making the
executed code mutable over time. This repo’s existing public-repo-guard workflow explicitly calls
out determinism and uses checksum verification to avoid out-of-band reprogramming/tampering,
demonstrating an established expectation for security gates to be pinned and verifiable.

.github/workflows/governance-enforce.yml[44-48]
.github/workflows/public-repo-guard.yml[9-14]
.github/workflows/public-repo-guard.yml[47-60]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The workflow installs `@wave-av/governance@^0.4.4`, making the required gate non-reproducible and allowing upstream publishes to change the gate without a repo change. Additionally, `npm install` executes lifecycle scripts by default.

### Issue Context
This is a security gate and will be used as a required check; reducing drift and minimizing runtime code execution risk improves safety and stability.

### Fix Focus Areas
- .github/workflows/governance-enforce.yml[44-48]

### Suggested changes
- Pin an exact version (e.g. `@wave-av/governance@0.4.4`) and update it explicitly via PRs.
- Consider adding `--ignore-scripts` (or `npm config set ignore-scripts true`) if the package does not require lifecycle scripts to function.
- If stronger integrity is desired, add an integrity check mechanism (e.g., install from a pre-built, immutable artifact/digest) consistent with other security gates in this repo.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Informational

2. Floating Node patchline 🐞 Bug ☼ Reliability
Description
actions/setup-node is configured with node-version: "22", which floats to the latest Node 22.x.y
over time and can change the gate’s runtime without a PR. This is primarily a
reproducibility/change-control risk for a required check, not a guaranteed failure.
Code

.github/workflows/governance-enforce.yml[R41-43]

+      - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
+        with:
+          node-version: "22"
Evidence
The new workflow installs Node with a major-only selector, which allows patch-level drift. Elsewhere
in this repo’s security gates, tooling is pinned and even checksum-verified (gitleaks), showing a
preference for deterministic gate tooling.

.github/workflows/governance-enforce.yml[41-43]
.github/workflows/public-repo-guard.yml[51-60]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The workflow uses a floating major (`22`) for Node, so the exact runtime can drift over time.

### Issue Context
This check is intended to become a required gate; tighter pinning can make behavior more reproducible.

### Fix Focus Areas
- .github/workflows/governance-enforce.yml[41-43]

### Suggested changes
- Option A: pin to an exact patch version (e.g., `22.?.?`) and bump intentionally.
- Option B: use `node-version-file` (e.g., `.nvmrc` / `.node-version`) so runtime updates are explicit and shared across tooling.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Context used
✅ REVIEW.md
Review mode: ⚖️ Balanced: This adds a security-sensitive CI enforcement workflow that installs and executes a package, handles credentials and diff-base selection, and affects repository governance; one focused hunk is not enough to justify extended, nor is it low-risk enough for lite.

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

Qodo Logo

qodo-code-review[bot]

This comment was marked as resolved.

@qodo-code-review

Copy link
Copy Markdown

Qodo Fixer

No findings are within the configured fix scope. To change which findings are fixed, adjust the setting on your Qodo configuration page.

devin-ai-integration[bot]

This comment was marked as resolved.

macroscopeapp[bot]
macroscopeapp Bot previously approved these changes Aug 5, 2026
cubic-dev-ai[bot]

This comment was marked as resolved.

…EAD has no parent

Co-authored-by: Codesmith <codesmith-bot@users.noreply.github.com>
devin-ai-integration[bot]

This comment was marked as resolved.

…othing

Five defects, none of them cosmetic. Refs wave-av/claude-workstation#1747.

1. FAIL-OPEN DIFF BASE. `BASE=$(git rev-parse HEAD~1 2>/dev/null || git rev-parse HEAD)`
   — on a root commit `git rev-parse HEAD~1` prints its unresolved argument to stdout AND
   fails, so the `||` branch appends and BASE becomes a two-line string. `git diff` then
   exits 128, and the pinned enforcer turned that into zero files and a green check. Now:
   a reachability-checked base (a force-push can leave `github.event.before` pointing at a
   commit this checkout does not have), and with no resolvable base at all it diffs against
   the EMPTY TREE so the whole repo is scanned rather than nothing.

2. THE PINNED ENFORCER ITSELF FAILED OPEN. `^0.4.4` resolved to 0.4.4, whose file lister is
   `catch { return []; }` — any git error became zero files and rendered as
   `OK[enforce]: 0 changed file(s) scanned — 0 A_BLOCK violations`. A git error and a clean
   diff were byte-identical in the output. The fix had sat unreleased on claude-workstation
   main since 2026-07-29 because no `governance-v*` tag was ever pushed. Released now as
   0.4.6 and pinned exactly here.

3. TOKEN IN SCOPE FOR THE WRONG STEPS. `NODE_AUTH_TOKEN` was job-level, so it was also in
   the environment of the step that executes the downloaded package. Now step-scoped, and
   the .npmrc holding it is removed on exit.

4. INSTALL SCRIPTS RAN WITH THAT TOKEN. `npm install` runs preinstall/postinstall by
   default. Added `--ignore-scripts`.

5. CANCELLED PUSH RUNS WERE SCANNED BY NOBODY. `cancel-in-progress: true` applied to push
   runs, and each push run only diffs its own before..HEAD range — so a cancelled run's
   commits were never examined by anything. Now PR-only.

Also: `timeout-minutes: 10` and `set -euo pipefail`.

Receipt, against a scratch repo whose root commit carries a no-hardcoded-paths violation,
simulating a branch-creation push (`before` = all zeros):
  old logic -> malformed base -> caught error -> [] -> OK, 0 files scanned, PASS
  new logic -> "no diff base resolved ... scanning the whole tree" -> BLOCK, exit 1

Credit where it is due: several of these were found by the review bots on the sibling
vendoring PRs and are folded in here — the step-scoped token, the .npmrc cleanup, the exact
pin, `--ignore-scripts`, the force-push reachability check, `timeout-minutes`, and the
concurrency hole (5), which was crest-console#7's catch and which I had missed entirely.
@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_131e5d02-41c0-4caa-a7e5-5508dc37d3b4)

Comment on lines +78 to +80
if [ -z "$BASE" ] || [ "$BASE" = "0000000000000000000000000000000000000000" ] \
|| ! git cat-file -e "$BASE^{commit}" 2>/dev/null; then
BASE="$(git rev-parse --verify --quiet 'HEAD~1' || true)"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟠 High workflows/governance-enforce.yml:78

When a force-push makes github.event.before unreachable in the checkout, the fallback at line 80 narrows the scan to HEAD~1, so only the final commit's diff is examined. Any earlier commits introduced by that force-push are skipped entirely, and a secret or hardcoded path pushed in one of those earlier commits reaches main without this gate examining it. Instead of silently narrowing the diff to HEAD~1, the fallback should fail closed or compute a reachable merge-base.

          if [ -z "$BASE" ] || [ "$BASE" = "0000000000000000000000000000000000000000" ] \
             || ! git cat-file -e "$BASE^{commit}" 2>/dev/null; then
-            BASE="$(git rev-parse --verify --quiet 'HEAD~1' || true)"
+            BASE="$(git merge-base --octopus HEAD 2>/dev/null || true)"
          fi
🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file @.github/workflows/governance-enforce.yml around lines 78-80:

When a force-push makes `github.event.before` unreachable in the checkout, the fallback at line 80 narrows the scan to `HEAD~1`, so only the final commit's diff is examined. Any earlier commits introduced by that force-push are skipped entirely, and a secret or hardcoded path pushed in one of those earlier commits reaches `main` without this gate examining it. Instead of silently narrowing the diff to `HEAD~1`, the fallback should fail closed or compute a reachable merge-base.

Evidence trail:
.github/workflows/governance-enforce.yml:74-93 @ 67d046c0; `git blame REVIEWED_COMMIT -L 74,91 -- .github/workflows/governance-enforce.yml`

@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 1 new potential issue.

Open in Devin Review

Comment on lines +88 to +93
if [ -z "$BASE" ]; then
BASE="$(git hash-object -t tree /dev/null)"
echo "::notice::no diff base resolved (root commit or unreachable before-sha) — scanning the whole tree against the empty tree"
fi
echo "diffing against $BASE"
exec node "$ENFORCE" --changed "$BASE"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔍 Empty-tree fallback depends on the enforcer accepting a tree-ish base

The fail-closed path substitutes the empty tree object (git hash-object -t tree /dev/null) as the --changed argument. This only produces a whole-tree scan if @wave-av/governance@0.4.6's enforcer runs a two-dot diff (git diff <base> HEAD) or git diff --name-only <base>. If it uses three-dot (<base>...HEAD) or resolves the argument via rev-parse <base>^{commit}, the empty tree hash is not a commit and the command will error — which, given 0.4.6 is described as failing closed on git errors, would turn every unresolvable-base run (root commit, unreachable force-push before-sha) into a hard red job rather than a full scan. Worth confirming against the package's bin/enforce.mjs behavior once observed in a real run.

Open in Devin Review

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

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Verified against the 0.4.6 source: changedArgs uses the two-argument git diff <base> HEAD form, which accepts trees by explicit design (its doc comment cites this exact empty-tree CI fallback), and running the enforcer with the empty-tree base against this repo scans all tracked files and exits 0. Both enforce.mjs and the spawned enforce-ramp.mjs share that code path, and neither resolves the base via ^{commit} or three-dot merge-base.

yakimoto and others added 2 commits August 6, 2026 00:24
… the scan to HEAD~1

Co-authored-by: Codesmith <codesmith-bot@users.noreply.github.com>
Co-authored-by: Codesmith <codesmith-bot@users.noreply.github.com>
devin-ai-integration[bot]

This comment was marked as resolved.

…l a false pass

Correction to the previous commit on this branch. Refs wave-av/claude-workstation#1747.

That commit replaced the fail-open `BASE=HEAD` with a fallback to `HEAD~1`. `HEAD~1` is
also wrong: it scans exactly ONE commit, so a five-commit push whose base is indeterminate
(branch creation, force-push, unreachable `github.event.before`) examines the last commit
and reports a confident pass on the other four. A narrowed scan reported as a full pass is
the same defect in a quieter costume.

Receipt — scratch repo, five-commit push, violation planted in commit 1:
  HEAD~1 base      -> OK[enforce]: 1 changed file(s) scanned  -> PASS   (never saw it)
  empty-tree base  -> 5 changed file(s) scanned -> BLOCK[enforce]: no-hardcoded-paths, exit 1

Now: with no resolvable base of any kind, diff against git's empty-tree object so every
tracked file reads as added and the whole repo is scanned. Loud, never partial, never empty.

Credit: wave-av/wave-rig's copy on main already had this right, with the reasoning in a
comment ("HEAD~1 would skip earlier commits in a multi-commit push and let a violation
through"). The fan-out copied the broken shape from elsewhere and I did not check the one
repo that had already solved it.

Also from wave-rig: `merge_group` is now a declared trigger and `github.event.merge_group.
base_sha` joins the base chain. None of these repos runs a merge queue today, so the trigger
is inert — but a required check that never reports on an event the repo actually uses is a
permanent deadlock, and this closes that in advance rather than after someone hits it.

@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 1 new potential issue.

Open in Devin Review

Comment on lines +96 to +105
# So: no resolvable base of any kind → diff against the EMPTY TREE, which makes every
# tracked file read as added and scans the whole repo. Loud, never partial, never empty.
# (`--all` also exists in 0.4.6 and would do most of this, but it is documented as NOT
# covering the diff-scoped over-grant detectors. Routing through the diff path with an
# empty base keeps every detector in play.)
if [ -z "$BASE" ] || [ "$BASE" = "0000000000000000000000000000000000000000" ] \
|| ! git cat-file -e "$BASE^{commit}" 2>/dev/null; then
BASE="$(git hash-object -t tree /dev/null)"
echo "::warning::indeterminate diff base (root commit, branch creation, or unreachable before-sha) — scanning the full tree against the empty-tree object so no commit is skipped"
fi

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔍 Empty-tree fallback turns the diff-scoped gate into a full-repo scan that will trip on legacy debt

The header states the gate is diff-scoped precisely so it "blocks NEW violations without failing on legacy debt" (lines 4-5). The new fallback makes every tracked file read as added, so any pre-existing hardcoded path or secret-shaped string anywhere in the repo will fail the job. On pull_request this cannot happen (base.sha is always present and fetched), but on a force-pushed branch's push to main, or a root commit, the job would fail for reasons unrelated to the pushed change. That is the intended "loud" behavior, but on push to main it produces a red default-branch build that no one can fix without whitelisting legacy debt — consider whether the fallback should warn-and-scan-full instead of blocking on non-PR events.

Open in Devin Review

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

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

Labels

rr:skip-cubic RF.P1 reviewer routing (#1039)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant