From 1b6489b530c9b3e8cda1c5b30cab1409b62bc320 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 14 May 2026 13:21:38 +0000 Subject: [PATCH 1/5] Initial plan From 97bd137077901789d9a0ed8f0a3638fc854dc5db Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 14 May 2026 13:27:08 +0000 Subject: [PATCH 2/5] perf(rust-guard): remove avoidable allocations in hot path helpers --- .../rust-guard/src/labels/tool_rules.rs | 7 +++--- guards/github-guard/rust-guard/src/lib.rs | 24 +++++++++++++++---- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/guards/github-guard/rust-guard/src/labels/tool_rules.rs b/guards/github-guard/rust-guard/src/labels/tool_rules.rs index 1ed4a4e3..dd1df783 100644 --- a/guards/github-guard/rust-guard/src/labels/tool_rules.rs +++ b/guards/github-guard/rust-guard/src/labels/tool_rules.rs @@ -745,17 +745,18 @@ fn check_file_secrecy( ctx: &PolicyContext, ) -> Vec { let path_lower = path.to_lowercase(); - let segments: Vec<&str> = path_lower.split('/').collect(); // Check for sensitive file extensions/names for pattern in SENSITIVE_FILE_PATTERNS { - if path_lower.ends_with(pattern) || segments.iter().any(|seg| seg.starts_with(*pattern)) { + if path_lower.ends_with(pattern) + || path_lower.split('/').any(|seg| seg.starts_with(*pattern)) + { return policy_private_scope_label(owner, repo, repo_id, ctx); } } // Get filename - let filename = segments.last().copied().unwrap_or(path_lower.as_str()); + let filename = path_lower.rsplit('/').next().unwrap_or(&path_lower); // Check for sensitive keywords in filename for keyword in SENSITIVE_FILE_KEYWORDS { diff --git a/guards/github-guard/rust-guard/src/lib.rs b/guards/github-guard/rust-guard/src/lib.rs index a4fab232..6368d386 100644 --- a/guards/github-guard/rust-guard/src/lib.rs +++ b/guards/github-guard/rust-guard/src/lib.rs @@ -21,6 +21,7 @@ use labels::{ use serde::{Deserialize, Serialize}; use serde_json::Value; use std::alloc::{alloc as std_alloc, dealloc as std_dealloc, Layout}; +use std::borrow::Cow; use std::slice; use std::sync::Mutex; @@ -257,9 +258,13 @@ struct LabelResponseOutput { items: Vec, } -fn infer_scope_for_baseline(tool_name: &str, tool_args: &Value, repo_id: &str) -> String { +fn infer_scope_for_baseline<'a>( + tool_name: &str, + tool_args: &Value, + repo_id: &'a str, +) -> Cow<'a, str> { if !repo_id.is_empty() { - return repo_id.to_string(); + return Cow::Borrowed(repo_id); } match tool_name { @@ -268,16 +273,16 @@ fn infer_scope_for_baseline(tool_name: &str, tool_args: &Value, repo_id: &str) - | "manage_notification_subscription" | "manage_repository_notification_subscription" | "create_repository" - | "fork_repository" => scope_names::GITHUB.to_string(), + | "fork_repository" => Cow::Borrowed(scope_names::GITHUB), "search_code" | "search_issues" | "search_pull_requests" => { let query = tool_args .get("query") .and_then(|v| v.as_str()) .unwrap_or(""); let (_, _, repo_from_query) = extract_repo_info_from_search_query(query); - repo_from_query + Cow::Owned(repo_from_query) } - _ => String::new(), + _ => Cow::Borrowed(""), } } @@ -1096,9 +1101,18 @@ mod tests { let tool_args = json!({"query": "repo:lpcox/github-guard README"}); let inferred = infer_scope_for_baseline("search_code", &tool_args, ""); + assert!(matches!(inferred, Cow::Owned(_))); assert_eq!(inferred, "lpcox/github-guard"); } + #[test] + fn infer_scope_for_baseline_borrows_repo_id_when_present() { + let tool_args = json!({}); + let inferred = infer_scope_for_baseline("get_file_contents", &tool_args, "octocat/hello-world"); + + assert!(matches!(inferred, Cow::Borrowed("octocat/hello-world"))); + } + #[test] fn search_code_baseline_preserves_scoped_integrity() { let ctx = PolicyContext { From 3cfc1491aa1e7416c9fd626c6b5247bac6d47f0f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 14 May 2026 13:29:32 +0000 Subject: [PATCH 3/5] test(rust-guard): cover all borrowed scope branches --- guards/github-guard/rust-guard/src/lib.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/guards/github-guard/rust-guard/src/lib.rs b/guards/github-guard/rust-guard/src/lib.rs index 6368d386..23e9a3bf 100644 --- a/guards/github-guard/rust-guard/src/lib.rs +++ b/guards/github-guard/rust-guard/src/lib.rs @@ -1113,6 +1113,22 @@ mod tests { assert!(matches!(inferred, Cow::Borrowed("octocat/hello-world"))); } + #[test] + fn infer_scope_for_baseline_borrows_github_scope_for_repo_creation() { + let tool_args = json!({}); + let inferred = infer_scope_for_baseline("create_repository", &tool_args, ""); + + assert!(matches!(inferred, Cow::Borrowed(scope_names::GITHUB))); + } + + #[test] + fn infer_scope_for_baseline_borrows_empty_scope_for_other_tools() { + let tool_args = json!({}); + let inferred = infer_scope_for_baseline("get_file_contents", &tool_args, ""); + + assert!(matches!(inferred, Cow::Borrowed(""))); + } + #[test] fn search_code_baseline_preserves_scoped_integrity() { let ctx = PolicyContext { From d895dd8f887cb64dbe1e4a59df53b7233db04817 Mon Sep 17 00:00:00 2001 From: Landon Cox Date: Thu, 14 May 2026 06:41:36 -0700 Subject: [PATCH 4/5] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- guards/github-guard/rust-guard/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/guards/github-guard/rust-guard/src/lib.rs b/guards/github-guard/rust-guard/src/lib.rs index 23e9a3bf..88a56a57 100644 --- a/guards/github-guard/rust-guard/src/lib.rs +++ b/guards/github-guard/rust-guard/src/lib.rs @@ -1101,7 +1101,7 @@ mod tests { let tool_args = json!({"query": "repo:lpcox/github-guard README"}); let inferred = infer_scope_for_baseline("search_code", &tool_args, ""); - assert!(matches!(inferred, Cow::Owned(_))); + assert!(matches!(&inferred, Cow::Owned(_))); assert_eq!(inferred, "lpcox/github-guard"); } From 71c2ba6c4dddddff5acc201cdf7a3e3d5f80b011 Mon Sep 17 00:00:00 2001 From: Landon Cox Date: Thu, 14 May 2026 06:41:46 -0700 Subject: [PATCH 5/5] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- .../rust-guard/src/labels/tool_rules.rs | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/guards/github-guard/rust-guard/src/labels/tool_rules.rs b/guards/github-guard/rust-guard/src/labels/tool_rules.rs index dd1df783..56238fe1 100644 --- a/guards/github-guard/rust-guard/src/labels/tool_rules.rs +++ b/guards/github-guard/rust-guard/src/labels/tool_rules.rs @@ -747,12 +747,19 @@ fn check_file_secrecy( let path_lower = path.to_lowercase(); // Check for sensitive file extensions/names - for pattern in SENSITIVE_FILE_PATTERNS { - if path_lower.ends_with(pattern) - || path_lower.split('/').any(|seg| seg.starts_with(*pattern)) - { - return policy_private_scope_label(owner, repo, repo_id, ctx); - } + if SENSITIVE_FILE_PATTERNS + .iter() + .any(|pattern| path_lower.ends_with(pattern)) + { + return policy_private_scope_label(owner, repo, repo_id, ctx); + } + + if path_lower.split('/').any(|seg| { + SENSITIVE_FILE_PATTERNS + .iter() + .any(|pattern| seg.starts_with(*pattern)) + }) { + return policy_private_scope_label(owner, repo, repo_id, ctx); } // Get filename