Skip to content

ci: scan issue and comment bodies — this repo has never scanned one - #45

Open
yakimoto wants to merge 6 commits into
mainfrom
ci/1747-public-repo-guard-body-scan
Open

ci: scan issue and comment bodies — this repo has never scanned one#45
yakimoto wants to merge 6 commits into
mainfrom
ci/1747-public-repo-guard-body-scan

Conversation

@yakimoto

@yakimoto yakimoto commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

This repo's public-repo-guard has never scanned a single issue or comment body.

Measured across all 28 public wave-av repos (wave-av/claude-workstation#1747, #1794): two coverage shapes satisfy the one required check name Secrets + content policy.

repos triggers jobs
27 pull_request, push, workflow_dispatch guard
1 + issues, issue_comment + body-guard

This repo is in the 27. All 28 report the same green check — because a required check asserts that something named X passed, never what X examined.

The outlier is wave-moq-edge, and its own comment says why it matters:

edited matters as much as opened: a body can be made to leak long after the PR is first raised, and until this workflow covered it, nothing ever re-scanned.

That gap was not theoretical there: a PR was blocked for naming a private repo in wrangler.toml while the very same name, with more operational detail attached, sat unchallenged in its body.

What lands

Three files — the bundle the workflow's own header names, minus what this repo already has (.gitleaks.toml and content-policy.sh are already vendored, and are checked as prerequisites; a repo missing either is refused rather than half-installed):

.github/workflows/public-repo-guard.yml               replaced (72 -> 163 lines)
scripts/public-repo-guard/body-policy.sh              new, mode 100755
scripts/public-repo-guard/tests/body-policy.test.sh   new, mode 100755

The reference workflow's header named four files as the install unit but executes a fifthtests/body-policy.test.sh, in its own self-test step. Omitting it installs a workflow that fails on a step nobody read, so the manifest ships it, and (after review flagged the same trap) the shipped header now lists all five. Modes are preserved via the git trees API; the contents API creates 100644 regardless, which would silently break running these scripts as executables.

Planned by governance/lib/vendor-bundle.mjs (claude-workstation#1850) against a checked-in manifest, not by ad-hoc shell.

One deliberate divergence from the reference, stated rather than silent

The shipped workflow is wave-moq-edge's with actions/checkout bumped from v5.0.1 to v7.0.1 (3d3c42e5aac5ba805825da76410c181273ba90b1), the pin already used by claude-workstation's own gate.

Copying verbatim was checked first and rejected on evidence: of the 18 target repos, 17 carry a byte-identical guard, and wave-realtime-edge already runs v7.0.0 — so a verbatim copy would have downgraded it, and shipped a stale pin to the other 17. A separate PR brings the reference itself up to the same pin.

More divergences, from review findings on this PR

Review (Qodo, Devin) caught real defects in the reference shape, fixed here:

  1. A required check that goes stale on body edits. The reference guard job skips PR edited events entirely, while only the non-required Body content policy check re-runs. If branch protection requires only Secrets + content policy, a post-approval body edit can introduce a leak behind that check's stale green result. Now guard runs on every PR action including edited, the PR title/body scan runs inside guard, and body-guard narrows to issues and comments, the detection-only surface.

  2. A partial run must not overwrite a full verdict. The first fix skipped the tree-scan steps on edited, and review caught the consequence: GitHub evaluates a required check from the LATEST check run of that name on the commit, so a green body-only run would have overwritten a red tree verdict, letting a body edit launder a failing secret scan. Every guard run is therefore FULL scope, which is also what makes cancel-in-progress safe:

# On pull_request it runs on EVERY action, `edited` included, and always runs
# the FULL scan. ... a partial (body-only) run would overwrite a red tree
# verdict with a green one, letting a body edit launder a failing secret scan.
  1. An allowlist filter that could fail open. The || true on body-policy.sh's allowlist pipeline masked real ripgrep errors (exit >= 2) along with the expected no-survivors exit 1, so a broken filter stage could empty the match set and report a pass. Each filter stage now checks its exit code explicitly and exits 2 (fail closed) on a real error.

  2. Regex precision holes in body-policy.sh. A global (?i) made lowercase identifiers like api_key count as credential names (blocking legitimate cross-repo PRs); the credential-name class could not span underscores, missing EXAMPLE_LEASE_ROTATION_SECRET-shaped names in repo-first order; the internal-marker rule missed sentence-initial capitals ("Do not share..."); and the about-the-control allowlist applied beyond its one safe rule; it is now internal-marker-only, because a credential, IP, path, or wiring topology quoted on a line that discusses the gate is re-published all the same. All fixed, each with a regression fixture.

  3. The fixtures themselves leaked. The test file pinned three real private repo names (and plausibly real credential names) into a public file inside scripts/public-repo-guard/, the one directory both scanners deliberately exclude. The fixtures now use obviously fictional names, with a comment explaining why they must stay that way.

Honest about what this can and cannot do

On a PR this PREVENTS the merge, and it does so under the one check name branch protection requires. On an issue or comment the text is already public the moment it posts, so this is DETECTION: it says go redact, fast. Only a client-side pre-write hook stops that class before publication.

Also inherited from the reference: concurrency moves from workflow-level to per job, because the two jobs want opposite behaviour. A workflow-level group forced one policy on both, and rapid body edits cancelled the tree job repeatedly — every cancelled check-run stays attached to the commit, so the PR reported UNSTABLE while the live runs were green.

The body gate ships with its own fixtures and runs them in CI. Its negative cases are the load-bearing half: a leak gate that blocks legitimate cross-repo references gets switched off, and then it protects nothing.

Refs wave-av/claude-workstation#1747.


Note

Cursor Bugbot is generating a summary for commit 8f29c21. Configure here.


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

Review in cubic

Note

Scan PR titles, bodies, issue bodies, and comment bodies in public-repo-guard CI

  • Adds body-policy.sh, a ripgrep-based script that checks untrusted text for credential patterns (Stripe keys, GitHub PATs, AWS access key IDs, PEM headers, etc.), internal markers, and private-repo references; BLOCK violations fail the job, WARN violations emit annotations only.
  • Extends public-repo-guard.yml to trigger on PR edits, issue opens/edits, and comment creates/edits; the existing guard job now also scans PR title and body, and a new body-guard job handles issue and comment bodies.
  • Adds body-policy.test.sh with fixture-based tests covering must-BLOCK, must-PASS, and fail-closed cases; the self-test runs inside the guard job on every invocation.
  • Matched content is redacted in annotations to avoid echoing secrets in CI logs.
  • Behavioral Change: PRs, issues, and comments that contain blocked patterns will now cause the guard or body-guard job to fail; previously these bodies were never scanned.

Macroscope summarized 52a7be5.

…ment body

Measured across all 28 public wave-av repos (claude-workstation#1747, #1794):
TWO coverage shapes satisfy the one required check name `Secrets + content policy`.

  27 repos  triggers: pull_request, push, workflow_dispatch      jobs: guard
   1 repo   triggers: + issues, issue_comment                    jobs: + body-guard

This repo is in the 27. All 28 report the same green check.

The outlier is wave-moq-edge, and its own comment says why it matters:

  "`edited` matters as much as `opened`: a body can be made to leak long after the
   PR is first raised, and until this workflow covered it, nothing ever re-scanned."

A PR/issue/comment BODY is exactly as world-readable as the tree, and until now it
was scanned by nothing server-side. That gap was not theoretical on wave-moq-edge: a
PR was blocked for naming a private repo in wrangler.toml while the very same name,
with more operational detail attached, sat unchallenged in its body.

WHAT LANDS HERE — the bundle the workflow's own header names, minus what this repo
already has (.gitleaks.toml and content-policy.sh are already vendored):

  .github/workflows/public-repo-guard.yml          replaced (73 -> 163 lines)
  scripts/public-repo-guard/body-policy.sh         new, mode 100755
  scripts/public-repo-guard/tests/body-policy.test.sh  new, mode 100755

Copied from wave-moq-edge, which has run this shape in production. Modes preserved
via the git trees API — the contents API would have created both scripts 100644.

HONEST ABOUT WHAT IT CAN DO. On a PR this PREVENTS the merge. On an issue or comment
the text is already public the moment it posts, so this is DETECTION: it says go
redact, fast. Only a client-side pre-write hook stops that class before publication.

Also inherited from the reference: concurrency moves from workflow-level to PER JOB,
because the two jobs want opposite behaviour. A workflow-level group forced one
policy on both, and rapid body edits cancelled the tree job repeatedly — every
cancelled check-run stays attached to the commit, so the PR reported UNSTABLE while
the live runs were green.

The body gate ships with its own fixtures and runs them in CI. Its NEGATIVE cases are
the load-bearing half: a leak gate that blocks legitimate cross-repo references gets
switched off, and then it protects nothing.

Refs wave-av/claude-workstation#1747.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@yakimoto yakimoto added the rr:skip-coderabbit RF.P1 reviewer routing (#1039) label Aug 6, 2026
@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_08e118ad-7abe-434d-8eb3-ea7fccf5399d)

@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: 57 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: d49e9bd2-e7c7-4934-930b-340ce427b520

📥 Commits

Reviewing files that changed from the base of the PR and between b1008d5 and 52a7be5.

📒 Files selected for processing (3)
  • .github/workflows/public-repo-guard.yml
  • scripts/public-repo-guard/body-policy.sh
  • scripts/public-repo-guard/tests/body-policy.test.sh

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

@cubic-dev-ai

cubic-dev-ai Bot commented Aug 6, 2026

Copy link
Copy Markdown

Running ultrareview automatically — This CI security gate now scans untrusted PR/issue/comment bodies and reworks concurrency; a subtle false-positive, fail-open, or injection bug could block every merge or let real secrets go public, so it warrants a deeper review.. I'll post findings when complete.

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

macroscopeapp Bot commented Aug 6, 2026

Copy link
Copy Markdown

Approvability

Verdict: Needs human review

Unable to check for correctness in 52a7be5. This PR introduces new security scanning capability for issue/comment bodies with significant CI workflow changes. Unresolved review comments identify potential bugs (comment events re-scanning PR bodies and failing main branch) and security gaps (fork PR neutralization, incomplete review-comment coverage) that warrant human attention.

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

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

CI: scan PR/issue/comment bodies in public-repo-guard (add body-guard job)

✨ Enhancement 🧪 Tests ⚙️ Configuration changes 🕐 40+ Minutes

Grey Divider

AI Description

• Add issue/comment/edited PR triggers and a dedicated body-guard job for text scanning.
• Introduce body-policy.sh to detect credential/infra leaks while avoiding noisy false positives.
• Add fixture-based self-tests and update checkout pin + per-job concurrency to prevent unstable
 runs.
Diagram

graph TD
  E["GitHub events"] --> W["public-repo-guard.yml"] --> G["guard job"] --> TS["Tree scan (gitleaks + content-policy.sh)"]
  G --> FT["Body-policy fixtures test"]
  W --> BG["body-guard job"] --> M["Materialize body.txt"] --> BP["body-policy.sh"]

  subgraph Legend
    direction LR
    _evt["Event source"] ~~~ _cfg["Workflow config"] ~~~ _job["Job"]
  end
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Use GitHub API to fetch bodies instead of event payload
  • ➕ Can unify handling of edge-case event schemas and edited content history
  • ➕ Can fetch additional context (e.g., issue timeline, full comment thread) if desired
  • ➖ Requires extra permissions and API calls (rate limits, auth complexity)
  • ➖ More moving parts than reading $GITHUB_EVENT_PATH; higher failure surface
2. Run gitleaks (or a single scanner) over body text too
  • ➕ Fewer bespoke regex rules to maintain
  • ➕ Potentially consistent detection semantics across tree + body
  • ➖ gitleaks rules are optimized for code/config, not prose; higher false positives in issues/comments
  • ➖ Harder to implement safe redaction/annotation behavior (no echoing matches) and precision allowlists
3. Rely on GitHub Advanced Security secret scanning / push protection
  • ➕ Vendor-maintained detection; minimal in-repo maintenance
  • ➕ Often catches common credential formats quickly
  • ➖ May not be enabled/available for all repos/org settings
  • ➖ Doesn’t cover org-specific “operational topology” rules (private repo + binding detail) as implemented here

Recommendation: Keep the PR’s approach: reading from $GITHUB_EVENT_PATH is the safest/lowest-permission way to obtain untrusted bodies, and the dedicated body-policy rules (with explicit allowlisting + fixture tests + redacted annotations) are well-suited to prose. Consider the GitHub API approach only if event-shape drift becomes frequent or you later need comment-thread context.

Files changed (3) +342 / -5

Enhancement (1) +139 / -0
body-policy.shIntroduce body-policy scanner for PR/issue/comment text +139/-0

Introduce body-policy scanner for PR/issue/comment text

• Adds a ripgrep-based policy scanner that reads untrusted body text from a file and flags credential formats, internal markers, and sensitive operational detail near private repo names (configured via GUARD_PRIVATE_REPOS). Implements explicit allowlisting (guard:allow and “about the control” patterns), redacts matched content in logs, and fails closed on scanner errors or invalid inputs.

scripts/public-repo-guard/body-policy.sh

Tests (1) +108 / -0
body-policy.test.shAdd fixture tests for body-policy precision and redaction safety +108/-0

Add fixture tests for body-policy precision and redaction safety

• Adds hermetic fixture tests covering both blocking violations and “must pass” cases (e.g., bare cross-repo references) to prevent the policy from becoming too noisy. Verifies that annotations never echo matched secret text and that invalid inputs fail closed with exit code 2.

scripts/public-repo-guard/tests/body-policy.test.sh

Other (1) +95 / -5
public-repo-guard.ymlAdd body scanning triggers and new body-guard job with per-job concurrency +95/-5

Add body scanning triggers and new body-guard job with per-job concurrency

• Extends workflow triggers to include issues and issue_comment events plus PR edited/reopened/synchronize. Splits behavior into two jobs: the existing tree-focused guard job (skipping edited/issues/comments) and a new body-guard job that materializes event text and runs body-policy.sh with sparse checkout. Updates actions/checkout pin to v7.0.1 and moves concurrency controls to the job level to avoid unstable canceled runs.

.github/workflows/public-repo-guard.yml

@qodo-code-review

qodo-code-review Bot commented Aug 6, 2026

Copy link
Copy Markdown

Code Review by Qodo

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

Grey Divider


Remediation recommended

1. Stale required check on edits ✓ Resolved 🐞 Bug ≡ Correctness
Description
In .github/workflows/public-repo-guard.yml, the guard job ("Secrets + content policy") is
skipped when a PR is edited, so a PR title/body edit can introduce a body-policy violation without
rerunning that check, leaving only a stale prior green result. This undermines the workflow’s stated
intent that PR bodies are merge-blocking unless branch protection is also updated to require the
separate body-guard check.
Code

.github/workflows/public-repo-guard.yml[R57-60]

+    if: >-
+      (github.event_name == 'pull_request' && github.event.action != 'edited')
+      || github.event_name == 'push'
+      || github.event_name == 'workflow_dispatch'
Evidence
The workflow is configured to fire on PR body/title edits, but the guard job is explicitly gated
to not execute on those edits; meanwhile, the workflow text claims PR body scanning is
merge-preventing, which won’t hold if only the guard check is required.

.github/workflows/public-repo-guard.yml[28-36]
.github/workflows/public-repo-guard.yml[52-63]
.github/workflows/public-repo-guard.yml[109-116]

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 triggers on `pull_request` `edited`, but the `guard` job (the existing check name) explicitly does not run on `edited`. If branch protection requires only `Secrets + content policy`, a PR body/title can change after the last `guard` run and still appear mergeable.

## Issue Context
`body-guard` does run on PR edits, but it produces a different check name (`Body content policy`), which is not guaranteed to be required.

## Fix Focus Areas
- .github/workflows/public-repo-guard.yml[28-36]
- .github/workflows/public-repo-guard.yml[52-63]
- .github/workflows/public-repo-guard.yml[113-116]

## Suggested fix
Make the required-check job run on PR `edited` too, while keeping the expensive tree scan skipped:
- Remove the job-level `if` exclusion for `edited` and instead add step-level `if` guards to skip gitleaks/tree scanning on `edited`.
- Always run the body materialization + `body-policy.sh` step for PR events inside the same required-check job, OR rename/merge so the required check name covers both tree and body scanning on PRs.

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


2. Allowlist filter can fail-open ✓ Resolved 🐞 Bug ☼ Reliability
Description
In scripts/public-repo-guard/body-policy.sh, the allowlist filtering pipeline ends with || true,
which masks not only ripgrep’s expected “no matches” (exit 1) but also real filtering failures (exit
>=2). If the allowlist-filter step errors, matches can become empty and the rule incorrectly
returns success, contradicting the script’s “fail closed” contract.
Code

scripts/public-repo-guard/body-policy.sh[R53-56]

+  matches="$(printf '%s' "$raw" \
+    | rg -vN -- 'guard:allow[[:space:]]+[^[:space:]]' \
+    | rg -vNiP -- "$ABOUT_THE_CONTROL" || true)"
+  [[ -z "$matches" ]] && return 0
Evidence
The script explicitly states it must fail closed when the scanner breaks, but the allowlist-filter
pipeline forces success regardless of ripgrep’s exit code, which can cause a false pass if the
filter step errors.

scripts/public-repo-guard/body-policy.sh[37-56]

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 `check()` function is designed to fail closed on scanner errors, but the allowlist filtering stage ends with `|| true`, which converts any pipeline failure (including real ripgrep errors) into success and can yield an empty `matches` set.

## Issue Context
`rg` returns:
- `0` when it outputs lines,
- `1` when it outputs nothing (normal for filters),
- `>=2` on real errors.
The code currently treats all failures the same due to `|| true`.

## Fix Focus Areas
- scripts/public-repo-guard/body-policy.sh[41-56]

## Suggested fix
Preserve the intended behavior (tolerate exit 1) while failing closed on exit >=2. For example:
- Run the filter pipeline with `set +e` locally, capture `$?`, and if `rc >= 2` then `exit 2`; otherwise accept empty output.
- Alternatively, split the filters into two stages, checking each stage’s exit status explicitly (accepting 1, rejecting >=2).

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


Grey Divider

Context used
Review mode: ⚖️ Balanced: Downgraded extended -> standard: change is below the extended eligibility bar (hunks 5/18, lines 347/200; both must reach the floor). Router rationale: This adds a security-sensitive GitHub Actions body-scanning path plus substantial independent shell-policy and fixture logic, creating multiple plausible, easy-to-miss defects across workflow events, untrusted payload handling, regex policy, and fail-closed behavior.

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 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 7 potential issues.

Open in Devin Review

Comment thread scripts/public-repo-guard/body-policy.sh Outdated
Comment thread scripts/public-repo-guard/body-policy.sh Outdated
Comment thread scripts/public-repo-guard/body-policy.sh Outdated
Comment on lines +128 to +133
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
# Only the gate's own scripts are needed — no reason to pay for the whole
# tree on every comment.
sparse-checkout: scripts/public-repo-guard
sparse-checkout-cone-mode: false

@devin-ai-integration devin-ai-integration Bot Aug 6, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔍 Fork PRs run the body gate from their own branch, so a fork can neutralize it

body-guard triggers on pull_request and checks out the PR's merge ref, then executes scripts/public-repo-guard/body-policy.sh from that checkout. A fork PR can therefore modify the gate script in the same PR and have the modified version judge its own body. The header of .github/workflows/public-repo-guard.yml:9-14 claims the gate "cannot be reprogrammed out-of-band", which is true for wave-av/.github but not for the PR branch itself. The pre-existing guard job has the same property, so this is not new, but the new job is explicitly described as PREVENTING a merge (.github/workflows/public-repo-guard.yml:109-112), which makes the assumption worth verifying. Pinning the script fetch to the base ref (e.g. checking out github.event.pull_request.base.sha for the scripts directory) would close it.

Open in Devin Review

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

Comment thread scripts/public-repo-guard/body-policy.sh Outdated
Comment thread .github/workflows/public-repo-guard.yml
Comment thread .github/workflows/public-repo-guard.yml
…ilter errors

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

@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 11m 3s

1 issue found and verified against the latest diff

Confidence score: 4/5

  • In .github/workflows/public-repo-guard.yml, subscribing only to issue_comment leaves PR review comments and review bodies unscanned, so leak-like content in those channels can slip past the guard and remain publicly visible—extend triggers to include PR review comment/review events and scan their payload fields as well.
Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name=".github/workflows/public-repo-guard.yml">

<violation number="1" location=".github/workflows/public-repo-guard.yml:35">
P2: Comment scanning is still incomplete because the workflow only subscribes to `issue_comment`. Public PR review comments (and review bodies) do not trigger this job, so leak-like content in those comment channels is currently outside the body-policy coverage. Expanding triggers to review comment/review events would close that gap.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Fix all with cubic | Re-trigger cubic

types: [opened, edited, reopened, synchronize]
issues:
types: [opened, edited]
issue_comment:

@cubic-dev-ai cubic-dev-ai Bot Aug 6, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2: Comment scanning is still incomplete because the workflow only subscribes to issue_comment. Public PR review comments (and review bodies) do not trigger this job, so leak-like content in those comment channels is currently outside the body-policy coverage. Expanding triggers to review comment/review events would close that gap.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .github/workflows/public-repo-guard.yml, line 35:

<comment>Comment scanning is still incomplete because the workflow only subscribes to `issue_comment`. Public PR review comments (and review bodies) do not trigger this job, so leak-like content in those comment channels is currently outside the body-policy coverage. Expanding triggers to review comment/review events would close that gap.</comment>

<file context>
@@ -25,24 +26,44 @@ name: public-repo-guard
+    types: [opened, edited, reopened, synchronize]
+  issues:
+    types: [opened, edited]
+  issue_comment:
+    types: [created, edited]
   push:
</file context>
Fix with cubic

devin-ai-integration[bot]

This comment was marked as resolved.

yakimoto and others added 2 commits August 6, 2026 17:38
Co-authored-by: Codesmith <codesmith-bot@users.noreply.github.com>
…re names

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

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

Open in Devin Review

Comment thread .github/workflows/public-repo-guard.yml Outdated
Comment thread scripts/public-repo-guard/body-policy.sh
Comment on lines +33 to +36
issues:
types: [opened, edited]
issue_comment:
types: [created, edited]

@devin-ai-integration devin-ai-integration Bot Aug 6, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔍 Review-comment bodies are still unscanned

issue_comment covers issue comments and top-level PR conversation comments, but NOT pull_request_review_comment (inline code-review comments) or pull_request_review (review summary bodies). Those bodies are equally world-readable and are exactly where operational detail tends to get pasted during review, so the stated gap ("an issue or comment BODY is scanned by nothing server-side") is only partly closed.

Open in Devin Review

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

…ternal-marker

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

This comment was marked as resolved.

…o WARN for bodies

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

@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 +112 to +113
- name: body policy self-test (fixtures)
run: bash scripts/public-repo-guard/tests/body-policy.test.sh

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟨 The leak gate runs the pull request's own copy of its scripts, so a PR can weaken or disable the check it must pass

The guard job checks out the PR merge ref and then executes scripts/public-repo-guard/tests/body-policy.test.sh (and, in the pre-existing step, content-policy.sh) from that checkout. A pull request — including one from a fork — can modify those vendored scripts in the same PR, so the run that is supposed to gate it executes attacker-controlled code. The self-test step in particular exists to prove the gate works, but a PR that edits the fixtures makes it prove nothing. The same job also passes the org variable GUARD_PRIVATE_REPOS (the list of private WAVE repo names the gate exists to keep out of public view) into a script the PR author controls, so a modified script can print those names into the public Actions log.

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-coderabbit RF.P1 reviewer routing (#1039)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant