commit 47ef6f21ed8a157d0cac900ea18e75f9f0377157
parent c3f8b0d732d12def73289caa15e0f9704b896ff2
Author: triesap <tyson@radroots.org>
Date: Fri, 19 Jun 2026 03:56:15 -0700
runtime: remove listing direct publish guard exceptions
- rename the app sync transport away from legacy direct publish identity
- remove obsolete listing publish SDK boundary allowlist entries
- keep remaining deferred account and local outbox guard exceptions explicit
- update source guard injection coverage for runtime SDK client rejection
Diffstat:
2 files changed, 29 insertions(+), 86 deletions(-)
diff --git a/crates/desktop/src/runtime.rs b/crates/desktop/src/runtime.rs
@@ -304,11 +304,11 @@ enum AppDirectRelayIngestError {
}
#[derive(Clone)]
-struct SdkDirectRelayAppSyncTransport {
+struct ConfiguredRelayAppSyncTransport {
relay_urls: Vec<String>,
}
-impl SdkDirectRelayAppSyncTransport {
+impl ConfiguredRelayAppSyncTransport {
fn new(_accounts_manager: RadrootsNostrAccountsManager, nostr_relay_urls: Vec<String>) -> Self {
Self {
relay_urls: nostr_relay_urls,
@@ -401,7 +401,7 @@ fn publish_payload_context(publish_payload: &AppPublishPayload) -> &AppPublishCo
}
}
-impl AppSyncTransport for SdkDirectRelayAppSyncTransport {
+impl AppSyncTransport for ConfiguredRelayAppSyncTransport {
fn sync(&mut self, request: AppSyncRequest) -> Result<AppSyncResult, AppSyncTransportError> {
self.sync_with_sdk(request)
}
@@ -1694,7 +1694,7 @@ impl DesktopAppRuntimeState {
));
let sync_transport: Box<dyn AppSyncTransport + Send> =
match accounts_bootstrap.accounts_manager.as_ref() {
- Some(accounts_manager) => Box::new(SdkDirectRelayAppSyncTransport::new(
+ Some(accounts_manager) => Box::new(ConfiguredRelayAppSyncTransport::new(
accounts_manager.clone(),
nostr_relay_urls.clone(),
)),
@@ -10714,11 +10714,11 @@ mod tests {
"585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df";
use super::{
- APP_DATABASE_FILE_NAME, APP_SYNC_PUBLISH_USES_SDK_RUNTIME_MESSAGE, DesktopAppRuntime,
- DesktopAppRuntimeActivityContextError, DesktopAppRuntimeCommandError,
- DesktopAppRuntimeMetadataSummary, DesktopAppRuntimeState, DesktopAppSdkDiagnosticsState,
- DesktopAppSyncStatusSummary, DesktopRemoteSignerPaths, SYNC_TRANSPORT_UNAVAILABLE_MESSAGE,
- SdkDirectRelayAppSyncTransport, TokioRuntimeBuilder, default_sync_transport,
+ APP_DATABASE_FILE_NAME, APP_SYNC_PUBLISH_USES_SDK_RUNTIME_MESSAGE,
+ ConfiguredRelayAppSyncTransport, DesktopAppRuntime, DesktopAppRuntimeActivityContextError,
+ DesktopAppRuntimeCommandError, DesktopAppRuntimeMetadataSummary, DesktopAppRuntimeState,
+ DesktopAppSdkDiagnosticsState, DesktopAppSyncStatusSummary, DesktopRemoteSignerPaths,
+ SYNC_TRANSPORT_UNAVAILABLE_MESSAGE, TokioRuntimeBuilder, default_sync_transport,
direct_relay_event_source_runtime, farm_sync_payload, is_hex_64,
order_decision_publish_payload_to_sdk_decision, pending_sync_upsert,
signed_event_from_local_record,
@@ -11084,7 +11084,7 @@ mod tests {
.clone();
runtime.lock_state_mut().nostr_relay_urls = vec![relay.url().to_owned()];
runtime.lock_state_mut().sync_transport =
- Box::new(SdkDirectRelayAppSyncTransport::with_relay_urls(
+ Box::new(ConfiguredRelayAppSyncTransport::with_relay_urls(
accounts_manager,
vec![relay.url().to_owned()],
));
@@ -11112,7 +11112,7 @@ mod tests {
});
let operation = PendingSyncOperation::from_publish_payload(payload, "2026-05-24T12:00:00Z")
.expect("typed farm publish work should serialize");
- let mut transport = SdkDirectRelayAppSyncTransport::with_relay_urls(
+ let mut transport = ConfiguredRelayAppSyncTransport::with_relay_urls(
manager,
vec![relay_a.url().to_owned(), relay_b.url().to_owned()],
);
@@ -11150,7 +11150,7 @@ mod tests {
let operation = PendingSyncOperation::from_publish_payload(payload, "2026-05-24T12:00:00Z")
.expect("typed listing publish work should serialize");
let mut transport =
- SdkDirectRelayAppSyncTransport::with_relay_urls(manager, vec![relay.url().to_owned()]);
+ ConfiguredRelayAppSyncTransport::with_relay_urls(manager, vec![relay.url().to_owned()]);
let error = transport
.sync(AppSyncRequest {
@@ -11242,7 +11242,7 @@ mod tests {
let operation = PendingSyncOperation::from_publish_payload(payload, "2026-05-24T12:00:00Z")
.expect("typed order request publish work should serialize");
let mut transport =
- SdkDirectRelayAppSyncTransport::with_relay_urls(manager, vec![relay.url().to_owned()]);
+ ConfiguredRelayAppSyncTransport::with_relay_urls(manager, vec![relay.url().to_owned()]);
let error = transport
.sync(AppSyncRequest {
@@ -11289,7 +11289,7 @@ mod tests {
let operation = PendingSyncOperation::from_publish_payload(payload, "2026-05-24T12:00:00Z")
.expect("typed order decision publish work should serialize");
let mut transport =
- SdkDirectRelayAppSyncTransport::with_relay_urls(manager, vec![relay.url().to_owned()]);
+ ConfiguredRelayAppSyncTransport::with_relay_urls(manager, vec![relay.url().to_owned()]);
let error = transport
.sync(AppSyncRequest {
@@ -11459,7 +11459,7 @@ mod tests {
})
.collect::<Vec<_>>();
let mut transport =
- SdkDirectRelayAppSyncTransport::with_relay_urls(manager, vec![relay.url().to_owned()]);
+ ConfiguredRelayAppSyncTransport::with_relay_urls(manager, vec![relay.url().to_owned()]);
let error = transport
.sync(AppSyncRequest {
@@ -11891,7 +11891,7 @@ mod tests {
"2026-05-24T12:01:00Z",
);
let mut transport =
- SdkDirectRelayAppSyncTransport::with_relay_urls(manager, vec![relay.url().to_owned()]);
+ ConfiguredRelayAppSyncTransport::with_relay_urls(manager, vec![relay.url().to_owned()]);
let error = transport
.sync(AppSyncRequest {
@@ -12001,7 +12001,7 @@ mod tests {
let operation = PendingSyncOperation::from_publish_payload(payload, "2026-05-25T07:00:00Z")
.expect("order publish payload should serialize");
let mut transport =
- SdkDirectRelayAppSyncTransport::with_relay_urls(manager, vec![relay.url().to_owned()]);
+ ConfiguredRelayAppSyncTransport::with_relay_urls(manager, vec![relay.url().to_owned()]);
let error = transport
.sync(AppSyncRequest {
@@ -12035,7 +12035,7 @@ mod tests {
let operation = PendingSyncOperation::from_publish_payload(payload, "2026-05-24T12:00:00Z")
.expect("typed listing publish work should serialize");
let mut transport =
- SdkDirectRelayAppSyncTransport::with_relay_urls(manager, vec![relay.url().to_owned()]);
+ ConfiguredRelayAppSyncTransport::with_relay_urls(manager, vec![relay.url().to_owned()]);
let error = transport
.sync(AppSyncRequest {
@@ -12065,7 +12065,7 @@ mod tests {
let operation = PendingSyncOperation::from_publish_payload(payload, "2026-05-24T12:00:00Z")
.expect("typed farm publish work should serialize");
let mut transport =
- SdkDirectRelayAppSyncTransport::with_relay_urls(manager, vec![relay.url().to_owned()]);
+ ConfiguredRelayAppSyncTransport::with_relay_urls(manager, vec![relay.url().to_owned()]);
let error = transport
.sync(AppSyncRequest {
@@ -12097,7 +12097,7 @@ mod tests {
let operation = PendingSyncOperation::from_publish_payload(payload, "2026-05-24T12:00:00Z")
.expect("typed farm publish work should serialize");
let mut transport =
- SdkDirectRelayAppSyncTransport::with_relay_urls(manager, vec![relay.url().to_owned()]);
+ ConfiguredRelayAppSyncTransport::with_relay_urls(manager, vec![relay.url().to_owned()]);
let error = transport
.sync(AppSyncRequest {
@@ -12143,7 +12143,7 @@ mod tests {
let operation = PendingSyncOperation::from_publish_payload(payload, "2026-05-24T12:00:00Z")
.expect("typed farm publish work should serialize");
let mut transport =
- SdkDirectRelayAppSyncTransport::with_relay_urls(manager, vec![relay.url().to_owned()]);
+ ConfiguredRelayAppSyncTransport::with_relay_urls(manager, vec![relay.url().to_owned()]);
let error = transport
.sync(AppSyncRequest {
diff --git a/crates/desktop/src/source_guards.rs b/crates/desktop/src/source_guards.rs
@@ -1308,55 +1308,6 @@ const STRICT_SDK_BOUNDARY_FORBIDDEN_PATTERNS: &[SdkBoundaryForbiddenPattern] = &
const LEGACY_SDK_BOUNDARY_ALLOWLIST: &[LegacySdkBoundaryAllowlistEntry] = &[
LegacySdkBoundaryAllowlistEntry {
- path: "crates/desktop/src/runtime.rs",
- pattern: "SdkDirectRelayAppSyncTransport",
- owner: "rpv1-app-sdk-refactor.07",
- reason: "desktop runtime still owns deferred direct relay publish transport for listing publish",
- removal_condition: "remove when listing publish workflow enqueues through AppSdkRuntime",
- },
- LegacySdkBoundaryAllowlistEntry {
- path: "crates/desktop/src/runtime.rs",
- pattern: "RadrootsSdkClient",
- owner: "rpv1-app-sdk-refactor.07",
- reason: "desktop runtime still constructs the legacy direct publish client for listing publish",
- removal_condition: "remove when direct publish workflows no longer construct SDK clients outside AppSdkRuntime",
- },
- LegacySdkBoundaryAllowlistEntry {
- path: "crates/desktop/src/runtime.rs",
- pattern: "RadrootsSdkConfig",
- owner: "rpv1-app-sdk-refactor.07",
- reason: "desktop runtime still configures the legacy direct publish client for listing publish",
- removal_condition: "remove when direct publish workflows no longer configure SDK clients outside AppSdkRuntime",
- },
- LegacySdkBoundaryAllowlistEntry {
- path: "crates/desktop/src/runtime.rs",
- pattern: "SdkTransportMode::RelayDirect",
- owner: "rpv1-app-sdk-refactor.07",
- reason: "desktop runtime still uses relay direct publish transport for listing publish",
- removal_condition: "remove when listing publish workflow routes through SDK canonical outbox and sync APIs",
- },
- LegacySdkBoundaryAllowlistEntry {
- path: "crates/desktop/src/runtime.rs",
- pattern: "SignerConfig::LocalIdentity",
- owner: "rpv1-app-sdk-refactor.07",
- reason: "desktop runtime still configures direct local signing for listing publish",
- removal_condition: "remove when publish signing is mediated by AppSdkRuntime and SDK signer adapters",
- },
- LegacySdkBoundaryAllowlistEntry {
- path: "crates/desktop/src/runtime.rs",
- pattern: "PendingSyncOperation::from_publish_payload",
- owner: "rpv1-app-sdk-refactor.07",
- reason: "desktop runtime still creates legacy local outbox publish work for listing publish",
- removal_condition: "remove when listing publish writes SDK canonical outbox requests instead of app local_outbox operations",
- },
- LegacySdkBoundaryAllowlistEntry {
- path: "crates/desktop/src/runtime.rs",
- pattern: "publish_with_identity",
- owner: "rpv1-app-sdk-refactor.07",
- reason: "desktop runtime still calls legacy direct SDK listing publish APIs",
- removal_condition: "remove when listing publish workflow enqueues through AppSdkRuntime",
- },
- LegacySdkBoundaryAllowlistEntry {
path: "crates/desktop/src/accounts.rs",
pattern: "RadrootsIdentity::from_secret_key_str",
owner: "rpv1-app-sdk-hardening.04",
@@ -1385,20 +1336,6 @@ const LEGACY_SDK_BOUNDARY_ALLOWLIST: &[LegacySdkBoundaryAllowlistEntry] = &[
removal_condition: "remove when remote signer protocol sessions are mediated by SDK signer adapters and protected store APIs",
},
LegacySdkBoundaryAllowlistEntry {
- path: "crates/sync/src/publish.rs",
- pattern: "SdkTransportMode::RelayDirect",
- owner: "rpv1-app-sdk-refactor.07",
- reason: "sync payload metadata still marks legacy listing local outbox publish work as relay direct",
- removal_condition: "remove when listing publish payload metadata is replaced by SDK canonical outbox requests",
- },
- LegacySdkBoundaryAllowlistEntry {
- path: "crates/sync/src/publish.rs",
- pattern: "publish_draft_with_identity",
- owner: "rpv1-app-sdk-refactor.07",
- reason: "sync payload metadata still names legacy listing SDK publish operations",
- removal_condition: "remove when listing publish payload metadata is replaced by SDK canonical outbox requests",
- },
- LegacySdkBoundaryAllowlistEntry {
path: "crates/store/src/lib.rs",
pattern: ".enqueue_pending_operation(",
owner: "rpv1-app-sdk-refactor.07",
@@ -1616,10 +1553,16 @@ fn strict_sdk_boundary_scanner_rejects_unallowlisted_new_production_paths() {
assert_eq!(findings.len(), 1);
assert_eq!(findings[0].pattern, "RadrootsSdkClient");
+ let runtime_findings = unallowlisted_sdk_boundary_patterns(
+ "crates/desktop/src/runtime.rs",
+ "fn publish() { let _ = RadrootsSdkClient::from_config(config); }",
+ );
+ assert_eq!(runtime_findings.len(), 1);
+ assert_eq!(runtime_findings[0].pattern, "RadrootsSdkClient");
assert!(
unallowlisted_sdk_boundary_patterns(
- "crates/desktop/src/runtime.rs",
- "fn publish() { let _ = RadrootsSdkClient::from_config(config); }",
+ "crates/desktop/src/accounts.rs",
+ "fn import() { let _ = RawSecretKey; }",
)
.is_empty()
);