commit a86d62821f7fe0eb50cf11dfe0dd5c4b7bc6b9cb
parent 8c509998e9e2b6350363b9b9998b01fe3e39c1a9
Author: triesap <tyson@radroots.org>
Date: Tue, 28 Jul 2026 20:15:15 +0000
protocol: quarantine superseded package surface
- migrate SDK production consumers to the final versioned protocol modules
- remove the retired runtime reexport and transport-publish dependency
- retain the private runtime shim only through the Step 270 CLI cutover
- record release classification, consumer evidence, and removal authority
Diffstat:
17 files changed, 112 insertions(+), 91 deletions(-)
diff --git a/.cargo/config.toml b/.cargo/config.toml
@@ -18,11 +18,11 @@ radroots_nostr = { path = "../lib/crates/nostr" }
radroots_nostr_connect = { path = "../lib/crates/nostr_connect" }
radroots_nostr_signer = { path = "../lib/crates/nostr_signer" }
radroots_outbox = { path = "../lib/crates/outbox" }
+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_transport = { path = "../lib/crates/transport" }
-radroots_transport_publish_protocol = { path = "../lib/crates/transport_publish_protocol" }
radroots_transport_nostr = { path = "../lib/crates/transport_nostr" }
radroots_transport_reticulum = { path = "../lib/crates/transport_reticulum" }
radroots_replica_store = { path = "../lib/crates/replica_store" }
diff --git a/Cargo.lock b/Cargo.lock
@@ -2003,6 +2003,7 @@ dependencies = [
"radroots_blossom",
"radroots_core",
"radroots_identity",
+ "radroots_protocol",
"secp256k1",
"serde",
"serde_json",
@@ -2199,6 +2200,13 @@ dependencies = [
]
[[package]]
+name = "radroots_protocol"
+version = "0.1.0-alpha"
+dependencies = [
+ "serde",
+]
+
+[[package]]
name = "radroots_protocol_contract_v1"
version = "0.1.0-alpha"
dependencies = [
@@ -2342,17 +2350,16 @@ dependencies = [
"radroots_nostr_signer",
"radroots_outbox",
"radroots_protected_store",
+ "radroots_protocol",
"radroots_replica_schema",
"radroots_replica_store",
"radroots_replica_sync",
- "radroots_runtime_contract_v1",
"radroots_runtime_paths",
"radroots_secret_vault",
"radroots_sql_core",
"radroots_trade",
"radroots_transport",
"radroots_transport_nostr",
- "radroots_transport_publish_protocol",
"radroots_transport_reticulum",
"reqwest",
"serde",
@@ -2472,14 +2479,6 @@ dependencies = [
]
[[package]]
-name = "radroots_transport_publish_protocol"
-version = "0.1.0-alpha"
-dependencies = [
- "radroots_transport",
- "serde",
-]
-
-[[package]]
name = "radroots_transport_reticulum"
version = "0.1.0-alpha"
dependencies = [
diff --git a/Cargo.toml b/Cargo.toml
@@ -63,12 +63,12 @@ radroots_nostr = { package = "radroots_nostr", version = "=0.1.0-alpha", default
radroots_nostr_connect = { package = "radroots_nostr_connect", version = "=0.1.0-alpha", default-features = false }
radroots_nostr_signer = { version = "=0.1.0-alpha", default-features = false }
radroots_outbox = { version = "=0.1.0-alpha", default-features = false }
+radroots_protocol = { version = "=0.1.0-alpha", default-features = false }
radroots_protocol_contract_v1 = { version = "=0.1.0-alpha", default-features = false }
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_transport = { package = "radroots_transport", version = "=0.1.0-alpha", default-features = false }
-radroots_transport_publish_protocol = { version = "=0.1.0-alpha", default-features = false }
radroots_transport_nostr = { package = "radroots_transport_nostr", version = "=0.1.0-alpha", default-features = false }
radroots_transport_reticulum = { version = "=0.1.0-alpha", default-features = false }
radroots_replica_store = { version = "=0.1.0-alpha", default-features = false }
diff --git a/contracts/releases/publication.toml b/contracts/releases/publication.toml
@@ -46,7 +46,7 @@ external_packages = [
]
[workspace_classification]
-private = ["radroots_runtime_contract_v1"]
+private = []
build_codegen = [
"radroots_core_bindings",
"radroots_event_bindings",
@@ -62,4 +62,4 @@ build_codegen = [
]
test_support = []
preview = []
-retired = []
+retired = ["radroots_runtime_contract_v1"]
diff --git a/crates/runtime_contract_v1/Cargo.toml b/crates/runtime_contract_v1/Cargo.toml
@@ -1,7 +1,7 @@
[package]
name = "radroots_runtime_contract_v1"
publish = false
-description = "Runtime Contract V1 descriptors for Radroots SDK hosts"
+description = "Private compatibility shim for legacy Radroots runtime-contract consumers"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
diff --git a/crates/runtime_contract_v1/README b/crates/runtime_contract_v1/README
@@ -1,13 +1,19 @@
# radroots_runtime_contract_v1
-This is the README for `radroots_runtime_contract_v1`, which contains Runtime Contract V1 descriptors, envelopes, error codes, request digest models, approval proof models, and transaction metadata for SDK-owned hosts.
+Private compatibility shim for first-party consumers that have not yet moved
+to `radroots_protocol::runtime::v1`.
-## Copyright
+This package is retired from the public crate architecture and remains
+`publish = false`. New SDK code must use `radroots_protocol` directly. The
+shim remains only for the CLI registry generator and the standalone `oss/cli`
+consumer; Step 270 removes those final dependencies and deletes this package.
-Except as otherwise noted, all files in the `radroots_runtime_contract_v1` distribution are
+## Copyright
- Copyright (c) 2026 Tyson Lupul
+Except as otherwise noted, all files in this distribution are Copyright (c)
+2026 Tyson Lupul.
## License
-This repository is licensed under either MIT or Apache-2.0, at your option. See LICENSE-MIT and LICENSE-APACHE.
+Licensed under either MIT or Apache-2.0, at your option. See `LICENSE-MIT` and
+`LICENSE-APACHE`.
diff --git a/crates/sdk/Cargo.toml b/crates/sdk/Cargo.toml
@@ -19,13 +19,11 @@ default = ["std", "serde", "serde_json", "identity-models"]
std = [
"radroots_event/std",
"radroots_event_codec/std",
- "radroots_runtime_contract_v1/std",
"radroots_trade/std",
]
serde = [
"dep:serde",
"radroots_event/serde",
- "radroots_runtime_contract_v1/serde",
"radroots_trade/serde",
]
serde_json = [
@@ -52,13 +50,13 @@ radrootsd-execution = [
"std",
"serde_json",
"dep:futures",
+ "dep:radroots_protocol",
"dep:radroots_transport",
- "dep:radroots_transport_publish_protocol",
"dep:radroots_transport_nostr",
"dep:reqwest",
+ "radroots_protocol/serde",
+ "radroots_protocol/std",
"radroots_transport/serde",
- "radroots_transport_publish_protocol/serde",
- "radroots_transport_publish_protocol/std",
"radroots_transport_nostr/std",
]
signer-adapters = [
@@ -142,14 +140,13 @@ radroots_event = { workspace = true, default-features = false }
radroots_event_codec = { workspace = true, default-features = false }
radroots_geocoder = { workspace = true, optional = true }
radroots_outbox = { workspace = true, optional = true, default-features = false }
+radroots_protocol = { workspace = true, optional = true, default-features = false }
radroots_protected_store = { workspace = true, optional = true, default-features = false }
radroots_transport = { workspace = true, optional = true, default-features = false }
-radroots_transport_publish_protocol = { workspace = true, optional = true, default-features = false }
radroots_transport_nostr = { workspace = true, optional = true, default-features = false }
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_runtime_contract_v1 = { path = "../runtime_contract_v1", version = "=0.1.0-alpha", default-features = false }
radroots_trade = { workspace = true, default-features = false }
radroots_identity = { workspace = true, default-features = false }
radroots_nostr = { workspace = true, optional = true, default-features = false }
diff --git a/crates/sdk/src/adapters/radrootsd.rs b/crates/sdk/src/adapters/radrootsd.rs
@@ -2,9 +2,10 @@ use core::fmt;
use core::time::Duration;
use radroots_event::draft::RadrootsSignedEvent;
-use radroots_transport_publish_protocol::{
- METHOD_EVENT, TransportPublishDeliveryPolicy, TransportPublishEventRequest,
- TransportPublishEventResponse, TransportPublishProtocolError, TransportPublishTargetPolicy,
+use radroots_protocol::radrootsd::transport_publish::v5::{
+ DeliveryPolicy as TransportPublishDeliveryPolicy, Error as TransportPublishProtocolError,
+ EventRequest as TransportPublishEventRequest, EventResponse as TransportPublishEventResponse,
+ METHOD_EVENT, TargetPolicy as TransportPublishTargetPolicy,
};
use reqwest::header::{AUTHORIZATION, CONTENT_TYPE, HeaderMap, HeaderValue};
use serde::{Deserialize, Serialize, de::DeserializeOwned};
diff --git a/crates/sdk/src/lib.rs b/crates/sdk/src/lib.rs
@@ -55,8 +55,6 @@ pub mod transport;
#[cfg(feature = "runtime")]
mod workflow_runtime;
-pub use radroots_runtime_contract_v1 as runtime_contract_v1;
-
#[cfg(feature = "runtime")]
pub use crate::error::{
RADROOTS_SDK_ERROR_CATALOG, RadrootsSdkError, RadrootsSdkErrorCatalogEntry,
diff --git a/crates/sdk/src/sync_runtime.rs b/crates/sdk/src/sync_runtime.rs
@@ -24,6 +24,13 @@ use radroots_outbox::{
RadrootsOutboxDeliveryTargetRecord, RadrootsOutboxDeliveryTargetStatus,
RadrootsOutboxEventState, RadrootsOutboxReticulumEventRecord, RadrootsOutboxStatusSummary,
};
+#[cfg(all(feature = "runtime", feature = "radrootsd-execution"))]
+use radroots_protocol::radrootsd::transport_publish::v5::{
+ DeliveryPolicy as TransportPublishDeliveryPolicy, Job as TransportPublishJobView,
+ JobStatus as TransportPublishJobStatus, OutcomeKind as TransportPublishOutcomeKind,
+ Target as TransportPublishTarget, TargetFingerprint as TransportPublishTargetFingerprint,
+ TargetOutcome as TransportPublishTargetOutcome, TargetPolicy as TransportPublishTargetPolicy,
+};
#[cfg(feature = "runtime")]
use radroots_trade::workflow::{
RADROOTS_TRADE_REDUCER_CONTRACT_ID, RADROOTS_TRADE_REDUCER_VERSION,
@@ -46,12 +53,6 @@ use radroots_transport_nostr::{
RadrootsOutboxPublishPolicy, RadrootsOutboxPublishReceipt, RadrootsOutboxPublishTargetReceipt,
RadrootsRelayOutcomeKind, publish_claimed_outbox_event_with_transport,
};
-#[cfg(all(feature = "runtime", feature = "radrootsd-execution"))]
-use radroots_transport_publish_protocol::{
- TransportPublishDeliveryPolicy, TransportPublishJobStatus, TransportPublishJobView,
- TransportPublishOutcomeKind, TransportPublishTarget, TransportPublishTargetOutcome,
- TransportPublishTargetPolicy,
-};
#[cfg(feature = "runtime")]
use sha2::{Digest, Sha256};
@@ -1338,16 +1339,22 @@ fn radrootsd_delivery_policy_from_remaining(
RadrootsTransportSatisfactionPolicy::Any { .. } => TransportPublishDeliveryPolicy::Any,
RadrootsTransportSatisfactionPolicy::All { .. } => TransportPublishDeliveryPolicy::All,
RadrootsTransportSatisfactionPolicy::RequiredTargets { .. } => {
- TransportPublishDeliveryPolicy::required_targets(
- required_remaining_targets
- .ok_or_else(|| RadrootsSdkError::InvalidRequest {
- message: "radrootsd publish missing required target fingerprints"
- .to_owned(),
- })?
- .to_vec(),
- )
- .map_err(|error| RadrootsSdkError::InvalidRequest {
- message: error.to_string(),
+ let targets = required_remaining_targets
+ .ok_or_else(|| RadrootsSdkError::InvalidRequest {
+ message: "radrootsd publish missing required target fingerprints".to_owned(),
+ })?
+ .iter()
+ .map(|fingerprint| {
+ TransportPublishTargetFingerprint::parse(fingerprint.as_str().to_owned())
+ .map_err(|error| RadrootsSdkError::InvalidRequest {
+ message: error.to_string(),
+ })
+ })
+ .collect::<Result<Vec<_>, _>>()?;
+ TransportPublishDeliveryPolicy::required_targets(targets).map_err(|error| {
+ RadrootsSdkError::InvalidRequest {
+ message: error.to_string(),
+ }
})?
}
RadrootsTransportSatisfactionPolicy::Quorum { .. } => {
diff --git a/crates/sdk/tests/runtime_contract_public_api.rs b/crates/sdk/tests/runtime_contract_public_api.rs
@@ -1,26 +0,0 @@
-use radroots_sdk::runtime_contract_v1::{
- RuntimeOperationIdV1, TransportKindV1, operation_descriptor, validate_runtime_contract_v1,
-};
-
-#[test]
-fn runtime_contract_v1_is_public_through_sdk_surface() {
- validate_runtime_contract_v1().expect("runtime contract validates");
-
- let descriptor = operation_descriptor(RuntimeOperationIdV1::TransportDeliveryRetry)
- .expect("delivery retry descriptor");
-
- assert!(
- descriptor
- .transport_capability
- .includes_transport(TransportKindV1::Nostr)
- );
- assert!(
- descriptor
- .transport_capability
- .includes_transport(TransportKindV1::Reticulum)
- );
- assert!(matches!(
- TransportKindV1::parse("reticulum"),
- Ok(TransportKindV1::Reticulum)
- ));
-}
diff --git a/crates/sdk/tests/unit/adapters_radrootsd_tests.rs b/crates/sdk/tests/unit/adapters_radrootsd_tests.rs
@@ -1,12 +1,16 @@
use super::*;
use radroots_event::wire::RadrootsNip01EventWire;
-use radroots_transport::RADROOTS_RETICULUM_ENDPOINT_URI;
-use radroots_transport_publish_protocol::{
- NostrPublishTargetSourcePolicy, TransportPublishDeliveryPolicy, TransportPublishEventRequest,
- TransportPublishEventResponse, TransportPublishJobStatus, TransportPublishJobView,
- TransportPublishOutcomeKind, TransportPublishReticulumBehavior, TransportPublishTarget,
- TransportPublishTargetOutcome, TransportPublishTargetPolicy, TransportPublishTargetSource,
+use radroots_protocol::radrootsd::transport_publish::v5::{
+ DeliveryPolicy as TransportPublishDeliveryPolicy, EventRequest as TransportPublishEventRequest,
+ EventResponse as TransportPublishEventResponse, Job as TransportPublishJobView,
+ JobStatus as TransportPublishJobStatus,
+ NostrTargetSourcePolicy as NostrPublishTargetSourcePolicy,
+ OutcomeKind as TransportPublishOutcomeKind,
+ ReticulumBehavior as TransportPublishReticulumBehavior, Target as TransportPublishTarget,
+ TargetOutcome as TransportPublishTargetOutcome, TargetPolicy as TransportPublishTargetPolicy,
+ TargetSource as TransportPublishTargetSource,
};
+use radroots_transport::RADROOTS_RETICULUM_ENDPOINT_URI;
use std::io::{Read, Write};
use std::net::TcpListener;
use std::thread::JoinHandle;
diff --git a/crates/sdk/tests/unit/sync_runtime_tests.rs b/crates/sdk/tests/unit/sync_runtime_tests.rs
@@ -42,6 +42,16 @@ use radroots_outbox::{
use radroots_outbox::{
RadrootsOutboxEventState, RadrootsOutboxEventStoreIngestReceipt, RadrootsOutboxStatusSummary,
};
+#[cfg(feature = "radrootsd-execution")]
+use radroots_protocol::radrootsd::transport_publish::v5::{
+ DeliveryPolicy as TransportPublishDeliveryPolicy, Job as TransportPublishJobView,
+ JobStatus as TransportPublishJobStatus,
+ NostrTargetSourcePolicy as NostrPublishTargetSourcePolicy,
+ OutcomeKind as TransportPublishOutcomeKind, Target as TransportPublishTarget,
+ TargetFingerprint as TransportPublishTargetFingerprint,
+ TargetOutcome as TransportPublishTargetOutcome, TargetPolicy as TransportPublishTargetPolicy,
+ TargetSource as TransportPublishTargetSource,
+};
use radroots_transport::{
RadrootsTransportDeliveryTargetStatus, RadrootsTransportMeshScopeId, RadrootsTransportTarget,
RadrootsTransportTargetLabel,
@@ -53,12 +63,6 @@ use radroots_transport_nostr::{
RadrootsRelayOutcomeKind, RadrootsRelayPublishAdapter, RadrootsRelayPublishRelayReceipt,
RadrootsRelayPublishRequest, RadrootsRelayTransportError,
};
-#[cfg(feature = "radrootsd-execution")]
-use radroots_transport_publish_protocol::{
- NostrPublishTargetSourcePolicy, TransportPublishDeliveryPolicy, TransportPublishJobStatus,
- TransportPublishJobView, TransportPublishOutcomeKind, TransportPublishTarget,
- TransportPublishTargetOutcome, TransportPublishTargetPolicy, TransportPublishTargetSource,
-};
use std::collections::BTreeSet;
#[cfg(feature = "radrootsd-execution")]
use std::io::ErrorKind;
@@ -886,10 +890,19 @@ async fn radrootsd_push_empty_queue_and_private_helpers_are_deterministic() {
.expect("required remaining targets")
.expect("required target policy");
assert_eq!(remaining, vec![second_required.fingerprint().clone()]);
+ let protocol_remaining = remaining
+ .iter()
+ .map(|fingerprint| {
+ TransportPublishTargetFingerprint::parse(fingerprint.as_str().to_owned())
+ .expect("protocol target fingerprint")
+ })
+ .collect();
assert_eq!(
radrootsd_delivery_policy_from_remaining(2, remaining.len(), Some(&remaining), &policy)
.expect("required target radrootsd policy"),
- TransportPublishDeliveryPolicy::RequiredTargets { targets: remaining }
+ TransportPublishDeliveryPolicy::RequiredTargets {
+ targets: protocol_remaining
+ }
);
assert!(matches!(
radrootsd_delivery_policy_from_remaining(0, 1, Some(&[]), &policy),
diff --git a/docs/implementation/COMPATIBILITY_SHIMS.md b/docs/implementation/COMPATIBILITY_SHIMS.md
@@ -0,0 +1,21 @@
+# Compatibility shim quarantine
+
+Step 064 retires version-suffixed packages from the public crate architecture.
+The remaining package is a private, non-publishable bridge only; it is not a
+second protocol authority.
+
+| Shim | Final owner | Remaining consumers | Final removal |
+| --- | --- | --- | --- |
+| `radroots_runtime_contract_v1` | `radroots_protocol::runtime::v1` | SDK CLI-host generator; standalone `oss/cli` runtime registry and command code | Step 270 |
+
+The `radroots_sdk` library no longer depends on or reexports the runtime shim.
+Its radrootsd execution path also consumes
+`radroots_protocol::radrootsd::transport_publish::v5` directly instead of the
+separate transport-publish package. Repository publication policy classifies
+the retained runtime shim as `retired`, and its manifest keeps
+`publish = false`.
+
+Source searches at this checkpoint also found the transport-publish shim in
+standalone `oss/radrootsd` and the runtime/protocol shims in standalone
+`oss/cli`; those consumers are assigned to Steps 286 and 270 respectively.
+No new consumer may be added before those cutovers.
diff --git a/docs/implementation/TRACEABILITY.md b/docs/implementation/TRACEABILITY.md
@@ -11,6 +11,7 @@ and verification. It adds no product requirements; the synchronized
| Public-only identity and separated signing/secrets | `radroots_identity`, `radroots_signing`, `radroots_secrets` | 052-054, 099-111, 147-155 | public API, feature, dependency, and redaction tests |
| One canonical `TradeId` | `radroots_event`, `radroots_trade` | 073-098 | compile/API inventory and trade conformance |
| Version-neutral protocol ownership | `radroots_protocol` and private generators | 055-064, 261-268 | contract vectors and generated freshness |
+| Superseded protocol packages are quarantined and removed | retired compatibility shims | 064, 270, 286 | release classification, source search, and final-removal evidence |
| Independent transport source/sink with extensible identity | `radroots_transport` and adapters | 112-134, 190-207 | transport conformance and forward-compatibility fixtures |
| Storage SPI with SQLite backend | `radroots_storage`, `radroots_storage_sqlite` | 156-189 | backend conformance, migration, recovery, and leakage gates |
| Shared sync engine and explicit lifecycle | `radroots_sync` | 208-225 | pull/push, idempotency, cancellation, and close tests |
diff --git a/docs/specs/radroots_crates_release_v1.md b/docs/specs/radroots_crates_release_v1.md
@@ -1218,9 +1218,9 @@ Names containing `common`, `utils`, `types`, `models`, `preview`, `unstable`, `v
| `radroots_core` | `radroots_core` | Retain the snake-case package name and remove RadrootsCore type prefixes. |
| `radroots_identity` | `radroots_identity + radroots_signing + radroots_secrets + radroots_storage` | Keep only public identity/account concepts in identity; move secrets, signers, and persistence. |
| `radroots_blossom` | `radroots_blossom` | Retain portable protocol primitives. |
-| `radroots_protocol_contract_v1` | `radroots_protocol::event::v1 / capability::v1` | Merge; generation becomes a module, never a package suffix. |
-| `radroots_runtime_contract_v1` | `radroots_protocol::runtime::v1` | Merge; generation becomes a module. |
-| `radroots_transport_publish_protocol` | `radroots_protocol::radrootsd::transport_publish::v5` | Merge daemon wire DTOs into the versioned protocol package. |
+| `radroots_protocol_contract_v1` | `radroots_protocol::event::v1 / capability::v1` | Retired, non-publishable compatibility package after merge; final removal at Step 270 after the CLI cutover. |
+| `radroots_runtime_contract_v1` | `radroots_protocol::runtime::v1` | Retired, non-publishable SDK compatibility package after merge; final removal at Step 270 after the CLI cutover. |
+| `radroots_transport_publish_protocol` | `radroots_protocol::radrootsd::transport_publish::v5` | Retired, non-publishable compatibility package after merge; final removal at Step 286 after the radrootsd cutover. |
| `radroots_event` | `radroots_event` | Retain singular package; narrow to canonical event-domain model. |
| `radroots_event_codec` | `radroots_event_codec` | Retain; remove live Nostr/upstream client responsibilities. |
| `radroots_event_index` | `radroots_storage::projection/index` | Merge; current checkpoint/manifest model is not an independent indexing engine. |
diff --git a/docs/specs/radroots_crates_release_v1.sha256 b/docs/specs/radroots_crates_release_v1.sha256
@@ -1,4 +1,4 @@
-1f6d3ba0420b75ab58ed1b663ee05fab8e3bec3634f1cec1d8e5fab84e13ab8a radroots_crates_release_v1.md
+5a11c6ad90cf03162ca2ce4d1692192d01fa57a31c03fd07d61f70093da5e703 radroots_crates_release_v1.md
7db533f32c70306b29adea35f85686e67287ae33abd33d1013a61590449f1296 radroots_crates_release_v1.toml
5020875c2cda4b2c9568c8b3f0fad5cd96756c3c779a72481a9652e558f77891 radroots_crates_release_v1_inventory.csv
d47de10be596a4d33fee102a4f0617f66700b49515a75a1f42d62c9710043059 radroots_crates_release_v1.dot