lib

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

commit 79ff8c411788096c014b6478585207358274d917
parent f758400e8790560105b19f393d1752d1c1b32502
Author: triesap <tyson@radroots.org>
Date:   Wed,  8 Jul 2026 08:47:16 +0000

sdk: record local import observations for signed workflows

- attach local import transport observations during signed workflow ingest
- keep SDK local provenance explicit with a stable local endpoint
- assert sync status includes local provenance plus publish observations
- add source-boundary coverage for the workflow ingest path

Diffstat:
Mcrates/sdk/src/workflow_runtime.rs | 17++++++++++++++---
Mcrates/sdk/tests/source_boundary.rs | 18++++++++++++++++++
Mcrates/sdk/tests/sync_runtime.rs | 1+
3 files changed, 33 insertions(+), 3 deletions(-)

diff --git a/crates/sdk/src/workflow_runtime.rs b/crates/sdk/src/workflow_runtime.rs @@ -5,7 +5,9 @@ use crate::{ SdkIdempotencyKey, TargetPolicy, TargetSet, TransportProfile, runtime::sdk_now_ms, }; use radroots_authority::{RadrootsActorContext, RadrootsEventSigner, sign_authorized_draft}; -use radroots_event_store::RadrootsEventIngest; +use radroots_event_store::{ + RadrootsEventIngest, RadrootsTransportObservation, RadrootsTransportObservationType, +}; use radroots_events::{ RadrootsNostrEvent, draft::{RadrootsFrozenEventDraft, RadrootsSignedNostrEvent}, @@ -15,10 +17,12 @@ use radroots_outbox::{ RadrootsOutboxDeliveryPlanInput, RadrootsOutboxEnqueueStatus, RadrootsOutboxReticulumPreviewBehavior, RadrootsOutboxSignedOperationInput, }; -use radroots_transport::RadrootsTransportSatisfactionPolicy; +use radroots_transport::{RadrootsTransportKind, RadrootsTransportSatisfactionPolicy}; #[cfg(test)] use sha2::{Digest, Sha256}; +const SDK_LOCAL_EVENT_ENDPOINT_URI: &str = "local:sdk"; + pub(crate) struct SdkWorkflowEnqueueRequest<'a> { pub(crate) operation_kind: &'static str, pub(crate) actor: &'a RadrootsActorContext, @@ -102,8 +106,15 @@ async fn enqueue_signed_workflow_event( let partial_failure_digest_prefix = digest_prefix(preflight.operation_idempotency_digest.as_str()); let event = event_from_signed(&signed_event); + let local_import_observation = RadrootsTransportObservation::new( + RadrootsTransportKind::Local, + SDK_LOCAL_EVENT_ENDPOINT_URI, + RadrootsTransportObservationType::LocalImport, + observed_at_ms, + )?; let ingest = RadrootsEventIngest::new(event, observed_at_ms) - .with_raw_json(signed_event.raw_json.clone()); + .with_raw_json(signed_event.raw_json.clone()) + .with_observation(local_import_observation); let ingest_receipt = sdk._event_store.ingest_event(ingest).await?; let outbox_input = signed_outbox_input( request.operation_kind, diff --git a/crates/sdk/tests/source_boundary.rs b/crates/sdk/tests/source_boundary.rs @@ -1491,6 +1491,24 @@ fn sdk_sync_status_sources_reject_retired_relay_shaped_generic_fields() { } #[test] +fn sdk_workflow_runtime_records_local_import_observations() { + let manifest_dir = Path::new(env!("CARGO_MANIFEST_DIR")); + let workflow_runtime = read_source(manifest_dir.join("src/workflow_runtime.rs").as_path()); + + for required in [ + "SDK_LOCAL_EVENT_ENDPOINT_URI", + "RadrootsTransportKind::Local", + "RadrootsTransportObservationType::LocalImport", + ".with_observation(local_import_observation)", + ] { + assert!( + workflow_runtime.contains(required), + "SDK workflow runtime must retain local import observation witness `{required}`" + ); + } +} + +#[test] fn sdk_transport_sources_keep_reticulum_preview_push_boundary() { let manifest_dir = Path::new(env!("CARGO_MANIFEST_DIR")); diff --git a/crates/sdk/tests/sync_runtime.rs b/crates/sdk/tests/sync_runtime.rs @@ -768,6 +768,7 @@ async fn sync_status_reports_pending_retryable_terminal_and_last_attempt_metadat .expect("status"); assert_eq!(receipt.event_store.total_events, 3); + assert_eq!(receipt.event_store.transport_observations, 4); assert_eq!(receipt.outbox.total_events, 3); assert_eq!(receipt.outbox.pending_events, 1); assert_eq!(receipt.outbox.retryable_events, 1);