commit 9eb1dd012c3463b95030e4403ce7078002d91df9
parent 09c68259bab9a746c912f67b93724f139be800b5
Author: triesap <tyson@radroots.org>
Date: Fri, 10 Jul 2026 19:30:52 +0000
transport: align CLI delivery-profile helpers
- replace the stale Nostr transport-profile registry helper with delivery-capable transport-profile semantics
- use the registry helper as the pre-runtime delivery gate in main
- rename farm and listing transport failure helpers away from generic relay wording
- add target CLI source-boundary coverage against stale helper names
Diffstat:
6 files changed, 88 insertions(+), 44 deletions(-)
diff --git a/src/main.rs b/src/main.rs
@@ -30,7 +30,7 @@ use radroots_cli::out::terminal::renderer::{
};
use radroots_cli::registry::{
ApprovalPolicy, NetworkRequirement, OPERATION_REGISTRY, network_requirement,
- requires_local_signer_mode,
+ requires_delivery_capable_transport_profile, requires_local_signer_mode,
};
use radroots_cli::runtime::config::{
OutputFormat as RuntimeOutputFormat, RuntimeConfig, SignerBackend, TransportProfileKind,
@@ -477,7 +477,7 @@ fn requires_local_signer_mode_for_transport_profile(
}
fn requires_pre_runtime_transport_target(operation_id: &str) -> bool {
- !is_transport_profile_routed_operation(operation_id)
+ !requires_delivery_capable_transport_profile(operation_id)
}
fn allows_offline_local_mutation(operation_id: &str) -> bool {
@@ -489,7 +489,7 @@ fn validate_transport_profile_contract(
config: &RuntimeConfig,
) -> Result<(), OperationAdapterError> {
let spec = request.spec();
- if !is_transport_profile_routed_operation(spec.operation_id) {
+ if !requires_delivery_capable_transport_profile(spec.operation_id) {
return Ok(());
}
if request.context().dry_run
@@ -542,17 +542,6 @@ fn validate_transport_profile_contract(
Ok(())
}
-fn is_transport_profile_routed_operation(operation_id: &str) -> bool {
- matches!(
- operation_id,
- "farm.publish"
- | "listing.publish"
- | "listing.update"
- | "listing.archive"
- | "transport.outbox.push"
- )
-}
-
fn transport_profile_delivery_unavailable_reason(config: &RuntimeConfig) -> Option<String> {
match config.transport.profile {
TransportProfileKind::Nostr | TransportProfileKind::Hybrid => {
diff --git a/src/ops/exec/farm.rs b/src/ops/exec/farm.rs
@@ -236,7 +236,7 @@ impl OperationService<FarmPublishRequest> for FarmOperationService<'_> {
self.config.transport.profile,
TransportProfileKind::Nostr | TransportProfileKind::Hybrid
) {
- require_relay_target(&request, self.config)?;
+ require_nostr_delivery_target(&request, self.config)?;
}
let view = crate::runtime::farm::publish(self.config, &args).map_err(|error| {
@@ -300,7 +300,9 @@ fn farm_publish_result(
) -> Result<OperationResult<FarmPublishResult>, OperationAdapterError> {
match view.disposition() {
CommandDisposition::Success => serialized_operation_result::<FarmPublishResult, _>(view),
- CommandDisposition::ExternalUnavailable if farm_publish_relay_unavailable(view) => {
+ CommandDisposition::ExternalUnavailable
+ if farm_publish_transport_delivery_unavailable(view) =>
+ {
Err(OperationAdapterError::network_unavailable_with_detail(
operation_id,
view.reason.clone().unwrap_or_else(|| {
@@ -348,13 +350,13 @@ fn farm_private_location_set_result(
}
}
-fn farm_publish_relay_unavailable(view: &FarmPublishView) -> bool {
+fn farm_publish_transport_delivery_unavailable(view: &FarmPublishView) -> bool {
view.state == "partial"
|| !view.profile.failed_transport_targets.is_empty()
|| !view.farm.failed_transport_targets.is_empty()
}
-fn require_relay_target<P>(
+fn require_nostr_delivery_target<P>(
request: &OperationRequest<P>,
config: &RuntimeConfig,
) -> Result<(), OperationAdapterError>
diff --git a/src/ops/exec/listing.rs b/src/ops/exec/listing.rs
@@ -307,7 +307,7 @@ where
{
match view.disposition() {
CommandDisposition::Success => serialized_operation_result::<R, _>(view),
- CommandDisposition::ExternalUnavailable if listing_relay_unavailable(view) => {
+ CommandDisposition::ExternalUnavailable if listing_transport_delivery_unavailable(view) => {
Err(OperationAdapterError::network_unavailable_with_detail(
operation_id,
view.reason.clone().unwrap_or_else(|| {
@@ -332,7 +332,7 @@ where
}
}
-fn listing_relay_unavailable(view: &ListingMutationView) -> bool {
+fn listing_transport_delivery_unavailable(view: &ListingMutationView) -> bool {
matches!(
view.source.as_str(),
"Nostr transport publish · local key" | "SDK listing publish · configured signer"
diff --git a/src/registry/mod.rs b/src/registry/mod.rs
@@ -235,22 +235,14 @@ pub fn requires_local_signer_mode(operation_id: &str) -> bool {
)
}
-pub fn requires_nostr_transport_profile(operation_id: &str) -> bool {
+pub fn requires_delivery_capable_transport_profile(operation_id: &str) -> bool {
matches!(
operation_id,
- "sync.push"
- | "transport.outbox.push"
+ "transport.outbox.push"
| "farm.publish"
| "listing.publish"
| "listing.update"
| "listing.archive"
- | "trade.submit"
- | "trade.accept"
- | "trade.decline"
- | "trade.cancel"
- | "trade.revision.propose"
- | "trade.revision.accept"
- | "trade.revision.decline"
)
}
@@ -269,8 +261,8 @@ mod tests {
use super::{
ApprovalPolicy, NetworkRequirement, OPERATION_REGISTRY, OperationRole, RiskLevel,
- get_operation, network_requirement, requires_local_signer_mode,
- requires_nostr_transport_profile,
+ get_operation, network_requirement, requires_delivery_capable_transport_profile,
+ requires_local_signer_mode,
};
const EXPECTED_OPERATION_IDS: &[&str] = &[
@@ -622,26 +614,18 @@ mod tests {
}
#[test]
- fn registry_nostr_publish_requirements_are_explicit() {
+ fn registry_delivery_capable_transport_profile_requirements_are_explicit() {
let publish = OPERATION_REGISTRY
.iter()
- .filter(|operation| requires_nostr_transport_profile(operation.operation_id))
+ .filter(|operation| requires_delivery_capable_transport_profile(operation.operation_id))
.map(|operation| operation.operation_id)
.collect::<BTreeSet<_>>();
let expected = [
- "sync.push",
"transport.outbox.push",
"farm.publish",
"listing.publish",
"listing.update",
"listing.archive",
- "trade.submit",
- "trade.accept",
- "trade.decline",
- "trade.cancel",
- "trade.revision.propose",
- "trade.revision.accept",
- "trade.revision.decline",
]
.into_iter()
.collect::<BTreeSet<_>>();
diff --git a/src/runtime/farm.rs b/src/runtime/farm.rs
@@ -614,10 +614,10 @@ fn farm_publish_readiness(
config: &RuntimeConfig,
account: &AccountRecordView,
) -> FarmPublishReadiness {
- relay_farm_publish_readiness(config, account)
+ transport_farm_publish_readiness(config, account)
}
-fn relay_farm_publish_readiness(
+fn transport_farm_publish_readiness(
config: &RuntimeConfig,
account: &AccountRecordView,
) -> FarmPublishReadiness {
diff --git a/tests/target_cli.rs b/tests/target_cli.rs
@@ -1868,6 +1868,75 @@ fn transport_source_boundary_rejects_removed_relay_and_publish_proxy_surfaces()
}
}
+ let registry_source =
+ fs::read_to_string(manifest_dir.join("src/registry/mod.rs")).expect("read registry source");
+ let main_source = fs::read_to_string(manifest_dir.join("src/main.rs")).expect("read main");
+ let farm_exec_source =
+ fs::read_to_string(manifest_dir.join("src/ops/exec/farm.rs")).expect("read farm ops");
+ let listing_exec_source =
+ fs::read_to_string(manifest_dir.join("src/ops/exec/listing.rs")).expect("read listing ops");
+ let farm_runtime_source =
+ fs::read_to_string(manifest_dir.join("src/runtime/farm.rs")).expect("read farm runtime");
+ for (relative_path, source) in [
+ ("src/registry/mod.rs", registry_source.as_str()),
+ ("src/main.rs", main_source.as_str()),
+ ("src/ops/exec/farm.rs", farm_exec_source.as_str()),
+ ("src/ops/exec/listing.rs", listing_exec_source.as_str()),
+ ("src/runtime/farm.rs", farm_runtime_source.as_str()),
+ ] {
+ for forbidden in [
+ "requires_nostr_transport_profile",
+ "registry_nostr_publish_requirements_are_explicit",
+ "is_transport_profile_routed_operation",
+ "farm_publish_relay_unavailable",
+ "require_relay_target",
+ "listing_relay_unavailable",
+ "relay_farm_publish_readiness",
+ ] {
+ assert!(
+ !source.contains(forbidden),
+ "{relative_path} must not retain stale transport-profile helper name `{forbidden}`"
+ );
+ }
+ }
+ for (relative_path, source, required) in [
+ (
+ "src/registry/mod.rs",
+ registry_source.as_str(),
+ "requires_delivery_capable_transport_profile",
+ ),
+ (
+ "src/main.rs",
+ main_source.as_str(),
+ "requires_delivery_capable_transport_profile",
+ ),
+ (
+ "src/ops/exec/farm.rs",
+ farm_exec_source.as_str(),
+ "farm_publish_transport_delivery_unavailable",
+ ),
+ (
+ "src/ops/exec/farm.rs",
+ farm_exec_source.as_str(),
+ "require_nostr_delivery_target",
+ ),
+ (
+ "src/ops/exec/listing.rs",
+ listing_exec_source.as_str(),
+ "listing_transport_delivery_unavailable",
+ ),
+ (
+ "src/runtime/farm.rs",
+ farm_runtime_source.as_str(),
+ "transport_farm_publish_readiness",
+ ),
+ ] {
+ assert!(
+ source.contains(required),
+ "{relative_path} must retain delivery-capable transport-profile witness `{required}`"
+ );
+ }
+
let transport_source =
fs::read_to_string(manifest_dir.join("src/runtime/transport.rs")).expect("read source");
let view_source =