Stop claiming we zeroize revealed secret values
The manual `impl Drop for Revealed` overwrote bytes in a way LLVM is
free to elide (no `ptr::write_volatile`, no compiler fence), so it
provided no real memory protection. More importantly, it gave the
appearance of a defense quire doesn't actually have: copies live in
the original `String` returned by `reveal`, in Lua VM internals, and
in intermediate `format!` allocations along the way — none zeroized.

Drop the half-measure and update the module doc to be honest about
what's protected (the `Debug` impl on `Revealed`, so values can't
accidentally print) and what isn't (memory after `reveal`).

Backing storage is `String` again, since the `Vec<u8>` indirection
was only there to feed the manual zero-loop.

Assisted-by: Claude Opus 4.7 (1M context)
change qslmqskvurtxxuuwtroszornssrxpvxy
commit 832d1124a08f72a85ad5de48527fb727c1d7a327
author Alpha Chen <alpha@kejadlen.dev>
date
parent tnprtxsl
diff --git a/src/ci/redact.rs b/src/ci/redact.rs
index 9f76862..9c6fd35 100644
--- a/src/ci/redact.rs
+++ b/src/ci/redact.rs
@@ -5,35 +5,28 @@
 //! replaces the previous split between `Runtime.secrets` and a
 //! separate redaction registry.
 //!
-//! Revealed values are stored opaquely (no [`Debug`] impl, manual
-//! [`Drop`] that overwrites bytes) to avoid re-introducing the secret
-//! in debug output or core dumps. This mirrors the protections in
-//! `crate::secret::SecretString`.
+//! [`Revealed`] is an opaque wrapper without a [`Debug`] impl, so a
+//! revealed value can't accidentally land in `tracing::debug!` or a
+//! panic message. That's the only memory-side protection here: copies
+//! made earlier in the pipeline (the `String` returned by `reveal`,
+//! Lua VM internals, intermediate `format!` allocations) aren't
+//! zeroized, so the registry is best thought of as preventing
+//! accidental display, not preventing memory disclosure.
 
 use std::collections::HashMap;
 
 use crate::secret::SecretString;
 
-/// Opaque wrapper for a revealed secret value.
-/// Zeroes its heap buffer on drop. No Debug impl.
-struct Revealed(Vec<u8>);
+/// Opaque wrapper for a revealed secret value. No Debug impl.
+struct Revealed(String);
 
 impl Revealed {
     fn new(value: String) -> Self {
-        Self(value.into_bytes())
+        Self(value)
     }
 
     fn as_str(&self) -> &str {
-        // Values were constructed from valid UTF-8 strings.
-        std::str::from_utf8(&self.0).unwrap_or("")
-    }
-}
-
-impl Drop for Revealed {
-    fn drop(&mut self) {
-        for byte in self.0.iter_mut() {
-            *byte = 0;
-        }
+        &self.0
     }
 }