app

Local-first trade for farms and co-ops
git clone https://radroots.dev/git/app.git
Log | Files | Refs | README | LICENSE

commit 30bfac2ff8dfe5604bd1b1b30912ba29e2356419
parent c0ac109f122be699c122bdd3c2220b352aa44fba
Author: triesap <tyson@radroots.org>
Date:   Sat,  4 Jul 2026 01:48:19 +0000

runtime: keep validation receipts pending

- preserve pending RHI state without trusted policy
- guard store projection against receipt-only commits
- update validation receipt workflow expectations
- avoid local trust rules outside SDK status

Diffstat:
Mcrates/desktop/src/source_guards.rs | 20++++++++++++++++++++
Mcrates/store/src/interop.rs | 26+++++++++++++-------------
2 files changed, 33 insertions(+), 13 deletions(-)

diff --git a/crates/desktop/src/source_guards.rs b/crates/desktop/src/source_guards.rs @@ -1524,6 +1524,26 @@ fn app_production_trade_event_kinds_use_shared_constants() { } #[test] +fn app_store_validation_receipts_do_not_commit_without_trust_policy() { + let source = read_source_path(app_root().join("crates/store/src/interop.rs").as_path()); + let valid_result_branch = "\"valid\" => ("; + let start = source + .find(valid_result_branch) + .expect("store interop should project valid validation receipt results"); + let end = source[start..] + .find("\"needs_review\" => (") + .map(|offset| start + offset) + .expect("store interop should project invalid validation receipt results"); + let branch = &source[start..end]; + + assert!(branch.contains("OrderStatus::NeedsAction.storage_key()")); + assert!(branch.contains("TradeAgreementStatus::AgreedPendingRhi.storage_key()")); + assert!(branch.contains("TradeInventoryStatus::Reserved.storage_key()")); + assert!(!branch.contains("OrderStatus::Scheduled.storage_key()")); + assert!(!branch.contains("TradeAgreementStatus::Committed.storage_key()")); +} + +#[test] fn app_production_sdk_boundary_usage_is_exception_scoped() { for (relative_path, source) in app_rust_source_files() { let production_source = production_source_without_tests(relative_path.as_str(), &source) diff --git a/crates/store/src/interop.rs b/crates/store/src/interop.rs @@ -1502,8 +1502,8 @@ impl<'a> AppLocalInteropRepository<'a> { }; let (status, agreement, inventory) = match result.as_str() { "valid" => ( - OrderStatus::Scheduled.storage_key(), - TradeAgreementStatus::Committed.storage_key(), + OrderStatus::NeedsAction.storage_key(), + TradeAgreementStatus::AgreedPendingRhi.storage_key(), TradeInventoryStatus::Reserved.storage_key(), ), "needs_review" => ( @@ -5453,8 +5453,8 @@ mod tests { } #[test] - fn valid_validation_receipt_commits_buyer_and_seller_order_details() { - let fixture = validation_receipt_order_fixture("validation-receipt-valid-commit"); + fn valid_validation_receipt_keeps_buyer_and_seller_order_pending_rhi() { + let fixture = validation_receipt_order_fixture("validation-receipt-valid-pending-rhi"); let valid_event = validation_receipt_event( hex_event_id(29).as_str(), fixture.seller_pubkey.as_str(), @@ -5468,7 +5468,7 @@ mod tests { fixture .events .append_record(&signed_order_event_record( - "cli:signed_event:validation-receipt:valid-commit", + "cli:signed_event:validation-receipt:valid-pending-rhi", &valid_event, fixture.listing_addr.as_str(), SourceRuntime::Cli, @@ -5483,23 +5483,23 @@ mod tests { let buyer_detail = fixture .app_store .load_buyer_order_detail(&fixture.buyer_context, fixture.order_id) - .expect("load buyer committed validation receipt detail") - .expect("buyer committed validation receipt detail"); + .expect("load buyer pending-rhi validation receipt detail") + .expect("buyer pending-rhi validation receipt detail"); let seller_detail = fixture .app_store .load_order_detail(fixture.seller_farm_id, fixture.order_id) - .expect("load seller committed validation receipt detail") - .expect("seller committed validation receipt detail"); + .expect("load seller pending-rhi validation receipt detail") + .expect("seller pending-rhi validation receipt detail"); - assert_eq!(buyer_detail.status, BuyerOrderStatus::Scheduled); - assert_eq!(seller_detail.status, OrderStatus::Scheduled); + assert_eq!(buyer_detail.status, BuyerOrderStatus::Placed); + assert_eq!(seller_detail.status, OrderStatus::NeedsAction); assert_eq!( buyer_detail.workflow.agreement, - TradeAgreementStatus::Committed + TradeAgreementStatus::AgreedPendingRhi ); assert_eq!( seller_detail.workflow.agreement, - TradeAgreementStatus::Committed + TradeAgreementStatus::AgreedPendingRhi ); assert_eq!( buyer_detail.workflow.inventory,