sdk

Radroots SDK and bindings
git clone https://radroots.dev/git/sdk.git
Log | Files | Refs | README

commit 9aa7d727eff8cc342fe698f53903e1339772ebf0
parent 267e76547d08db145df6133dc2e8ffbf25b48e50
Author: triesap <tyson@radroots.org>
Date:   Sat,  1 Aug 2026 11:57:54 +0000

secrets: migrate workspace consumers

- activate the final SDK secrets dependency edge
- confine predecessor imports to private storage
- enforce the SDK source migration boundary
- record ordered storage and removal gates

Diffstat:
M.cargo/config.toml | 1+
MCargo.lock | 9+++++++++
MCargo.toml | 1+
Mcrates/sdk/Cargo.toml | 8+++++++-
Mcrates/sdk/src/private_store.rs | 4++++
Acrates/sdk/tests/secrets_migration_boundary.rs | 62++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mdocs/implementation/DEVIATIONS.md | 1+
Mdocs/implementation/deviations.toml | 25+++++++++++++++++++++++++
8 files changed, 110 insertions(+), 1 deletion(-)

diff --git a/.cargo/config.toml b/.cargo/config.toml @@ -21,6 +21,7 @@ radroots_protocol = { path = "../lib/crates/protocol" } radroots_protocol_contract_v1 = { path = "../lib/crates/protocol_contract_v1" } radroots_protected_store = { path = "../lib/crates/protected_store" } radroots_secret_vault = { path = "../lib/crates/secret_vault" } +radroots_secrets = { path = "../lib/crates/secrets" } radroots_signing = { path = "../lib/crates/signing" } radroots_transport = { path = "../lib/crates/transport" } radroots_transport_nostr = { path = "../lib/crates/transport_nostr" } diff --git a/Cargo.lock b/Cargo.lock @@ -2362,6 +2362,7 @@ dependencies = [ "radroots_replica_sync", "radroots_runtime_paths", "radroots_secret_vault", + "radroots_secrets", "radroots_signing", "radroots_sql_core", "radroots_trade", @@ -2418,6 +2419,14 @@ name = "radroots_secret_vault" version = "0.1.0-alpha" [[package]] +name = "radroots_secrets" +version = "0.1.0-alpha" +dependencies = [ + "chacha20poly1305", + "zeroize", +] + +[[package]] name = "radroots_signing" version = "0.1.0-alpha" dependencies = [ diff --git a/Cargo.toml b/Cargo.toml @@ -67,6 +67,7 @@ radroots_protocol_contract_v1 = { version = "=0.1.0-alpha", default-features = f radroots_protected_store = { version = "=0.1.0-alpha", default-features = false } radroots_runtime_contract_v1 = { path = "crates/runtime_contract_v1", version = "=0.1.0-alpha", default-features = false } radroots_secret_vault = { version = "=0.1.0-alpha", default-features = false } +radroots_secrets = { package = "radroots_secrets", version = "=0.1.0-alpha", default-features = false } radroots_signing = { package = "radroots_signing", version = "=0.1.0-alpha", default-features = false } radroots_transport = { package = "radroots_transport", version = "=0.1.0-alpha", default-features = false } radroots_transport_nostr = { package = "radroots_transport_nostr", version = "=0.1.0-alpha", default-features = false } diff --git a/crates/sdk/Cargo.toml b/crates/sdk/Cargo.toml @@ -114,7 +114,12 @@ runtime = [ "radroots_transport_nostr/storage", "radroots_transport_nostr/runtime-tokio", ] -local-signer = ["runtime", "signing", "radroots_nostr/signing"] +local-signer = [ + "runtime", + "signing", + "dep:radroots_secrets", + "radroots_nostr/signing", +] transport-nostr-runtime = [ "runtime", "dep:radroots_nostr", @@ -157,6 +162,7 @@ radroots_transport_nostr = { workspace = true, optional = true, default-features radroots_transport_reticulum = { workspace = true, optional = true, default-features = false } radroots_runtime_paths = { workspace = true, optional = true, default-features = false } radroots_secret_vault = { workspace = true, optional = true, default-features = false } +radroots_secrets = { workspace = true, optional = true, default-features = false } radroots_signing = { workspace = true, default-features = false } radroots_trade = { workspace = true, default-features = false } radroots_identity = { workspace = true, default-features = false } diff --git a/crates/sdk/src/private_store.rs b/crates/sdk/src/private_store.rs @@ -1,5 +1,9 @@ #![cfg(feature = "runtime")] +// RCRV1-DEV-008: this module is the sole SDK quarantine for predecessor secret +// storage until Step 179 transfers the private store into radroots_storage_sqlite. +// New SDK secret integrations must use radroots_secrets. + use crate::RadrootsSdkError; use radroots_event::envelope::kind::KIND_FARM; use radroots_event::id::{AddressableCoordinate, AddressableCoordinateParts}; diff --git a/crates/sdk/tests/secrets_migration_boundary.rs b/crates/sdk/tests/secrets_migration_boundary.rs @@ -0,0 +1,62 @@ +use std::fs; +use std::path::Path; + +const ROOT_MANIFEST: &str = include_str!("../../../Cargo.toml"); +const PACKAGE_MANIFEST: &str = include_str!("../Cargo.toml"); +const CARGO_CONFIG: &str = include_str!("../../../.cargo/config.toml"); +const PRIVATE_STORE: &str = include_str!("../src/private_store.rs"); +const DEVIATIONS: &str = include_str!("../../../docs/implementation/deviations.toml"); + +#[test] +fn final_secret_dependency_is_activated_at_the_sdk_boundary() { + assert!(ROOT_MANIFEST.contains( + "radroots_secrets = { package = \"radroots_secrets\", version = \"=0.1.0-alpha\", default-features = false }" + )); + assert!(PACKAGE_MANIFEST.contains( + "radroots_secrets = { workspace = true, optional = true, default-features = false }" + )); + assert!(PACKAGE_MANIFEST.contains("\"dep:radroots_secrets\"")); + assert!(CARGO_CONFIG.contains("radroots_secrets = { path = \"../lib/crates/secrets\" }")); +} + +#[test] +fn predecessor_secret_imports_are_confined_to_the_private_store_quarantine() { + let source_root = Path::new(env!("CARGO_MANIFEST_DIR")).join("src"); + let mut legacy_sources = Vec::new(); + collect_rust_sources(&source_root, &mut legacy_sources); + legacy_sources.retain(|path| { + let source = fs::read_to_string(path).expect("read SDK source"); + source.contains("radroots_protected_store") || source.contains("radroots_secret_vault") + }); + + assert_eq!(legacy_sources, vec![source_root.join("private_store.rs")]); + assert!(PRIVATE_STORE.contains("RCRV1-DEV-008")); + assert!(PRIVATE_STORE.contains("Step 179 transfers the private store")); +} + +#[test] +fn quarantine_has_exact_future_removal_gates() { + for required in [ + "id = \"RCRV1-DEV-008\"", + "affected_steps = [\"153\", \"155\", \"171\", \"179\", \"226\", \"288\", \"293\", \"313\"]", + "Step 179 transfers canonical private storage", + "Step 313 removes every remaining compatibility package and legacy name", + ] { + assert!( + DEVIATIONS.contains(required), + "secret consumer quarantine is missing `{required}`" + ); + } +} + +fn collect_rust_sources(root: &Path, sources: &mut Vec<std::path::PathBuf>) { + for entry in fs::read_dir(root).expect("read SDK source directory") { + let path = entry.expect("SDK source entry").path(); + if path.is_dir() { + collect_rust_sources(&path, sources); + } else if path.extension().is_some_and(|extension| extension == "rs") { + sources.push(path); + } + } + sources.sort(); +} diff --git a/docs/implementation/DEVIATIONS.md b/docs/implementation/DEVIATIONS.md @@ -14,6 +14,7 @@ silently change `radroots.crates.release.v1`. | `RCRV1-DEV-005` | 013, 019-026, 226, 247, 249-268, 305 | Pin every Rust crate and internal Radroots dependency in `radrootslabs/sdk` to exactly `0.1.0-alpha` until further explicit authority. | | `RCRV1-DEV-006` | 073, 261-268 | Retire public event/trade codegen edges now and authenticate the predecessor TypeScript snapshots until their scheduled protocol/codec replacement. | | `RCRV1-DEV-007` | 122, 170, 235, 305 | Remove the predecessor monolithic transport SPI now; quarantine publish-frozen runtime, SDK, CLI, and daemon consumer shims until their explicit removal gates. | +| `RCRV1-DEV-008` | 153, 155, 171, 179, 226, 288, 293, 313 | Activate final secrets dependency edges now; quarantine legacy vault/store consumers until their ordered storage, SDK, downstream, and final-removal gates. | ## Record template diff --git a/docs/implementation/deviations.toml b/docs/implementation/deviations.toml @@ -2,6 +2,31 @@ schema_version = 1 architecture_id = "radroots.crates.release.v1" [[deviation]] +id = "RCRV1-DEV-008" +date = "2026-08-01" +status = "active" +approval = "All code-review recommendations and the full multi-RCLD implementation sequence were explicitly approved by the user." +affected_steps = ["153", "155", "171", "179", "226", "288", "293", "313"] +spec_anchors = [ + "docs/specs/radroots_crates_release_v1.md#12-radroots_secrets", + "docs/specs/radroots_crates_release_v1.md#20-current-to-target-migration-map", +] +source_evidence = [ + "Step 179, not Step 153, owns transfer of the current SDK private database and its encrypted records into canonical SQLite storage.", + "The SDK can activate the final radroots_secrets dependency now while its private_store module remains the sole predecessor secret-store quarantine.", + "Mixed publish-frozen runtime, Myc, and other external hosts still require predecessor vault/store behavior until their ordered migration steps.", +] +replacement_action = "Activate the final optional radroots_secrets edge in Step 153; confine predecessor vault/store imports to private_store.rs; Step 179 transfers canonical private storage, Steps 226/288/293 migrate the remaining SDK and downstream consumers, and Step 313 removes every remaining compatibility package and legacy name." +verification = [ + "SDK source-boundary tests confine predecessor imports to private_store.rs and require the final optional radroots_secrets dependency edge.", + "The local-signer feature activates radroots_secrets without changing the current runtime storage implementation before Step 179.", + "Step 155 release-policy validation keeps every quarantine package non-publishable until its exact removal gate.", +] +unresolved_risk = "Publish-frozen compatibility code remains reachable inside the SDK private-store path until Steps 179, 226, 288, 293, and 313; no package-realistic publication may proceed while it remains." +normative_architecture_change = false +adr_required = false + +[[deviation]] id = "RCRV1-DEV-001" date = "2026-07-27" status = "active"