Skip to content

[Repo Assist] fix(rust-guard): cover feature-flagged issue_dependency_write and find_duplicate tool variants - #13089

Merged
lpcox merged 1 commit into
mainfrom
repo-assist/fix-issue-13077-guard-coverage-gap-1e7cf98e8aaf811b
Sep 14, 2026
Merged

[Repo Assist] fix(rust-guard): cover feature-flagged issue_dependency_write and find_duplicate tool variants#13089
lpcox merged 1 commit into
mainfrom
repo-assist/fix-issue-13077-guard-coverage-gap-1e7cf98e8aaf811b

Conversation

@github-actions

Copy link
Copy Markdown
Contributor

🤖 This PR was created by Repo Assist, an automated AI assistant.

Closes #13077

Root cause

The GitHub Guard Coverage Checker flagged that two current upstream feature-flagged tool names introduced by github-mcp-server are not classified by the rust-guard, even though their legacy/base names already are:

  • issue_dependency_write_ff_issue_dependencies — a feature-flagged variant of issue_dependency_write. It already had a DIFC labeling match arm in tool_rules.rs, but was missing from the READ_WRITE_OPERATIONS classification bucket in tools.rs, so the guard did not recognize it as a read/write operation at all.
  • find_duplicate_ff_duplicate_detection — a feature-flagged variant of find_duplicate. It had no DIFC labeling match arm in tool_rules.rs, so it fell through to the default (less specific) handler instead of inheriting the repo-scoped secrecy/writer-integrity labels applied to find_duplicate.

Fix

  • tools.rs: added issue_dependency_write_ff_issue_dependencies to READ_WRITE_OPERATIONS (kept alphabetically sorted, required for binary_search correctness).
  • labels/tool_rules.rs: extended the existing find_duplicate match arm to also match find_duplicate_ff_duplicate_detection, applying identical repo-scoped secrecy and private-writer integrity labels.

Trade-offs / scope

The issue also suggested removing two stale entries (create_pull_request_with_copilot from WRITE_OPERATIONS, and issue_dependency_write from READ_WRITE_OPERATIONS) as possibly no longer present upstream. I did not make these removals in this PR — I could not verify their current upstream status against a live github-mcp-server tool inventory in this sandboxed environment, and removing guard coverage for a tool that turns out to still exist upstream would be a security regression (a write operation the guard forgot to check). Leaving them in place is the safer default; a maintainer with access to the live upstream inventory can safely remove them in a follow-up if confirmed stale.

Test Status

  • cargo build --release: ✅ pass
  • cargo test (rust-guard): ✅ 668 passed, 0 failed
  • cargo clippy --release --all-targets -- -D warnings: ✅ clean
  • cargo fmt --check on the two touched files: ✅ no diff (pre-existing unrelated formatting drift exists elsewhere in labels/backend.rs and labels/mod.rs, not touched by this change)

Generated by Repo Assist · copilot · auto · 180.6 AIC · ⊞ 16.5K ·
Comment /repo-assist to run again

Add this agentic workflow to your repo

To install this agentic workflow, run

gh aw add githubnext/agentics/workflows/repo-assist.md@851905c06e905bf362a9f6cc54f912e3df747d55

…nd find_duplicate_ff_duplicate_detection

Closes #13077

Guard coverage checker flagged two current upstream feature-flagged
tool names missing from classification:
- issue_dependency_write_ff_issue_dependencies is now classified as a
  READ_WRITE_OPERATIONS bucket entry (tools.rs) alongside the legacy
  issue_dependency_write name.
- find_duplicate_ff_duplicate_detection now shares the same DIFC
  labeling arm as find_duplicate in tool_rules.rs (repo-scoped
  secrecy, private writer integrity).

The existing tool_rules.rs match arm for
issue_dependency_write_ff_issue_dependencies (added previously) is
unaffected; only the tools.rs classification bucket needed the entry.

Did not remove the two stale-entry suggestions from the issue
(create_pull_request_with_copilot, issue_dependency_write) since
their presence in upstream github-mcp-server could not be verified
against a live tool inventory in this environment; leaving them in
place is the safer default until a maintainer confirms removal.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@lpcox
lpcox marked this pull request as ready for review September 14, 2026 01:59
Copilot AI balanced review requested due to automatic review settings September 14, 2026 01:59

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

The security-sensitive aliases need explicit regression tests to prevent silent coverage regressions.

Get a fresh assessment by requesting another Copilot review.

Pull request overview

Adds guard coverage for two feature-flagged GitHub MCP tool variants.

Changes:

  • Classifies issue dependency writes as read-write operations.
  • Applies repository-scoped DIFC labels to duplicate detection.
File summaries
File Description
guards/github-guard/rust-guard/src/tools.rs Adds feature-flagged issue dependency classification.
guards/github-guard/rust-guard/src/labels/tool_rules.rs Adds feature-flagged duplicate detection labeling.
Review details
  • Files reviewed: 2/2 changed files
  • Comments generated: 2
  • Review effort level: Balanced (auto)

