commit cf5dadb4b3ef3c65c782c55faacacf81f981d47f
parent 5fa8b5e962ce3c7f6a601b14383f5c94792e4e4f
Author: triesap <tyson@radroots.org>
Date: Mon, 3 Aug 2026 07:27:05 +0000
transport-nostr: migrate workspace consumers
- Remove legacy Nostr client integration from predecessor default feature closures.
- Keep the private runtime and NostrDB adapters behind the governed removal gate.
- Enforce a source census against imports of the removed live-client API.
- Verify the complete default workspace and architecture contract gates.
Diffstat:
5 files changed, 98 insertions(+), 5 deletions(-)
diff --git a/crates/nostr_runtime/Cargo.toml b/crates/nostr_runtime/Cargo.toml
@@ -12,7 +12,7 @@ homepage.workspace = true
readme = "README"
[features]
-default = ["std", "nostr-client", "rt"]
+default = ["std"]
std = []
rt = ["std", "dep:futures", "dep:tokio"]
nostr-client = ["std", "dep:nostr", "dep:radroots_nostr", "dep:radroots_transport_nostr"]
diff --git a/crates/nostr_runtime/README b/crates/nostr_runtime/README
@@ -1,7 +1,10 @@
# radroots_nostr_runtime
-This is the README for `radroots_nostr_runtime`, which provides Nostr runtime
-coordination for the `radroots` core libraries.
+`radroots_nostr_runtime` is a private, publication-frozen predecessor package.
+Its former client/runtime integration is no longer active by default and must
+not receive new consumers. Final source/sink orchestration belongs to
+`radroots_sync`; the remaining opt-in predecessor surface is governed by
+`RCRV1-DEV-007` and must be removed at its sync-orchestration gate.
## Overview
@@ -10,7 +13,8 @@ coordination for the `radroots` core libraries.
models;
* sink abstractions and snapshot types used by higher-level network
orchestration;
- * feature-gated integration with client, runtime, and nostrdb adapter crates.
+ * quarantined feature-gated predecessor integration retained only for the
+ governed removal gate.
## Copyright
diff --git a/crates/nostr_runtime/src/types.rs b/crates/nostr_runtime/src/types.rs
@@ -1,9 +1,13 @@
use alloc::string::String;
+#[cfg(feature = "nostr-client")]
use nostr::PublicKey as RadrootsNostrPublicKey;
+#[cfg(feature = "nostr-client")]
use radroots_nostr::event::Timestamp as RadrootsNostrTimestamp;
+#[cfg(feature = "nostr-client")]
use radroots_nostr::event::post_filter;
#[cfg(feature = "nostr-client")]
use radroots_nostr::filter::Filter as RadrootsNostrFilter;
+#[cfg(feature = "nostr-client")]
use radroots_nostr::filter::kind as nostr_kind;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
diff --git a/crates/nostrdb/Cargo.toml b/crates/nostrdb/Cargo.toml
@@ -12,7 +12,7 @@ homepage.workspace = true
readme = "README"
[features]
-default = ["std", "rt", "nostrdb", "runtime-adapter"]
+default = ["std", "rt", "nostrdb"]
std = []
rt = ["std", "dep:futures", "dep:tokio"]
nostrdb = ["std", "dep:nostrdb"]
diff --git a/crates/transport_nostr/tests/workspace_consumers.rs b/crates/transport_nostr/tests/workspace_consumers.rs
@@ -0,0 +1,85 @@
+use std::fs;
+use std::path::{Path, PathBuf};
+
+const REMOVED_CLIENT_NAMES: [&str; 5] = [
+ "RadrootsNostrClient",
+ "RadrootsNostrClientKey",
+ "RadrootsNostrMonitor",
+ "RadrootsNostrMonitorNotification",
+ "RadrootsNostrRelayStatus",
+];
+
+#[test]
+fn ready_workspace_consumers_do_not_import_the_removed_client_surface() {
+ let workspace = workspace_root();
+ let allowed = [
+ workspace.join("crates/net/src"),
+ workspace.join("crates/nostr_runtime/src"),
+ ];
+
+ for source in rust_sources(workspace.join("crates")) {
+ if allowed.iter().any(|root| source.starts_with(root)) {
+ continue;
+ }
+ let contents = fs::read_to_string(&source).expect("read workspace source");
+ for removed in REMOVED_CLIENT_NAMES {
+ assert!(
+ !contents.contains(removed),
+ "ready consumer {} imports removed `{removed}`",
+ source.display()
+ );
+ }
+ }
+}
+
+#[test]
+fn predecessor_runtime_is_publish_frozen_and_not_default_reachable() {
+ let workspace = workspace_root();
+ let manifest = fs::read_to_string(workspace.join("crates/nostr_runtime/Cargo.toml"))
+ .expect("runtime manifest");
+ let nostrdb_manifest =
+ fs::read_to_string(workspace.join("crates/nostrdb/Cargo.toml")).expect("nostrdb manifest");
+ let readme =
+ fs::read_to_string(workspace.join("crates/nostr_runtime/README")).expect("runtime readme");
+ let deviations = fs::read_to_string(workspace.join("docs/implementation/deviations.toml"))
+ .expect("deviation authority");
+
+ assert!(manifest.contains("publish = false"));
+ assert!(manifest.contains("default = [\"std\"]"));
+ assert!(!manifest.contains("default = [\"std\", \"nostr-client\""));
+ assert!(
+ !nostrdb_manifest.contains("default = [\"std\", \"rt\", \"nostrdb\", \"runtime-adapter\"]")
+ );
+ assert!(readme.contains("RCRV1-DEV-007"));
+ assert!(readme.contains("radroots_sync"));
+ assert!(deviations.contains("id = \"RCRV1-DEV-007\""));
+ assert!(deviations.contains("affected_steps = [\"122\", \"170\", \"215\", \"235\", \"305\"]"));
+}
+
+fn workspace_root() -> PathBuf {
+ Path::new(env!("CARGO_MANIFEST_DIR"))
+ .join("../..")
+ .canonicalize()
+ .expect("workspace root")
+}
+
+fn rust_sources(root: PathBuf) -> Vec<PathBuf> {
+ let mut pending = vec![root];
+ let mut sources = Vec::new();
+ while let Some(path) = pending.pop() {
+ for entry in fs::read_dir(path).expect("read source directory") {
+ let path = entry.expect("source entry").path();
+ if path.is_dir() {
+ pending.push(path);
+ } else if path.extension().is_some_and(|extension| extension == "rs")
+ && path
+ .components()
+ .any(|component| component.as_os_str() == "src")
+ {
+ sources.push(path);
+ }
+ }
+ }
+ sources.sort();
+ sources
+}