lib

Core libraries for Radroots
git clone https://radroots.dev/git/lib.git
Log | Files | Refs | README

commit 5667824c6f254a3e7cf8ea0680a38ada9f32fc9e
parent c0cdadea2712312c5d4ed25c1e55b1217572dafa
Author: triesap <tyson@radroots.org>
Date:   Sun,  9 Aug 2026 17:31:56 +0000

mobile_core: restore actionable media draft state

- Derive aggregate draft state from every persisted media prerequisite.
- Leave byte-verified uploads editable until the authored operation is queued.
- Return failed media to the retryable preparation surface with orphan evidence intact.
- Lock successful and failed real-I/O Blossom transitions with regression assertions.

Diffstat:
Mcrates/mobile_core/src/runtime/product_surface/outbox.rs | 26+++++---------------------
Mcrates/mobile_ffi/tests/local_mvp_real_io.rs | 2++
2 files changed, 7 insertions(+), 21 deletions(-)

diff --git a/crates/mobile_core/src/runtime/product_surface/outbox.rs b/crates/mobile_core/src/runtime/product_surface/outbox.rs @@ -884,15 +884,7 @@ impl RadrootsRuntime { media.failure_code = None; } media.validate()?; - let next_stage = match stage { - Phase1MediaStage::Pending | Phase1MediaStage::Preparing => { - AuthoredDraftStage::MediaPreparing - } - Phase1MediaStage::Uploading - | Phase1MediaStage::Verified - | Phase1MediaStage::Failed - | Phase1MediaStage::Orphaned => AuthoredDraftStage::MediaUploading, - }; + let next_stage = draft_stage_for_media(&payload.media); let next = head .successor(payload.encode()?, next_stage, None, updated_at_unix_ms) .map_err(|_| Phase1DraftError::RevisionConflict)?; @@ -946,13 +938,9 @@ impl RadrootsRuntime { media.verified_at_unix_ms = Some(receipt.verified_at_unix_ms()); media.orphan = None; media.validate()?; + let next_stage = draft_stage_for_media(&payload.media); let next = head - .successor( - payload.encode()?, - AuthoredDraftStage::MediaUploading, - None, - updated_at_unix_ms, - ) + .successor(payload.encode()?, next_stage, None, updated_at_unix_ms) .map_err(|_| Phase1DraftError::RevisionConflict)?; let receipt = storage .append_authored_draft(next, Some(expected)) @@ -1016,13 +1004,9 @@ impl RadrootsRuntime { recorded_at_unix_ms: updated_at_unix_ms, }); media.validate()?; + let next_stage = draft_stage_for_media(&payload.media); let next = head - .successor( - payload.encode()?, - AuthoredDraftStage::MediaUploading, - None, - updated_at_unix_ms, - ) + .successor(payload.encode()?, next_stage, None, updated_at_unix_ms) .map_err(|_| Phase1DraftError::RevisionConflict)?; let receipt = storage .append_authored_draft(next, Some(expected)) diff --git a/crates/mobile_ffi/tests/local_mvp_real_io.rs b/crates/mobile_ffi/tests/local_mvp_real_io.rs @@ -233,6 +233,7 @@ async fn public_runtime_completes_the_local_mvp_against_real_protocol_services() .await .expect("upload and re-fetch exact media"); assert_eq!(uploaded.media[0].stage, FfiMediaStage::Verified); + assert_eq!(uploaded.state, FfiOutboxState::MediaPreparing); let evidence = publisher .sdk_blossom_evidence() .expect("Blossom evidence") @@ -818,6 +819,7 @@ async fn prove_corrupted_media_fails( .await .expect("durable corrupt-media status"); assert_eq!(failed.media[0].stage, FfiMediaStage::Failed); + assert_eq!(failed.state, FfiOutboxState::MediaPreparing); assert!(failed.media[0].possible_orphan); let evidence = runtime .sdk_blossom_evidence()