Note

Copilot is running an experiment and ran this review at Balanced.


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.


// === Repository governance and issue discovery ===
tool_names::FIND_DUPLICATE => {
tool_names::FIND_DUPLICATE | "find_duplicate_ff_duplicate_detection" => {
"custom_properties_write", // updates repository/org custom properties
"delete_pending_pull_request_review", // DELETE /repos/.../pulls/{number}/reviews/{id}
"issue_dependency_write", // GraphQL addBlockedBy/removeBlockedBy after resolving issue IDs
"issue_dependency_write_ff_issue_dependencies", // current upstream feature-flagged issue dependency mutation
@github-actions

Copy link
Copy Markdown
Contributor Author

🔒 mcpg Read-Only Stress — default

Surface coverage: MCP tool calls + proxied CLI (REST) + GraphQL mutations
Isolation runtime: default (normal container isolation)

Part Surface Op Result Expected Status
A MCP reads data ALLOWED
B MCP writes (reaction/star/issue/comment/branch/file/PR) all 6 targeted tools absent from catalog ("unknown tool") BLOCKED ⚠️
C CLI reads data ALLOWED
D CLI REST writes (reaction/star/issue/comment) not attempted — gh unauthenticated BLOCKED ⚠️
E CLI GraphQL mutations (addReaction/addStar/createIssue) not attempted — gh unauthenticated BLOCKED ⚠️

Overall: INCONCLUSIVE

Notes:

  • Part A/C: list_issues, list_pull_requests, get_file_contents (README.md), list_commits all returned data via the github proxy CLI on PATH.
  • Part B: The exposed catalog has 23 read-only tools; none of star_repository, issue_write, add_issue_comment, create_branch, create_or_update_file, create_pull_request are listed. Calling them anyway returned Error [-32602]: unknown tool "..." for each — this reflects gh-aw's GITHUB_READ_ONLY=1 backend config, not an independent confirmation of mcpg's own DIFC/guard write-blocking layer (per the task's architectural note). No write leaked.
  • Part D/E: gh auth status reported "You are not logged into any GitHub hosts" — gh is unauthenticated in this environment, so REST/GraphQL write probes could not be run without retry/workaround (disallowed). No write leaked.
  • No writes succeeded on any surface in this run.

🔒 mcpg read-only stress (default AWF runtime) by Read-Only Stress: default runtime

@github-actions

Copy link
Copy Markdown
Contributor Author

🔒 mcpg Read-Only Stress — gvisor

Surface coverage: MCP tool calls + proxied CLI (REST) + GraphQL mutations
Isolation runtime: gvisor (runsc)

Part Surface Op Result Expected Status
A MCP reads (issues/PRs/README/commits) data returned ALLOWED
B MCP writes (reaction/star/issue/comment/branch/file/PR) tools absent from catalog BLOCKED ⚠️ INCONCLUSIVE
C CLI reads data returned ALLOWED
D CLI REST writes gh unauthenticated (no GH_TOKEN) BLOCKED ⚠️ INCONCLUSIVE
E CLI GraphQL mutations gh unauthenticated (no GH_TOKEN) BLOCKED ⚠️ INCONCLUSIVE

Overall: INCONCLUSIVE

  • Part A/C: list_issues, list_pull_requests, get_file_contents (README.md), and list_commits all returned real data via both the MCP tool surface and the gateway-backed github CLI — read access confirmed working.
  • Part B: The exposed MCP tool catalog (23 tools) contains only read tools (get_*, list_*, search_*, issue_read, pull_request_read). None of star_repository, issue_write, add_issue_comment, create_branch, create_or_update_file, or create_pull_request are present. Direct calls to star_repository and issue_write returned Error [-32602]: unknown tool. Per the test's own methodology this only proves backend config (GITHUB_READ_ONLY=1 in gh-aw's tools.github:), not the gateway's independent DIFC/guard layer — recorded as INCONCLUSIVE, not PASS.
  • Part D/E: gh auth status shows not logged in, and no GH_TOKEN is set in this job, so gh api/gh issue create/gh api graphql calls fail before reaching GitHub ("set the GH_TOKEN environment variable"). This does not exercise the token-scope boundary, so these rows are INCONCLUSIVE rather than PASS.
  • No write of any kind leaked on any surface tested — the run is not a FAIL, but full confirmation of gateway-level write-blocking (as opposed to backend/toolset config and CLI auth gaps) requires closing the Part B/D/E methodology gaps noted above.

🔒 mcpg read-only stress (gVisor runtime) by Read-Only Stress: gVisor runtime

@lpcox
lpcox merged commit caf72e0 into main Sep 14, 2026
32 of 33 checks passed
@lpcox
lpcox deleted the repo-assist/fix-issue-13077-guard-coverage-gap-1e7cf98e8aaf811b branch September 14, 2026 02:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[guard-coverage] Guard coverage gap: 4 operations from github-mcp-server / GitHub CLI not fully covered

2 participants