Repository navigation
[rust-guard] Rust Guard: list_commits Vec clone + project-item test coverage #6940
Description
🦀 Rust Guard Improvement Report
Improvement 1: Eliminate Redundant Vec<String> Clone in list_commits Arm
Category: Performance
File(s): guards/github-guard/rust-guard/src/labels/response_paths.rs
Effort: Small (< 15 min)
Risk: Low
Problem
In the list_commits arm of label_response_paths (around line 341–354), default_secrecy is created as a Vec<String>, immediately cloned to produce default_secrecy_shared: SharedLabels, and then the original is moved into default_labels. This wastes one full Vec<String> deep-clone (N string copies, one new backing buffer) on every list_commits call, even though the three other recently-fixed arms (list_pull_requests, list_issues, list_releases) already use the correct pattern.
// CURRENT — wasteful
let default_secrecy =
repo_visibility_secrecy(&arg_owner, &arg_repo, &default_repo, ctx);
// ...
let default_secrecy_shared: crate::SharedLabels = default_secrecy.clone().into(); // ← Vec clone here
// ...
return Some(PathLabelResult {
...
default_labels: Some(crate::ResourceLabels {
secrecy: default_secrecy.into(), // ← original moved here
...
}),
...
});Suggested Change
Convert to SharedLabels immediately, then clone the Arc (O(1)) wherever needed:
Before
let default_secrecy =
repo_visibility_secrecy(&arg_owner, &arg_repo, &default_repo, ctx);
// ...further down...
let default_secrecy_shared: crate::SharedLabels = default_secrecy.clone().into();
// ...in per-item loop...
secrecy: default_secrecy_shared.clone(),
// ...in default_labels...
secrecy: default_secrecy.into(),After
let default_secrecy: crate::SharedLabels =
repo_visibility_secrecy(&arg_owner, &arg_repo, &default_repo, ctx).into();
// ...further down, no separate `clone().into()` needed...
// ...in per-item loop...
secrecy: default_secrecy.clone(),
// ...in default_labels...
secrecy: default_secrecy, // move (last use)Why This Matters
SharedLabels wraps Arc<Vec<String>>, so every .clone() on it is a single atomic refcount increment — O(1), zero allocations. The current Vec::clone() allocates a new buffer and copies every string. For a typical list_commits response with private-repo secrecy labels (1–2 strings), this is minor, but the same pattern was already corrected in every other multi-item arm in this file (list_pull_requests, list_issues, list_releases, list_gists, list_notifications). Making list_commits consistent with those eliminates the last remaining clone().into() in the file.
Improvement 2: Add Unit Tests for list_project_items / projects_list in response_paths.rs
Category: Test Coverage
File(s): guards/github-guard/rust-guard/src/labels/response_paths.rs
Effort: Medium (15–30 min)
Risk: Low
Problem
The list_project_items | projects_list arm of label_response_paths contains three distinct security-relevant code paths, none of which have any test coverage in the existing 8 tests for this file:
ISSUE/PULL_REQUEST— extractscontentsub-object, callsextract_repo_from_item, appliesrepo_visibility_secrecy_for_repo_id, then derives integrity fromauthor_association_floor_from_str. Also has a fail-secure fallback when the repo cannot be determined.DRAFT_ISSUE/ unknown type — skips repo context entirely; always returnswriter_integrity(&arg_owner, ctx)with empty secrecy.items_pathforwarding — theitems_pathreturned byextract_items_arrayshould propagate toPathLabelResult.items_path.
Suggested Change
Add at least three focused tests to the mod tests block:
#[test]
fn list_project_items_issue_type_gets_repo_scoped_secrecy_and_association_integrity() {
let tool_args = json!({"owner": "octocat"});
let response = json!({
"items": [{
"type": "ISSUE",
"content": {
"repository_url": "https://api.github.com/repos/octocat/hello-world",
"author_association": "CONTRIBUTOR"
}
}]
});
let result = label_response_paths("list_project_items", &tool_args, &response, &ctx())
.expect("should produce path labels");
assert_eq!(result.labeled_paths.len(), 1);
let entry = &result.labeled_paths[0];
// CONTRIBUTOR association → at least reader-level integrity (non-empty)
assert!(!entry.labels.integrity.is_empty(),
"ISSUE item should have non-empty integrity; got {:?}", entry.labels.integrity);
assert_eq!(entry.labels.description, "project-item:issue");
}
#[test]
fn list_project_items_draft_issue_gets_writer_integrity_and_empty_secrecy() {
let tool_args = json!({"owner": "octocat"});
let response = json!({
"items": [{"type": "DRAFT_ISSUE", "title": "todo item"}]
});
let result = label_response_paths("list_project_items", &tool_args, &response, &ctx())
.expect("should produce path labels");
let entry = &result.labeled_paths[0];
assert!(entry.labels.secrecy.is_empty(),
"DRAFT_ISSUE should have empty secrecy; got {:?}", entry.labels.secrecy);
// writer_integrity(owner) must be non-empty
assert!(!entry.labels.integrity.is_empty(),
"DRAFT_ISSUE should have non-empty integrity; got {:?}", entry.labels.integrity);
assert_eq!(entry.labels.description, "project-item:draft_issue");
}
#[test]
fn projects_list_alias_behaves_identically_to_list_project_items() {
let tool_args = json!({"owner": "octocat"});
let response = json!({
"items": [{"type": "PULL_REQUEST", "content": {
"repository_url": "https://api.github.com/repos/octocat/hello-world",
"author_association": "MEMBER"
}}]
});
let r1 = label_response_paths("list_project_items", &tool_args, &response, &ctx());
let r2 = label_response_paths("projects_list", &tool_args, &response, &ctx());
// Both aliases must produce results with the same number of labeled paths
assert_eq!(
r1.as_ref().map(|r| r.labeled_paths.len()),
r2.as_ref().map(|r| r.labeled_paths.len()),
"projects_list alias must match list_project_items"
);
}Why This Matters
The list_project_items arm chooses between repo-scoped secrecy (for linked issues/PRs) and empty secrecy (for draft items) with no test safety net. A future refactor could accidentally swap the branches, flip the is_empty() fail-secure check, or break the projects_list alias — all silently. Tests also document the intended contract: that DRAFT items are always public-scoped, and that items with an unknown repo fail secure rather than defaulting to public.
Codebase Health Summary
- Total Rust files: 10
- Total lines: ~14,970
- Areas analyzed:
lib.rs,tools.rs,labels/mod.rs,labels/helpers.rs,labels/constants.rs,labels/tool_rules.rs,labels/response_paths.rs,labels/response_items.rs,labels/backend.rs - Areas with no further improvements:
tools.rs(binary_search + sorted tests complete),lib.rs(parse_integrity + scope_string tests added)
Generated by Rust Guard Improver • Run: §26879421386
Generated by Rust Guard Improver · sonnet46 4.4M · ◷
- expires on Jun 10, 2026, 10:46 AM UTC
Activity
github-actions commentedon Jun 3, 2026
🤖 This is an automated response from Repo Assist.
Both improvements look solid. Copilot opened draft PR #6941 to address them. A few notes:
Improvement 1 (
list_commitsVec clone): The analysis is accurate — the three sister arms (list_pull_requests,list_issues,list_releases) already use theSharedLabels-first pattern, solist_commitsis the outlier. Converting immediately toSharedLabelsand cloningArc(O(1)) rather than cloning theVec(O(n) strings) is strictly better, and the PR applies this consistently.Improvement 2 (project-item tests): The three missing cases (ISSUE with repo context, DRAFT_ISSUE with owner-writer integrity + empty secrecy, and
projects_listalias parity) are the right ones to pin down — the fail-secure branch in particular is easy to accidentally break in a refactor without a regression test guarding it.PR #6941 looks like it handles both. Worth a review pass to confirm the
items_pathcontract test is also included.Add this agentic workflows to your repo
To install this agentic workflow, run