From 92c2f6e27ca1493ca40013f5c06d5be5ea8b1f25 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 23 Apr 2026 12:56:04 +0000 Subject: [PATCH] perf(rust-guard): eliminate ctx.clone() and use &'static str in NormalizedPolicy Implements two improvements identified in issue #4380: 1. Eliminate ctx.clone() in label_agent: compute integrity labels before calling set_runtime_policy_context so ctx can be moved rather than cloned. PolicyContext holds eight heap-allocated Vec/String fields; deep-copying it on every label_agent call was pure overhead. 2. Use &'static str for NormalizedPolicy fields: both scope_kind and min_integrity are always compile-time constants. Add ScopeKind::as_str() alongside the existing Display impl (Display now delegates to as_str), change normalized_scope_kind() to return &'static str, and update NormalizedPolicy struct accordingly. Removes three unnecessary heap allocations per label_agent call. Closes #4380 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../github-guard/rust-guard/src/labels/helpers.rs | 15 ++++++++++----- guards/github-guard/rust-guard/src/lib.rs | 15 ++++++++------- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/guards/github-guard/rust-guard/src/labels/helpers.rs b/guards/github-guard/rust-guard/src/labels/helpers.rs index 009df8990..e93b4728a 100644 --- a/guards/github-guard/rust-guard/src/labels/helpers.rs +++ b/guards/github-guard/rust-guard/src/labels/helpers.rs @@ -63,16 +63,21 @@ pub enum ScopeKind { RepoPrefix, } -impl std::fmt::Display for ScopeKind { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let s = match self { +impl ScopeKind { + pub fn as_str(self) -> &'static str { + match self { ScopeKind::All => "All", ScopeKind::Public => "Public", ScopeKind::Owner => "Owner", ScopeKind::Repo => "Repo", ScopeKind::RepoPrefix => "RepoPrefix", - }; - f.write_str(s) + } + } +} + +impl std::fmt::Display for ScopeKind { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str(self.as_str()) } } diff --git a/guards/github-guard/rust-guard/src/lib.rs b/guards/github-guard/rust-guard/src/lib.rs index 22f46c2a3..2e356fbc6 100644 --- a/guards/github-guard/rust-guard/src/lib.rs +++ b/guards/github-guard/rust-guard/src/lib.rs @@ -332,9 +332,9 @@ struct AgentLabels { #[derive(Debug, Serialize)] struct NormalizedPolicy { - scope_kind: String, + scope_kind: &'static str, #[serde(rename = "min-integrity")] - min_integrity: String, + min_integrity: &'static str, } // ============================================================================ @@ -483,11 +483,11 @@ fn scope_token(scopes: &[PolicyScopeEntry]) -> String { } } -fn normalized_scope_kind(scopes: &[PolicyScopeEntry]) -> String { +fn normalized_scope_kind(scopes: &[PolicyScopeEntry]) -> &'static str { if scopes.len() == 1 { - scopes[0].scope_kind.to_string() + scopes[0].scope_kind.as_str() } else { - "Composite".to_string() + "Composite" } } @@ -557,18 +557,19 @@ pub extern "C" fn label_agent( disapproval_integrity: policy.disapproval_integrity, endorser_min_integrity: policy.endorser_min_integrity, }; - set_runtime_policy_context(ctx.clone()); + // Compute integrity before moving ctx into the global — borrows ctx, no clone needed. let integrity = match integrity_floor { MinIntegrity::None => labels::none_integrity(&token, &ctx), MinIntegrity::Unapproved => labels::reader_integrity(&token, &ctx), MinIntegrity::Approved => labels::writer_integrity(&token, &ctx), MinIntegrity::Merged => labels::merged_integrity(&token, &ctx), }; + set_runtime_policy_context(ctx); let normalized_policy = NormalizedPolicy { scope_kind: scope_kind_str, - min_integrity: integrity_floor.as_str().to_string(), + min_integrity: integrity_floor.as_str(), }; let output = LabelAgentOutput {