t1405: scope boundary for worker dispatch — pulse dispatches only within pulse-enabled repos#2933
Conversation
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request introduces a critical scope boundary for AI agents dispatched by the pulse system. The primary goal is to prevent automated workers from inadvertently making code changes (branches, PRs, commits) in repositories that are not explicitly managed or intended for modification by the user's pulse configuration. While maintaining the ability for agents to report issues across any repository for valuable feedback, this change ensures that active code development is strictly confined to designated, pulse-enabled repositories, thereby enhancing control and preventing unintended external interactions. Highlights
Changelog
Activity
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
WalkthroughAdds a pulse scope boundary: PULSE_SCOPE_REPOS (comma-separated repo slugs) is exported to dispatched workers; workers may file issues on any repo but may only create branches/PRs/commits on repos listed in PULSE_SCOPE_REPOS. Interactive (unset/empty) mode disables scope restrictions. Changes
Sequence Diagram(s)sequenceDiagram
participant Pulse as Pulse (prefetch)
participant Env as Env (PULSE_SCOPE_REPOS)
participant Worker as Dispatched Worker
participant Repo as Target Repo
participant Queue as Repo Maintainers' Queue
Pulse->>Env: compute PULSE_SCOPE_REPOS (comma list)
Pulse-->>Worker: start worker (inherits PULSE_SCOPE_REPOS)
Worker->>Repo: discover issue or required fix
alt Repo in PULSE_SCOPE_REPOS
Worker->>Repo: create branch / open PR
else Repo not in scope
Worker->>Repo: file issue
Worker->>Queue: stop implementation (dispatch halted)
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested labels
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Code Review
This pull request introduces a crucial scope boundary for pulse-dispatched workers, preventing them from making code changes outside of explicitly configured repositories. The implementation is well-layered, with changes to pulse-wrapper.sh to set the scope via an environment variable, and updates to documentation and agent prompts to ensure workers respect this boundary. My review found one minor opportunity to improve the robustness of how the scoped repository list is generated. Overall, this is a solid improvement for security and correctness.
Note: Security Review did not run due to the size of the PR.
.agents/scripts/pulse-wrapper.sh
Outdated
| # Workers CAN file issues on any repo (cross-repo self-improvement), | ||
| # but code changes (branches, PRs) are restricted to this list. | ||
| local scope_slugs | ||
| scope_slugs=$(echo "$repo_entries" | cut -d'|' -f1 | paste -sd ',' -) |
There was a problem hiding this comment.
To make the creation of PULSE_SCOPE_REPOS more robust, consider filtering out empty slugs that might arise from malformed entries in repos.json. An empty slug in the list could result in a ,, substring, which could cause the scope check logic (grep -F ,,) to incorrectly pass for an empty target repository. Adding grep . to the pipeline is a simple way to filter out empty lines and ensure only valid slugs are included.
| scope_slugs=$(echo "$repo_entries" | cut -d'|' -f1 | paste -sd ',' -) | |
| scope_slugs=$(echo "$repo_entries" | cut -d'|' -f1 | grep . | paste -sd ',' -) |
cd6062f to
af983b1
Compare
|
/qlty check |
Separate 'observe and report' from 'observe and fix' for pulse-dispatched workers. Workers CAN file issues on any repo (cross-repo self-improvement), but code changes (branches, PRs) are restricted to repos listed in the PULSE_SCOPE_REPOS env var, which is set by pulse-wrapper.sh from repos with pulse: true in repos.json. This prevents the pattern where pulse-dispatched workers create PRs on repos outside the user's managed scope (observed: 4 PRs + a fork on a repo the user doesn't own). Closes #2928
791d386 to
c28ab93
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.agents/scripts/commands/full-loop.md:
- Around line 483-494: The scope-guard currently files an issue for out-of-scope
repos but does not stop execution; after the gh issue create call inside the
if-block that detects TARGET_SLUG not in PULSE_SCOPE_REPOS, add an explicit
control-flow stop (e.g., exit or return) immediately after filing the issue so
the script enforces "file the issue and stop" and prevents any subsequent
branch/commit/PR logic from running; update the block that references
TARGET_SLUG, PULSE_SCOPE_REPOS, and the gh issue create invocation to include
this exit.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: eee7df94-9bfc-404b-8abb-87856ba09f42
📒 Files selected for processing (5)
.agents/AGENTS.md.agents/prompts/build.txt.agents/scripts/commands/full-loop.md.agents/scripts/commands/pulse.md.agents/scripts/pulse-wrapper.sh
CI StatusAll checks pass except qlty check which reports "Build errored" — this is a qlty cloud infrastructure error, not a code quality finding. Local verification (all pass):
Evidence this is a qlty cloud issue:
The branch has been rebased onto latest main. The PR is mergeable. |
🔍 Code Quality Report�[0;35m[MONITOR]�[0m Code Review Monitoring Report �[0;34m[INFO]�[0m Latest Quality Status: �[0;34m[INFO]�[0m Recent monitoring activity: 📈 Current Quality Metrics
Generated on: Thu Mar 5 17:37:12 UTC 2026 Generated by AI DevOps Framework Code Review Monitoring |
…(t1405) - Add explicit exit 0 after gh issue create in scope guard to enforce 'file the issue and stop' behavior (CodeRabbit CHANGES_REQUESTED) - Fix indentation in scope guard code block - Filter empty slugs from PULSE_SCOPE_REPOS to prevent malformed entries from bypassing scope check (Gemini review suggestion)
🔍 Code Quality Report�[0;35m[MONITOR]�[0m Code Review Monitoring Report �[0;34m[INFO]�[0m Latest Quality Status: �[0;34m[INFO]�[0m Recent monitoring activity: 📈 Current Quality Metrics
Generated on: Thu Mar 5 18:15:09 UTC 2026 Generated by AI DevOps Framework Code Review Monitoring |
|
There was a problem hiding this comment.
🧹 Nitpick comments (1)
.agents/prompts/build.txt (1)
239-240: Consider adding supervisor routing context for completeness.The current text says "file the issue and stop — do not implement the fix" but doesn't explain what happens after filing the issue. The full-loop.md documentation (lines 475) includes helpful context: "The pulse supervisor will pick up the cross-repo issue on its next cycle." Adding a brief mention of this continuation path would help workers understand that filing the issue is a proper handoff, not a dead-end.
Optional refinement to clarify the workflow
-**Pulse scope boundary (t1405, GH#2928):** When dispatched by the pulse, `PULSE_SCOPE_REPOS` (comma-separated repo slugs) defines which repos you may create branches and PRs on. Filing issues is always allowed on any repo. Code changes (branches, PRs, commits) are restricted to repos in `PULSE_SCOPE_REPOS`. If the target repo is not in scope, file the issue and stop — do not implement the fix. If `PULSE_SCOPE_REPOS` is empty or unset (interactive mode), no scope restriction applies. This prevents pulse-dispatched workers from creating PRs on repos outside the user's managed scope. +**Pulse scope boundary (t1405, GH#2928):** When dispatched by the pulse, `PULSE_SCOPE_REPOS` (comma-separated repo slugs) defines which repos you may create branches and PRs on. Filing issues is always allowed on any repo. Code changes (branches, PRs, commits) are restricted to repos in `PULSE_SCOPE_REPOS`. If the target repo is not in scope, file the issue and stop — do not implement the fix; the pulse supervisor will pick it up on the next cycle. If `PULSE_SCOPE_REPOS` is empty or unset (interactive mode), no scope restriction applies. This prevents pulse-dispatched workers from creating PRs on repos outside the user's managed scope.This adds 11 words to clarify that cross-repo issues are routed to the supervisor, consistent with the detailed explanation in full-loop.md.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.agents/prompts/build.txt around lines 239 - 240, Update the PULSE_SCOPE_REPOS guidance to mention what happens after filing a cross-repo issue: when a worker detects the target repo is out of scope it should "file the issue and stop — do not implement the fix", and you must append a short note that the filed cross-repo issue will be picked up by the pulse supervisor on its next cycle (consistent with full-loop.md). Locate the paragraph referencing PULSE_SCOPE_REPOS in .agents/prompts/build.txt and add a brief sentence about supervisor routing so workers know filing the issue hands it off rather than leaving it untracked.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In @.agents/prompts/build.txt:
- Around line 239-240: Update the PULSE_SCOPE_REPOS guidance to mention what
happens after filing a cross-repo issue: when a worker detects the target repo
is out of scope it should "file the issue and stop — do not implement the fix",
and you must append a short note that the filed cross-repo issue will be picked
up by the pulse supervisor on its next cycle (consistent with full-loop.md).
Locate the paragraph referencing PULSE_SCOPE_REPOS in .agents/prompts/build.txt
and add a brief sentence about supervisor routing so workers know filing the
issue hands it off rather than leaving it untracked.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 4c414e7f-f443-4f6e-a954-f9caae1893b1
📒 Files selected for processing (5)
.agents/AGENTS.md.agents/prompts/build.txt.agents/scripts/commands/full-loop.md.agents/scripts/commands/pulse.md.agents/scripts/pulse-wrapper.sh
🚧 Files skipped from review as they are similar to previous changes (3)
- .agents/AGENTS.md
- .agents/scripts/commands/pulse.md
- .agents/scripts/commands/full-loop.md
…ws (#2980) When bots are rate-limited, they post quota/rate-limit notices instead of actual code reviews. The gate was counting these as valid reviews (PASS) because it only checked for comment existence, not content. Now both the helper script and CI workflow: - Base64-encode comment bodies to handle multi-line content correctly - Check each bot comment against known rate-limit patterns - Only count comments as real reviews if they don't match rate-limit patterns - Return WAITING (not PASS) when all bot comments are rate-limit notices - Show rate-limited bots separately in output and CI summary Tested against PR #2978 (rate-limited → WAITING) and PR #2933 (real review → PASS).
…ws (#2980) (#2982) When bots are rate-limited, they post quota/rate-limit notices instead of actual code reviews. The gate was counting these as valid reviews (PASS) because it only checked for comment existence, not content. Now both the helper script and CI workflow: - Base64-encode comment bodies to handle multi-line content correctly - Check each bot comment against known rate-limit patterns - Only count comments as real reviews if they don't match rate-limit patterns - Return WAITING (not PASS) when all bot comments are rate-limit notices - Show rate-limited bots separately in output and CI summary Tested against PR #2978 (rate-limited → WAITING) and PR #2933 (real review → PASS).



Summary
PULSE_SCOPE_REPOSenv var (comma-separated repo slugs) exported bypulse-wrapper.shfrompulse: truerepos in repos.jsonProblem
The pulse correctly pre-fetches only
pulse: truerepos, but workers dispatched by the pulse could independently discover and act on issues in other repos via self-improvement routing. This led to workers creating 4 PRs, a fork, and branches on a repo the user doesn't own — without the user's knowledge.Solution
Separate "observe and report" from "observe and fix":
PULSE_SCOPE_REPOSThe enforcement is layered:
pulse-wrapper.sh): ExportsPULSE_SCOPE_REPOSbefore spawning the pulse agentpulse.md): Documents that dispatch must only target in-scope reposfull-loop.md): Workers check scope before creating code changes on other reposbuild.txt): All agents are aware of the scope boundaryRelationship to related issues
Closes #2928
Summary by CodeRabbit
Documentation
Chores