Warn when a short secret value skips redaction
Resolve silently dropped values under 8 bytes from the redaction map,
which is the worst failure mode for a security feature: an operator
declares a 6-char API key, sees it appear in CI logs unmodified, and
has no signal that the threshold is what stopped it. Emit a
WARN-level trace event so the skip is visible.

Assisted-by: Claude Opus 4.7 (1M context)
change punmuwzzmsmuyltmrrqpuokoxrtkntxm
commit 8b0b0e42f626e41612d3b44d7b9de2f5da45b4ee
author Alpha Chen <alpha@kejadlen.dev>
date
parent qslmqskv
diff --git a/src/ci/redact.rs b/src/ci/redact.rs
index 9c6fd35..21cee12 100644
--- a/src/ci/redact.rs
+++ b/src/ci/redact.rs
@@ -62,9 +62,11 @@ impl SecretRegistry {
     /// for redaction. Returns `Err` if the name isn't declared or
     /// the source can't be read.
     ///
-    /// Values shorter than 8 characters are cached for lookup but
-    /// not registered for redaction (high false-positive rate on
-    /// common short strings like "set", "yes", "true", "no").
+    /// Values shorter than 8 characters are returned to the caller
+    /// but not registered for redaction — the false-positive rate on
+    /// common short strings like "true" or "yes" is too high. A warn
+    /// is emitted so an operator can see why a short token is showing
+    /// up unredacted in CI output.
     pub fn resolve(&mut self, name: &str) -> super::error::Result<String> {
         let secret = self
             .declared
@@ -74,6 +76,12 @@ impl SecretRegistry {
         if value.len() >= 8 {
             self.revealed
                 .insert(name.to_string(), Revealed::new(value.clone()));
+        } else {
+            tracing::warn!(
+                secret = %name,
+                length = value.len(),
+                "secret value is shorter than the 8-byte minimum and will not be redacted from CI output"
+            );
         }
         Ok(value)
     }