commit a97cf153fdfd4374945c0aa83aa7026d3be4e425
parent 6f16fa242bf1138d8e1d5210faa0438523cdd62c
Author: triesap <tyson@radroots.org>
Date: Tue, 7 Jul 2026 19:21:08 +0000
sync: surface deferred preview outbox status
- add preview-unavailable and deferred-until-implemented SDK status fields
- preserve explicit non-actionable Reticulum work in sync push readiness
- update runtime and sync status JSON witnesses for the new counters
- confirm generated TypeScript and package metadata remain unchanged
Diffstat:
7 files changed, 40 insertions(+), 2 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
@@ -2223,6 +2223,7 @@ dependencies = [
name = "radroots_transport_publish_protocol"
version = "0.1.0-alpha.2"
dependencies = [
+ "radroots_transport",
"serde",
]
diff --git a/crates/sdk/src/runtime.rs b/crates/sdk/src/runtime.rs
@@ -226,6 +226,8 @@ pub struct SdkOutboxStorageStatus {
pub retryable_events: i64,
pub terminal_events: i64,
pub failed_terminal_events: i64,
+ pub preview_unavailable_events: i64,
+ pub deferred_until_implemented_events: i64,
pub ready_signed_events: i64,
pub publishing_events: i64,
pub last_attempt_at_ms: Option<i64>,
@@ -627,6 +629,8 @@ impl RadrootsClient {
retryable_events: outbox_summary.retryable_events,
terminal_events: outbox_summary.terminal_events,
failed_terminal_events: outbox_summary.failed_terminal_events,
+ preview_unavailable_events: outbox_summary.preview_unavailable_events,
+ deferred_until_implemented_events: outbox_summary.deferred_until_implemented_events,
ready_signed_events: outbox_summary.ready_signed_events,
publishing_events: outbox_summary.publishing_events,
last_attempt_at_ms: outbox_summary.last_attempt_at_ms,
diff --git a/crates/sdk/src/sync_runtime.rs b/crates/sdk/src/sync_runtime.rs
@@ -123,6 +123,8 @@ pub struct SyncOutboxStatus {
pub retryable_events: i64,
pub terminal_events: i64,
pub failed_terminal_events: i64,
+ pub preview_unavailable_events: i64,
+ pub deferred_until_implemented_events: i64,
pub ready_signed_events: i64,
pub publishing_events: i64,
pub last_attempt_at_ms: Option<i64>,
@@ -138,6 +140,8 @@ impl From<RadrootsOutboxStatusSummary> for SyncOutboxStatus {
retryable_events: summary.retryable_events,
terminal_events: summary.terminal_events,
failed_terminal_events: summary.failed_terminal_events,
+ preview_unavailable_events: summary.preview_unavailable_events,
+ deferred_until_implemented_events: summary.deferred_until_implemented_events,
ready_signed_events: summary.ready_signed_events,
publishing_events: summary.publishing_events,
last_attempt_at_ms: summary.last_attempt_at_ms,
@@ -588,7 +592,9 @@ impl<'sdk> SyncClient<'sdk> {
let summary = self.sdk._outbox.status_summary(now_ms).await?;
Ok(summary.ready_signed_events == 0
&& summary.pending_events == 0
- && summary.retryable_events == 0)
+ && summary.retryable_events == 0
+ && summary.preview_unavailable_events == 0
+ && summary.deferred_until_implemented_events == 0)
}
pub async fn push_outbox_with_adapter<A>(
diff --git a/crates/sdk/tests/runtime_foundation.rs b/crates/sdk/tests/runtime_foundation.rs
@@ -769,6 +769,8 @@ fn storage_backup_and_integrity_contract_dtos_serialize() {
retryable_events: 1,
terminal_events: 1,
failed_terminal_events: 0,
+ preview_unavailable_events: 0,
+ deferred_until_implemented_events: 0,
ready_signed_events: 1,
publishing_events: 0,
last_attempt_at_ms: Some(1_700_000_000_000),
@@ -818,6 +820,8 @@ fn storage_backup_and_integrity_contract_dtos_serialize() {
"retryable_events": 1,
"terminal_events": 1,
"failed_terminal_events": 0,
+ "preview_unavailable_events": 0,
+ "deferred_until_implemented_events": 0,
"ready_signed_events": 1,
"publishing_events": 0,
"last_attempt_at_ms": 1700000000000i64,
diff --git a/crates/sdk/tests/sync_runtime.rs b/crates/sdk/tests/sync_runtime.rs
@@ -595,6 +595,8 @@ async fn sync_status_empty_store_reports_canonical_sources_and_configured_relays
"retryable_events": 0,
"terminal_events": 0,
"failed_terminal_events": 0,
+ "preview_unavailable_events": 0,
+ "deferred_until_implemented_events": 0,
"ready_signed_events": 0,
"publishing_events": 0,
"last_attempt_at_ms": null,
@@ -1934,7 +1936,22 @@ async fn sync_runtime_product_push_outbox_reticulum_preview_reports_specific_rea
.await
.expect("status");
assert_eq!(status.outbox.ready_signed_events, 0);
- assert_eq!(status.outbox.pending_events, 1);
+ assert_eq!(status.outbox.pending_events, 0);
+ let expected_preview = if behavior == ReticulumPreviewBehavior::RejectDeliveryAttempts {
+ 1
+ } else {
+ 0
+ };
+ let expected_deferred = if behavior == ReticulumPreviewBehavior::DeferDeliveryPlans {
+ 1
+ } else {
+ 0
+ };
+ assert_eq!(status.outbox.preview_unavailable_events, expected_preview);
+ assert_eq!(
+ status.outbox.deferred_until_implemented_events,
+ expected_deferred
+ );
assert_eq!(status.outbox.total_events, 1);
assert_eq!(enqueue.outbox_event_id, 1);
}
diff --git a/crates/sdk/tests/unit/runtime_tests.rs b/crates/sdk/tests/unit/runtime_tests.rs
@@ -97,6 +97,8 @@ fn storage_status() -> StorageStatusReceipt {
retryable_events: 0,
terminal_events: 0,
failed_terminal_events: 0,
+ preview_unavailable_events: 0,
+ deferred_until_implemented_events: 0,
ready_signed_events: 0,
publishing_events: 0,
last_attempt_at_ms: None,
diff --git a/crates/sdk/tests/unit/sync_runtime_tests.rs b/crates/sdk/tests/unit/sync_runtime_tests.rs
@@ -392,6 +392,8 @@ fn sync_status_summary_conversions_preserve_all_fields() {
retryable_events: 4,
terminal_events: 2,
failed_terminal_events: 1,
+ preview_unavailable_events: 9,
+ deferred_until_implemented_events: 10,
ready_signed_events: 6,
publishing_events: 8,
last_attempt_at_ms: Some(1_700_000_000_001),
@@ -403,6 +405,8 @@ fn sync_status_summary_conversions_preserve_all_fields() {
assert_eq!(outbox_status.retryable_events, 4);
assert_eq!(outbox_status.terminal_events, 2);
assert_eq!(outbox_status.failed_terminal_events, 1);
+ assert_eq!(outbox_status.preview_unavailable_events, 9);
+ assert_eq!(outbox_status.deferred_until_implemented_events, 10);
assert_eq!(outbox_status.ready_signed_events, 6);
assert_eq!(outbox_status.publishing_events, 8);
assert_eq!(outbox_status.last_attempt_at_ms, Some(1_700_000_000_001));