-
Notifications
You must be signed in to change notification settings - Fork 21
Guard coverage: block all modifying gh repo operations
#2806
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -38,11 +38,13 @@ pub const WRITE_OPERATIONS: &[&str] = &[ | |
| // Dynamically enables additional toolsets, expanding the agent's capability set | ||
| "enable_toolset", | ||
| // Pre-emptive entries for anticipated future MCP tools (no equivalent tool today) | ||
| "archive_repository", // gh repo archive | ||
| "transfer_issue", // gh issue transfer | ||
| "transfer_repository", // gh repo transfer — blocked: repo ownership transfer is irreversible | ||
| "pin_issue", // gh issue pin | ||
| "unpin_issue", // gh issue unpin | ||
| "archive_repository", // gh repo archive — blocked: repo settings change unsupported | ||
| "unarchive_repository", // gh repo unarchive — blocked: symmetric to archive_repository | ||
| "rename_repository", // gh repo rename — blocked: breaks clone URLs and integrations | ||
| "transfer_issue", // gh issue transfer | ||
| "transfer_repository", // gh repo transfer — blocked: repo ownership transfer is irreversible | ||
| "pin_issue", // gh issue pin | ||
| "unpin_issue", // gh issue unpin | ||
| "enable_workflow", // gh workflow enable | ||
| "disable_workflow", // gh workflow disable | ||
| "set_secret", // gh secret set | ||
|
|
@@ -116,8 +118,17 @@ pub fn is_unlock_operation(tool_name: &str) -> bool { | |
| /// Current entries: | ||
| /// - `transfer_repository`: repository ownership transfer is irreversible and | ||
| /// must never be performed by an automated agent. | ||
| /// - `archive_repository`: archives a repository, restricting contributions; unsupported as an | ||
| /// agent operation. | ||
| /// - `unarchive_repository`: re-enables contributions to a previously archived repository; | ||
| /// symmetric to `archive_repository` and equally unsupported. | ||
| /// - `rename_repository`: renames a repository, breaking all clone URLs, webhooks, and external | ||
| /// references; unsupported as an agent operation. | ||
| pub fn is_blocked_tool(tool_name: &str) -> bool { | ||
| matches!(tool_name, "transfer_repository") | ||
| matches!( | ||
| tool_name, | ||
| "transfer_repository" | "archive_repository" | "unarchive_repository" | "rename_repository" | ||
| ) | ||
|
Comment on lines
127
to
+131
|
||
| } | ||
|
|
||
| #[cfg(test)] | ||
|
|
@@ -132,6 +143,17 @@ mod tests { | |
| ); | ||
| } | ||
|
|
||
| #[test] | ||
| fn test_is_blocked_tool_repo_modifying_operations() { | ||
| for op in &["archive_repository", "unarchive_repository", "rename_repository"] { | ||
| assert!( | ||
| is_blocked_tool(op), | ||
| "{} must be unconditionally blocked (modifying gh repo operation)", | ||
| op | ||
| ); | ||
| } | ||
| } | ||
|
|
||
| #[test] | ||
| fn test_is_blocked_tool_other_write_ops_not_blocked() { | ||
| // Regular write operations should not be blocked | ||
|
|
@@ -152,6 +174,17 @@ mod tests { | |
| ); | ||
| } | ||
|
|
||
| #[test] | ||
| fn test_repo_modifying_operations_are_write_operations() { | ||
| for op in &["archive_repository", "unarchive_repository", "rename_repository"] { | ||
| assert!( | ||
| is_write_operation(op), | ||
| "{} must be classified as a write operation", | ||
| op | ||
| ); | ||
| } | ||
| } | ||
|
|
||
| #[test] | ||
| fn test_pin_unpin_issue_are_write_operations() { | ||
| assert!( | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are existing
apply_tool_labelsunit tests fortransfer_repositoryinlabels/mod.rs, but none covering this new match arm. Add tests that callapply_tool_labels("archive_repository"|"unarchive_repository"|"rename_repository", …)to verify the secrecy behavior matchestransfer_repository(and that the call completes deterministically incfg(test)without relying on the backend host).