lib

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

commit 85abda4da9ffd76f4967ac61df519d5095172a81
parent a8cbaf8f98fd0a7d4e0232feefc2c3bf005f853f
Author: triesap <tyson@radroots.org>
Date:   Tue, 14 Jul 2026 18:36:44 +0000

contract: retire legacy event operation names

- replace retired event names in the public operations contract
- align synthetic operation fixtures with target-state event and wire names
- reject retired event names in operation contract validation
- validate with contract and xtask contract test lanes

Diffstat:
Mcontracts/operations.toml | 44++++++++++++++++++++++----------------------
Mtools/xtask/src/contract.rs | 108+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------
2 files changed, 123 insertions(+), 29 deletions(-)

diff --git a/contracts/operations.toml b/contracts/operations.toml @@ -16,12 +16,12 @@ domains = [ [shared_types] public = [ - "WireEventParts", - "RadrootsFrozenEventDraft", + "RadrootsNip01EventWireParts", + "RadrootsEventDraft", "RadrootsSignedEvent", - "RadrootsNostrEvent", - "RadrootsNostrEventRef", - "RadrootsNostrEventPtr", + "RadrootsEventEnvelope", + "RadrootsEventRef", + "RadrootsEventPtr", "RadrootsListingAddress", "RadrootsProfile", "RadrootsFarm", @@ -86,7 +86,7 @@ domain = "profile" id = "profile.build_draft" stability = "beta" inputs = ["RadrootsProfile", "RadrootsProfileType?"] -outputs = ["WireEventParts"] +outputs = ["RadrootsNip01EventWireParts"] error_class = "encode_error" deterministic = true signing = "native" @@ -104,7 +104,7 @@ domain = "farm" id = "farm.build_draft" stability = "beta" inputs = ["RadrootsFarm"] -outputs = ["WireEventParts"] +outputs = ["RadrootsNip01EventWireParts"] error_class = "encode_error" deterministic = true signing = "native" @@ -143,7 +143,7 @@ domain = "listing" id = "listing.build_draft" stability = "beta" inputs = ["RadrootsListing"] -outputs = ["WireEventParts"] +outputs = ["RadrootsNip01EventWireParts"] error_class = "encode_error" deterministic = true signing = "native" @@ -163,7 +163,7 @@ vector = "contracts/conformance/vectors/listing/build_draft.v1.json" domain = "listing" id = "listing.parse_event" stability = "beta" -inputs = ["RadrootsNostrEvent"] +inputs = ["RadrootsEventEnvelope"] outputs = ["RadrootsListing"] error_class = "parse_error" deterministic = true @@ -173,7 +173,7 @@ transport = "native" [operations.listing_parse_event.implementation] rust_modules = ["crates/trade/src/listing/codec.rs"] rust_types = [ - "radroots_event::RadrootsNostrEvent", + "radroots_event::RadrootsEventEnvelope", "radroots_event::listing::RadrootsListing", ] @@ -310,8 +310,8 @@ vector = "contracts/conformance/vectors/social/mvp.v1.json" domain = "order" id = "order.build_order_request_draft" stability = "beta" -inputs = ["RadrootsOrderRequest", "RadrootsNostrEventPtr"] -outputs = ["WireEventParts"] +inputs = ["RadrootsOrderRequest", "RadrootsEventPtr"] +outputs = ["RadrootsNip01EventWireParts"] error_class = "encode_error" deterministic = true signing = "native" @@ -320,7 +320,7 @@ transport = "native" [operations.order_build_order_request_draft.implementation] rust_modules = ["crates/event_codec/src/order/encode.rs"] rust_types = [ - "radroots_event::RadrootsNostrEventPtr", + "radroots_event::RadrootsEventPtr", "radroots_event::order::RadrootsOrderRequest", ] @@ -332,7 +332,7 @@ domain = "order" id = "order.build_order_decision_draft" stability = "beta" inputs = ["root_event_id", "prev_event_id", "RadrootsOrderDecision"] -outputs = ["WireEventParts"] +outputs = ["RadrootsNip01EventWireParts"] error_class = "encode_error" deterministic = true signing = "native" @@ -349,7 +349,7 @@ vector = "contracts/conformance/vectors/order/build_order_decision_draft.v1.json domain = "order" id = "order.parse_order_request" stability = "beta" -inputs = ["RadrootsNostrEvent"] +inputs = ["RadrootsEventEnvelope"] outputs = ["RadrootsOrderEnvelope", "RadrootsOrderRequest"] error_class = "parse_error" deterministic = true @@ -359,7 +359,7 @@ transport = "native" [operations.order_parse_order_request.implementation] rust_modules = ["crates/event_codec/src/order/decode.rs"] rust_types = [ - "radroots_event::RadrootsNostrEvent", + "radroots_event::RadrootsEventEnvelope", "radroots_event::order::RadrootsOrderEnvelope", "radroots_event::order::RadrootsOrderRequest", ] @@ -371,7 +371,7 @@ vector = "contracts/conformance/vectors/order/parse_order_request.v1.json" domain = "order" id = "order.parse_order_decision" stability = "beta" -inputs = ["RadrootsNostrEvent"] +inputs = ["RadrootsEventEnvelope"] outputs = ["RadrootsOrderEnvelope", "RadrootsOrderDecision"] error_class = "parse_error" deterministic = true @@ -381,7 +381,7 @@ transport = "native" [operations.order_parse_order_decision.implementation] rust_modules = ["crates/event_codec/src/order/decode.rs"] rust_types = [ - "radroots_event::RadrootsNostrEvent", + "radroots_event::RadrootsEventEnvelope", "radroots_event::order::RadrootsOrderEnvelope", "radroots_event::order::RadrootsOrderDecision", ] @@ -411,7 +411,7 @@ vector = "contracts/conformance/vectors/order/parse_listing_address.v1.json" domain = "trade_validation" id = "trade_validation.validate_listing_event" stability = "beta" -inputs = ["RadrootsNostrEvent"] +inputs = ["RadrootsEventEnvelope"] outputs = ["TradeListingValidateResult"] error_class = "validation_error" deterministic = true @@ -421,7 +421,7 @@ transport = "native" [operations.trade_validation_validate_listing_event.implementation] rust_modules = ["crates/trade/src/listing/validation.rs"] rust_types = [ - "radroots_event::RadrootsNostrEvent", + "radroots_event::RadrootsEventEnvelope", "radroots_trade::listing::validation::RadrootsTradeListing", ] @@ -452,7 +452,7 @@ vector = "contracts/conformance/vectors/knowledge/manifest_and_decode.v1.json" domain = "knowledge" id = "knowledge.verify_and_decode_event" stability = "beta" -inputs = ["RadrootsNostrEvent"] +inputs = ["RadrootsEventEnvelope"] outputs = ["RadrootsDecodedEvent"] error_class = "decode_error" deterministic = true @@ -465,7 +465,7 @@ rust_modules = [ "crates/event_codec/src/knowledge/decode.rs", ] rust_types = [ - "radroots_event::RadrootsNostrEvent", + "radroots_event::RadrootsEventEnvelope", "radroots_event_codec::verification::RadrootsDecodedEvent", ] diff --git a/tools/xtask/src/contract.rs b/tools/xtask/src/contract.rs @@ -46,6 +46,13 @@ const DTO_TOOLING_DEPENDENCIES: [&str; 4] = [ "dto_bindgen_core", "dto_bindgen_macros", ]; +const RETIRED_OPERATION_EVENT_NAMES: [&str; 5] = [ + "WireEventParts", + "RadrootsFrozenEventDraft", + "RadrootsNostrEvent", + "RadrootsNostrEventRef", + "RadrootsNostrEventPtr", +]; const EVENT_BOUNDARY_MATRIX_RELATIVES: [&str; 1] = [ "docs/platform/canonical/open_source/radroots_v1_spec/02_public_contract_and_runtime/08_event_boundary_matrix.md", ]; @@ -2791,6 +2798,10 @@ fn validate_operations_contract( if shared_types.is_empty() { return Err("shared_types.public must not be empty".to_string()); } + validate_no_retired_operation_event_names( + &operations_manifest.shared_types.public, + "shared_types.public", + )?; let error_classes = collect_non_empty_set(&operations_manifest.errors.classes, "errors.classes")?; if error_classes.is_empty() { @@ -2864,6 +2875,10 @@ fn validate_operations_contract( &operation.inputs, &format!("operation {} inputs", operation.id), )?; + validate_no_retired_operation_event_names( + &operation.inputs, + &format!("operation {} inputs", operation.id), + )?; if operation.outputs.is_empty() { return Err(format!( "operation {} outputs must not be empty", @@ -2874,6 +2889,10 @@ fn validate_operations_contract( &operation.outputs, &format!("operation {} outputs", operation.id), )?; + validate_no_retired_operation_event_names( + &operation.outputs, + &format!("operation {} outputs", operation.id), + )?; if !error_classes.contains(&operation.error_class) { return Err(format!( "operation {} references unknown error class {}", @@ -2896,6 +2915,10 @@ fn validate_operations_contract( &operation.implementation.rust_types, &format!("operation {} implementation.rust_types", operation.id), )?; + validate_no_retired_operation_event_names( + &operation.implementation.rust_types, + &format!("operation {} implementation.rust_types", operation.id), + )?; for rust_module in &operation.implementation.rust_modules { if rust_module.trim().is_empty() { return Err(format!( @@ -2941,6 +2964,22 @@ fn validate_operations_contract( Ok(()) } +fn validate_no_retired_operation_event_names( + values: &[String], + context: &str, +) -> Result<(), String> { + for value in values { + for retired in RETIRED_OPERATION_EVENT_NAMES { + if value == retired || value.ends_with(&format!("::{retired}")) { + return Err(format!( + "{context} uses retired event type {retired}; use target-state event and wire names" + )); + } + } + } + Ok(()) +} + fn package_field_configured(table: &toml::value::Table, field: &str) -> bool { let Some(value) = table.get(field) else { return false; @@ -4354,12 +4393,12 @@ domains = ["profile", "farm", "listing", "trade"] [shared_types] public = [ - "WireEventParts", - "RadrootsFrozenEventDraft", + "RadrootsNip01EventWireParts", + "RadrootsEventDraft", "RadrootsSignedEvent", - "RadrootsNostrEvent", - "RadrootsNostrEventRef", - "RadrootsNostrEventPtr", + "RadrootsEventEnvelope", + "RadrootsEventRef", + "RadrootsEventPtr", "RadrootsListingAddress", "RadrootsProfile", "RadrootsFarm", @@ -4378,7 +4417,7 @@ domain = "profile" id = "profile.build_draft" stability = "beta" inputs = ["RadrootsProfile", "RadrootsProfileType?"] -outputs = ["WireEventParts"] +outputs = ["RadrootsNip01EventWireParts"] error_class = "encode_error" deterministic = true signing = "native" @@ -4396,7 +4435,7 @@ domain = "listing" id = "listing.build_draft" stability = "beta" inputs = ["RadrootsListing"] -outputs = ["WireEventParts"] +outputs = ["RadrootsNip01EventWireParts"] error_class = "encode_error" deterministic = true signing = "native" @@ -5985,6 +6024,61 @@ rust_package = "radroots_sdk" .domains .clear(); }); + assert_bundle_error( + "shared_types.public uses retired event type RadrootsNostrEvent", + |bundle| { + bundle + .operations_manifest + .as_mut() + .expect("operations manifest") + .shared_types + .public + .push("RadrootsNostrEvent".to_string()); + }, + ); + assert_bundle_error( + "operation profile.build_draft inputs uses retired event type RadrootsNostrEvent", + |bundle| { + bundle + .operations_manifest + .as_mut() + .expect("operations manifest") + .operations + .get_mut("profile_build_draft") + .expect("profile operation") + .inputs + .push("RadrootsNostrEvent".to_string()); + }, + ); + assert_bundle_error( + "operation profile.build_draft outputs uses retired event type WireEventParts", + |bundle| { + bundle + .operations_manifest + .as_mut() + .expect("operations manifest") + .operations + .get_mut("profile_build_draft") + .expect("profile operation") + .outputs + .push("WireEventParts".to_string()); + }, + ); + assert_bundle_error( + "operation profile.build_draft implementation.rust_types uses retired event type RadrootsNostrEventPtr", + |bundle| { + bundle + .operations_manifest + .as_mut() + .expect("operations manifest") + .operations + .get_mut("profile_build_draft") + .expect("profile operation") + .implementation + .rust_types + .push("radroots_event::RadrootsNostrEventPtr".to_string()); + }, + ); let _ = fs::remove_dir_all(root); }