commit 63c0baf12f49f3f298b17f3f87d425a204ca61ec
parent 40c40f1e592f7b999cc67be5d76e9a163bc97c42
Author: triesap <tyson@radroots.org>
Date: Sat, 1 Aug 2026 12:49:19 +0000
secrets: quarantine legacy packages
- mark predecessor crates as publish-frozen shims
- forbid new consumers and name the replacement
- hide compatibility crates from generated documentation
- enforce release classification and removal gates
Diffstat:
7 files changed, 95 insertions(+), 0 deletions(-)
diff --git a/crates/protected_store/Cargo.toml b/crates/protected_store/Cargo.toml
@@ -12,6 +12,13 @@ homepage.workspace = true
documentation = "https://docs.rs/radroots_protected_store"
readme = "README"
+[package.metadata.radroots.compatibility]
+status = "publish_frozen"
+replacement = "radroots_secrets"
+deviation = "RCRV1-DEV-008"
+removal_step = 313
+new_consumers_forbidden = true
+
[features]
default = []
std = ["radroots_secret_vault/std"]
diff --git a/crates/protected_store/README b/crates/protected_store/README
@@ -3,6 +3,11 @@
This is the README for `radroots_protected_store`, which provides authenticated
local store envelopes for the `radroots` core libraries.
+> Compatibility quarantine: this package is permanently `publish = false` and
+> must not gain new consumers. `radroots_secrets` is the replacement. Existing
+> first-party consumers migrate at their ordered release-refactor gates, and
+> Step 313 removes this package under `RCRV1-DEV-008`.
+
## Overview
* versioned envelope and header types for protected local records;
diff --git a/crates/protected_store/src/lib.rs b/crates/protected_store/src/lib.rs
@@ -1,5 +1,7 @@
#![forbid(unsafe_code)]
#![no_std]
+#![doc(hidden)]
+#![doc = "Publish-frozen compatibility crate; use `radroots_secrets` for new integrations."]
extern crate alloc;
#[cfg(any(feature = "std", test))]
diff --git a/crates/secret_vault/Cargo.toml b/crates/secret_vault/Cargo.toml
@@ -12,6 +12,13 @@ homepage.workspace = true
documentation = "https://docs.rs/radroots_secret_vault"
readme = "README"
+[package.metadata.radroots.compatibility]
+status = "publish_frozen"
+replacement = "radroots_secrets"
+deviation = "RCRV1-DEV-008"
+removal_step = 313
+new_consumers_forbidden = true
+
[features]
default = []
std = []
diff --git a/crates/secret_vault/README b/crates/secret_vault/README
@@ -3,6 +3,11 @@
This is the README for `radroots_secret_vault`, which provides secret backend
selection and wrapping semantics for the `radroots` core libraries.
+> Compatibility quarantine: this package is permanently `publish = false` and
+> must not gain new consumers. `radroots_secrets` is the replacement. Existing
+> first-party consumers migrate at their ordered release-refactor gates, and
+> Step 313 removes this package under `RCRV1-DEV-008`.
+
## Overview
* backend kinds, capability models, policy types, and selection outcomes for
diff --git a/crates/secret_vault/src/lib.rs b/crates/secret_vault/src/lib.rs
@@ -1,5 +1,7 @@
#![forbid(unsafe_code)]
#![no_std]
+#![doc(hidden)]
+#![doc = "Publish-frozen compatibility crate; use `radroots_secrets` for new integrations."]
extern crate alloc;
#[cfg(any(feature = "std", test))]
diff --git a/crates/secrets/tests/consumer_migration.rs b/crates/secrets/tests/consumer_migration.rs
@@ -3,6 +3,13 @@ use std::fs;
use std::path::{Path, PathBuf};
const DEVIATIONS: &str = include_str!("../../../docs/implementation/deviations.toml");
+const PUBLISH_POLICY: &str = include_str!("../../../contracts/releases/publish_policy.toml");
+const SECRET_VAULT_MANIFEST: &str = include_str!("../../secret_vault/Cargo.toml");
+const SECRET_VAULT_ROOT: &str = include_str!("../../secret_vault/src/lib.rs");
+const SECRET_VAULT_README: &str = include_str!("../../secret_vault/README");
+const PROTECTED_STORE_MANIFEST: &str = include_str!("../../protected_store/Cargo.toml");
+const PROTECTED_STORE_ROOT: &str = include_str!("../../protected_store/src/lib.rs");
+const PROTECTED_STORE_README: &str = include_str!("../../protected_store/README");
#[test]
fn legacy_secret_dependencies_are_confined_to_publish_frozen_quarantines() {
@@ -57,6 +64,66 @@ fn quarantine_has_exact_future_removal_gates() {
}
}
+#[test]
+fn superseded_packages_are_fail_closed_compatibility_quarantines() {
+ for (package, manifest, root, readme) in [
+ (
+ "radroots_secret_vault",
+ SECRET_VAULT_MANIFEST,
+ SECRET_VAULT_ROOT,
+ SECRET_VAULT_README,
+ ),
+ (
+ "radroots_protected_store",
+ PROTECTED_STORE_MANIFEST,
+ PROTECTED_STORE_ROOT,
+ PROTECTED_STORE_README,
+ ),
+ ] {
+ for required in [
+ "publish = false",
+ "[package.metadata.radroots.compatibility]",
+ "status = \"publish_frozen\"",
+ "replacement = \"radroots_secrets\"",
+ "deviation = \"RCRV1-DEV-008\"",
+ "removal_step = 313",
+ "new_consumers_forbidden = true",
+ ] {
+ assert!(
+ manifest.contains(required),
+ "{package} manifest is missing `{required}`"
+ );
+ }
+ assert!(root.contains("#![doc(hidden)]"));
+ assert!(root.contains("use `radroots_secrets` for new integrations"));
+ assert!(readme.contains("Compatibility quarantine"));
+ assert!(readme.contains("Step 313 removes this package"));
+ }
+
+ let approved = PUBLISH_POLICY
+ .split_once("[workspace_classification]")
+ .map(|(publication, _)| publication)
+ .expect("workspace classification");
+ for package in ["radroots_secret_vault", "radroots_protected_store"] {
+ assert!(
+ !approved.contains(package),
+ "compatibility package cannot enter the approved release inventory: {package}"
+ );
+ }
+
+ let private = PUBLISH_POLICY
+ .split_once("private = [")
+ .and_then(|(_, rest)| rest.split_once(']'))
+ .map(|(entries, _)| entries)
+ .expect("private package classification");
+ for package in ["radroots_secret_vault", "radroots_protected_store"] {
+ assert!(
+ private.contains(&format!("\"{package}\"")),
+ "compatibility package must remain private: {package}"
+ );
+ }
+}
+
fn collect_manifests(root: &Path, manifests: &mut Vec<PathBuf>) {
for entry in fs::read_dir(root).expect("read crates directory") {
let path = entry.expect("crate entry").path();