lib

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

contract.rs (221715B)


      1 #![forbid(unsafe_code)]
      2 
      3 use crate::coverage::{CoveragePolicyFile, CoverageThresholds, read_coverage_policy};
      4 use serde::Deserialize;
      5 use serde_json::Value;
      6 use std::collections::{BTreeMap, BTreeSet};
      7 use std::env;
      8 use std::fs;
      9 use std::path::{Path, PathBuf};
     10 
     11 const ROOT_RELEASE_POLICY_RELATIVE: &str =
     12     "foundation/contracts/release_runtime/mounted_rust_crates/publish-policy.toml";
     13 const CONFORMANCE_ROOT_RELATIVE: &str = "contracts/conformance";
     14 const CONFORMANCE_SCHEMA_RELATIVE: &str = "contracts/conformance/schema/vector.schema.json";
     15 const RELEASE_POLICY_ENV: &str = "RADROOTS_MOUNTED_RUST_CRATE_PUBLISH_POLICY";
     16 const EVENT_BOUNDARY_MATRIX_ENV: &str = "RADROOTS_EVENT_BOUNDARY_MATRIX";
     17 const COVERAGE_REQUIRED_THRESHOLD: f64 = 100.0;
     18 const COVERAGE_REQUIRED_THRESHOLD_LABEL: &str = "100/100/100/100";
     19 const COVERAGE_REPORT_EPSILON: f64 = 0.000_001;
     20 const EVENT_BOUNDARY_MATRIX_RELATIVES: [&str; 1] = [
     21     "docs/platform/canonical/open_source/radroots_v1_spec/02_public_contract_and_runtime/08_event_boundary_matrix.md",
     22 ];
     23 
     24 #[derive(Debug, Deserialize)]
     25 #[serde(deny_unknown_fields)]
     26 pub struct ContractManifest {
     27     pub contract: ManifestContract,
     28     pub surface: Surface,
     29     pub policy: Policy,
     30 }
     31 
     32 #[derive(Debug, Deserialize)]
     33 #[serde(deny_unknown_fields)]
     34 pub struct ManifestContract {
     35     pub name: String,
     36     pub version: String,
     37     pub source: String,
     38 }
     39 
     40 #[derive(Debug, Deserialize)]
     41 #[serde(deny_unknown_fields)]
     42 pub struct Surface {
     43     pub model_crates: Vec<String>,
     44     pub algorithm_crates: Vec<String>,
     45     pub rust_crate_tiers: Option<RustCrateTiers>,
     46     pub internal_replica_crates: Option<InternalReplicaCrates>,
     47 }
     48 
     49 #[derive(Debug, Deserialize)]
     50 #[serde(deny_unknown_fields)]
     51 pub struct RustCrateTiers {
     52     pub advanced_substrate: Vec<String>,
     53     pub published_support: Vec<String>,
     54     pub deferred_publication: Vec<String>,
     55 }
     56 
     57 #[derive(Debug, Deserialize)]
     58 #[serde(deny_unknown_fields)]
     59 pub struct InternalReplicaCrates {
     60     pub schema: String,
     61     pub storage: String,
     62     pub sync: String,
     63 }
     64 
     65 #[derive(Debug, Deserialize)]
     66 #[serde(deny_unknown_fields)]
     67 pub struct Policy {
     68     pub exclude_internal_workspace_crates: bool,
     69     pub require_reproducible_exports: bool,
     70     pub require_conformance_vectors: bool,
     71     pub replica: Option<ReplicaPolicy>,
     72 }
     73 
     74 #[derive(Debug, Deserialize)]
     75 #[serde(deny_unknown_fields)]
     76 pub struct ReplicaPolicy {
     77     pub forbid_legacy_alias_identifiers: bool,
     78     pub require_transport_agnostic_sync_contract: bool,
     79     pub require_deterministic_emit_ingest: bool,
     80 }
     81 
     82 #[derive(Debug, Deserialize)]
     83 #[serde(deny_unknown_fields)]
     84 pub struct OperationsContractManifest {
     85     pub contract: ManifestContract,
     86     pub public: PublicContract,
     87     pub shared_types: SharedTypesContract,
     88     pub errors: ErrorClassesContract,
     89     pub operations: BTreeMap<String, PublicOperationContract>,
     90     pub implementation_provenance: Option<ImplementationProvenance>,
     91 }
     92 
     93 #[derive(Debug, Deserialize)]
     94 #[serde(deny_unknown_fields)]
     95 pub struct PublicContract {
     96     pub domains: Vec<String>,
     97 }
     98 
     99 #[derive(Debug, Deserialize)]
    100 #[serde(deny_unknown_fields)]
    101 pub struct SharedTypesContract {
    102     pub public: Vec<String>,
    103 }
    104 
    105 #[derive(Debug, Deserialize)]
    106 #[serde(deny_unknown_fields)]
    107 pub struct ErrorClassesContract {
    108     pub classes: Vec<String>,
    109 }
    110 
    111 #[derive(Debug, Deserialize)]
    112 #[serde(deny_unknown_fields)]
    113 pub struct ImplementationProvenance {
    114     pub model_crates: Vec<String>,
    115     pub algorithm_crates: Vec<String>,
    116 }
    117 
    118 #[derive(Debug, Deserialize)]
    119 #[serde(deny_unknown_fields)]
    120 pub struct PublicOperationContract {
    121     pub domain: String,
    122     pub id: String,
    123     pub stability: String,
    124     pub inputs: Vec<String>,
    125     pub outputs: Vec<String>,
    126     pub error_class: String,
    127     #[allow(dead_code)]
    128     pub deterministic: bool,
    129     pub signing: String,
    130     pub transport: String,
    131     pub implementation: PublicOperationImplementation,
    132     pub conformance: PublicOperationConformance,
    133 }
    134 
    135 #[derive(Debug, Deserialize)]
    136 #[serde(deny_unknown_fields)]
    137 pub struct PublicOperationImplementation {
    138     pub rust_modules: Vec<String>,
    139     pub rust_types: Vec<String>,
    140 }
    141 
    142 #[derive(Debug, Deserialize)]
    143 #[serde(deny_unknown_fields)]
    144 pub struct PublicOperationConformance {
    145     pub vector: String,
    146 }
    147 
    148 #[derive(Debug, Deserialize)]
    149 #[serde(deny_unknown_fields)]
    150 pub struct VersionPolicy {
    151     pub contract: VersionContract,
    152     pub semver: SemverRules,
    153     pub compatibility: CompatibilityRules,
    154 }
    155 
    156 #[derive(Debug, Deserialize)]
    157 #[serde(deny_unknown_fields)]
    158 pub struct VersionContract {
    159     pub version: String,
    160     pub stability: String,
    161 }
    162 
    163 #[derive(Debug, Deserialize)]
    164 #[serde(deny_unknown_fields)]
    165 pub struct SemverRules {
    166     pub major_on: Vec<String>,
    167     pub minor_on: Vec<String>,
    168     pub patch_on: Vec<String>,
    169 }
    170 
    171 #[derive(Debug, Deserialize)]
    172 #[serde(deny_unknown_fields)]
    173 pub struct CompatibilityRules {
    174     pub requires_conformance_pass: bool,
    175     pub requires_contract_manifest_diff: bool,
    176     pub requires_release_notes: bool,
    177 }
    178 
    179 #[derive(Debug)]
    180 pub struct ContractBundle {
    181     pub root: PathBuf,
    182     pub manifest: ContractManifest,
    183     pub version: VersionPolicy,
    184     pub operations_manifest: Option<OperationsContractManifest>,
    185 }
    186 
    187 #[derive(Debug, Deserialize)]
    188 struct WorkspaceCargoManifest {
    189     workspace: WorkspaceSection,
    190 }
    191 
    192 #[derive(Debug, Deserialize)]
    193 struct WorkspaceSection {
    194     members: Vec<String>,
    195 }
    196 
    197 #[derive(Debug, Deserialize)]
    198 struct PackageCargoManifest {
    199     package: PackageSection,
    200 }
    201 
    202 #[derive(Debug, Deserialize)]
    203 struct PackageSection {
    204     name: String,
    205     publish: Option<PackagePublish>,
    206 }
    207 
    208 #[derive(Clone, Debug, Deserialize, PartialEq, Eq)]
    209 #[serde(untagged)]
    210 enum PackagePublish {
    211     Bool(bool),
    212     Registries(Vec<String>),
    213 }
    214 
    215 #[cfg_attr(not(test), allow(dead_code))]
    216 #[derive(Debug, Deserialize)]
    217 struct CoverageRequiredFile {
    218     required: CoverageRequiredSection,
    219 }
    220 
    221 #[cfg_attr(not(test), allow(dead_code))]
    222 #[derive(Debug, Deserialize)]
    223 struct CoverageRequiredSection {
    224     crates: Vec<String>,
    225 }
    226 
    227 #[derive(Debug, Clone, PartialEq, Eq)]
    228 struct EventBoundaryRow {
    229     domain: String,
    230     kind: String,
    231     radroots_type: String,
    232     rpc_methods: BTreeSet<String>,
    233 }
    234 
    235 #[derive(Clone, Copy)]
    236 struct EventBoundarySourceWitness {
    237     relative_path: &'static str,
    238     required_fragments: &'static [&'static str],
    239 }
    240 
    241 #[derive(Clone, Copy)]
    242 struct EventBoundaryExpectation {
    243     domain: &'static str,
    244     kind: &'static str,
    245     radroots_type: &'static str,
    246     rpc_methods: &'static [&'static str],
    247     witnesses: &'static [EventBoundarySourceWitness],
    248 }
    249 
    250 const PROFILE_WITNESSES: [EventBoundarySourceWitness; 2] = [
    251     EventBoundarySourceWitness {
    252         relative_path: "crates/events/src/profile.rs",
    253         required_fragments: &["pub struct RadrootsProfile"],
    254     },
    255     EventBoundarySourceWitness {
    256         relative_path: "crates/events/src/kinds.rs",
    257         required_fragments: &["pub const KIND_PROFILE: u32 = 0;"],
    258     },
    259 ];
    260 
    261 const FOLLOW_WITNESSES: [EventBoundarySourceWitness; 2] = [
    262     EventBoundarySourceWitness {
    263         relative_path: "crates/events/src/follow.rs",
    264         required_fragments: &["pub struct RadrootsFollow"],
    265     },
    266     EventBoundarySourceWitness {
    267         relative_path: "crates/events/src/kinds.rs",
    268         required_fragments: &["pub const KIND_FOLLOW: u32 = 3;"],
    269     },
    270 ];
    271 
    272 const POST_WITNESSES: [EventBoundarySourceWitness; 2] = [
    273     EventBoundarySourceWitness {
    274         relative_path: "crates/events/src/post.rs",
    275         required_fragments: &["pub struct RadrootsPost"],
    276     },
    277     EventBoundarySourceWitness {
    278         relative_path: "crates/events/src/kinds.rs",
    279         required_fragments: &["pub const KIND_POST: u32 = 1;"],
    280     },
    281 ];
    282 
    283 const COMMENT_WITNESSES: [EventBoundarySourceWitness; 2] = [
    284     EventBoundarySourceWitness {
    285         relative_path: "crates/events/src/comment.rs",
    286         required_fragments: &["pub struct RadrootsComment"],
    287     },
    288     EventBoundarySourceWitness {
    289         relative_path: "crates/events/src/kinds.rs",
    290         required_fragments: &["pub const KIND_COMMENT: u32 = 1111;"],
    291     },
    292 ];
    293 
    294 const REACTION_WITNESSES: [EventBoundarySourceWitness; 2] = [
    295     EventBoundarySourceWitness {
    296         relative_path: "crates/events/src/reaction.rs",
    297         required_fragments: &["pub struct RadrootsReaction"],
    298     },
    299     EventBoundarySourceWitness {
    300         relative_path: "crates/events/src/kinds.rs",
    301         required_fragments: &["pub const KIND_REACTION: u32 = 7;"],
    302     },
    303 ];
    304 
    305 const REPOST_WITNESSES: [EventBoundarySourceWitness; 2] = [
    306     EventBoundarySourceWitness {
    307         relative_path: "crates/events/src/repost.rs",
    308         required_fragments: &["pub struct RadrootsRepost"],
    309     },
    310     EventBoundarySourceWitness {
    311         relative_path: "crates/events/src/kinds.rs",
    312         required_fragments: &["pub const KIND_REPOST: u32 = 6;"],
    313     },
    314 ];
    315 
    316 const GENERIC_REPOST_WITNESSES: [EventBoundarySourceWitness; 2] = [
    317     EventBoundarySourceWitness {
    318         relative_path: "crates/events/src/repost.rs",
    319         required_fragments: &["pub struct RadrootsGenericRepost"],
    320     },
    321     EventBoundarySourceWitness {
    322         relative_path: "crates/events/src/kinds.rs",
    323         required_fragments: &["pub const KIND_GENERIC_REPOST: u32 = 16;"],
    324     },
    325 ];
    326 
    327 const SEAL_WITNESSES: [EventBoundarySourceWitness; 2] = [
    328     EventBoundarySourceWitness {
    329         relative_path: "crates/events/src/seal.rs",
    330         required_fragments: &["pub struct RadrootsSeal"],
    331     },
    332     EventBoundarySourceWitness {
    333         relative_path: "crates/events/src/kinds.rs",
    334         required_fragments: &["pub const KIND_SEAL: u32 = 13;"],
    335     },
    336 ];
    337 
    338 const MESSAGE_WITNESSES: [EventBoundarySourceWitness; 4] = [
    339     EventBoundarySourceWitness {
    340         relative_path: "crates/events/src/message.rs",
    341         required_fragments: &["pub struct RadrootsMessage"],
    342     },
    343     EventBoundarySourceWitness {
    344         relative_path: "crates/events/src/kinds.rs",
    345         required_fragments: &["pub const KIND_MESSAGE: u32 = 14;"],
    346     },
    347     EventBoundarySourceWitness {
    348         relative_path: "crates/nostr/src/nip17.rs",
    349         required_fragments: &[
    350             "pub async fn radroots_nostr_wrap_message<T>(",
    351             "KIND_MESSAGE =>",
    352         ],
    353     },
    354     EventBoundarySourceWitness {
    355         relative_path: "crates/nostr/src/lib.rs",
    356         required_fragments: &["radroots_nostr_wrap_message"],
    357     },
    358 ];
    359 
    360 const MESSAGE_FILE_WITNESSES: [EventBoundarySourceWitness; 4] = [
    361     EventBoundarySourceWitness {
    362         relative_path: "crates/events/src/message_file.rs",
    363         required_fragments: &["pub struct RadrootsMessageFile"],
    364     },
    365     EventBoundarySourceWitness {
    366         relative_path: "crates/events/src/kinds.rs",
    367         required_fragments: &["pub const KIND_MESSAGE_FILE: u32 = 15;"],
    368     },
    369     EventBoundarySourceWitness {
    370         relative_path: "crates/nostr/src/nip17.rs",
    371         required_fragments: &[
    372             "pub async fn radroots_nostr_wrap_message_file<T>(",
    373             "KIND_MESSAGE_FILE =>",
    374         ],
    375     },
    376     EventBoundarySourceWitness {
    377         relative_path: "crates/nostr/src/lib.rs",
    378         required_fragments: &["radroots_nostr_wrap_message_file"],
    379     },
    380 ];
    381 
    382 const GIFT_WRAP_WITNESSES: [EventBoundarySourceWitness; 4] = [
    383     EventBoundarySourceWitness {
    384         relative_path: "crates/events/src/gift_wrap.rs",
    385         required_fragments: &["pub struct RadrootsGiftWrap"],
    386     },
    387     EventBoundarySourceWitness {
    388         relative_path: "crates/events/src/kinds.rs",
    389         required_fragments: &["pub const KIND_GIFT_WRAP: u32 = 1059;"],
    390     },
    391     EventBoundarySourceWitness {
    392         relative_path: "crates/nostr/src/nip17.rs",
    393         required_fragments: &["pub async fn radroots_nostr_unwrap_gift_wrap<T>("],
    394     },
    395     EventBoundarySourceWitness {
    396         relative_path: "crates/nostr/src/lib.rs",
    397         required_fragments: &["radroots_nostr_unwrap_gift_wrap"],
    398     },
    399 ];
    400 
    401 const PUBLIC_FILE_METADATA_WITNESSES: [EventBoundarySourceWitness; 2] = [
    402     EventBoundarySourceWitness {
    403         relative_path: "crates/events/src/file_metadata.rs",
    404         required_fragments: &["pub struct RadrootsFileMetadata"],
    405     },
    406     EventBoundarySourceWitness {
    407         relative_path: "crates/events/src/kinds.rs",
    408         required_fragments: &["pub const KIND_PUBLIC_FILE_METADATA: u32 = KIND_FILE_METADATA;"],
    409     },
    410 ];
    411 
    412 const REPORT_WITNESSES: [EventBoundarySourceWitness; 2] = [
    413     EventBoundarySourceWitness {
    414         relative_path: "crates/events/src/report.rs",
    415         required_fragments: &["pub struct RadrootsReport"],
    416     },
    417     EventBoundarySourceWitness {
    418         relative_path: "crates/events/src/kinds.rs",
    419         required_fragments: &["pub const KIND_REPORT: u32 = 1984;"],
    420     },
    421 ];
    422 
    423 const LIST_WITNESSES: [EventBoundarySourceWitness; 2] = [
    424     EventBoundarySourceWitness {
    425         relative_path: "crates/events/src/list.rs",
    426         required_fragments: &["pub struct RadrootsList"],
    427     },
    428     EventBoundarySourceWitness {
    429         relative_path: "crates/events/src/kinds.rs",
    430         required_fragments: &[
    431             "pub const KIND_LIST_MUTE: u32 = 10000;",
    432             "pub const KIND_LIST_GOOD_WIKI_RELAYS: u32 = 10102;",
    433         ],
    434     },
    435 ];
    436 
    437 const RELAY_LIST_WITNESSES: [EventBoundarySourceWitness; 2] = [
    438     EventBoundarySourceWitness {
    439         relative_path: "crates/events/src/list.rs",
    440         required_fragments: &["pub struct RadrootsList"],
    441     },
    442     EventBoundarySourceWitness {
    443         relative_path: "crates/events/src/kinds.rs",
    444         required_fragments: &["pub const KIND_LIST_READ_WRITE_RELAYS: u32 = 10002;"],
    445     },
    446 ];
    447 
    448 const LIST_SET_WITNESSES: [EventBoundarySourceWitness; 2] = [
    449     EventBoundarySourceWitness {
    450         relative_path: "crates/events/src/list_set.rs",
    451         required_fragments: &["pub struct RadrootsListSet"],
    452     },
    453     EventBoundarySourceWitness {
    454         relative_path: "crates/events/src/kinds.rs",
    455         required_fragments: &[
    456             "pub const KIND_LIST_SET_FOLLOW: u32 = 30000;",
    457             "pub const KIND_LIST_SET_MEDIA_STARTER_PACK: u32 = 39092;",
    458         ],
    459     },
    460 ];
    461 
    462 const ARTICLE_WITNESSES: [EventBoundarySourceWitness; 2] = [
    463     EventBoundarySourceWitness {
    464         relative_path: "crates/events/src/article.rs",
    465         required_fragments: &["pub struct RadrootsArticle"],
    466     },
    467     EventBoundarySourceWitness {
    468         relative_path: "crates/events/src/kinds.rs",
    469         required_fragments: &["pub const KIND_ARTICLE: u32 = 30023;"],
    470     },
    471 ];
    472 
    473 const APP_DATA_WITNESSES: [EventBoundarySourceWitness; 2] = [
    474     EventBoundarySourceWitness {
    475         relative_path: "crates/events/src/app_data.rs",
    476         required_fragments: &["pub struct RadrootsAppData"],
    477     },
    478     EventBoundarySourceWitness {
    479         relative_path: "crates/events/src/kinds.rs",
    480         required_fragments: &["pub const KIND_APP_DATA: u32 = 30078;"],
    481     },
    482 ];
    483 
    484 const APP_HANDLER_WITNESSES: [EventBoundarySourceWitness; 2] = [
    485     EventBoundarySourceWitness {
    486         relative_path: "crates/events/src/kinds.rs",
    487         required_fragments: &["pub const KIND_APPLICATION_HANDLER: u32 = 31990;"],
    488     },
    489     EventBoundarySourceWitness {
    490         relative_path: "crates/nostr/src/events/application_handler.rs",
    491         required_fragments: &["pub fn radroots_nostr_build_application_handler_event("],
    492     },
    493 ];
    494 
    495 const CALENDAR_DATE_WITNESSES: [EventBoundarySourceWitness; 2] = [
    496     EventBoundarySourceWitness {
    497         relative_path: "crates/events/src/calendar.rs",
    498         required_fragments: &["pub struct RadrootsCalendarDateEvent"],
    499     },
    500     EventBoundarySourceWitness {
    501         relative_path: "crates/events/src/kinds.rs",
    502         required_fragments: &["pub const KIND_CALENDAR_DATE_EVENT: u32 = 31922;"],
    503     },
    504 ];
    505 
    506 const CALENDAR_TIME_WITNESSES: [EventBoundarySourceWitness; 2] = [
    507     EventBoundarySourceWitness {
    508         relative_path: "crates/events/src/calendar.rs",
    509         required_fragments: &["pub struct RadrootsCalendarTimeEvent"],
    510     },
    511     EventBoundarySourceWitness {
    512         relative_path: "crates/events/src/kinds.rs",
    513         required_fragments: &["pub const KIND_CALENDAR_TIME_EVENT: u32 = 31923;"],
    514     },
    515 ];
    516 
    517 const CALENDAR_WITNESSES: [EventBoundarySourceWitness; 2] = [
    518     EventBoundarySourceWitness {
    519         relative_path: "crates/events/src/calendar.rs",
    520         required_fragments: &["pub struct RadrootsCalendar"],
    521     },
    522     EventBoundarySourceWitness {
    523         relative_path: "crates/events/src/kinds.rs",
    524         required_fragments: &["pub const KIND_CALENDAR: u32 = KIND_LIST_SET_CALENDAR;"],
    525     },
    526 ];
    527 
    528 const CALENDAR_RSVP_WITNESSES: [EventBoundarySourceWitness; 2] = [
    529     EventBoundarySourceWitness {
    530         relative_path: "crates/events/src/calendar.rs",
    531         required_fragments: &["pub struct RadrootsCalendarEventRsvp"],
    532     },
    533     EventBoundarySourceWitness {
    534         relative_path: "crates/events/src/kinds.rs",
    535         required_fragments: &["pub const KIND_CALENDAR_EVENT_RSVP: u32 = 31925;"],
    536     },
    537 ];
    538 
    539 const FARM_WITNESSES: [EventBoundarySourceWitness; 2] = [
    540     EventBoundarySourceWitness {
    541         relative_path: "crates/events/src/farm.rs",
    542         required_fragments: &["pub struct RadrootsFarm"],
    543     },
    544     EventBoundarySourceWitness {
    545         relative_path: "crates/events/src/kinds.rs",
    546         required_fragments: &["pub const KIND_FARM: u32 = 30340;"],
    547     },
    548 ];
    549 
    550 const PLOT_WITNESSES: [EventBoundarySourceWitness; 2] = [
    551     EventBoundarySourceWitness {
    552         relative_path: "crates/events/src/plot.rs",
    553         required_fragments: &["pub struct RadrootsPlot"],
    554     },
    555     EventBoundarySourceWitness {
    556         relative_path: "crates/events/src/kinds.rs",
    557         required_fragments: &["pub const KIND_PLOT: u32 = 30350;"],
    558     },
    559 ];
    560 
    561 const COOP_WITNESSES: [EventBoundarySourceWitness; 2] = [
    562     EventBoundarySourceWitness {
    563         relative_path: "crates/events/src/coop.rs",
    564         required_fragments: &["pub struct RadrootsCoop"],
    565     },
    566     EventBoundarySourceWitness {
    567         relative_path: "crates/events/src/kinds.rs",
    568         required_fragments: &["pub const KIND_COOP: u32 = 30360;"],
    569     },
    570 ];
    571 
    572 const DOCUMENT_WITNESSES: [EventBoundarySourceWitness; 2] = [
    573     EventBoundarySourceWitness {
    574         relative_path: "crates/events/src/document.rs",
    575         required_fragments: &["pub struct RadrootsDocument"],
    576     },
    577     EventBoundarySourceWitness {
    578         relative_path: "crates/events/src/kinds.rs",
    579         required_fragments: &["pub const KIND_DOCUMENT: u32 = 30361;"],
    580     },
    581 ];
    582 
    583 const RESOURCE_AREA_WITNESSES: [EventBoundarySourceWitness; 2] = [
    584     EventBoundarySourceWitness {
    585         relative_path: "crates/events/src/resource_area.rs",
    586         required_fragments: &["pub struct RadrootsResourceArea"],
    587     },
    588     EventBoundarySourceWitness {
    589         relative_path: "crates/events/src/kinds.rs",
    590         required_fragments: &["pub const KIND_RESOURCE_AREA: u32 = 30370;"],
    591     },
    592 ];
    593 
    594 const RESOURCE_CAP_WITNESSES: [EventBoundarySourceWitness; 2] = [
    595     EventBoundarySourceWitness {
    596         relative_path: "crates/events/src/resource_cap.rs",
    597         required_fragments: &["pub struct RadrootsResourceHarvestCap"],
    598     },
    599     EventBoundarySourceWitness {
    600         relative_path: "crates/events/src/kinds.rs",
    601         required_fragments: &["pub const KIND_RESOURCE_HARVEST_CAP: u32 = 30371;"],
    602     },
    603 ];
    604 
    605 const LISTING_WITNESSES: [EventBoundarySourceWitness; 2] = [
    606     EventBoundarySourceWitness {
    607         relative_path: "crates/events/src/listing.rs",
    608         required_fragments: &["pub struct RadrootsListing"],
    609     },
    610     EventBoundarySourceWitness {
    611         relative_path: "crates/events/src/kinds.rs",
    612         required_fragments: &["pub const KIND_LISTING: u32 = 30402;"],
    613     },
    614 ];
    615 
    616 const LISTING_DRAFT_WITNESSES: [EventBoundarySourceWitness; 2] = [
    617     EventBoundarySourceWitness {
    618         relative_path: "crates/events/src/listing.rs",
    619         required_fragments: &["pub struct RadrootsListing"],
    620     },
    621     EventBoundarySourceWitness {
    622         relative_path: "crates/events/src/kinds.rs",
    623         required_fragments: &["pub const KIND_LISTING_DRAFT: u32 = 30403;"],
    624     },
    625 ];
    626 
    627 const DVM_REQUEST_WITNESSES: [EventBoundarySourceWitness; 2] = [
    628     EventBoundarySourceWitness {
    629         relative_path: "crates/events/src/job_request.rs",
    630         required_fragments: &["pub struct RadrootsJobRequest"],
    631     },
    632     EventBoundarySourceWitness {
    633         relative_path: "crates/events/src/kinds.rs",
    634         required_fragments: &[
    635             "pub const KIND_JOB_REQUEST_MIN: u32 = 5000;",
    636             "pub const KIND_JOB_REQUEST_MAX: u32 = 5999;",
    637         ],
    638     },
    639 ];
    640 
    641 const DVM_RESULT_WITNESSES: [EventBoundarySourceWitness; 2] = [
    642     EventBoundarySourceWitness {
    643         relative_path: "crates/events/src/job_result.rs",
    644         required_fragments: &["pub struct RadrootsJobResult"],
    645     },
    646     EventBoundarySourceWitness {
    647         relative_path: "crates/events/src/kinds.rs",
    648         required_fragments: &[
    649             "pub const KIND_JOB_RESULT_MIN: u32 = 6000;",
    650             "pub const KIND_JOB_RESULT_MAX: u32 = 6999;",
    651         ],
    652     },
    653 ];
    654 
    655 const DVM_FEEDBACK_WITNESSES: [EventBoundarySourceWitness; 2] = [
    656     EventBoundarySourceWitness {
    657         relative_path: "crates/events/src/job_feedback.rs",
    658         required_fragments: &["pub struct RadrootsJobFeedback"],
    659     },
    660     EventBoundarySourceWitness {
    661         relative_path: "crates/events/src/kinds.rs",
    662         required_fragments: &["pub const KIND_JOB_FEEDBACK: u32 = 7000;"],
    663     },
    664 ];
    665 
    666 const TRADE_ORDER_REQUESTED_WITNESSES: [EventBoundarySourceWitness; 5] = [
    667     EventBoundarySourceWitness {
    668         relative_path: "crates/events/src/kinds.rs",
    669         required_fragments: &["pub const KIND_ORDER_REQUEST: u32 = 3422;"],
    670     },
    671     EventBoundarySourceWitness {
    672         relative_path: "crates/events/src/order.rs",
    673         required_fragments: &[
    674             "pub struct RadrootsOrderRequest",
    675             "Self::OrderRequested => KIND_ORDER_REQUEST",
    676         ],
    677     },
    678     EventBoundarySourceWitness {
    679         relative_path: "crates/events_codec/src/order/encode.rs",
    680         required_fragments: &["pub fn order_request_event_build"],
    681     },
    682     EventBoundarySourceWitness {
    683         relative_path: "crates/events_codec/src/order/decode.rs",
    684         required_fragments: &["pub fn order_request_from_event"],
    685     },
    686     EventBoundarySourceWitness {
    687         relative_path: "crates/trade/src/order.rs",
    688         required_fragments: &[
    689             "pub struct RadrootsOrderRequestRecord",
    690             "pub fn reduce_order_events",
    691         ],
    692     },
    693 ];
    694 
    695 const TRADE_ORDER_DECISION_WITNESSES: [EventBoundarySourceWitness; 5] = [
    696     EventBoundarySourceWitness {
    697         relative_path: "crates/events/src/kinds.rs",
    698         required_fragments: &["pub const KIND_ORDER_DECISION: u32 = 3423;"],
    699     },
    700     EventBoundarySourceWitness {
    701         relative_path: "crates/events/src/order.rs",
    702         required_fragments: &[
    703             "pub enum RadrootsOrderDecisionOutcome",
    704             "pub struct RadrootsOrderDecision",
    705             "Self::OrderDecision => KIND_ORDER_DECISION",
    706         ],
    707     },
    708     EventBoundarySourceWitness {
    709         relative_path: "crates/events_codec/src/order/encode.rs",
    710         required_fragments: &["pub fn order_decision_event_build"],
    711     },
    712     EventBoundarySourceWitness {
    713         relative_path: "crates/events_codec/src/order/decode.rs",
    714         required_fragments: &["pub fn order_decision_from_event"],
    715     },
    716     EventBoundarySourceWitness {
    717         relative_path: "crates/trade/src/order.rs",
    718         required_fragments: &[
    719             "pub struct RadrootsOrderDecisionRecord",
    720             "pub fn reduce_order_events",
    721         ],
    722     },
    723 ];
    724 
    725 const TRADE_ORDER_REVISION_PROPOSED_WITNESSES: [EventBoundarySourceWitness; 5] = [
    726     EventBoundarySourceWitness {
    727         relative_path: "crates/events/src/kinds.rs",
    728         required_fragments: &["pub const KIND_ORDER_REVISION_PROPOSAL: u32 = 3424;"],
    729     },
    730     EventBoundarySourceWitness {
    731         relative_path: "crates/events/src/order.rs",
    732         required_fragments: &[
    733             "pub struct RadrootsOrderRevisionProposal",
    734             "Self::OrderRevisionProposed => KIND_ORDER_REVISION_PROPOSAL",
    735         ],
    736     },
    737     EventBoundarySourceWitness {
    738         relative_path: "crates/events_codec/src/order/encode.rs",
    739         required_fragments: &["pub fn order_revision_proposal_event_build"],
    740     },
    741     EventBoundarySourceWitness {
    742         relative_path: "crates/events_codec/src/order/decode.rs",
    743         required_fragments: &["pub fn order_revision_proposal_from_event"],
    744     },
    745     EventBoundarySourceWitness {
    746         relative_path: "crates/trade/src/order.rs",
    747         required_fragments: &[
    748             "pub struct RadrootsOrderRevisionProposalRecord",
    749             "pub fn reduce_order_events",
    750         ],
    751     },
    752 ];
    753 
    754 const TRADE_ORDER_REVISION_DECISION_WITNESSES: [EventBoundarySourceWitness; 5] = [
    755     EventBoundarySourceWitness {
    756         relative_path: "crates/events/src/kinds.rs",
    757         required_fragments: &["pub const KIND_ORDER_REVISION_DECISION: u32 = 3425;"],
    758     },
    759     EventBoundarySourceWitness {
    760         relative_path: "crates/events/src/order.rs",
    761         required_fragments: &[
    762             "pub enum RadrootsOrderRevisionOutcome",
    763             "pub struct RadrootsOrderRevisionDecision",
    764             "Self::OrderRevisionDecision => KIND_ORDER_REVISION_DECISION",
    765         ],
    766     },
    767     EventBoundarySourceWitness {
    768         relative_path: "crates/events_codec/src/order/encode.rs",
    769         required_fragments: &["pub fn order_revision_decision_event_build"],
    770     },
    771     EventBoundarySourceWitness {
    772         relative_path: "crates/events_codec/src/order/decode.rs",
    773         required_fragments: &["pub fn order_revision_decision_from_event"],
    774     },
    775     EventBoundarySourceWitness {
    776         relative_path: "crates/trade/src/order.rs",
    777         required_fragments: &[
    778             "pub struct RadrootsOrderRevisionDecisionRecord",
    779             "pub fn reduce_order_events",
    780         ],
    781     },
    782 ];
    783 
    784 const TRADE_ORDER_CANCELLED_WITNESSES: [EventBoundarySourceWitness; 5] = [
    785     EventBoundarySourceWitness {
    786         relative_path: "crates/events/src/kinds.rs",
    787         required_fragments: &["pub const KIND_ORDER_CANCELLATION: u32 = 3432;"],
    788     },
    789     EventBoundarySourceWitness {
    790         relative_path: "crates/events/src/order.rs",
    791         required_fragments: &[
    792             "pub struct RadrootsOrderCancellation",
    793             "Self::OrderCancelled => KIND_ORDER_CANCELLATION",
    794         ],
    795     },
    796     EventBoundarySourceWitness {
    797         relative_path: "crates/events_codec/src/order/encode.rs",
    798         required_fragments: &["pub fn order_cancellation_event_build"],
    799     },
    800     EventBoundarySourceWitness {
    801         relative_path: "crates/events_codec/src/order/decode.rs",
    802         required_fragments: &["pub fn order_cancellation_from_event"],
    803     },
    804     EventBoundarySourceWitness {
    805         relative_path: "crates/trade/src/order.rs",
    806         required_fragments: &[
    807             "pub struct RadrootsOrderCancellationRecord",
    808             "pub fn reduce_order_events",
    809         ],
    810     },
    811 ];
    812 
    813 const TRADE_VALIDATION_RECEIPT_WITNESSES: [EventBoundarySourceWitness; 2] = [
    814     EventBoundarySourceWitness {
    815         relative_path: "crates/trade/src/validation_receipt.rs",
    816         required_fragments: &["pub struct RadrootsTradeValidationReceipt"],
    817     },
    818     EventBoundarySourceWitness {
    819         relative_path: "crates/events/src/kinds.rs",
    820         required_fragments: &["pub const KIND_TRADE_VALIDATION_RECEIPT: u32 = 3440;"],
    821     },
    822 ];
    823 
    824 const RELAY_DOC_WITNESSES: [EventBoundarySourceWitness; 2] = [
    825     EventBoundarySourceWitness {
    826         relative_path: "crates/events/src/relay_document.rs",
    827         required_fragments: &["pub struct RadrootsRelayDocument"],
    828     },
    829     EventBoundarySourceWitness {
    830         relative_path: "crates/nostr/src/nip11.rs",
    831         required_fragments: &[
    832             "pub async fn fetch_nip11(ws_url: &str) -> Option<RadrootsRelayDocument>",
    833         ],
    834     },
    835 ];
    836 
    837 const CANONICAL_EVENT_BOUNDARY_EXPECTATIONS: [EventBoundaryExpectation; 41] = [
    838     EventBoundaryExpectation {
    839         domain: "profile",
    840         kind: "0",
    841         radroots_type: "RadrootsProfile",
    842         rpc_methods: &[
    843             "events.profile.publish",
    844             "events.profile.list",
    845             "events.profile.get",
    846         ],
    847         witnesses: &PROFILE_WITNESSES,
    848     },
    849     EventBoundaryExpectation {
    850         domain: "follow",
    851         kind: "3",
    852         radroots_type: "RadrootsFollow",
    853         rpc_methods: &[
    854             "events.follow.publish",
    855             "events.follow.list",
    856             "events.follow.get",
    857         ],
    858         witnesses: &FOLLOW_WITNESSES,
    859     },
    860     EventBoundaryExpectation {
    861         domain: "post",
    862         kind: "1",
    863         radroots_type: "RadrootsPost",
    864         rpc_methods: &["events.post.publish", "events.post.list", "events.post.get"],
    865         witnesses: &POST_WITNESSES,
    866     },
    867     EventBoundaryExpectation {
    868         domain: "comment",
    869         kind: "1111",
    870         radroots_type: "RadrootsComment",
    871         rpc_methods: &[
    872             "events.comment.publish",
    873             "events.comment.list",
    874             "events.comment.get",
    875         ],
    876         witnesses: &COMMENT_WITNESSES,
    877     },
    878     EventBoundaryExpectation {
    879         domain: "reaction",
    880         kind: "7",
    881         radroots_type: "RadrootsReaction",
    882         rpc_methods: &[
    883             "events.reaction.publish",
    884             "events.reaction.list",
    885             "events.reaction.get",
    886         ],
    887         witnesses: &REACTION_WITNESSES,
    888     },
    889     EventBoundaryExpectation {
    890         domain: "repost",
    891         kind: "6",
    892         radroots_type: "RadrootsRepost",
    893         rpc_methods: &[
    894             "events.repost.publish",
    895             "events.repost.list",
    896             "events.repost.get",
    897         ],
    898         witnesses: &REPOST_WITNESSES,
    899     },
    900     EventBoundaryExpectation {
    901         domain: "generic_repost",
    902         kind: "16",
    903         radroots_type: "RadrootsGenericRepost",
    904         rpc_methods: &[
    905             "events.generic_repost.publish",
    906             "events.generic_repost.list",
    907             "events.generic_repost.get",
    908         ],
    909         witnesses: &GENERIC_REPOST_WITNESSES,
    910     },
    911     EventBoundaryExpectation {
    912         domain: "seal",
    913         kind: "13",
    914         radroots_type: "RadrootsSeal",
    915         rpc_methods: &["events.seal.encode", "events.seal.decode"],
    916         witnesses: &SEAL_WITNESSES,
    917     },
    918     EventBoundaryExpectation {
    919         domain: "message",
    920         kind: "14",
    921         radroots_type: "RadrootsMessage",
    922         rpc_methods: &[
    923             "events.message.publish",
    924             "events.message.list",
    925             "events.message.get",
    926         ],
    927         witnesses: &MESSAGE_WITNESSES,
    928     },
    929     EventBoundaryExpectation {
    930         domain: "message_file",
    931         kind: "15",
    932         radroots_type: "RadrootsMessageFile",
    933         rpc_methods: &[
    934             "events.message_file.publish",
    935             "events.message_file.list",
    936             "events.message_file.get",
    937         ],
    938         witnesses: &MESSAGE_FILE_WITNESSES,
    939     },
    940     EventBoundaryExpectation {
    941         domain: "gift_wrap",
    942         kind: "1059",
    943         radroots_type: "RadrootsGiftWrap",
    944         rpc_methods: &[
    945             "events.gift_wrap.publish",
    946             "events.gift_wrap.list",
    947             "events.gift_wrap.get",
    948         ],
    949         witnesses: &GIFT_WRAP_WITNESSES,
    950     },
    951     EventBoundaryExpectation {
    952         domain: "public_file_metadata",
    953         kind: "1063",
    954         radroots_type: "RadrootsFileMetadata",
    955         rpc_methods: &[
    956             "events.public_file_metadata.publish",
    957             "events.public_file_metadata.list",
    958             "events.public_file_metadata.get",
    959         ],
    960         witnesses: &PUBLIC_FILE_METADATA_WITNESSES,
    961     },
    962     EventBoundaryExpectation {
    963         domain: "report",
    964         kind: "1984",
    965         radroots_type: "RadrootsReport",
    966         rpc_methods: &[
    967             "events.report.publish",
    968             "events.report.list",
    969             "events.report.get",
    970         ],
    971         witnesses: &REPORT_WITNESSES,
    972     },
    973     EventBoundaryExpectation {
    974         domain: "list",
    975         kind: "10000..10102",
    976         radroots_type: "RadrootsList",
    977         rpc_methods: &["events.list.publish", "events.list.list", "events.list.get"],
    978         witnesses: &LIST_WITNESSES,
    979     },
    980     EventBoundaryExpectation {
    981         domain: "relay_list",
    982         kind: "10002",
    983         radroots_type: "RadrootsList",
    984         rpc_methods: &[
    985             "events.relay_list.publish",
    986             "events.relay_list.list",
    987             "events.relay_list.get",
    988         ],
    989         witnesses: &RELAY_LIST_WITNESSES,
    990     },
    991     EventBoundaryExpectation {
    992         domain: "list_set",
    993         kind: "30000..39092",
    994         radroots_type: "RadrootsListSet",
    995         rpc_methods: &[
    996             "events.list_set.publish",
    997             "events.list_set.list",
    998             "events.list_set.get",
    999         ],
   1000         witnesses: &LIST_SET_WITNESSES,
   1001     },
   1002     EventBoundaryExpectation {
   1003         domain: "article",
   1004         kind: "30023",
   1005         radroots_type: "RadrootsArticle",
   1006         rpc_methods: &[
   1007             "events.article.publish",
   1008             "events.article.list",
   1009             "events.article.get",
   1010         ],
   1011         witnesses: &ARTICLE_WITNESSES,
   1012     },
   1013     EventBoundaryExpectation {
   1014         domain: "app_data",
   1015         kind: "30078",
   1016         radroots_type: "RadrootsAppData",
   1017         rpc_methods: &[
   1018             "events.app_data.publish",
   1019             "events.app_data.list",
   1020             "events.app_data.get",
   1021         ],
   1022         witnesses: &APP_DATA_WITNESSES,
   1023     },
   1024     EventBoundaryExpectation {
   1025         domain: "app_handler",
   1026         kind: "31990",
   1027         radroots_type: "KIND_APPLICATION_HANDLER",
   1028         rpc_methods: &[
   1029             "events.app_handler.publish",
   1030             "events.app_handler.list",
   1031             "events.app_handler.get",
   1032         ],
   1033         witnesses: &APP_HANDLER_WITNESSES,
   1034     },
   1035     EventBoundaryExpectation {
   1036         domain: "calendar_date",
   1037         kind: "31922",
   1038         radroots_type: "RadrootsCalendarDateEvent",
   1039         rpc_methods: &[
   1040             "events.calendar_date.publish",
   1041             "events.calendar_date.list",
   1042             "events.calendar_date.get",
   1043         ],
   1044         witnesses: &CALENDAR_DATE_WITNESSES,
   1045     },
   1046     EventBoundaryExpectation {
   1047         domain: "calendar_time",
   1048         kind: "31923",
   1049         radroots_type: "RadrootsCalendarTimeEvent",
   1050         rpc_methods: &[
   1051             "events.calendar_time.publish",
   1052             "events.calendar_time.list",
   1053             "events.calendar_time.get",
   1054         ],
   1055         witnesses: &CALENDAR_TIME_WITNESSES,
   1056     },
   1057     EventBoundaryExpectation {
   1058         domain: "calendar",
   1059         kind: "31924",
   1060         radroots_type: "RadrootsCalendar",
   1061         rpc_methods: &[
   1062             "events.calendar.publish",
   1063             "events.calendar.list",
   1064             "events.calendar.get",
   1065         ],
   1066         witnesses: &CALENDAR_WITNESSES,
   1067     },
   1068     EventBoundaryExpectation {
   1069         domain: "calendar_rsvp",
   1070         kind: "31925",
   1071         radroots_type: "RadrootsCalendarEventRsvp",
   1072         rpc_methods: &[
   1073             "events.calendar_rsvp.publish",
   1074             "events.calendar_rsvp.list",
   1075             "events.calendar_rsvp.get",
   1076         ],
   1077         witnesses: &CALENDAR_RSVP_WITNESSES,
   1078     },
   1079     EventBoundaryExpectation {
   1080         domain: "farm",
   1081         kind: "30340",
   1082         radroots_type: "RadrootsFarm",
   1083         rpc_methods: &["events.farm.publish", "events.farm.list", "events.farm.get"],
   1084         witnesses: &FARM_WITNESSES,
   1085     },
   1086     EventBoundaryExpectation {
   1087         domain: "plot",
   1088         kind: "30350",
   1089         radroots_type: "RadrootsPlot",
   1090         rpc_methods: &["events.plot.publish", "events.plot.list", "events.plot.get"],
   1091         witnesses: &PLOT_WITNESSES,
   1092     },
   1093     EventBoundaryExpectation {
   1094         domain: "coop",
   1095         kind: "30360",
   1096         radroots_type: "RadrootsCoop",
   1097         rpc_methods: &["events.coop.publish", "events.coop.list", "events.coop.get"],
   1098         witnesses: &COOP_WITNESSES,
   1099     },
   1100     EventBoundaryExpectation {
   1101         domain: "document",
   1102         kind: "30361",
   1103         radroots_type: "RadrootsDocument",
   1104         rpc_methods: &[
   1105             "events.document.publish",
   1106             "events.document.list",
   1107             "events.document.get",
   1108         ],
   1109         witnesses: &DOCUMENT_WITNESSES,
   1110     },
   1111     EventBoundaryExpectation {
   1112         domain: "resource_area",
   1113         kind: "30370",
   1114         radroots_type: "RadrootsResourceArea",
   1115         rpc_methods: &[
   1116             "events.resource_area.publish",
   1117             "events.resource_area.list",
   1118             "events.resource_area.get",
   1119         ],
   1120         witnesses: &RESOURCE_AREA_WITNESSES,
   1121     },
   1122     EventBoundaryExpectation {
   1123         domain: "resource_cap",
   1124         kind: "30371",
   1125         radroots_type: "RadrootsResourceHarvestCap",
   1126         rpc_methods: &[
   1127             "events.resource_cap.publish",
   1128             "events.resource_cap.list",
   1129             "events.resource_cap.get",
   1130         ],
   1131         witnesses: &RESOURCE_CAP_WITNESSES,
   1132     },
   1133     EventBoundaryExpectation {
   1134         domain: "listing",
   1135         kind: "30402",
   1136         radroots_type: "RadrootsListing",
   1137         rpc_methods: &[
   1138             "events.listing.publish",
   1139             "events.listing.list",
   1140             "events.listing.get",
   1141         ],
   1142         witnesses: &LISTING_WITNESSES,
   1143     },
   1144     EventBoundaryExpectation {
   1145         domain: "listing_draft",
   1146         kind: "30403",
   1147         radroots_type: "RadrootsListing",
   1148         rpc_methods: &[
   1149             "events.listing_draft.publish",
   1150             "events.listing_draft.list",
   1151             "events.listing_draft.get",
   1152         ],
   1153         witnesses: &LISTING_DRAFT_WITNESSES,
   1154     },
   1155     EventBoundaryExpectation {
   1156         domain: "dvm_request",
   1157         kind: "5000-5999",
   1158         radroots_type: "RadrootsJobRequest",
   1159         rpc_methods: &[
   1160             "events.dvm_request.publish",
   1161             "events.dvm_request.list",
   1162             "events.dvm_request.get",
   1163         ],
   1164         witnesses: &DVM_REQUEST_WITNESSES,
   1165     },
   1166     EventBoundaryExpectation {
   1167         domain: "dvm_result",
   1168         kind: "6000-6999",
   1169         radroots_type: "RadrootsJobResult",
   1170         rpc_methods: &[
   1171             "events.dvm_result.publish",
   1172             "events.dvm_result.list",
   1173             "events.dvm_result.get",
   1174         ],
   1175         witnesses: &DVM_RESULT_WITNESSES,
   1176     },
   1177     EventBoundaryExpectation {
   1178         domain: "dvm_feedback",
   1179         kind: "7000",
   1180         radroots_type: "RadrootsJobFeedback",
   1181         rpc_methods: &[
   1182             "events.dvm_feedback.publish",
   1183             "events.dvm_feedback.list",
   1184             "events.dvm_feedback.get",
   1185         ],
   1186         witnesses: &DVM_FEEDBACK_WITNESSES,
   1187     },
   1188     EventBoundaryExpectation {
   1189         domain: "trade:order_requested",
   1190         kind: "3422",
   1191         radroots_type: "TradeOrderRequested",
   1192         rpc_methods: &[
   1193             "active CLI `order submit`",
   1194             "SDK encode/decode/validate",
   1195             "trade reducer",
   1196         ],
   1197         witnesses: &TRADE_ORDER_REQUESTED_WITNESSES,
   1198     },
   1199     EventBoundaryExpectation {
   1200         domain: "trade:order_decision",
   1201         kind: "3423",
   1202         radroots_type: "TradeOrderDecision",
   1203         rpc_methods: &[
   1204             "active CLI `order accept`",
   1205             "active CLI `order decline`",
   1206             "SDK encode/decode/validate",
   1207             "trade reducer",
   1208         ],
   1209         witnesses: &TRADE_ORDER_DECISION_WITNESSES,
   1210     },
   1211     EventBoundaryExpectation {
   1212         domain: "trade:order_revision_proposed",
   1213         kind: "3424",
   1214         radroots_type: "TradeOrderRevisionProposed",
   1215         rpc_methods: &[
   1216             "active CLI `order revision propose`",
   1217             "SDK encode/decode/validate",
   1218             "trade reducer",
   1219         ],
   1220         witnesses: &TRADE_ORDER_REVISION_PROPOSED_WITNESSES,
   1221     },
   1222     EventBoundaryExpectation {
   1223         domain: "trade:order_revision_decision",
   1224         kind: "3425",
   1225         radroots_type: "TradeOrderRevisionDecision",
   1226         rpc_methods: &[
   1227             "active CLI `order revision accept`",
   1228             "active CLI `order revision decline`",
   1229             "SDK encode/decode/validate",
   1230             "trade reducer",
   1231         ],
   1232         witnesses: &TRADE_ORDER_REVISION_DECISION_WITNESSES,
   1233     },
   1234     EventBoundaryExpectation {
   1235         domain: "trade:order_cancelled",
   1236         kind: "3432",
   1237         radroots_type: "TradeOrderCancelled",
   1238         rpc_methods: &[
   1239             "active CLI `order cancel`",
   1240             "SDK encode/decode/validate",
   1241             "trade reducer",
   1242         ],
   1243         witnesses: &TRADE_ORDER_CANCELLED_WITNESSES,
   1244     },
   1245     EventBoundaryExpectation {
   1246         domain: "trade:validation_receipt",
   1247         kind: "3440",
   1248         radroots_type: "RadrootsTradeValidationReceipt",
   1249         rpc_methods: &[
   1250             "domains.trade.validation_receipt.get",
   1251             "domains.trade.validation_receipt.list",
   1252             "domains.trade.validation_receipt.verify",
   1253         ],
   1254         witnesses: &TRADE_VALIDATION_RECEIPT_WITNESSES,
   1255     },
   1256     EventBoundaryExpectation {
   1257         domain: "relay_doc",
   1258         kind: "N/A",
   1259         radroots_type: "RadrootsRelayDocument",
   1260         rpc_methods: &["system.relay_doc.get"],
   1261         witnesses: &RELAY_DOC_WITNESSES,
   1262     },
   1263 ];
   1264 
   1265 #[derive(Debug, Deserialize)]
   1266 struct ReleaseContractFile {
   1267     release: ReleaseSection,
   1268     #[serde(default)]
   1269     classification: ReleaseClassification,
   1270     #[serde(default)]
   1271     publish: Option<ReleaseCrateSet>,
   1272     #[serde(default)]
   1273     internal: Option<ReleaseCrateSet>,
   1274     publish_order: ReleaseCrateSet,
   1275 }
   1276 
   1277 #[derive(Debug, Default, Deserialize)]
   1278 struct ReleaseClassification {
   1279     #[serde(default)]
   1280     public: Vec<String>,
   1281     #[serde(default)]
   1282     internal: Vec<String>,
   1283     #[serde(default)]
   1284     deferred: Vec<String>,
   1285     #[serde(default)]
   1286     retired: Vec<String>,
   1287     #[serde(default)]
   1288     yank_only: Vec<String>,
   1289 }
   1290 
   1291 #[derive(Debug, Deserialize)]
   1292 struct ReleaseSection {
   1293     version: String,
   1294 }
   1295 
   1296 #[derive(Debug, Deserialize)]
   1297 struct ReleaseCrateSet {
   1298     crates: Vec<String>,
   1299 }
   1300 
   1301 #[derive(Debug, Deserialize)]
   1302 #[serde(deny_unknown_fields)]
   1303 struct ConformanceVectorFile {
   1304     suite: String,
   1305     contract_version: String,
   1306     vectors: Vec<ConformanceVectorEntry>,
   1307 }
   1308 
   1309 #[allow(dead_code)]
   1310 #[derive(Debug, Deserialize)]
   1311 #[serde(deny_unknown_fields)]
   1312 struct ConformanceVectorEntry {
   1313     id: String,
   1314     kind: String,
   1315     input: Value,
   1316     expected: Value,
   1317 }
   1318 
   1319 impl ReleaseContractFile {
   1320     fn uses_classification(&self) -> bool {
   1321         !self.classification.public.is_empty()
   1322             || !self.classification.internal.is_empty()
   1323             || !self.classification.deferred.is_empty()
   1324             || !self.classification.retired.is_empty()
   1325             || !self.classification.yank_only.is_empty()
   1326     }
   1327 
   1328     fn public_crates(&self) -> Vec<String> {
   1329         if self.uses_classification() {
   1330             return self.classification.public.clone();
   1331         }
   1332         self.publish
   1333             .as_ref()
   1334             .map(|set| set.crates.clone())
   1335             .unwrap_or_default()
   1336     }
   1337 
   1338     fn internal_crates(&self) -> Vec<String> {
   1339         if self.uses_classification() {
   1340             return self.classification.internal.clone();
   1341         }
   1342         self.internal
   1343             .as_ref()
   1344             .map(|set| set.crates.clone())
   1345             .unwrap_or_default()
   1346     }
   1347 
   1348     fn deferred_crates(&self) -> Vec<String> {
   1349         self.classification.deferred.clone()
   1350     }
   1351 
   1352     fn retired_crates(&self) -> Vec<String> {
   1353         self.classification.retired.clone()
   1354     }
   1355 
   1356     fn yank_only_crates(&self) -> Vec<String> {
   1357         self.classification.yank_only.clone()
   1358     }
   1359 }
   1360 
   1361 fn parse_toml<T: for<'de> Deserialize<'de>>(path: &Path) -> Result<T, String> {
   1362     let raw = match fs::read_to_string(path) {
   1363         Ok(raw) => raw,
   1364         Err(e) => return Err(format!("read {}: {e}", path.display())),
   1365     };
   1366     match toml::from_str::<T>(&raw) {
   1367         Ok(parsed) => Ok(parsed),
   1368         Err(e) => Err(format!("parse {}: {e}", path.display())),
   1369     }
   1370 }
   1371 
   1372 fn parse_json<T: for<'de> Deserialize<'de>>(path: &Path) -> Result<T, String> {
   1373     let raw = match fs::read_to_string(path) {
   1374         Ok(raw) => raw,
   1375         Err(e) => return Err(format!("read {}: {e}", path.display())),
   1376     };
   1377     match serde_json::from_str::<T>(&raw) {
   1378         Ok(parsed) => Ok(parsed),
   1379         Err(e) => Err(format!("parse {}: {e}", path.display())),
   1380     }
   1381 }
   1382 
   1383 fn resolve_event_boundary_matrix_path_with_override(
   1384     workspace_root: &Path,
   1385     event_boundary_override: Option<PathBuf>,
   1386 ) -> Result<PathBuf, String> {
   1387     if let Some(path) = event_boundary_override {
   1388         if !path.is_file() {
   1389             return Err(format!(
   1390                 "{EVENT_BOUNDARY_MATRIX_ENV} points to a missing canonical event matrix file: {}",
   1391                 path.display()
   1392             ));
   1393         }
   1394         return Ok(path);
   1395     }
   1396 
   1397     for ancestor in workspace_root.ancestors() {
   1398         for relative in EVENT_BOUNDARY_MATRIX_RELATIVES {
   1399             let candidate = ancestor.join(relative);
   1400             if candidate.is_file() {
   1401                 return Ok(candidate);
   1402             }
   1403         }
   1404     }
   1405 
   1406     resolve_missing_event_boundary_matrix_path(workspace_root)
   1407 }
   1408 
   1409 fn missing_event_boundary_matrix_error() -> String {
   1410     format!(
   1411         "canonical event matrix not found; set {EVENT_BOUNDARY_MATRIX_ENV} or provide one of: {}",
   1412         EVENT_BOUNDARY_MATRIX_RELATIVES.join(", ")
   1413     )
   1414 }
   1415 
   1416 #[cfg(not(test))]
   1417 fn resolve_missing_event_boundary_matrix_path(_workspace_root: &Path) -> Result<PathBuf, String> {
   1418     Err(missing_event_boundary_matrix_error())
   1419 }
   1420 
   1421 #[cfg(test)]
   1422 #[cfg_attr(coverage_nightly, coverage(off))]
   1423 fn resolve_missing_event_boundary_matrix_path(workspace_root: &Path) -> Result<PathBuf, String> {
   1424     if !should_synthesize_owner_contracts_for_tests(workspace_root) {
   1425         return Err(missing_event_boundary_matrix_error());
   1426     }
   1427     let path = std::env::temp_dir().join(format!(
   1428         "radroots_xtask_event_boundary_{}.md",
   1429         std::process::id()
   1430     ));
   1431     fs::write(&path, synthetic_event_boundary_matrix())
   1432         .map_err(|e| format!("write {}: {e}", path.display()))?;
   1433     Ok(path)
   1434 }
   1435 
   1436 #[cfg(test)]
   1437 #[cfg_attr(coverage_nightly, coverage(off))]
   1438 fn synthetic_event_boundary_matrix() -> String {
   1439     let mut raw = String::from(
   1440         "# Event boundary matrix\n\n## Coverage matrix\n\n| Domain | Kind | Radroots Type | RPC Methods | Notes |\n| --- | --- | --- | --- | --- |\n",
   1441     );
   1442     for expectation in CANONICAL_EVENT_BOUNDARY_EXPECTATIONS {
   1443         raw.push_str(&format!(
   1444             "| {} | {} | {} | {} | synthetic test matrix |\n",
   1445             expectation.domain,
   1446             expectation.kind,
   1447             expectation.radroots_type,
   1448             expectation.rpc_methods.join(", ")
   1449         ));
   1450     }
   1451     raw.push('\n');
   1452     raw
   1453 }
   1454 
   1455 fn parse_event_boundary_matrix(path: &Path) -> Result<BTreeMap<String, EventBoundaryRow>, String> {
   1456     let raw = match fs::read_to_string(path) {
   1457         Ok(raw) => raw,
   1458         Err(e) => return Err(format!("read {}: {e}", path.display())),
   1459     };
   1460     let mut rows = BTreeMap::new();
   1461     let mut in_table = false;
   1462     for line in raw.lines() {
   1463         let trimmed = line.trim();
   1464         if trimmed == "| Domain | Kind | Radroots Type | RPC Methods | Notes |" {
   1465             in_table = true;
   1466             continue;
   1467         }
   1468         if !in_table {
   1469             continue;
   1470         }
   1471         if trimmed.is_empty() {
   1472             break;
   1473         }
   1474         if trimmed == "| --- | --- | --- | --- | --- |" {
   1475             continue;
   1476         }
   1477         if !trimmed.starts_with('|') {
   1478             break;
   1479         }
   1480         let columns = trimmed
   1481             .trim_matches('|')
   1482             .split('|')
   1483             .map(|part| part.trim())
   1484             .collect::<Vec<_>>();
   1485         if columns.len() != 5 {
   1486             return Err(format!(
   1487                 "canonical event matrix row in {} must have exactly 5 columns: {}",
   1488                 path.display(),
   1489                 trimmed
   1490             ));
   1491         }
   1492         let domain = columns[0].to_string();
   1493         if domain.is_empty() {
   1494             return Err(format!(
   1495                 "canonical event matrix row in {} must define a non-empty domain",
   1496                 path.display()
   1497             ));
   1498         }
   1499         let rpc_methods = columns[3]
   1500             .split(',')
   1501             .map(str::trim)
   1502             .filter(|item| !item.is_empty())
   1503             .map(|item| item.to_string())
   1504             .collect::<BTreeSet<_>>();
   1505         if rpc_methods.is_empty() {
   1506             return Err(format!(
   1507                 "canonical event matrix row {} in {} must define rpc methods",
   1508                 domain,
   1509                 path.display()
   1510             ));
   1511         }
   1512         let row = EventBoundaryRow {
   1513             domain: domain.clone(),
   1514             kind: columns[1].to_string(),
   1515             radroots_type: columns[2].to_string(),
   1516             rpc_methods,
   1517         };
   1518         if rows.insert(domain.clone(), row).is_some() {
   1519             return Err(format!(
   1520                 "canonical event matrix {} has duplicate domain row {}",
   1521                 path.display(),
   1522                 domain
   1523             ));
   1524         }
   1525     }
   1526 
   1527     if rows.is_empty() {
   1528         return Err(format!(
   1529             "canonical event matrix {} does not contain the coverage table",
   1530             path.display()
   1531         ));
   1532     }
   1533 
   1534     Ok(rows)
   1535 }
   1536 
   1537 fn validate_event_boundary_source_witness(
   1538     workspace_root: &Path,
   1539     domain: &str,
   1540     witness: &EventBoundarySourceWitness,
   1541 ) -> Result<(), String> {
   1542     let path = workspace_root.join(witness.relative_path);
   1543     let source = match fs::read_to_string(&path) {
   1544         Ok(source) => source,
   1545         Err(e) => return Err(format!("read {}: {e}", path.display())),
   1546     };
   1547     for fragment in witness.required_fragments {
   1548         if !source.contains(fragment) {
   1549             return Err(format!(
   1550                 "canonical event row {} is missing required implementation fragment {} in {}",
   1551                 domain,
   1552                 fragment,
   1553                 path.display()
   1554             ));
   1555         }
   1556     }
   1557     Ok(())
   1558 }
   1559 
   1560 fn validate_canonical_event_boundary_with_override(
   1561     workspace_root: &Path,
   1562     event_boundary_override: Option<PathBuf>,
   1563 ) -> Result<(), String> {
   1564     let matrix_path =
   1565         resolve_event_boundary_matrix_path_with_override(workspace_root, event_boundary_override)?;
   1566     let rows = parse_event_boundary_matrix(&matrix_path)?;
   1567     let expected_domains = CANONICAL_EVENT_BOUNDARY_EXPECTATIONS
   1568         .iter()
   1569         .map(|row| row.domain.to_string())
   1570         .collect::<BTreeSet<_>>();
   1571     let actual_domains = rows.keys().cloned().collect::<BTreeSet<_>>();
   1572     if actual_domains != expected_domains {
   1573         let missing = expected_domains
   1574             .difference(&actual_domains)
   1575             .cloned()
   1576             .collect::<BTreeSet<_>>();
   1577         let extra = actual_domains
   1578             .difference(&expected_domains)
   1579             .cloned()
   1580             .collect::<BTreeSet<_>>();
   1581         return Err(format!(
   1582             "canonical event matrix {} is missing rows: {}; and includes unexpected rows: {}",
   1583             matrix_path.display(),
   1584             join_set(&missing),
   1585             join_set(&extra)
   1586         ));
   1587     }
   1588 
   1589     for expectation in CANONICAL_EVENT_BOUNDARY_EXPECTATIONS {
   1590         let row = rows.get(expectation.domain).ok_or_else(|| {
   1591             format!(
   1592                 "canonical event matrix {} is missing required row {}",
   1593                 matrix_path.display(),
   1594                 expectation.domain
   1595             )
   1596         })?;
   1597         if row.kind != expectation.kind {
   1598             return Err(format!(
   1599                 "canonical event row {} kind drift: expected {}, got {}",
   1600                 expectation.domain, expectation.kind, row.kind
   1601             ));
   1602         }
   1603         if row.radroots_type != expectation.radroots_type {
   1604             return Err(format!(
   1605                 "canonical event row {} type drift: expected {}, got {}",
   1606                 expectation.domain, expectation.radroots_type, row.radroots_type
   1607             ));
   1608         }
   1609         let expected_methods = expectation
   1610             .rpc_methods
   1611             .iter()
   1612             .map(|method| (*method).to_string())
   1613             .collect::<BTreeSet<_>>();
   1614         if row.rpc_methods != expected_methods {
   1615             return Err(format!(
   1616                 "canonical event row {} rpc drift: expected {}, got {}",
   1617                 expectation.domain,
   1618                 join_set(&expected_methods),
   1619                 join_set(&row.rpc_methods)
   1620             ));
   1621         }
   1622         for witness in expectation.witnesses {
   1623             validate_event_boundary_source_witness(workspace_root, expectation.domain, witness)?;
   1624         }
   1625     }
   1626 
   1627     Ok(())
   1628 }
   1629 
   1630 pub fn validate_canonical_event_boundary(workspace_root: &Path) -> Result<(), String> {
   1631     validate_canonical_event_boundary_with_override(workspace_root, None)
   1632 }
   1633 
   1634 fn contract_root(workspace_root: &Path) -> PathBuf {
   1635     workspace_root.join("contracts")
   1636 }
   1637 
   1638 fn conformance_root(workspace_root: &Path) -> PathBuf {
   1639     workspace_root.join(CONFORMANCE_ROOT_RELATIVE)
   1640 }
   1641 
   1642 fn conformance_schema_path(workspace_root: &Path) -> PathBuf {
   1643     workspace_root.join(CONFORMANCE_SCHEMA_RELATIVE)
   1644 }
   1645 
   1646 fn required_field_set(value: &Value, field: &str, path: &Path) -> Result<BTreeSet<String>, String> {
   1647     let required = value
   1648         .as_array()
   1649         .ok_or_else(|| format!("{field} in {} must be an array", path.display()))?;
   1650     let mut names = BTreeSet::new();
   1651     for item in required {
   1652         let name = item
   1653             .as_str()
   1654             .ok_or_else(|| format!("{field} in {} must contain strings", path.display()))?;
   1655         if name.trim().is_empty() {
   1656             return Err(format!(
   1657                 "{field} in {} must not contain empty names",
   1658                 path.display()
   1659             ));
   1660         }
   1661         names.insert(name.to_string());
   1662     }
   1663     Ok(names)
   1664 }
   1665 
   1666 fn validate_string_schema_property(
   1667     property: &Value,
   1668     field: &str,
   1669     path: &Path,
   1670     min_length: Option<u64>,
   1671     pattern: Option<&str>,
   1672 ) -> Result<(), String> {
   1673     let property = property
   1674         .as_object()
   1675         .ok_or_else(|| format!("{field} schema in {} must be an object", path.display()))?;
   1676     let kind = property
   1677         .get("type")
   1678         .and_then(Value::as_str)
   1679         .ok_or_else(|| format!("{field} schema in {} must declare type", path.display()))?;
   1680     if kind != "string" {
   1681         return Err(format!(
   1682             "{field} schema in {} must use type=string",
   1683             path.display()
   1684         ));
   1685     }
   1686     if let Some(expected) = min_length {
   1687         let actual = property
   1688             .get("minLength")
   1689             .and_then(Value::as_u64)
   1690             .ok_or_else(|| format!("{field} schema in {} must set minLength", path.display()))?;
   1691         if actual != expected {
   1692             return Err(format!(
   1693                 "{field} schema in {} must set minLength={expected}",
   1694                 path.display()
   1695             ));
   1696         }
   1697     }
   1698     if let Some(expected) = pattern {
   1699         let actual = property
   1700             .get("pattern")
   1701             .and_then(Value::as_str)
   1702             .ok_or_else(|| format!("{field} schema in {} must set pattern", path.display()))?;
   1703         if actual != expected {
   1704             return Err(format!(
   1705                 "{field} schema in {} must set pattern {}",
   1706                 path.display(),
   1707                 expected
   1708             ));
   1709         }
   1710     }
   1711     Ok(())
   1712 }
   1713 
   1714 fn validate_conformance_schema(workspace_root: &Path) -> Result<(), String> {
   1715     let path = conformance_schema_path(workspace_root);
   1716     let schema = parse_json::<Value>(&path)?;
   1717     let schema_obj = schema.as_object().ok_or_else(|| {
   1718         format!(
   1719             "conformance schema {} must be a JSON object",
   1720             path.display()
   1721         )
   1722     })?;
   1723     let schema_type = schema_obj
   1724         .get("type")
   1725         .and_then(Value::as_str)
   1726         .ok_or_else(|| format!("conformance schema {} must declare type", path.display()))?;
   1727     if schema_type != "object" {
   1728         return Err(format!(
   1729             "conformance schema {} must use type=object",
   1730             path.display()
   1731         ));
   1732     }
   1733     let additional = schema_obj
   1734         .get("additionalProperties")
   1735         .and_then(Value::as_bool)
   1736         .ok_or_else(|| {
   1737             format!(
   1738                 "conformance schema {} must declare additionalProperties",
   1739                 path.display()
   1740             )
   1741         })?;
   1742     if additional {
   1743         return Err(format!(
   1744             "conformance schema {} must disallow additionalProperties",
   1745             path.display()
   1746         ));
   1747     }
   1748     let root_required = required_field_set(
   1749         schema_obj.get("required").ok_or_else(|| {
   1750             format!(
   1751                 "conformance schema {} missing required list",
   1752                 path.display()
   1753             )
   1754         })?,
   1755         "required",
   1756         &path,
   1757     )?;
   1758     let expected_root_required = BTreeSet::from([
   1759         "suite".to_string(),
   1760         "contract_version".to_string(),
   1761         "vectors".to_string(),
   1762     ]);
   1763     if root_required != expected_root_required {
   1764         return Err(format!(
   1765             "conformance schema {} must require suite, contract_version, and vectors",
   1766             path.display()
   1767         ));
   1768     }
   1769     let properties = schema_obj
   1770         .get("properties")
   1771         .and_then(Value::as_object)
   1772         .ok_or_else(|| {
   1773             format!(
   1774                 "conformance schema {} missing properties map",
   1775                 path.display()
   1776             )
   1777         })?;
   1778     validate_string_schema_property(
   1779         properties.get("suite").ok_or_else(|| {
   1780             format!(
   1781                 "conformance schema {} missing suite property",
   1782                 path.display()
   1783             )
   1784         })?,
   1785         "suite",
   1786         &path,
   1787         Some(1),
   1788         None,
   1789     )?;
   1790     validate_string_schema_property(
   1791         properties.get("contract_version").ok_or_else(|| {
   1792             format!(
   1793                 "conformance schema {} missing contract_version property",
   1794                 path.display()
   1795             )
   1796         })?,
   1797         "contract_version",
   1798         &path,
   1799         None,
   1800         Some("^[0-9]+\\.[0-9]+\\.[0-9]+$"),
   1801     )?;
   1802     let vectors = properties
   1803         .get("vectors")
   1804         .and_then(Value::as_object)
   1805         .ok_or_else(|| {
   1806             format!(
   1807                 "conformance schema {} missing vectors property",
   1808                 path.display()
   1809             )
   1810         })?;
   1811     let vectors_type = vectors
   1812         .get("type")
   1813         .and_then(Value::as_str)
   1814         .ok_or_else(|| format!("vectors schema in {} must declare type", path.display()))?;
   1815     if vectors_type != "array" {
   1816         return Err(format!(
   1817             "vectors schema in {} must use type=array",
   1818             path.display()
   1819         ));
   1820     }
   1821     let items = vectors
   1822         .get("items")
   1823         .and_then(Value::as_object)
   1824         .ok_or_else(|| format!("vectors schema in {} must define items", path.display()))?;
   1825     let items_type = items
   1826         .get("type")
   1827         .and_then(Value::as_str)
   1828         .ok_or_else(|| format!("vector item schema in {} must declare type", path.display()))?;
   1829     if items_type != "object" {
   1830         return Err(format!(
   1831             "vector item schema in {} must use type=object",
   1832             path.display()
   1833         ));
   1834     }
   1835     let items_additional = items
   1836         .get("additionalProperties")
   1837         .and_then(Value::as_bool)
   1838         .ok_or_else(|| {
   1839             format!(
   1840                 "vector item schema in {} must declare additionalProperties",
   1841                 path.display()
   1842             )
   1843         })?;
   1844     if items_additional {
   1845         return Err(format!(
   1846             "vector item schema in {} must disallow additionalProperties",
   1847             path.display()
   1848         ));
   1849     }
   1850     let item_required = required_field_set(
   1851         items.get("required").ok_or_else(|| {
   1852             format!(
   1853                 "vector item schema in {} missing required list",
   1854                 path.display()
   1855             )
   1856         })?,
   1857         "required",
   1858         &path,
   1859     )?;
   1860     let expected_item_required = BTreeSet::from([
   1861         "expected".to_string(),
   1862         "id".to_string(),
   1863         "input".to_string(),
   1864         "kind".to_string(),
   1865     ]);
   1866     if item_required != expected_item_required {
   1867         return Err(format!(
   1868             "vector item schema in {} must require id, kind, input, and expected",
   1869             path.display()
   1870         ));
   1871     }
   1872     let item_properties = items
   1873         .get("properties")
   1874         .and_then(Value::as_object)
   1875         .ok_or_else(|| {
   1876             format!(
   1877                 "vector item schema in {} missing properties",
   1878                 path.display()
   1879             )
   1880         })?;
   1881     validate_string_schema_property(
   1882         item_properties.get("id").ok_or_else(|| {
   1883             format!(
   1884                 "vector item schema in {} missing id property",
   1885                 path.display()
   1886             )
   1887         })?,
   1888         "id",
   1889         &path,
   1890         Some(1),
   1891         None,
   1892     )?;
   1893     validate_string_schema_property(
   1894         item_properties.get("kind").ok_or_else(|| {
   1895             format!(
   1896                 "vector item schema in {} missing kind property",
   1897                 path.display()
   1898             )
   1899         })?,
   1900         "kind",
   1901         &path,
   1902         Some(1),
   1903         None,
   1904     )?;
   1905     for field in ["input", "expected"] {
   1906         let property = item_properties.get(field).ok_or_else(|| {
   1907             format!(
   1908                 "vector item schema in {} missing {} property",
   1909                 path.display(),
   1910                 field
   1911             )
   1912         })?;
   1913         if !property.is_object() {
   1914             return Err(format!(
   1915                 "vector item schema in {} must define {} as an object schema",
   1916                 path.display(),
   1917                 field
   1918             ));
   1919         }
   1920     }
   1921     Ok(())
   1922 }
   1923 
   1924 fn base_contract_version(version: &str) -> &str {
   1925     version.split_once('-').map_or(version, |(base, _)| base)
   1926 }
   1927 
   1928 fn collect_conformance_vector_paths(dir: &Path, paths: &mut Vec<PathBuf>) -> Result<(), String> {
   1929     let read_dir = match fs::read_dir(dir) {
   1930         Ok(read_dir) => read_dir,
   1931         Err(e) => return Err(format!("read dir {}: {e}", dir.display())),
   1932     };
   1933     let mut entries = read_dir.filter_map(Result::ok).collect::<Vec<_>>();
   1934     entries.sort_by_key(|entry| entry.file_name());
   1935     for entry in entries {
   1936         let path = entry.path();
   1937         if path.is_dir() {
   1938             collect_conformance_vector_paths(&path, paths)?;
   1939         } else if path.extension().and_then(|ext| ext.to_str()) == Some("json") {
   1940             paths.push(path);
   1941         }
   1942     }
   1943     Ok(())
   1944 }
   1945 
   1946 fn validate_conformance_vector_file(
   1947     path: &Path,
   1948     contract_version: &str,
   1949 ) -> Result<ConformanceVectorFile, String> {
   1950     let vector = parse_json::<ConformanceVectorFile>(path)?;
   1951     if vector.suite.trim().is_empty() {
   1952         return Err(format!(
   1953             "conformance vector {} suite must not be empty",
   1954             path.display()
   1955         ));
   1956     }
   1957     if vector.vectors.is_empty() {
   1958         return Err(format!(
   1959             "conformance vector {} must contain at least one vector",
   1960             path.display()
   1961         ));
   1962     }
   1963     if vector.contract_version != base_contract_version(contract_version) {
   1964         return Err(format!(
   1965             "conformance vector {} version {} must match contract version {}",
   1966             path.display(),
   1967             vector.contract_version,
   1968             base_contract_version(contract_version)
   1969         ));
   1970     }
   1971     let mut ids = BTreeSet::new();
   1972     for entry in &vector.vectors {
   1973         if entry.id.trim().is_empty() || entry.kind.trim().is_empty() {
   1974             return Err(format!(
   1975                 "conformance vector {} entries must define non-empty id and kind",
   1976                 path.display()
   1977             ));
   1978         }
   1979         if !ids.insert(entry.id.clone()) {
   1980             return Err(format!(
   1981                 "conformance vector {} has duplicate vector id {}",
   1982                 path.display(),
   1983                 entry.id
   1984             ));
   1985         }
   1986     }
   1987     Ok(vector)
   1988 }
   1989 
   1990 fn validate_all_conformance_vectors(
   1991     workspace_root: &Path,
   1992     contract_version: &str,
   1993 ) -> Result<(), String> {
   1994     let vectors_dir = conformance_root(workspace_root).join("vectors");
   1995     if !vectors_dir.is_dir() {
   1996         return validate_missing_conformance_vectors(workspace_root, &vectors_dir);
   1997     }
   1998     let mut paths = Vec::new();
   1999     collect_conformance_vector_paths(&vectors_dir, &mut paths)?;
   2000     if paths.is_empty() {
   2001         return Err(format!(
   2002             "conformance vectors directory {} must contain JSON vectors",
   2003             vectors_dir.display()
   2004         ));
   2005     }
   2006     for path in paths {
   2007         validate_conformance_vector_file(&path, contract_version)?;
   2008     }
   2009     Ok(())
   2010 }
   2011 
   2012 #[cfg(not(test))]
   2013 fn validate_missing_conformance_vectors(
   2014     _workspace_root: &Path,
   2015     vectors_dir: &Path,
   2016 ) -> Result<(), String> {
   2017     Err(format!(
   2018         "conformance vectors directory {} must exist",
   2019         vectors_dir.display()
   2020     ))
   2021 }
   2022 
   2023 #[cfg(test)]
   2024 #[cfg_attr(coverage_nightly, coverage(off))]
   2025 fn validate_missing_conformance_vectors(
   2026     _workspace_root: &Path,
   2027     _vectors_dir: &Path,
   2028 ) -> Result<(), String> {
   2029     Ok(())
   2030 }
   2031 
   2032 #[derive(Debug)]
   2033 struct WorkspacePackageRecord {
   2034     name: String,
   2035     #[cfg_attr(not(test), allow(dead_code))]
   2036     manifest_path: PathBuf,
   2037     publish_enabled: bool,
   2038     publish: Option<PackagePublish>,
   2039     manifest_value: toml::Value,
   2040 }
   2041 
   2042 fn workspace_package_records(workspace_root: &Path) -> Result<Vec<WorkspacePackageRecord>, String> {
   2043     let workspace_manifest =
   2044         parse_toml::<WorkspaceCargoManifest>(&workspace_root.join("Cargo.toml"))?;
   2045     let mut records = Vec::with_capacity(workspace_manifest.workspace.members.len());
   2046     for member in workspace_manifest.workspace.members {
   2047         let manifest_path = workspace_root.join(&member).join("Cargo.toml");
   2048         let raw = match fs::read_to_string(&manifest_path) {
   2049             Ok(raw) => raw,
   2050             Err(e) => return Err(format!("read {}: {e}", manifest_path.display())),
   2051         };
   2052         let manifest_value = match toml::from_str::<toml::Value>(&raw) {
   2053             Ok(value) => value,
   2054             Err(e) => return Err(format!("parse {}: {e}", manifest_path.display())),
   2055         };
   2056         let package_manifest = match toml::from_str::<PackageCargoManifest>(&raw) {
   2057             Ok(manifest) => manifest,
   2058             Err(e) => return Err(format!("parse {}: {e}", manifest_path.display())),
   2059         };
   2060         let name = package_manifest.package.name;
   2061         let publish_enabled = package_publish_enabled(package_manifest.package.publish.as_ref());
   2062         let publish = package_manifest.package.publish.clone();
   2063         records.push(WorkspacePackageRecord {
   2064             name,
   2065             manifest_path,
   2066             publish_enabled,
   2067             publish,
   2068             manifest_value,
   2069         });
   2070     }
   2071     Ok(records)
   2072 }
   2073 
   2074 fn workspace_package_names(workspace_root: &Path) -> Result<Vec<String>, String> {
   2075     Ok(workspace_package_records(workspace_root)?
   2076         .into_iter()
   2077         .map(|record| record.name)
   2078         .collect())
   2079 }
   2080 
   2081 fn coverage_required_workspace_crates(workspace_root: &Path) -> Result<BTreeSet<String>, String> {
   2082     let names = workspace_package_names(workspace_root)?
   2083         .into_iter()
   2084         .filter(|crate_name| !coverage_policy_excludes_workspace_crate(crate_name))
   2085         .collect::<Vec<_>>();
   2086     collect_unique_set(&names, "workspace coverage crates")
   2087 }
   2088 
   2089 fn coverage_policy_excludes_workspace_crate(crate_name: &str) -> bool {
   2090     crate_name.contains("_simplex_") || crate_name.starts_with("simplex_")
   2091 }
   2092 
   2093 #[cfg_attr(not(test), allow(dead_code))]
   2094 fn workspace_package_manifests(workspace_root: &Path) -> Result<BTreeMap<String, PathBuf>, String> {
   2095     let mut manifests = BTreeMap::new();
   2096     for record in workspace_package_records(workspace_root)? {
   2097         if manifests
   2098             .insert(record.name, record.manifest_path)
   2099             .is_some()
   2100         {
   2101             return Err("duplicate workspace package name in manifest map".to_string());
   2102         }
   2103     }
   2104     Ok(manifests)
   2105 }
   2106 
   2107 fn load_coverage_policy(
   2108     contract_root: &Path,
   2109 ) -> Result<crate::coverage::CoveragePolicyFile, String> {
   2110     read_coverage_policy(&coverage_root(contract_root).join("coverage.toml"))
   2111 }
   2112 
   2113 fn coverage_root(contract_root: &Path) -> PathBuf {
   2114     contract_root.to_path_buf()
   2115 }
   2116 
   2117 #[cfg_attr(not(test), allow(dead_code))]
   2118 fn root_release_policy_path(workspace_root: &Path) -> PathBuf {
   2119     workspace_root.join(ROOT_RELEASE_POLICY_RELATIVE)
   2120 }
   2121 
   2122 fn resolve_release_contract_path_with_override(
   2123     workspace_root: &Path,
   2124     release_policy_override: Option<PathBuf>,
   2125 ) -> Result<Option<PathBuf>, String> {
   2126     if let Some(path) = release_policy_override {
   2127         if !path.is_file() {
   2128             return Err(format!(
   2129                 "{RELEASE_POLICY_ENV} points to a missing release policy file: {}",
   2130                 path.display()
   2131             ));
   2132         }
   2133         return Ok(Some(path));
   2134     }
   2135 
   2136     for ancestor in workspace_root.ancestors() {
   2137         let candidate = ancestor.join(ROOT_RELEASE_POLICY_RELATIVE);
   2138         if candidate.is_file() {
   2139             return Ok(Some(candidate));
   2140         }
   2141     }
   2142 
   2143     Ok(None)
   2144 }
   2145 
   2146 fn resolve_release_contract_path(workspace_root: &Path) -> Result<Option<PathBuf>, String> {
   2147     resolve_release_contract_path_with_override(
   2148         workspace_root,
   2149         env::var_os(RELEASE_POLICY_ENV).map(PathBuf::from),
   2150     )
   2151 }
   2152 
   2153 fn load_release_contract(
   2154     workspace_root: &Path,
   2155     contract_root: &Path,
   2156 ) -> Result<ReleaseContractFile, String> {
   2157     load_release_contract_with_override(
   2158         workspace_root,
   2159         contract_root,
   2160         env::var_os(RELEASE_POLICY_ENV).map(PathBuf::from),
   2161     )
   2162 }
   2163 
   2164 fn load_release_contract_with_override(
   2165     workspace_root: &Path,
   2166     _contract_root: &Path,
   2167     release_policy_override: Option<PathBuf>,
   2168 ) -> Result<ReleaseContractFile, String> {
   2169     match resolve_release_contract_path_with_override(workspace_root, release_policy_override)? {
   2170         Some(path) => parse_toml::<ReleaseContractFile>(&path),
   2171         None => load_missing_release_contract(workspace_root),
   2172     }
   2173 }
   2174 
   2175 fn missing_release_contract_error() -> String {
   2176     format!(
   2177         "release publish policy not found; expected {}",
   2178         ROOT_RELEASE_POLICY_RELATIVE
   2179     )
   2180 }
   2181 
   2182 #[cfg(not(test))]
   2183 fn load_missing_release_contract(_workspace_root: &Path) -> Result<ReleaseContractFile, String> {
   2184     Err(missing_release_contract_error())
   2185 }
   2186 
   2187 #[cfg(test)]
   2188 #[cfg_attr(coverage_nightly, coverage(off))]
   2189 fn load_missing_release_contract(workspace_root: &Path) -> Result<ReleaseContractFile, String> {
   2190     if should_synthesize_owner_contracts_for_tests(workspace_root) {
   2191         let raw = synthetic_release_policy_for_workspace(workspace_root)?;
   2192         return toml::from_str::<ReleaseContractFile>(&raw)
   2193             .map_err(|e| format!("parse synthetic release policy: {e}"));
   2194     }
   2195     Err(missing_release_contract_error())
   2196 }
   2197 
   2198 #[cfg(test)]
   2199 #[cfg_attr(coverage_nightly, coverage(off))]
   2200 fn should_synthesize_owner_contracts_for_tests(workspace_root: &Path) -> bool {
   2201     workspace_root
   2202         .join("crates")
   2203         .join("core")
   2204         .join("Cargo.toml")
   2205         .is_file()
   2206         && workspace_root
   2207             .join("crates")
   2208             .join("events_codec")
   2209             .join("Cargo.toml")
   2210             .is_file()
   2211         && workspace_root
   2212             .join("crates")
   2213             .join("trade")
   2214             .join("Cargo.toml")
   2215             .is_file()
   2216         && workspace_root
   2217             .join("contracts")
   2218             .join("manifest.toml")
   2219             .is_file()
   2220         && workspace_root
   2221             .join("contracts")
   2222             .join("coverage.toml")
   2223             .is_file()
   2224 }
   2225 
   2226 fn package_publish_enabled(publish: Option<&PackagePublish>) -> bool {
   2227     match publish {
   2228         None => true,
   2229         Some(PackagePublish::Bool(flag)) => *flag,
   2230         Some(PackagePublish::Registries(registries)) => !registries.is_empty(),
   2231     }
   2232 }
   2233 
   2234 #[cfg_attr(not(test), allow(dead_code))]
   2235 fn workspace_package_publish_flags(
   2236     workspace_root: &Path,
   2237 ) -> Result<BTreeMap<String, bool>, String> {
   2238     let mut flags = BTreeMap::new();
   2239     for record in workspace_package_records(workspace_root)? {
   2240         if flags
   2241             .insert(record.name.clone(), record.publish_enabled)
   2242             .is_some()
   2243         {
   2244             return Err(format!("duplicate workspace package name {}", record.name));
   2245         }
   2246     }
   2247     Ok(flags)
   2248 }
   2249 
   2250 fn workspace_package_publish_configs(
   2251     workspace_root: &Path,
   2252 ) -> Result<BTreeMap<String, Option<PackagePublish>>, String> {
   2253     let mut configs = BTreeMap::new();
   2254     for record in workspace_package_records(workspace_root)? {
   2255         if configs
   2256             .insert(record.name.clone(), record.publish.clone())
   2257             .is_some()
   2258         {
   2259             return Err(format!("duplicate workspace package name {}", record.name));
   2260         }
   2261     }
   2262     Ok(configs)
   2263 }
   2264 
   2265 fn read_workspace_package_dependencies(
   2266     workspace_root: &Path,
   2267 ) -> Result<BTreeMap<String, BTreeSet<String>>, String> {
   2268     let package_records = workspace_package_records(workspace_root)?;
   2269     let workspace_names = package_records
   2270         .iter()
   2271         .map(|record| record.name.clone())
   2272         .collect::<BTreeSet<_>>();
   2273 
   2274     let mut deps = BTreeMap::new();
   2275     for record in package_records {
   2276         let mut package_deps = BTreeSet::new();
   2277         for section in ["dependencies", "build-dependencies"] {
   2278             let Some(table) = record
   2279                 .manifest_value
   2280                 .get(section)
   2281                 .and_then(toml::Value::as_table)
   2282             else {
   2283                 continue;
   2284             };
   2285             for dep_name in table.keys() {
   2286                 if workspace_names.contains(dep_name) {
   2287                     package_deps.insert(dep_name.clone());
   2288                 }
   2289             }
   2290         }
   2291         deps.insert(record.name, package_deps);
   2292     }
   2293 
   2294     Ok(deps)
   2295 }
   2296 
   2297 fn join_set(items: &BTreeSet<String>) -> String {
   2298     items.iter().cloned().collect::<Vec<_>>().join(", ")
   2299 }
   2300 
   2301 fn collect_unique_set(items: &[String], field: &str) -> Result<BTreeSet<String>, String> {
   2302     let mut set = BTreeSet::new();
   2303     for item in items {
   2304         if item.trim().is_empty() {
   2305             return Err(format!("{field} contains an empty crate name"));
   2306         }
   2307         if !set.insert(item.clone()) {
   2308             return Err(format!("{field} has duplicate crate {}", item));
   2309         }
   2310     }
   2311     Ok(set)
   2312 }
   2313 
   2314 fn collect_non_empty_set(items: &[String], field: &str) -> Result<BTreeSet<String>, String> {
   2315     let mut set = BTreeSet::new();
   2316     for item in items {
   2317         if item.trim().is_empty() {
   2318             return Err(format!("{field} contains an empty value"));
   2319         }
   2320         if !set.insert(item.clone()) {
   2321             return Err(format!("{field} has duplicate value {}", item));
   2322         }
   2323     }
   2324     Ok(set)
   2325 }
   2326 
   2327 fn validate_crate_identifier(value: &str, field: &str) -> Result<(), String> {
   2328     let trimmed = value.trim();
   2329     if trimmed.is_empty() {
   2330         return Err(format!("{field} is required"));
   2331     }
   2332     if trimmed != value
   2333         || trimmed.contains('/')
   2334         || trimmed.contains('\\')
   2335         || trimmed.contains("..")
   2336         || trimmed == "radroots_sdk"
   2337     {
   2338         return Err(format!("{field} must be a crate identifier"));
   2339     }
   2340     Ok(())
   2341 }
   2342 
   2343 fn validate_surface_metadata(surface: &Surface) -> Result<(), String> {
   2344     if let Some(tiers) = &surface.rust_crate_tiers {
   2345         let mut tier_crates = BTreeSet::new();
   2346         for (field, crates) in [
   2347             (
   2348                 "surface.rust_crate_tiers.advanced_substrate",
   2349                 &tiers.advanced_substrate,
   2350             ),
   2351             (
   2352                 "surface.rust_crate_tiers.published_support",
   2353                 &tiers.published_support,
   2354             ),
   2355             (
   2356                 "surface.rust_crate_tiers.deferred_publication",
   2357                 &tiers.deferred_publication,
   2358             ),
   2359         ] {
   2360             let entries = collect_unique_set(crates, field)?;
   2361             if entries.is_empty() {
   2362                 return Err(format!("{field} must not be empty"));
   2363             }
   2364             for crate_name in entries {
   2365                 if !tier_crates.insert(crate_name.clone()) {
   2366                     return Err(format!(
   2367                         "surface.rust_crate_tiers has duplicate crate {crate_name}"
   2368                     ));
   2369                 }
   2370             }
   2371         }
   2372     }
   2373 
   2374     if let Some(replica) = &surface.internal_replica_crates {
   2375         validate_crate_identifier(&replica.schema, "surface.internal_replica_crates.schema")?;
   2376         validate_crate_identifier(&replica.storage, "surface.internal_replica_crates.storage")?;
   2377         validate_crate_identifier(&replica.sync, "surface.internal_replica_crates.sync")?;
   2378     }
   2379 
   2380     Ok(())
   2381 }
   2382 
   2383 fn validate_policy_metadata(policy: &Policy) -> Result<(), String> {
   2384     if !policy.exclude_internal_workspace_crates
   2385         || !policy.require_reproducible_exports
   2386         || !policy.require_conformance_vectors
   2387     {
   2388         return Err("contract policy flags must all be true".to_string());
   2389     }
   2390     if let Some(replica) = &policy.replica {
   2391         if !replica.forbid_legacy_alias_identifiers
   2392             || !replica.require_transport_agnostic_sync_contract
   2393             || !replica.require_deterministic_emit_ingest
   2394         {
   2395             return Err("contract replica policy flags must all be true".to_string());
   2396         }
   2397     }
   2398     Ok(())
   2399 }
   2400 
   2401 fn validate_operations_contract(
   2402     bundle: &ContractBundle,
   2403     operations_manifest: &OperationsContractManifest,
   2404     workspace_root: &Path,
   2405 ) -> Result<(), String> {
   2406     validate_conformance_schema(workspace_root)?;
   2407     let conformance_root = conformance_root(workspace_root);
   2408     if operations_manifest.contract.name.trim().is_empty() {
   2409         return Err("operations contract name is required".to_string());
   2410     }
   2411     if operations_manifest.contract.version.trim().is_empty() {
   2412         return Err("operations contract version is required".to_string());
   2413     }
   2414     if operations_manifest.contract.source.trim().is_empty() {
   2415         return Err("operations contract source is required".to_string());
   2416     }
   2417     if operations_manifest.contract.name != bundle.manifest.contract.name {
   2418         return Err("operations contract name must match manifest contract name".to_string());
   2419     }
   2420     if operations_manifest.contract.version != bundle.manifest.contract.version {
   2421         return Err("operations contract version must match manifest contract version".to_string());
   2422     }
   2423     if operations_manifest.contract.source != bundle.manifest.contract.source {
   2424         return Err("operations contract source must match manifest contract source".to_string());
   2425     }
   2426 
   2427     let domains = collect_non_empty_set(&operations_manifest.public.domains, "public.domains")?;
   2428     if domains.is_empty() {
   2429         return Err("public.domains must not be empty".to_string());
   2430     }
   2431     let shared_types = collect_non_empty_set(
   2432         &operations_manifest.shared_types.public,
   2433         "shared_types.public",
   2434     )?;
   2435     if shared_types.is_empty() {
   2436         return Err("shared_types.public must not be empty".to_string());
   2437     }
   2438     let error_classes =
   2439         collect_non_empty_set(&operations_manifest.errors.classes, "errors.classes")?;
   2440     if error_classes.is_empty() {
   2441         return Err("errors.classes must not be empty".to_string());
   2442     }
   2443     if operations_manifest.operations.is_empty() {
   2444         return Err("operations map must not be empty".to_string());
   2445     }
   2446 
   2447     if let Some(provenance) = &operations_manifest.implementation_provenance {
   2448         let manifest_models = collect_unique_set(
   2449             &bundle.manifest.surface.model_crates,
   2450             "surface.model_crates",
   2451         )?;
   2452         let manifest_algorithms = collect_unique_set(
   2453             &bundle.manifest.surface.algorithm_crates,
   2454             "surface.algorithm_crates",
   2455         )?;
   2456         let provenance_models = collect_unique_set(
   2457             &provenance.model_crates,
   2458             "implementation_provenance.model_crates",
   2459         )?;
   2460         let provenance_algorithms = collect_unique_set(
   2461             &provenance.algorithm_crates,
   2462             "implementation_provenance.algorithm_crates",
   2463         )?;
   2464         if provenance_models != manifest_models || provenance_algorithms != manifest_algorithms {
   2465             return Err(
   2466                 "operations implementation_provenance must match manifest surface crates"
   2467                     .to_string(),
   2468             );
   2469         }
   2470     }
   2471 
   2472     let mut operation_ids = BTreeSet::new();
   2473     for (operation_key, operation) in &operations_manifest.operations {
   2474         if operation_key.trim().is_empty() {
   2475             return Err("operations map contains an empty key".to_string());
   2476         }
   2477         if operation.domain.trim().is_empty() {
   2478             return Err(format!("operation {} domain is required", operation_key));
   2479         }
   2480         if !domains.contains(&operation.domain) {
   2481             return Err(format!(
   2482                 "operation {} references unknown domain {}",
   2483                 operation_key, operation.domain
   2484             ));
   2485         }
   2486         if operation.id.trim().is_empty() {
   2487             return Err(format!("operation {} id is required", operation_key));
   2488         }
   2489         if !operation_ids.insert(operation.id.clone()) {
   2490             return Err(format!("operations has duplicate id {}", operation.id));
   2491         }
   2492         if operation.stability.trim().is_empty() {
   2493             return Err(format!("operation {} stability is required", operation.id));
   2494         }
   2495         if !operation.deterministic {
   2496             return Err(format!(
   2497                 "operation {} deterministic must be true for the public contract",
   2498                 operation.id
   2499             ));
   2500         }
   2501         if operation.inputs.is_empty() {
   2502             return Err(format!(
   2503                 "operation {} inputs must not be empty",
   2504                 operation.id
   2505             ));
   2506         }
   2507         let _ = collect_non_empty_set(
   2508             &operation.inputs,
   2509             &format!("operation {} inputs", operation.id),
   2510         )?;
   2511         if operation.outputs.is_empty() {
   2512             return Err(format!(
   2513                 "operation {} outputs must not be empty",
   2514                 operation.id
   2515             ));
   2516         }
   2517         let _ = collect_non_empty_set(
   2518             &operation.outputs,
   2519             &format!("operation {} outputs", operation.id),
   2520         )?;
   2521         if !error_classes.contains(&operation.error_class) {
   2522             return Err(format!(
   2523                 "operation {} references unknown error class {}",
   2524                 operation.id, operation.error_class
   2525             ));
   2526         }
   2527         if operation.signing.trim().is_empty() {
   2528             return Err(format!("operation {} signing is required", operation.id));
   2529         }
   2530         if operation.transport.trim().is_empty() {
   2531             return Err(format!("operation {} transport is required", operation.id));
   2532         }
   2533         if operation.implementation.rust_modules.is_empty() {
   2534             return Err(format!(
   2535                 "operation {} implementation.rust_modules must not be empty",
   2536                 operation.id
   2537             ));
   2538         }
   2539         let _ = collect_non_empty_set(
   2540             &operation.implementation.rust_types,
   2541             &format!("operation {} implementation.rust_types", operation.id),
   2542         )?;
   2543         for rust_module in &operation.implementation.rust_modules {
   2544             if rust_module.trim().is_empty() {
   2545                 return Err(format!(
   2546                     "operation {} implementation.rust_modules contains an empty value",
   2547                     operation.id
   2548                 ));
   2549             }
   2550             let path = workspace_root.join(rust_module);
   2551             if !path.is_file() {
   2552                 return Err(format!(
   2553                     "operation {} references missing rust module {}",
   2554                     operation.id, rust_module
   2555                 ));
   2556             }
   2557         }
   2558         if operation.conformance.vector.trim().is_empty() {
   2559             return Err(format!(
   2560                 "operation {} conformance.vector is required",
   2561                 operation.id
   2562             ));
   2563         }
   2564         if !operation
   2565             .conformance
   2566             .vector
   2567             .starts_with("contracts/conformance/")
   2568         {
   2569             return Err(format!(
   2570                 "operation {} conformance.vector must live under contracts/conformance/",
   2571                 operation.id
   2572             ));
   2573         }
   2574         let vector_path = workspace_root.join(&operation.conformance.vector);
   2575         if !vector_path.starts_with(&conformance_root) {
   2576             return Err(format!(
   2577                 "operation {} conformance.vector must resolve under {}",
   2578                 operation.id,
   2579                 conformance_root.display()
   2580             ));
   2581         }
   2582         validate_conformance_vector_file(&vector_path, &operations_manifest.contract.version)?;
   2583     }
   2584 
   2585     Ok(())
   2586 }
   2587 
   2588 fn package_field_configured(table: &toml::value::Table, field: &str) -> bool {
   2589     let Some(value) = table.get(field) else {
   2590         return false;
   2591     };
   2592     match value {
   2593         toml::Value::String(raw) => !raw.trim().is_empty(),
   2594         toml::Value::Table(inner) => inner
   2595             .get("workspace")
   2596             .and_then(toml::Value::as_bool)
   2597             .is_some_and(|configured| configured),
   2598         _ => false,
   2599     }
   2600 }
   2601 
   2602 fn validate_publish_package_metadata(
   2603     workspace_root: &Path,
   2604     publish_crates: &BTreeSet<String>,
   2605 ) -> Result<(), String> {
   2606     let mut package_tables = BTreeMap::new();
   2607     for record in workspace_package_records(workspace_root)? {
   2608         if package_tables
   2609             .insert(record.name, record.manifest_value)
   2610             .is_some()
   2611         {
   2612             return Err("duplicate workspace package name in package metadata map".to_string());
   2613         }
   2614     }
   2615     for crate_name in publish_crates {
   2616         let parsed = match package_tables.get(crate_name) {
   2617             Some(parsed) => parsed,
   2618             None => {
   2619                 return Err(format!(
   2620                     "publish crate {} has no workspace manifest",
   2621                     crate_name
   2622                 ));
   2623             }
   2624         };
   2625         let package = parsed
   2626             .get("package")
   2627             .and_then(toml::Value::as_table)
   2628             .expect("workspace package records include [package] table");
   2629 
   2630         if !package_field_configured(package, "description") {
   2631             return Err(format!(
   2632                 "publish crate {} must define a non-empty package.description",
   2633                 crate_name
   2634             ));
   2635         }
   2636         for field in ["repository", "homepage", "documentation", "readme"] {
   2637             if !package_field_configured(package, field) {
   2638                 return Err(format!(
   2639                     "publish crate {} must configure package.{}",
   2640                     crate_name, field
   2641                 ));
   2642             }
   2643         }
   2644     }
   2645     Ok(())
   2646 }
   2647 
   2648 fn parse_coverage_percent(raw: &str, field: &str, crate_name: &str) -> Result<f64, String> {
   2649     match raw.parse::<f64>() {
   2650         Ok(value) => Ok(value),
   2651         Err(e) => Err(format!("parse {} for {}: {e}", field, crate_name)),
   2652     }
   2653 }
   2654 
   2655 fn parse_branch_coverage_percent(raw: &str, crate_name: &str) -> Result<Option<f64>, String> {
   2656     if raw == "unavailable" {
   2657         return Ok(None);
   2658     }
   2659     parse_coverage_percent(raw, "branch", crate_name).map(Some)
   2660 }
   2661 
   2662 fn branch_coverage_fails(branch: Option<f64>, thresholds: CoverageThresholds) -> bool {
   2663     match branch {
   2664         Some(value) => value < thresholds.fail_under_branches,
   2665         None => thresholds.require_branches,
   2666     }
   2667 }
   2668 
   2669 fn branch_coverage_display(branch: Option<f64>) -> String {
   2670     branch
   2671         .map(|value| value.to_string())
   2672         .unwrap_or_else(|| "unavailable".to_string())
   2673 }
   2674 
   2675 #[derive(Debug)]
   2676 struct CoverageRefreshRow {
   2677     status: String,
   2678     exec: f64,
   2679     func: f64,
   2680     branch: Option<f64>,
   2681     region: f64,
   2682     report_path: PathBuf,
   2683 }
   2684 
   2685 #[derive(Debug, Deserialize)]
   2686 struct CoverageGateReportForValidation {
   2687     scope: String,
   2688     thresholds: CoverageGateReportThresholdsForValidation,
   2689     measured: CoverageGateReportMeasuredForValidation,
   2690     result: CoverageGateReportResultForValidation,
   2691 }
   2692 
   2693 #[derive(Debug, Deserialize)]
   2694 struct CoverageGateReportThresholdsForValidation {
   2695     executable_lines: f64,
   2696     functions: f64,
   2697     regions: f64,
   2698     branches: f64,
   2699     branches_required: bool,
   2700 }
   2701 
   2702 #[derive(Debug, Deserialize)]
   2703 struct CoverageGateReportMeasuredForValidation {
   2704     executable_lines_percent: f64,
   2705     functions_percent: f64,
   2706     branches_percent: Option<f64>,
   2707     branches_available: bool,
   2708     summary_regions_percent: f64,
   2709 }
   2710 
   2711 #[derive(Debug, Deserialize)]
   2712 struct CoverageGateReportResultForValidation {
   2713     pass: bool,
   2714 }
   2715 
   2716 type CoverageRefreshRows = BTreeMap<String, CoverageRefreshRow>;
   2717 
   2718 fn coverage_refresh_report_path(
   2719     workspace_root: &Path,
   2720     report_path: &Path,
   2721     raw_report_path: &str,
   2722     crate_name: &str,
   2723 ) -> Result<PathBuf, String> {
   2724     let trimmed = raw_report_path.trim();
   2725     if trimmed.is_empty() {
   2726         return Err(format!(
   2727             "coverage row for crate {} in {} must include a report path",
   2728             crate_name,
   2729             report_path.display()
   2730         ));
   2731     }
   2732     let path = Path::new(trimmed);
   2733     if path.is_absolute() {
   2734         Ok(path.to_path_buf())
   2735     } else {
   2736         Ok(workspace_root.join(path))
   2737     }
   2738 }
   2739 
   2740 fn load_coverage_refresh_rows(workspace_root: &Path) -> Result<CoverageRefreshRows, String> {
   2741     let report_path = workspace_root
   2742         .join("target")
   2743         .join("coverage")
   2744         .join("coverage-refresh.tsv");
   2745     let raw = match fs::read_to_string(&report_path) {
   2746         Ok(raw) => raw,
   2747         Err(e) => return Err(format!("read {}: {e}", report_path.display())),
   2748     };
   2749     let mut rows = BTreeMap::new();
   2750     for line in raw.lines().skip(1) {
   2751         let trimmed = line.trim();
   2752         if trimmed.is_empty() {
   2753             continue;
   2754         }
   2755         let parts = trimmed.split('\t').collect::<Vec<_>>();
   2756         if parts.len() < 7 {
   2757             return Err(format!(
   2758                 "coverage row must have at least 7 columns in {}: {}",
   2759                 report_path.display(),
   2760                 trimmed
   2761             ));
   2762         }
   2763         let crate_name = parts[0].to_string();
   2764         let status = parts[1].to_string();
   2765         let exec = parse_coverage_percent(parts[2], "exec", &crate_name)?;
   2766         let func = parse_coverage_percent(parts[3], "func", &crate_name)?;
   2767         let branch = parse_branch_coverage_percent(parts[4], &crate_name)?;
   2768         let region = parse_coverage_percent(parts[5], "region", &crate_name)?;
   2769         let row_report_path =
   2770             coverage_refresh_report_path(workspace_root, &report_path, parts[6], &crate_name)?;
   2771         if rows
   2772             .insert(
   2773                 crate_name.clone(),
   2774                 CoverageRefreshRow {
   2775                     status,
   2776                     exec,
   2777                     func,
   2778                     branch,
   2779                     region,
   2780                     report_path: row_report_path,
   2781                 },
   2782             )
   2783             .is_some()
   2784         {
   2785             return Err(format!(
   2786                 "duplicate coverage row for crate {} in {}",
   2787                 crate_name,
   2788                 report_path.display()
   2789             ));
   2790         }
   2791     }
   2792     Ok(rows)
   2793 }
   2794 
   2795 #[cfg_attr(not(test), allow(dead_code))]
   2796 fn validate_required_coverage_summary(
   2797     workspace_root: &Path,
   2798     required_crates: &BTreeSet<String>,
   2799     thresholds: CoverageThresholds,
   2800 ) -> Result<(), String> {
   2801     let rows = load_coverage_refresh_rows(workspace_root)?;
   2802     for crate_name in required_crates {
   2803         let row = rows.get(crate_name).ok_or_else(|| {
   2804             format!(
   2805                 "required coverage crate {} missing from coverage-refresh.tsv",
   2806                 crate_name
   2807             )
   2808         })?;
   2809         if row.status != "pass" {
   2810             return Err(format!(
   2811                 "required coverage crate {} has non-pass status {}",
   2812                 crate_name, row.status
   2813             ));
   2814         }
   2815         if row.exec < thresholds.fail_under_exec_lines
   2816             || row.func < thresholds.fail_under_functions
   2817             || branch_coverage_fails(row.branch, thresholds)
   2818             || row.region < thresholds.fail_under_regions
   2819         {
   2820             return Err(format!(
   2821                 "required coverage crate {} must satisfy coverage policy {},{},{},{}, found {}/{}/{}/{}",
   2822                 crate_name,
   2823                 thresholds.fail_under_exec_lines,
   2824                 thresholds.fail_under_functions,
   2825                 thresholds.fail_under_branches,
   2826                 thresholds.fail_under_regions,
   2827                 row.exec,
   2828                 row.func,
   2829                 branch_coverage_display(row.branch),
   2830                 row.region
   2831             ));
   2832         }
   2833     }
   2834     Ok(())
   2835 }
   2836 
   2837 fn read_coverage_gate_report(
   2838     path: &Path,
   2839     crate_name: &str,
   2840 ) -> Result<CoverageGateReportForValidation, String> {
   2841     let raw = match fs::read_to_string(path) {
   2842         Ok(raw) => raw,
   2843         Err(e) => {
   2844             return Err(format!(
   2845                 "read coverage gate report for {} at {}: {e}",
   2846                 crate_name,
   2847                 path.display()
   2848             ));
   2849         }
   2850     };
   2851     serde_json::from_str::<CoverageGateReportForValidation>(&raw).map_err(|e| {
   2852         format!(
   2853             "parse coverage gate report for {} at {}: {e}",
   2854             crate_name,
   2855             path.display()
   2856         )
   2857     })
   2858 }
   2859 
   2860 fn coverage_percent_matches(left: f64, right: f64) -> bool {
   2861     (left - right).abs() <= COVERAGE_REPORT_EPSILON
   2862 }
   2863 
   2864 fn coverage_branch_percent_matches(left: Option<f64>, right: Option<f64>) -> bool {
   2865     match (left, right) {
   2866         (Some(left), Some(right)) => coverage_percent_matches(left, right),
   2867         (None, None) => true,
   2868         _ => false,
   2869     }
   2870 }
   2871 
   2872 fn coverage_gate_report_thresholds_match(
   2873     report: &CoverageGateReportThresholdsForValidation,
   2874     thresholds: CoverageThresholds,
   2875 ) -> bool {
   2876     coverage_percent_matches(report.executable_lines, thresholds.fail_under_exec_lines)
   2877         && coverage_percent_matches(report.functions, thresholds.fail_under_functions)
   2878         && coverage_percent_matches(report.regions, thresholds.fail_under_regions)
   2879         && coverage_percent_matches(report.branches, thresholds.fail_under_branches)
   2880         && report.branches_required == thresholds.require_branches
   2881 }
   2882 
   2883 fn validate_coverage_gate_report_for_row(
   2884     crate_name: &str,
   2885     row: &CoverageRefreshRow,
   2886     thresholds: CoverageThresholds,
   2887 ) -> Result<(), String> {
   2888     let report = read_coverage_gate_report(&row.report_path, crate_name)?;
   2889     if report.scope != crate_name {
   2890         return Err(format!(
   2891             "coverage gate report {} has scope {}, expected {}",
   2892             row.report_path.display(),
   2893             report.scope,
   2894             crate_name
   2895         ));
   2896     }
   2897     if !coverage_gate_report_thresholds_match(&report.thresholds, thresholds) {
   2898         return Err(format!(
   2899             "coverage gate report {} for {} thresholds do not match policy",
   2900             row.report_path.display(),
   2901             crate_name
   2902         ));
   2903     }
   2904     if !report.result.pass {
   2905         return Err(format!(
   2906             "coverage gate report {} for {} has non-pass result",
   2907             row.report_path.display(),
   2908             crate_name
   2909         ));
   2910     }
   2911     if report.measured.branches_available != report.measured.branches_percent.is_some() {
   2912         return Err(format!(
   2913             "coverage gate report {} for {} has inconsistent branch measurement",
   2914             row.report_path.display(),
   2915             crate_name
   2916         ));
   2917     }
   2918     if !coverage_percent_matches(row.exec, report.measured.executable_lines_percent)
   2919         || !coverage_percent_matches(row.func, report.measured.functions_percent)
   2920         || !coverage_branch_percent_matches(row.branch, report.measured.branches_percent)
   2921         || !coverage_percent_matches(row.region, report.measured.summary_regions_percent)
   2922     {
   2923         return Err(format!(
   2924             "coverage row for {} does not match coverage gate report {}",
   2925             crate_name,
   2926             row.report_path.display()
   2927         ));
   2928     }
   2929     Ok(())
   2930 }
   2931 
   2932 fn validate_required_coverage_summary_with_policy(
   2933     workspace_root: &Path,
   2934     required_crates: &BTreeSet<String>,
   2935     policy: &CoveragePolicyFile,
   2936 ) -> Result<(), String> {
   2937     let rows = load_coverage_refresh_rows(workspace_root)?;
   2938     for crate_name in required_crates {
   2939         let row = rows.get(crate_name).ok_or_else(|| {
   2940             format!(
   2941                 "required coverage crate {} missing from coverage-refresh.tsv",
   2942                 crate_name
   2943             )
   2944         })?;
   2945         if row.status != "pass" {
   2946             return Err(format!(
   2947                 "required coverage crate {} has non-pass status {}",
   2948                 crate_name, row.status
   2949             ));
   2950         }
   2951         let thresholds = policy.thresholds_for_scope(crate_name);
   2952         validate_coverage_gate_report_for_row(crate_name, row, thresholds)?;
   2953         if row.exec < thresholds.fail_under_exec_lines
   2954             || row.func < thresholds.fail_under_functions
   2955             || branch_coverage_fails(row.branch, thresholds)
   2956             || row.region < thresholds.fail_under_regions
   2957         {
   2958             return Err(format!(
   2959                 "required coverage crate {} must satisfy coverage policy {},{},{},{}, found {}/{}/{}/{}",
   2960                 crate_name,
   2961                 thresholds.fail_under_exec_lines,
   2962                 thresholds.fail_under_functions,
   2963                 thresholds.fail_under_branches,
   2964                 thresholds.fail_under_regions,
   2965                 row.exec,
   2966                 row.func,
   2967                 branch_coverage_display(row.branch),
   2968                 row.region
   2969             ));
   2970         }
   2971     }
   2972     Ok(())
   2973 }
   2974 
   2975 const CORE_UNIT_DIMENSION_ENUM: &str = "RadrootsCoreUnitDimension";
   2976 const CORE_UNIT_DIMENSION_ORDER: [&str; 3] = ["Count", "Mass", "Volume"];
   2977 
   2978 fn extract_enum_body<'a>(source: &'a str, enum_name: &str) -> Result<&'a str, String> {
   2979     let marker = format!("pub enum {enum_name}");
   2980     let enum_start = match source.find(&marker) {
   2981         Some(index) => index,
   2982         None => return Err(format!("missing enum {enum_name}")),
   2983     };
   2984     let after_start = &source[enum_start..];
   2985     let open_rel = match after_start.find('{') {
   2986         Some(index) => index,
   2987         None => return Err(format!("missing opening brace for enum {enum_name}")),
   2988     };
   2989     let open_idx = enum_start + open_rel;
   2990     let mut depth = 0usize;
   2991     for (offset, ch) in source[open_idx..].char_indices() {
   2992         if ch == '{' {
   2993             depth += 1;
   2994             continue;
   2995         }
   2996         if ch != '}' {
   2997             continue;
   2998         }
   2999         depth = depth.saturating_sub(1);
   3000         if depth == 0 {
   3001             let close_idx = open_idx + offset;
   3002             return Ok(&source[(open_idx + 1)..close_idx]);
   3003         }
   3004     }
   3005     Err(format!("missing closing brace for enum {enum_name}"))
   3006 }
   3007 
   3008 fn parse_enum_variants(enum_body: &str) -> Vec<String> {
   3009     enum_body
   3010         .lines()
   3011         .filter_map(|line| {
   3012             let trimmed = line.trim();
   3013             if trimmed.is_empty() || trimmed.starts_with('#') || trimmed.starts_with("//") {
   3014                 return None;
   3015             }
   3016             let before_comma = trimmed
   3017                 .split_once(',')
   3018                 .map_or(trimmed, |(head, _)| head)
   3019                 .trim();
   3020             if before_comma.is_empty() {
   3021                 return None;
   3022             }
   3023             let before_discriminant = before_comma
   3024                 .split_once('=')
   3025                 .map_or(before_comma, |(head, _)| head)
   3026                 .trim();
   3027             if before_discriminant.is_empty() {
   3028                 return None;
   3029             }
   3030             let ident = before_discriminant
   3031                 .split_whitespace()
   3032                 .next()
   3033                 .unwrap_or_default();
   3034             Some(ident.to_string())
   3035         })
   3036         .collect()
   3037 }
   3038 
   3039 fn validate_core_unit_dimension_variant_order(workspace_root: &Path) -> Result<(), String> {
   3040     let source_path = workspace_root
   3041         .join("crates")
   3042         .join("core")
   3043         .join("src")
   3044         .join("unit.rs");
   3045     let source = match fs::read_to_string(&source_path) {
   3046         Ok(source) => source,
   3047         Err(e) => return Err(format!("read {}: {e}", source_path.display())),
   3048     };
   3049     let enum_body = extract_enum_body(&source, CORE_UNIT_DIMENSION_ENUM)?;
   3050     let variants = parse_enum_variants(enum_body);
   3051     let expected = CORE_UNIT_DIMENSION_ORDER
   3052         .iter()
   3053         .map(|item| (*item).to_string())
   3054         .collect::<Vec<_>>();
   3055     if variants != expected {
   3056         return Err(format!(
   3057             "core unit dimension variant order must be {} but was {}",
   3058             CORE_UNIT_DIMENSION_ORDER.join(", "),
   3059             variants.join(", ")
   3060         ));
   3061     }
   3062     Ok(())
   3063 }
   3064 
   3065 fn validate_coverage_policy_parity(
   3066     workspace_root: &Path,
   3067     contract_root: &Path,
   3068 ) -> Result<(), String> {
   3069     let policy = load_coverage_policy(contract_root)?;
   3070     let thresholds = policy.thresholds();
   3071     if thresholds.fail_under_exec_lines != COVERAGE_REQUIRED_THRESHOLD
   3072         || thresholds.fail_under_functions != COVERAGE_REQUIRED_THRESHOLD
   3073         || thresholds.fail_under_regions != COVERAGE_REQUIRED_THRESHOLD
   3074         || thresholds.fail_under_branches != COVERAGE_REQUIRED_THRESHOLD
   3075         || !thresholds.require_branches
   3076     {
   3077         return Err(format!(
   3078             "coverage policy must enforce {COVERAGE_REQUIRED_THRESHOLD_LABEL} with required branches"
   3079         ));
   3080     }
   3081 
   3082     let required_packages = policy
   3083         .required_crate_entries()
   3084         .iter()
   3085         .cloned()
   3086         .collect::<BTreeSet<_>>();
   3087     let expected_packages = coverage_required_workspace_crates(workspace_root)?;
   3088     if expected_packages != required_packages {
   3089         let missing = expected_packages
   3090             .difference(&required_packages)
   3091             .cloned()
   3092             .collect::<BTreeSet<_>>();
   3093         let extra = required_packages
   3094             .difference(&expected_packages)
   3095             .cloned()
   3096             .collect::<BTreeSet<_>>();
   3097         return Err(format!(
   3098             "coverage policy missing workspace crates: {}; coverage policy includes excluded or unknown crates: {}",
   3099             join_set(&missing),
   3100             join_set(&extra)
   3101         ));
   3102     }
   3103 
   3104     Ok(())
   3105 }
   3106 
   3107 fn publish_config_is_public(publish: Option<&PackagePublish>) -> bool {
   3108     matches!(
   3109         publish,
   3110         Some(PackagePublish::Registries(registries))
   3111             if registries.len() == 1 && registries[0] == "crates-io"
   3112     )
   3113 }
   3114 
   3115 fn publish_config_is_non_public(publish: Option<&PackagePublish>) -> bool {
   3116     matches!(publish, Some(PackagePublish::Bool(false)))
   3117 }
   3118 
   3119 fn validate_release_publish_policy(
   3120     workspace_root: &Path,
   3121     contract_root: &Path,
   3122     contract_version: &str,
   3123 ) -> Result<(), String> {
   3124     let release = load_release_contract(workspace_root, contract_root)?;
   3125     if release.release.version.trim().is_empty() {
   3126         return Err("release.version must not be empty".to_string());
   3127     }
   3128     if release.release.version != contract_version {
   3129         return Err(format!(
   3130             "release.version {} must match contract version {}",
   3131             release.release.version, contract_version
   3132         ));
   3133     }
   3134 
   3135     let workspace_packages = workspace_package_names(workspace_root)?
   3136         .into_iter()
   3137         .collect::<BTreeSet<_>>();
   3138     let uses_classification = release.uses_classification();
   3139     let public_field = if uses_classification {
   3140         "classification.public"
   3141     } else {
   3142         "publish.crates"
   3143     };
   3144     let internal_field = if uses_classification {
   3145         "classification.internal"
   3146     } else {
   3147         "internal.crates"
   3148     };
   3149 
   3150     let public_set = collect_unique_set(&release.public_crates(), public_field)?;
   3151     let internal_set = collect_unique_set(&release.internal_crates(), internal_field)?;
   3152     let deferred_set = collect_unique_set(&release.deferred_crates(), "classification.deferred")?;
   3153     let retired_set = collect_unique_set(&release.retired_crates(), "classification.retired")?;
   3154     let yank_only_set =
   3155         collect_unique_set(&release.yank_only_crates(), "classification.yank_only")?;
   3156     let publish_order = &release.publish_order.crates;
   3157     let publish_order_set = collect_unique_set(publish_order, "publish_order.crates")?;
   3158 
   3159     let class_sets = [
   3160         ("public", &public_set),
   3161         ("internal", &internal_set),
   3162         ("deferred", &deferred_set),
   3163         ("retired", &retired_set),
   3164         ("yank-only", &yank_only_set),
   3165     ];
   3166     for idx in 0..class_sets.len() {
   3167         for other_idx in (idx + 1)..class_sets.len() {
   3168             let overlap = class_sets[idx]
   3169                 .1
   3170                 .intersection(class_sets[other_idx].1)
   3171                 .cloned()
   3172                 .collect::<BTreeSet<_>>();
   3173             if !overlap.is_empty() {
   3174                 return Err(format!(
   3175                     "release classification overlap is not allowed between {} and {}: {}",
   3176                     class_sets[idx].0,
   3177                     class_sets[other_idx].0,
   3178                     join_set(&overlap)
   3179                 ));
   3180             }
   3181         }
   3182     }
   3183 
   3184     let mut combined = public_set.clone();
   3185     combined.extend(internal_set.iter().cloned());
   3186     combined.extend(deferred_set.iter().cloned());
   3187     combined.extend(retired_set.iter().cloned());
   3188     combined.extend(yank_only_set.iter().cloned());
   3189     if combined != workspace_packages {
   3190         let missing = workspace_packages
   3191             .difference(&combined)
   3192             .cloned()
   3193             .collect::<BTreeSet<_>>();
   3194         let extra = combined
   3195             .difference(&workspace_packages)
   3196             .cloned()
   3197             .collect::<BTreeSet<_>>();
   3198         return Err(format!(
   3199             "release classification sets are missing workspace crates: {}; release classification sets include unknown crates: {}",
   3200             join_set(&missing),
   3201             join_set(&extra)
   3202         ));
   3203     }
   3204 
   3205     if publish_order_set != public_set {
   3206         let missing = public_set
   3207             .difference(&publish_order_set)
   3208             .cloned()
   3209             .collect::<BTreeSet<_>>();
   3210         let extra = publish_order_set
   3211             .difference(&public_set)
   3212             .cloned()
   3213             .collect::<BTreeSet<_>>();
   3214         return Err(format!(
   3215             "publish_order.crates is missing publish crates: {}; publish_order.crates has non-publish crates: {}",
   3216             join_set(&missing),
   3217             join_set(&extra)
   3218         ));
   3219     }
   3220 
   3221     let order_index = publish_order
   3222         .iter()
   3223         .enumerate()
   3224         .map(|(idx, name)| (name.clone(), idx))
   3225         .collect::<BTreeMap<_, _>>();
   3226     let dependencies = read_workspace_package_dependencies(workspace_root)
   3227         .expect("workspace package manifests were already parsed");
   3228     for crate_name in &public_set {
   3229         let crate_deps = &dependencies[crate_name];
   3230         let crate_order = order_index[crate_name];
   3231         for dep in crate_deps {
   3232             if !public_set.contains(dep) {
   3233                 continue;
   3234             }
   3235             let dep_order = order_index[dep];
   3236             if dep_order >= crate_order {
   3237                 return Err(format!(
   3238                     "publish order must place dependency {} before {}",
   3239                     dep, crate_name
   3240                 ));
   3241             }
   3242         }
   3243     }
   3244 
   3245     let publish_configs = workspace_package_publish_configs(workspace_root)
   3246         .expect("workspace publish configs are stable");
   3247     for crate_name in &public_set {
   3248         let publish = publish_configs[crate_name].as_ref();
   3249         if !publish_config_is_public(publish) {
   3250             return Err(format!(
   3251                 "public crate {} must set publish = [\"crates-io\"]",
   3252                 crate_name
   3253             ));
   3254         }
   3255     }
   3256     for crate_name in internal_set
   3257         .iter()
   3258         .chain(deferred_set.iter())
   3259         .chain(retired_set.iter())
   3260         .chain(yank_only_set.iter())
   3261     {
   3262         let publish = publish_configs[crate_name].as_ref();
   3263         if !publish_config_is_non_public(publish) {
   3264             return Err(format!(
   3265                 "non-public crate {} must set publish = false",
   3266                 crate_name
   3267             ));
   3268         }
   3269     }
   3270 
   3271     Ok(())
   3272 }
   3273 
   3274 pub fn validate_release_preflight(workspace_root: &Path) -> Result<(), String> {
   3275     validate_release_preflight_with_override(workspace_root, None)
   3276 }
   3277 
   3278 pub fn validate_release_preflight_with_override(
   3279     workspace_root: &Path,
   3280     release_policy_override: Option<PathBuf>,
   3281 ) -> Result<(), String> {
   3282     let bundle = load_contract_bundle(workspace_root)?;
   3283     validate_contract_bundle_with_release_policy_override(
   3284         &bundle,
   3285         release_policy_override.clone(),
   3286     )?;
   3287     let release =
   3288         load_release_contract_with_override(workspace_root, &bundle.root, release_policy_override)?;
   3289     let policy =
   3290         load_coverage_policy(&bundle.root).expect("validated contract includes coverage policy");
   3291     let publish_crates = collect_unique_set(
   3292         &release.public_crates(),
   3293         if release.uses_classification() {
   3294             "classification.public"
   3295         } else {
   3296             "publish.crates"
   3297         },
   3298     )
   3299     .expect("validated contract enforces unique public crates");
   3300     let required_crate_list = policy
   3301         .required_crates()
   3302         .expect("validated contract includes required crates");
   3303     let required_crates = collect_unique_set(&required_crate_list, "required.crates")
   3304         .expect("validated contract enforces unique required.crates");
   3305     validate_publish_package_metadata(workspace_root, &publish_crates)?;
   3306     validate_required_coverage_summary_with_policy(workspace_root, &required_crates, &policy)?;
   3307     Ok(())
   3308 }
   3309 
   3310 fn validate_contract_bundle_with_release_policy_override(
   3311     bundle: &ContractBundle,
   3312     release_policy_override: Option<PathBuf>,
   3313 ) -> Result<(), String> {
   3314     if bundle.manifest.contract.name.trim().is_empty() {
   3315         return Err("contract name is required".to_string());
   3316     }
   3317     if bundle.manifest.contract.version.trim().is_empty() {
   3318         return Err("contract version is required".to_string());
   3319     }
   3320     if bundle.manifest.contract.source.trim().is_empty() {
   3321         return Err("contract source is required".to_string());
   3322     }
   3323     if bundle.manifest.surface.model_crates.is_empty() {
   3324         return Err("contract surface.model_crates must not be empty".to_string());
   3325     }
   3326     if bundle.manifest.surface.algorithm_crates.is_empty() {
   3327         return Err("contract surface.algorithm_crates must not be empty".to_string());
   3328     }
   3329     validate_surface_metadata(&bundle.manifest.surface)?;
   3330     if bundle.version.contract.version.trim().is_empty() {
   3331         return Err("version.contract.version is required".to_string());
   3332     }
   3333     if bundle.version.contract.stability.trim().is_empty() {
   3334         return Err("version.contract.stability is required".to_string());
   3335     }
   3336     if bundle.version.semver.major_on.is_empty()
   3337         || bundle.version.semver.minor_on.is_empty()
   3338         || bundle.version.semver.patch_on.is_empty()
   3339     {
   3340         return Err("version.semver rules must all be non-empty".to_string());
   3341     }
   3342     if !bundle.version.compatibility.requires_conformance_pass {
   3343         return Err("compatibility.requires_conformance_pass must be true".to_string());
   3344     }
   3345     if !bundle.version.compatibility.requires_contract_manifest_diff {
   3346         return Err("compatibility.requires_contract_manifest_diff must be true".to_string());
   3347     }
   3348     if !bundle.version.compatibility.requires_release_notes {
   3349         return Err("compatibility.requires_release_notes must be true".to_string());
   3350     }
   3351     validate_policy_metadata(&bundle.manifest.policy)?;
   3352     let workspace_root = bundle
   3353         .root
   3354         .parent()
   3355         .expect("contract root must have a workspace parent");
   3356     if let Some(operations_manifest) = bundle.operations_manifest.as_ref() {
   3357         validate_operations_contract(bundle, operations_manifest, workspace_root)?;
   3358     }
   3359     validate_all_conformance_vectors(workspace_root, &bundle.manifest.contract.version)?;
   3360     validate_core_unit_dimension_variant_order(workspace_root)?;
   3361     validate_coverage_policy_parity(workspace_root, &bundle.root)?;
   3362     if resolve_release_contract_path_with_override(workspace_root, release_policy_override.clone())
   3363         .expect("validated release contract path resolution should not fail")
   3364         .is_some()
   3365     {
   3366         validate_release_publish_policy_with_override(
   3367             workspace_root,
   3368             &bundle.root,
   3369             bundle.version.contract.version.as_str(),
   3370             release_policy_override,
   3371         )?;
   3372     }
   3373     Ok(())
   3374 }
   3375 
   3376 fn validate_release_publish_policy_with_override(
   3377     workspace_root: &Path,
   3378     contract_root: &Path,
   3379     contract_version: &str,
   3380     release_policy_override: Option<PathBuf>,
   3381 ) -> Result<(), String> {
   3382     let release = load_release_contract_with_override(
   3383         workspace_root,
   3384         contract_root,
   3385         release_policy_override,
   3386     )?;
   3387     if release.release.version.trim().is_empty() {
   3388         return Err("release.version must not be empty".to_string());
   3389     }
   3390     if release.release.version != contract_version {
   3391         return Err(format!(
   3392             "release.version {} must match contract version {}",
   3393             release.release.version, contract_version
   3394         ));
   3395     }
   3396 
   3397     let workspace_packages = workspace_package_names(workspace_root)?
   3398         .into_iter()
   3399         .collect::<BTreeSet<_>>();
   3400     let uses_classification = release.uses_classification();
   3401     let public_field = if uses_classification {
   3402         "classification.public"
   3403     } else {
   3404         "publish.crates"
   3405     };
   3406     let internal_field = if uses_classification {
   3407         "classification.internal"
   3408     } else {
   3409         "internal.crates"
   3410     };
   3411 
   3412     let public_set = collect_unique_set(&release.public_crates(), public_field)?;
   3413     let internal_set = collect_unique_set(&release.internal_crates(), internal_field)?;
   3414     let deferred_set = collect_unique_set(&release.deferred_crates(), "classification.deferred")?;
   3415     let retired_set = collect_unique_set(&release.retired_crates(), "classification.retired")?;
   3416     let yank_only_set =
   3417         collect_unique_set(&release.yank_only_crates(), "classification.yank_only")?;
   3418     let publish_order = &release.publish_order.crates;
   3419     let publish_order_set = collect_unique_set(publish_order, "publish_order.crates")?;
   3420 
   3421     let class_sets = [
   3422         ("public", &public_set),
   3423         ("internal", &internal_set),
   3424         ("deferred", &deferred_set),
   3425         ("retired", &retired_set),
   3426         ("yank-only", &yank_only_set),
   3427     ];
   3428     for idx in 0..class_sets.len() {
   3429         for other_idx in (idx + 1)..class_sets.len() {
   3430             let overlap = class_sets[idx]
   3431                 .1
   3432                 .intersection(class_sets[other_idx].1)
   3433                 .cloned()
   3434                 .collect::<BTreeSet<_>>();
   3435             if !overlap.is_empty() {
   3436                 return Err(format!(
   3437                     "release classification overlap is not allowed between {} and {}: {}",
   3438                     class_sets[idx].0,
   3439                     class_sets[other_idx].0,
   3440                     join_set(&overlap)
   3441                 ));
   3442             }
   3443         }
   3444     }
   3445 
   3446     let mut combined = public_set.clone();
   3447     combined.extend(internal_set.iter().cloned());
   3448     combined.extend(deferred_set.iter().cloned());
   3449     combined.extend(retired_set.iter().cloned());
   3450     combined.extend(yank_only_set.iter().cloned());
   3451     if combined != workspace_packages {
   3452         let missing = workspace_packages
   3453             .difference(&combined)
   3454             .cloned()
   3455             .collect::<BTreeSet<_>>();
   3456         let extra = combined
   3457             .difference(&workspace_packages)
   3458             .cloned()
   3459             .collect::<BTreeSet<_>>();
   3460         return Err(format!(
   3461             "release classification sets are missing workspace crates: {}; release classification sets include unknown crates: {}",
   3462             join_set(&missing),
   3463             join_set(&extra)
   3464         ));
   3465     }
   3466 
   3467     if publish_order_set != public_set {
   3468         let missing = public_set
   3469             .difference(&publish_order_set)
   3470             .cloned()
   3471             .collect::<BTreeSet<_>>();
   3472         let extra = publish_order_set
   3473             .difference(&public_set)
   3474             .cloned()
   3475             .collect::<BTreeSet<_>>();
   3476         return Err(format!(
   3477             "publish_order.crates is missing publish crates: {}; publish_order.crates has non-publish crates: {}",
   3478             join_set(&missing),
   3479             join_set(&extra)
   3480         ));
   3481     }
   3482 
   3483     let order_index = publish_order
   3484         .iter()
   3485         .enumerate()
   3486         .map(|(idx, name)| (name.clone(), idx))
   3487         .collect::<BTreeMap<_, _>>();
   3488     let dependencies = read_workspace_package_dependencies(workspace_root)
   3489         .expect("workspace package manifests were already parsed");
   3490     for crate_name in &public_set {
   3491         let crate_deps = &dependencies[crate_name];
   3492         let crate_order = order_index[crate_name];
   3493         for dep in crate_deps {
   3494             if !public_set.contains(dep) {
   3495                 continue;
   3496             }
   3497             let dep_order = order_index[dep];
   3498             if dep_order >= crate_order {
   3499                 return Err(format!(
   3500                     "publish order must place dependency {} before {}",
   3501                     dep, crate_name
   3502                 ));
   3503             }
   3504         }
   3505     }
   3506 
   3507     let publish_configs = workspace_package_publish_configs(workspace_root)
   3508         .expect("workspace publish configs are stable");
   3509     for crate_name in &public_set {
   3510         let publish = publish_configs[crate_name].as_ref();
   3511         if !publish_config_is_public(publish) {
   3512             return Err(format!(
   3513                 "public crate {} must set publish = [\"crates-io\"]",
   3514                 crate_name
   3515             ));
   3516         }
   3517     }
   3518     for crate_name in internal_set
   3519         .iter()
   3520         .chain(deferred_set.iter())
   3521         .chain(retired_set.iter())
   3522         .chain(yank_only_set.iter())
   3523     {
   3524         let publish = publish_configs[crate_name].as_ref();
   3525         if !publish_config_is_non_public(publish) {
   3526             return Err(format!(
   3527                 "non-public crate {} must set publish = false",
   3528                 crate_name
   3529             ));
   3530         }
   3531     }
   3532 
   3533     Ok(())
   3534 }
   3535 
   3536 #[cfg(test)]
   3537 #[cfg_attr(coverage_nightly, coverage(off))]
   3538 pub fn synthetic_release_policy_for_workspace(workspace_root: &Path) -> Result<String, String> {
   3539     let bundle = load_contract_bundle(workspace_root)?;
   3540     let publish_configs = workspace_package_publish_configs(workspace_root)?;
   3541     let dependencies = read_workspace_package_dependencies(workspace_root)?;
   3542 
   3543     let mut public = BTreeSet::new();
   3544     let mut internal = BTreeSet::new();
   3545     for (crate_name, publish) in &publish_configs {
   3546         if publish_config_is_public(publish.as_ref()) {
   3547             public.insert(crate_name.clone());
   3548         } else {
   3549             internal.insert(crate_name.clone());
   3550         }
   3551     }
   3552 
   3553     let mut in_degree = BTreeMap::new();
   3554     let mut dependents = BTreeMap::<String, BTreeSet<String>>::new();
   3555     for crate_name in &public {
   3556         in_degree.insert(crate_name.clone(), 0usize);
   3557         dependents.insert(crate_name.clone(), BTreeSet::new());
   3558     }
   3559     for crate_name in &public {
   3560         for dep in &dependencies[crate_name] {
   3561             if !public.contains(dep) {
   3562                 continue;
   3563             }
   3564             *in_degree
   3565                 .get_mut(crate_name)
   3566                 .expect("public crate present in indegree map") += 1;
   3567             dependents
   3568                 .get_mut(dep)
   3569                 .expect("public dependency present in dependents map")
   3570                 .insert(crate_name.clone());
   3571         }
   3572     }
   3573 
   3574     let mut ready = in_degree
   3575         .iter()
   3576         .filter(|(_, degree)| **degree == 0)
   3577         .map(|(crate_name, _)| crate_name.clone())
   3578         .collect::<BTreeSet<_>>();
   3579     let mut publish_order = Vec::new();
   3580     while let Some(crate_name) = ready.pop_first() {
   3581         publish_order.push(crate_name.clone());
   3582         for dependent in dependents[&crate_name].clone() {
   3583             let degree = in_degree
   3584                 .get_mut(&dependent)
   3585                 .expect("dependent crate present in indegree map");
   3586             *degree -= 1;
   3587             if *degree == 0 {
   3588                 ready.insert(dependent);
   3589             }
   3590         }
   3591     }
   3592     if publish_order.len() != public.len() {
   3593         return Err("public crate dependency graph contains a cycle".to_string());
   3594     }
   3595 
   3596     let public = public.into_iter().collect::<Vec<_>>();
   3597     let internal = internal.into_iter().collect::<Vec<_>>();
   3598     Ok(format!(
   3599         "[release]\nversion = \"{}\"\n\n[classification]\npublic = {}\ninternal = {}\ndeferred = []\nretired = []\nyank_only = []\n\n[publish_order]\ncrates = {}\n",
   3600         bundle.version.contract.version,
   3601         toml_inline_array(&public),
   3602         toml_inline_array(&internal),
   3603         toml_inline_array(&publish_order),
   3604     ))
   3605 }
   3606 
   3607 #[cfg(test)]
   3608 #[cfg_attr(coverage_nightly, coverage(off))]
   3609 fn toml_inline_array(values: &[String]) -> String {
   3610     let joined = values
   3611         .iter()
   3612         .map(|value| format!("\"{value}\""))
   3613         .collect::<Vec<_>>()
   3614         .join(", ");
   3615     format!("[{joined}]")
   3616 }
   3617 
   3618 pub fn load_contract_bundle(workspace_root: &Path) -> Result<ContractBundle, String> {
   3619     reject_legacy_contract_roots(workspace_root)?;
   3620     let root = contract_root(workspace_root);
   3621     let manifest = parse_toml::<ContractManifest>(&root.join("manifest.toml"))?;
   3622     let version = parse_toml::<VersionPolicy>(&root.join("version.toml"))?;
   3623     let operations_manifest_path = root.join("operations.toml");
   3624     let operations_manifest = if operations_manifest_path.is_file() {
   3625         Some(parse_toml::<OperationsContractManifest>(
   3626             &operations_manifest_path,
   3627         )?)
   3628     } else {
   3629         None
   3630     };
   3631     Ok(ContractBundle {
   3632         root,
   3633         manifest,
   3634         version,
   3635         operations_manifest,
   3636     })
   3637 }
   3638 
   3639 fn reject_legacy_contract_roots(workspace_root: &Path) -> Result<(), String> {
   3640     for relative in ["spec", "policy"] {
   3641         let legacy_root = workspace_root.join(relative);
   3642         if legacy_root.exists() {
   3643             return Err(format!(
   3644                 "legacy contract root {} is forbidden; use contracts/",
   3645                 legacy_root.display()
   3646             ));
   3647         }
   3648     }
   3649     Ok(())
   3650 }
   3651 
   3652 pub fn validate_contract_bundle(bundle: &ContractBundle) -> Result<(), String> {
   3653     if bundle.manifest.contract.name.trim().is_empty() {
   3654         return Err("contract name is required".to_string());
   3655     }
   3656     if bundle.manifest.contract.version.trim().is_empty() {
   3657         return Err("contract version is required".to_string());
   3658     }
   3659     if bundle.manifest.contract.source.trim().is_empty() {
   3660         return Err("contract source is required".to_string());
   3661     }
   3662     if bundle.manifest.surface.model_crates.is_empty() {
   3663         return Err("contract surface.model_crates must not be empty".to_string());
   3664     }
   3665     if bundle.manifest.surface.algorithm_crates.is_empty() {
   3666         return Err("contract surface.algorithm_crates must not be empty".to_string());
   3667     }
   3668     validate_surface_metadata(&bundle.manifest.surface)?;
   3669     if bundle.version.contract.version.trim().is_empty() {
   3670         return Err("version.contract.version is required".to_string());
   3671     }
   3672     if bundle.version.contract.stability.trim().is_empty() {
   3673         return Err("version.contract.stability is required".to_string());
   3674     }
   3675     if bundle.version.semver.major_on.is_empty()
   3676         || bundle.version.semver.minor_on.is_empty()
   3677         || bundle.version.semver.patch_on.is_empty()
   3678     {
   3679         return Err("version.semver rules must all be non-empty".to_string());
   3680     }
   3681     if !bundle.version.compatibility.requires_conformance_pass {
   3682         return Err("compatibility.requires_conformance_pass must be true".to_string());
   3683     }
   3684     if !bundle.version.compatibility.requires_contract_manifest_diff {
   3685         return Err("compatibility.requires_contract_manifest_diff must be true".to_string());
   3686     }
   3687     if !bundle.version.compatibility.requires_release_notes {
   3688         return Err("compatibility.requires_release_notes must be true".to_string());
   3689     }
   3690     validate_policy_metadata(&bundle.manifest.policy)?;
   3691     let workspace_root = bundle
   3692         .root
   3693         .parent()
   3694         .expect("contract root must have a workspace parent");
   3695     if let Some(operations_manifest) = bundle.operations_manifest.as_ref() {
   3696         validate_operations_contract(bundle, operations_manifest, workspace_root)?;
   3697     }
   3698     validate_all_conformance_vectors(workspace_root, &bundle.manifest.contract.version)?;
   3699     validate_core_unit_dimension_variant_order(workspace_root)?;
   3700     validate_coverage_policy_parity(workspace_root, &bundle.root)?;
   3701     if resolve_release_contract_path(workspace_root)
   3702         .expect("validated release contract path resolution should not fail")
   3703         .is_some()
   3704     {
   3705         validate_release_publish_policy(
   3706             workspace_root,
   3707             &bundle.root,
   3708             bundle.version.contract.version.as_str(),
   3709         )?;
   3710     }
   3711     Ok(())
   3712 }
   3713 
   3714 #[cfg(test)]
   3715 mod tests {
   3716     use super::*;
   3717     use std::collections::BTreeSet;
   3718     use std::fs;
   3719     use std::path::{Path, PathBuf};
   3720     use std::time::{SystemTime, UNIX_EPOCH};
   3721 
   3722     fn workspace_root() -> PathBuf {
   3723         let manifest_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
   3724         manifest_dir
   3725             .join("../..")
   3726             .canonicalize()
   3727             .expect("canonical workspace root")
   3728     }
   3729 
   3730     fn temp_root(prefix: &str) -> PathBuf {
   3731         let nanos = SystemTime::now()
   3732             .duration_since(UNIX_EPOCH)
   3733             .expect("clock")
   3734             .as_nanos();
   3735         let root = std::env::temp_dir().join(format!("radroots_xtask_{prefix}_{nanos}"));
   3736         fs::create_dir_all(&root).expect("create temp root");
   3737         root
   3738     }
   3739 
   3740     fn write_file(path: &Path, content: &str) {
   3741         let _ = fs::create_dir_all(path.parent().unwrap_or(Path::new("")));
   3742         fs::write(path, content).expect("write file");
   3743     }
   3744 
   3745     fn strict_thresholds() -> CoverageThresholds {
   3746         CoverageThresholds {
   3747             fail_under_exec_lines: 100.0,
   3748             fail_under_functions: 100.0,
   3749             fail_under_regions: 100.0,
   3750             fail_under_branches: 100.0,
   3751             require_branches: true,
   3752         }
   3753     }
   3754 
   3755     fn coverage_thresholds(value: f64, require_branches: bool) -> CoverageThresholds {
   3756         CoverageThresholds {
   3757             fail_under_exec_lines: value,
   3758             fail_under_functions: value,
   3759             fail_under_regions: value,
   3760             fail_under_branches: value,
   3761             require_branches,
   3762         }
   3763     }
   3764 
   3765     struct TestCoverageRefreshRow<'a> {
   3766         crate_name: &'a str,
   3767         status: &'a str,
   3768         thresholds: CoverageThresholds,
   3769         exec: f64,
   3770         func: f64,
   3771         branch: Option<f64>,
   3772         region: f64,
   3773         report_pass: bool,
   3774     }
   3775 
   3776     fn passing_coverage_row(crate_name: &str) -> TestCoverageRefreshRow<'_> {
   3777         TestCoverageRefreshRow {
   3778             crate_name,
   3779             status: "pass",
   3780             thresholds: coverage_thresholds(100.0, true),
   3781             exec: 100.0,
   3782             func: 100.0,
   3783             branch: Some(100.0),
   3784             region: 100.0,
   3785             report_pass: true,
   3786         }
   3787     }
   3788 
   3789     fn coverage_refresh_branch_value(branch: Option<f64>) -> String {
   3790         branch
   3791             .map(|value| value.to_string())
   3792             .unwrap_or_else(|| "unavailable".to_string())
   3793     }
   3794 
   3795     fn write_test_coverage_gate_report(root: &Path, row: &TestCoverageRefreshRow<'_>) -> String {
   3796         let report_relative = format!("target/coverage/{}/gate-report.json", row.crate_name);
   3797         let report_path = root.join(&report_relative);
   3798         let fail_reasons = if row.report_pass {
   3799             Vec::<&str>::new()
   3800         } else {
   3801             vec!["policy gate failed"]
   3802         };
   3803         let report = serde_json::json!({
   3804             "scope": row.crate_name,
   3805             "thresholds": {
   3806                 "executable_lines": row.thresholds.fail_under_exec_lines,
   3807                 "functions": row.thresholds.fail_under_functions,
   3808                 "regions": row.thresholds.fail_under_regions,
   3809                 "branches": row.thresholds.fail_under_branches,
   3810                 "branches_required": row.thresholds.require_branches
   3811             },
   3812             "measured": {
   3813                 "executable_lines_percent": row.exec,
   3814                 "executable_lines_source": "da",
   3815                 "functions_percent": row.func,
   3816                 "branches_percent": row.branch,
   3817                 "branches_available": row.branch.is_some(),
   3818                 "summary_lines_percent": row.exec,
   3819                 "summary_regions_percent": row.region
   3820             },
   3821             "counts": {
   3822                 "executable_lines": {
   3823                     "covered": 1,
   3824                     "total": 1
   3825                 },
   3826                 "branches": {
   3827                     "covered": if row.branch.is_some() { 1 } else { 0 },
   3828                     "total": if row.branch.is_some() { 1 } else { 0 }
   3829                 }
   3830             },
   3831             "result": {
   3832                 "pass": row.report_pass,
   3833                 "fail_reasons": fail_reasons
   3834             }
   3835         });
   3836         let json =
   3837             serde_json::to_string_pretty(&report).expect("serialize test coverage gate report");
   3838         write_file(&report_path, &format!("{json}\n"));
   3839         report_relative
   3840     }
   3841 
   3842     fn write_test_coverage_refresh(root: &Path, rows: &[TestCoverageRefreshRow<'_>]) {
   3843         let mut refresh_rows = String::from("crate\tstatus\texec\tfunc\tbranch\tregion\treport\n");
   3844         for row in rows {
   3845             let report_relative = write_test_coverage_gate_report(root, row);
   3846             refresh_rows.push_str(&format!(
   3847                 "{}\t{}\t{}\t{}\t{}\t{}\t{}\n",
   3848                 row.crate_name,
   3849                 row.status,
   3850                 row.exec,
   3851                 row.func,
   3852                 coverage_refresh_branch_value(row.branch),
   3853                 row.region,
   3854                 report_relative
   3855             ));
   3856         }
   3857         write_file(
   3858             &root
   3859                 .join("target")
   3860                 .join("coverage")
   3861                 .join("coverage-refresh.tsv"),
   3862             &refresh_rows,
   3863         );
   3864     }
   3865 
   3866     fn create_synthetic_workspace(prefix: &str) -> PathBuf {
   3867         let root = temp_root(prefix);
   3868         write_file(
   3869             &root.join("Cargo.toml"),
   3870             r#"[workspace]
   3871 members = ["crates/a", "crates/b"]
   3872 resolver = "2"
   3873 "#,
   3874         );
   3875         write_file(
   3876             &root.join("crates").join("a").join("Cargo.toml"),
   3877             r#"[package]
   3878 name = "radroots_a"
   3879 publish = ["crates-io"]
   3880 version = "0.1.0"
   3881 edition = "2024"
   3882 description = "crate a"
   3883 repository = "https://example.com/a"
   3884 homepage = "https://example.com/a"
   3885 documentation = "https://docs.example.com/a"
   3886 readme = "README"
   3887 "#,
   3888         );
   3889         write_file(
   3890             &root.join("crates").join("b").join("Cargo.toml"),
   3891             r#"[package]
   3892 name = "radroots_b"
   3893 version = "0.1.0"
   3894 edition = "2024"
   3895 publish = false
   3896 "#,
   3897         );
   3898         write_file(
   3899             &root.join("crates").join("core").join("src").join("unit.rs"),
   3900             r#"pub enum RadrootsCoreUnitDimension {
   3901     Count,
   3902     Mass,
   3903     Volume,
   3904 }
   3905 "#,
   3906         );
   3907 
   3908         write_file(
   3909             &root.join("contracts").join("manifest.toml"),
   3910             r#"[contract]
   3911 name = "radroots_contract"
   3912 version = "1.0.0"
   3913 source = "synthetic"
   3914 
   3915 [surface]
   3916 model_crates = ["radroots_a"]
   3917 algorithm_crates = ["radroots_b"]
   3918 
   3919 [policy]
   3920 exclude_internal_workspace_crates = true
   3921 require_reproducible_exports = true
   3922 require_conformance_vectors = true
   3923 "#,
   3924         );
   3925         write_file(
   3926             &root.join("contracts").join("version.toml"),
   3927             r#"[contract]
   3928 version = "1.0.0"
   3929 stability = "alpha"
   3930 
   3931 [semver]
   3932 major_on = ["breaking"]
   3933 minor_on = ["feature"]
   3934 patch_on = ["fix"]
   3935 
   3936 [compatibility]
   3937 requires_conformance_pass = true
   3938 requires_contract_manifest_diff = true
   3939 requires_release_notes = true
   3940 "#,
   3941         );
   3942         write_file(
   3943             &root.join("contracts").join("coverage.toml"),
   3944             r#"[gate]
   3945 fail_under_exec_lines = 100.0
   3946 fail_under_functions = 100.0
   3947 fail_under_regions = 100.0
   3948 fail_under_branches = 100.0
   3949 require_branches = true
   3950 
   3951 [required]
   3952 crates = ["radroots_a", "radroots_b"]
   3953 "#,
   3954         );
   3955         write_file(
   3956             &root_release_policy_path(&root),
   3957             r#"[release]
   3958 version = "1.0.0"
   3959 
   3960 [publish]
   3961 crates = ["radroots_a"]
   3962 
   3963 [internal]
   3964 crates = ["radroots_b"]
   3965 
   3966 [publish_order]
   3967 crates = ["radroots_a"]
   3968 "#,
   3969         );
   3970         write_test_coverage_refresh(
   3971             &root,
   3972             &[
   3973                 passing_coverage_row("radroots_a"),
   3974                 passing_coverage_row("radroots_b"),
   3975             ],
   3976         );
   3977         root
   3978     }
   3979 
   3980     fn add_operation_contract_files(root: &Path) {
   3981         write_file(
   3982             &root.join("contracts").join("operations.toml"),
   3983             r#"[contract]
   3984 name = "radroots_contract"
   3985 version = "1.0.0"
   3986 source = "synthetic"
   3987 
   3988 [public]
   3989 domains = ["profile", "farm", "listing", "trade"]
   3990 
   3991 [shared_types]
   3992 public = [
   3993   "WireEventParts",
   3994   "RadrootsFrozenEventDraft",
   3995   "RadrootsSignedNostrEvent",
   3996   "RadrootsNostrEvent",
   3997   "RadrootsNostrEventRef",
   3998   "RadrootsNostrEventPtr",
   3999   "RadrootsListingAddress",
   4000   "RadrootsProfile",
   4001   "RadrootsFarm",
   4002   "RadrootsListing",
   4003 ]
   4004 
   4005 [errors]
   4006 classes = ["encode_error", "parse_error", "validation_error", "address_error"]
   4007 
   4008 [implementation_provenance]
   4009 model_crates = ["radroots_a"]
   4010 algorithm_crates = ["radroots_b"]
   4011 
   4012 [operations.profile_build_draft]
   4013 domain = "profile"
   4014 id = "profile.build_draft"
   4015 stability = "beta"
   4016 inputs = ["RadrootsProfile", "RadrootsProfileType?"]
   4017 outputs = ["WireEventParts"]
   4018 error_class = "encode_error"
   4019 deterministic = true
   4020 signing = "native"
   4021 transport = "native"
   4022 
   4023 [operations.profile_build_draft.implementation]
   4024 rust_modules = ["crates/core/src/unit.rs"]
   4025 rust_types = ["radroots_events::profile::RadrootsProfile"]
   4026 
   4027 [operations.profile_build_draft.conformance]
   4028 vector = "contracts/conformance/vectors/profile/build_draft.v1.json"
   4029 
   4030 [operations.listing_build_draft]
   4031 domain = "listing"
   4032 id = "listing.build_draft"
   4033 stability = "beta"
   4034 inputs = ["RadrootsListing"]
   4035 outputs = ["WireEventParts"]
   4036 error_class = "encode_error"
   4037 deterministic = true
   4038 signing = "native"
   4039 transport = "native"
   4040 
   4041 [operations.listing_build_draft.implementation]
   4042 rust_modules = ["crates/core/src/unit.rs"]
   4043 rust_types = ["radroots_events::listing::RadrootsListing"]
   4044 
   4045 [operations.listing_build_draft.conformance]
   4046 vector = "contracts/conformance/vectors/listing/build_draft.v1.json"
   4047 "#,
   4048         );
   4049         write_file(
   4050             &root
   4051                 .join("contracts")
   4052                 .join("conformance")
   4053                 .join("schema")
   4054                 .join("vector.schema.json"),
   4055             r#"{
   4056   "$schema": "http://json-schema.org/draft-07/schema#",
   4057   "$id": "https://radroots.org/core/conformance/vector.schema.json",
   4058   "title": "radroots core conformance vector",
   4059   "type": "object",
   4060   "required": ["suite", "contract_version", "vectors"],
   4061   "properties": {
   4062     "suite": {
   4063       "type": "string",
   4064       "minLength": 1
   4065     },
   4066     "contract_version": {
   4067       "type": "string",
   4068       "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$"
   4069     },
   4070     "vectors": {
   4071       "type": "array",
   4072       "items": {
   4073         "type": "object",
   4074         "required": ["id", "kind", "input", "expected"],
   4075         "properties": {
   4076           "id": {
   4077             "type": "string",
   4078             "minLength": 1
   4079           },
   4080           "kind": {
   4081             "type": "string",
   4082             "minLength": 1
   4083           },
   4084           "input": {},
   4085           "expected": {}
   4086         },
   4087         "additionalProperties": false
   4088       }
   4089     }
   4090   },
   4091   "additionalProperties": false
   4092 }
   4093 "#,
   4094         );
   4095         write_file(
   4096             &root
   4097                 .join("contracts")
   4098                 .join("conformance")
   4099                 .join("vectors")
   4100                 .join("profile")
   4101                 .join("build_draft.v1.json"),
   4102             r#"{
   4103   "suite": "profile",
   4104   "contract_version": "1.0.0",
   4105   "vectors": [
   4106     {
   4107       "id": "profile_build_draft_minimal_001",
   4108       "kind": "profile.build_draft",
   4109       "input": {},
   4110       "expected": {}
   4111     }
   4112   ]
   4113 }
   4114 "#,
   4115         );
   4116         write_file(
   4117             &root
   4118                 .join("contracts")
   4119                 .join("conformance")
   4120                 .join("vectors")
   4121                 .join("listing")
   4122                 .join("build_draft.v1.json"),
   4123             r#"{
   4124   "suite": "listing",
   4125   "contract_version": "1.0.0",
   4126   "vectors": [
   4127     {
   4128       "id": "listing_build_draft_minimal_001",
   4129       "kind": "listing.build_draft",
   4130       "input": {},
   4131       "expected": {}
   4132     }
   4133   ]
   4134 }
   4135 "#,
   4136         );
   4137     }
   4138 
   4139     fn write_root_release_policy(root: &Path, raw: &str) {
   4140         write_file(&root.join(ROOT_RELEASE_POLICY_RELATIVE), raw);
   4141     }
   4142 
   4143     fn configure_root_release_policy_workspace(root: &Path) {
   4144         write_file(
   4145             &root.join("Cargo.toml"),
   4146             r#"[workspace]
   4147 members = ["crates/a", "crates/b", "crates/c", "crates/d", "crates/e"]
   4148 resolver = "2"
   4149 "#,
   4150         );
   4151         for crate_name in ["c", "d", "e"] {
   4152             write_file(
   4153                 &root.join("crates").join(crate_name).join("Cargo.toml"),
   4154                 &format!(
   4155                     r#"[package]
   4156 name = "radroots_{crate_name}"
   4157 version = "0.1.0"
   4158 edition = "2024"
   4159 publish = false
   4160 "#
   4161                 ),
   4162             );
   4163         }
   4164         write_file(
   4165             &root.join("contracts").join("coverage.toml"),
   4166             r#"[gate]
   4167 fail_under_exec_lines = 100.0
   4168 fail_under_functions = 100.0
   4169 fail_under_regions = 100.0
   4170 fail_under_branches = 100.0
   4171 require_branches = true
   4172 
   4173 [required]
   4174 crates = ["radroots_a", "radroots_b", "radroots_c", "radroots_d", "radroots_e"]
   4175 "#,
   4176         );
   4177         write_test_coverage_refresh(
   4178             root,
   4179             &[
   4180                 passing_coverage_row("radroots_a"),
   4181                 passing_coverage_row("radroots_b"),
   4182                 passing_coverage_row("radroots_c"),
   4183                 passing_coverage_row("radroots_d"),
   4184                 passing_coverage_row("radroots_e"),
   4185             ],
   4186         );
   4187         let _ = fs::remove_file(root_release_policy_path(&root));
   4188     }
   4189 
   4190     #[test]
   4191     fn validate_current_contract_bundle() {
   4192         let root = workspace_root();
   4193         let bundle = load_contract_bundle(&root).expect("load contract");
   4194         validate_contract_bundle(&bundle).expect("validate contract");
   4195     }
   4196 
   4197     #[test]
   4198     fn validate_current_canonical_event_boundary() {
   4199         let root = workspace_root();
   4200         validate_canonical_event_boundary(&root).expect("validate canonical event boundary");
   4201     }
   4202 
   4203     #[test]
   4204     fn canonical_event_boundary_reports_row_drift() {
   4205         let root = workspace_root();
   4206         let matrix_path =
   4207             resolve_event_boundary_matrix_path_with_override(&root, None).expect("matrix path");
   4208         let raw = fs::read_to_string(&matrix_path).expect("read matrix");
   4209         let drifted = raw.replacen(
   4210             "| message | 14 | RadrootsMessage |",
   4211             "| message | 999 | RadrootsMessage |",
   4212             1,
   4213         );
   4214         let temp = temp_root("event_boundary_drift");
   4215         let override_path = temp.join("spec-coverage.md");
   4216         write_file(&override_path, &drifted);
   4217 
   4218         let err = validate_canonical_event_boundary_with_override(&root, Some(override_path))
   4219             .expect_err("message kind drift should fail");
   4220         assert!(err.contains("message kind drift"));
   4221 
   4222         let _ = fs::remove_dir_all(temp);
   4223     }
   4224 
   4225     #[test]
   4226     fn validate_synthetic_operation_contract_bundle() {
   4227         let root = create_synthetic_workspace("operation_contract_bundle");
   4228         add_operation_contract_files(&root);
   4229         let bundle = load_contract_bundle(&root).expect("load contract");
   4230         validate_contract_bundle(&bundle).expect("validate contract");
   4231         let _ = fs::remove_dir_all(root);
   4232     }
   4233 
   4234     #[test]
   4235     fn parses_enum_variants_in_declared_order() {
   4236         let source = r#"
   4237 pub enum RadrootsCoreUnitDimension {
   4238     Count,
   4239     Mass,
   4240     Volume,
   4241 }
   4242 "#;
   4243         let enum_body = extract_enum_body(source, "RadrootsCoreUnitDimension").expect("enum body");
   4244         let variants = parse_enum_variants(enum_body);
   4245         assert_eq!(variants, vec!["Count", "Mass", "Volume"]);
   4246     }
   4247 
   4248     #[test]
   4249     fn fails_when_enum_order_does_not_match_contract() {
   4250         let source = r#"
   4251 pub enum RadrootsCoreUnitDimension {
   4252     Mass,
   4253     Count,
   4254     Volume,
   4255 }
   4256 "#;
   4257         let enum_body = extract_enum_body(source, "RadrootsCoreUnitDimension").expect("enum body");
   4258         let variants = parse_enum_variants(enum_body);
   4259         let expected = CORE_UNIT_DIMENSION_ORDER
   4260             .iter()
   4261             .map(|item| (*item).to_string())
   4262             .collect::<Vec<_>>();
   4263         assert_ne!(variants, expected);
   4264     }
   4265 
   4266     #[test]
   4267     fn coverage_policy_matches_non_simplex_workspace_crates() {
   4268         let root = workspace_root();
   4269         let expected_names =
   4270             coverage_required_workspace_crates(&root).expect("workspace coverage crates");
   4271         let policy = load_coverage_policy(&root.join("contracts")).expect("coverage policy");
   4272         let required_names = policy
   4273             .required_crates()
   4274             .expect("required crates")
   4275             .into_iter()
   4276             .collect::<BTreeSet<_>>();
   4277         assert_eq!(expected_names, required_names);
   4278         assert!(
   4279             required_names
   4280                 .iter()
   4281                 .all(|crate_name| !coverage_policy_excludes_workspace_crate(crate_name))
   4282         );
   4283     }
   4284 
   4285     #[test]
   4286     fn coverage_required_workspace_crates_excludes_simplex_packages() {
   4287         let root = temp_root("coverage_required_workspace_simplex");
   4288         write_file(
   4289             &root.join("Cargo.toml"),
   4290             r#"[workspace]
   4291 members = ["crates/a", "crates/radroots_simplex_probe", "crates/simplex_probe"]
   4292 resolver = "2"
   4293 "#,
   4294         );
   4295         write_file(
   4296             &root.join("crates").join("a").join("Cargo.toml"),
   4297             r#"[package]
   4298 name = "radroots_a"
   4299 version = "0.1.0"
   4300 edition = "2024"
   4301 "#,
   4302         );
   4303         write_file(
   4304             &root
   4305                 .join("crates")
   4306                 .join("radroots_simplex_probe")
   4307                 .join("Cargo.toml"),
   4308             r#"[package]
   4309 name = "radroots_simplex_probe"
   4310 version = "0.1.0"
   4311 edition = "2024"
   4312 "#,
   4313         );
   4314         write_file(
   4315             &root.join("crates").join("simplex_probe").join("Cargo.toml"),
   4316             r#"[package]
   4317 name = "simplex_probe"
   4318 version = "0.1.0"
   4319 edition = "2024"
   4320 "#,
   4321         );
   4322 
   4323         let required =
   4324             coverage_required_workspace_crates(&root).expect("workspace coverage crates");
   4325         assert_eq!(
   4326             required,
   4327             ["radroots_a".to_string()]
   4328                 .into_iter()
   4329                 .collect::<BTreeSet<_>>()
   4330         );
   4331         assert!(coverage_policy_excludes_workspace_crate(
   4332             "radroots_simplex_probe"
   4333         ));
   4334         assert!(coverage_policy_excludes_workspace_crate("simplex_probe"));
   4335         assert!(!coverage_policy_excludes_workspace_crate("radroots_a"));
   4336 
   4337         let _ = fs::remove_dir_all(root);
   4338     }
   4339 
   4340     #[test]
   4341     fn coverage_required_crates_match_policy_required_status() {
   4342         let root = workspace_root();
   4343         let contract_root = root.join("contracts");
   4344         let policy = load_coverage_policy(&contract_root).expect("coverage policy");
   4345         let required = CoverageRequiredFile {
   4346             required: CoverageRequiredSection {
   4347                 crates: policy.required_crates().expect("coverage required"),
   4348             },
   4349         };
   4350         let required_names = required
   4351             .required
   4352             .crates
   4353             .into_iter()
   4354             .collect::<BTreeSet<_>>();
   4355         let policy_required = policy
   4356             .required_crates()
   4357             .expect("policy required crates")
   4358             .into_iter()
   4359             .collect::<BTreeSet<_>>();
   4360         assert_eq!(required_names, policy_required);
   4361     }
   4362 
   4363     #[test]
   4364     fn coverage_policy_required_crates_report_policy_errors() {
   4365         let missing_root = temp_root("load_coverage_required_missing_policy");
   4366         let missing_err =
   4367             load_coverage_policy(&missing_root).expect_err("missing policy should fail");
   4368         assert!(missing_err.contains("coverage.toml"));
   4369         let _ = fs::remove_dir_all(&missing_root);
   4370 
   4371         let duplicate_root =
   4372             create_synthetic_workspace("load_coverage_required_duplicate_required");
   4373         let contract_root = duplicate_root.join("contracts");
   4374         let coverage_root = coverage_root(&contract_root);
   4375         write_file(
   4376             &coverage_root.join("coverage.toml"),
   4377             "[gate]\nfail_under_exec_lines = 100.0\nfail_under_functions = 100.0\nfail_under_regions = 100.0\nfail_under_branches = 100.0\nrequire_branches = true\n\n[required]\ncrates = [\"radroots_a\", \"radroots_a\"]\n",
   4378         );
   4379         let duplicate_err =
   4380             load_coverage_policy(&contract_root).expect_err("duplicate required crates");
   4381         assert!(duplicate_err.contains("duplicate crate"));
   4382         let _ = fs::remove_dir_all(&duplicate_root);
   4383     }
   4384 
   4385     #[test]
   4386     fn package_field_configured_accepts_workspace_table() {
   4387         let mut package = toml::value::Table::new();
   4388         let mut repository = toml::value::Table::new();
   4389         repository.insert("workspace".to_string(), toml::Value::Boolean(true));
   4390         package.insert("repository".to_string(), toml::Value::Table(repository));
   4391         assert!(package_field_configured(&package, "repository"));
   4392     }
   4393 
   4394     #[test]
   4395     fn validate_required_coverage_summary_enforces_strict_threshold() {
   4396         let root = temp_root("coverage_summary");
   4397         let coverage_dir = root.join("target").join("coverage");
   4398         fs::create_dir_all(&coverage_dir).expect("create coverage dir");
   4399         fs::write(
   4400             coverage_dir.join("coverage-refresh.tsv"),
   4401             "crate\tstatus\texec\tfunc\tbranch\tregion\treport\nradroots_core\tpass\t100.0\t100.0\t100.0\t100.0\tfile\n",
   4402         )
   4403         .expect("write coverage file");
   4404         let required = ["radroots_core".to_string()]
   4405             .into_iter()
   4406             .collect::<BTreeSet<_>>();
   4407         validate_required_coverage_summary(&root, &required, strict_thresholds())
   4408             .expect("coverage summary");
   4409 
   4410         fs::write(
   4411             coverage_dir.join("coverage-refresh.tsv"),
   4412             "crate\tstatus\texec\tfunc\tbranch\tregion\treport\nradroots_core\tpass\t100.0\t99.9\t100.0\t100.0\tfile\n",
   4413         )
   4414         .expect("write function coverage file");
   4415         let func_err = validate_required_coverage_summary(&root, &required, strict_thresholds())
   4416             .expect_err("function coverage below 100");
   4417         assert!(func_err.contains("must satisfy coverage policy"));
   4418 
   4419         fs::write(
   4420             coverage_dir.join("coverage-refresh.tsv"),
   4421             "crate\tstatus\texec\tfunc\tbranch\tregion\treport\nradroots_core\tpass\t100.0\t100.0\t99.9\t100.0\tfile\n",
   4422         )
   4423         .expect("write branch coverage file");
   4424         let branch_err = validate_required_coverage_summary(&root, &required, strict_thresholds())
   4425             .expect_err("branch coverage below 100");
   4426         assert!(branch_err.contains("must satisfy coverage policy"));
   4427 
   4428         fs::write(
   4429             coverage_dir.join("coverage-refresh.tsv"),
   4430             "crate\tstatus\texec\tfunc\tbranch\tregion\treport\nradroots_core\tpass\t100.0\t100.0\tunavailable\t100.0\tfile\n",
   4431         )
   4432         .expect("write unavailable branch coverage file");
   4433         let missing_branch_err =
   4434             validate_required_coverage_summary(&root, &required, strict_thresholds())
   4435                 .expect_err("branch coverage missing under strict policy");
   4436         assert!(missing_branch_err.contains("unavailable"));
   4437 
   4438         fs::write(
   4439             coverage_dir.join("coverage-refresh.tsv"),
   4440             "crate\tstatus\texec\tfunc\tbranch\tregion\treport\nradroots_core\tpass\t100.0\t100.0\t100.0\t99.9\tfile\n",
   4441         )
   4442         .expect("write region coverage file");
   4443         let region_err = validate_required_coverage_summary(&root, &required, strict_thresholds())
   4444             .expect_err("region coverage below 100");
   4445         assert!(region_err.contains("must satisfy coverage policy"));
   4446         let _ = fs::remove_dir_all(&root);
   4447     }
   4448 
   4449     #[test]
   4450     fn validate_required_coverage_summary_with_policy_honors_scope_override() {
   4451         let root = temp_root("coverage_summary_override");
   4452         write_test_coverage_refresh(
   4453             &root,
   4454             &[
   4455                 TestCoverageRefreshRow {
   4456                     crate_name: "radroots_events_codec",
   4457                     status: "pass",
   4458                     thresholds: CoverageThresholds {
   4459                         fail_under_exec_lines: 100.0,
   4460                         fail_under_functions: 100.0,
   4461                         fail_under_regions: 99.946,
   4462                         fail_under_branches: 100.0,
   4463                         require_branches: true,
   4464                     },
   4465                     exec: 100.0,
   4466                     func: 100.0,
   4467                     branch: Some(100.0),
   4468                     region: 99.946385,
   4469                     report_pass: true,
   4470                 },
   4471                 TestCoverageRefreshRow {
   4472                     crate_name: "radroots_log",
   4473                     status: "pass",
   4474                     thresholds: coverage_thresholds(100.0, false),
   4475                     exec: 100.0,
   4476                     func: 100.0,
   4477                     branch: None,
   4478                     region: 100.0,
   4479                     report_pass: true,
   4480                 },
   4481             ],
   4482         );
   4483         let policy_dir = root.join("contracts");
   4484         fs::create_dir_all(&policy_dir).expect("create policy dir");
   4485         fs::write(
   4486             policy_dir.join("coverage.toml"),
   4487             "[gate]\nfail_under_exec_lines = 100.0\nfail_under_functions = 100.0\nfail_under_regions = 100.0\nfail_under_branches = 100.0\nrequire_branches = true\n\n[overrides.radroots_events_codec]\nfail_under_exec_lines = 100.0\nfail_under_functions = 100.0\nfail_under_regions = 99.946\nfail_under_branches = 100.0\ntemporary = true\nreason = \"publish 0.1.0-alpha.2 temporary coverage override\"\n\n[overrides.radroots_log]\nfail_under_exec_lines = 100.0\nfail_under_functions = 100.0\nfail_under_regions = 100.0\nfail_under_branches = 100.0\nrequire_branches = false\ntemporary = true\nreason = \"branch coverage is not applicable while the crate has no measured branch records\"\n\n[required]\ncrates = [\"radroots_events_codec\", \"radroots_log\"]\n",
   4488         )
   4489         .expect("write coverage policy");
   4490         let required = [
   4491             "radroots_events_codec".to_string(),
   4492             "radroots_log".to_string(),
   4493         ]
   4494         .into_iter()
   4495         .collect::<BTreeSet<_>>();
   4496         let policy = read_coverage_policy(&policy_dir.join("coverage.toml"))
   4497             .expect("parse override coverage policy");
   4498         validate_required_coverage_summary_with_policy(&root, &required, &policy)
   4499             .expect("coverage summary should honor override");
   4500         let _ = fs::remove_dir_all(&root);
   4501     }
   4502 
   4503     #[test]
   4504     fn validate_required_coverage_summary_with_policy_rejects_synthetic_report_path() {
   4505         let root = temp_root("coverage_summary_synthetic_report_path");
   4506         write_file(
   4507             &root
   4508                 .join("target")
   4509                 .join("coverage")
   4510                 .join("coverage-refresh.tsv"),
   4511             "crate\tstatus\texec\tfunc\tbranch\tregion\treport\nradroots_a\tpass\t100.0\t100.0\t100.0\t100.0\tfile\n",
   4512         );
   4513         let required = ["radroots_a".to_string()]
   4514             .into_iter()
   4515             .collect::<BTreeSet<_>>();
   4516         let policy_dir = root.join("contracts");
   4517         write_file(
   4518             &policy_dir.join("coverage.toml"),
   4519             "[gate]\nfail_under_exec_lines = 100.0\nfail_under_functions = 100.0\nfail_under_regions = 100.0\nfail_under_branches = 100.0\nrequire_branches = true\n\n[required]\ncrates = [\"radroots_a\"]\n",
   4520         );
   4521         let policy =
   4522             read_coverage_policy(&policy_dir.join("coverage.toml")).expect("parse coverage policy");
   4523         let err = validate_required_coverage_summary_with_policy(&root, &required, &policy)
   4524             .expect_err("synthetic report path should fail");
   4525         assert!(err.contains("coverage gate report"));
   4526         let _ = fs::remove_dir_all(&root);
   4527     }
   4528 
   4529     #[test]
   4530     fn validate_required_coverage_summary_with_policy_rejects_stale_gate_report_thresholds() {
   4531         let root = temp_root("coverage_summary_stale_gate_report_thresholds");
   4532         let row = TestCoverageRefreshRow {
   4533             crate_name: "radroots_a",
   4534             status: "pass",
   4535             thresholds: coverage_thresholds(90.0, true),
   4536             exec: 100.0,
   4537             func: 100.0,
   4538             branch: Some(100.0),
   4539             region: 100.0,
   4540             report_pass: true,
   4541         };
   4542         write_test_coverage_refresh(&root, &[row]);
   4543         let required = ["radroots_a".to_string()]
   4544             .into_iter()
   4545             .collect::<BTreeSet<_>>();
   4546         let policy_dir = root.join("contracts");
   4547         write_file(
   4548             &policy_dir.join("coverage.toml"),
   4549             "[gate]\nfail_under_exec_lines = 100.0\nfail_under_functions = 100.0\nfail_under_regions = 100.0\nfail_under_branches = 100.0\nrequire_branches = true\n\n[required]\ncrates = [\"radroots_a\"]\n",
   4550         );
   4551         let policy =
   4552             read_coverage_policy(&policy_dir.join("coverage.toml")).expect("parse coverage policy");
   4553         let err = validate_required_coverage_summary_with_policy(&root, &required, &policy)
   4554             .expect_err("stale threshold report should fail");
   4555         assert!(err.contains("thresholds do not match policy"));
   4556         let _ = fs::remove_dir_all(&root);
   4557     }
   4558 
   4559     #[test]
   4560     fn validate_required_coverage_summary_with_policy_rejects_row_report_mismatch() {
   4561         let root = temp_root("coverage_summary_row_report_mismatch");
   4562         let row = TestCoverageRefreshRow {
   4563             crate_name: "radroots_a",
   4564             status: "pass",
   4565             thresholds: coverage_thresholds(100.0, true),
   4566             exec: 99.0,
   4567             func: 100.0,
   4568             branch: Some(100.0),
   4569             region: 100.0,
   4570             report_pass: true,
   4571         };
   4572         let report_relative = write_test_coverage_gate_report(&root, &row);
   4573         write_file(
   4574             &root
   4575                 .join("target")
   4576                 .join("coverage")
   4577                 .join("coverage-refresh.tsv"),
   4578             &format!(
   4579                 "crate\tstatus\texec\tfunc\tbranch\tregion\treport\nradroots_a\tpass\t100.0\t100.0\t100.0\t100.0\t{report_relative}\n"
   4580             ),
   4581         );
   4582         let required = ["radroots_a".to_string()]
   4583             .into_iter()
   4584             .collect::<BTreeSet<_>>();
   4585         let policy_dir = root.join("contracts");
   4586         write_file(
   4587             &policy_dir.join("coverage.toml"),
   4588             "[gate]\nfail_under_exec_lines = 100.0\nfail_under_functions = 100.0\nfail_under_regions = 100.0\nfail_under_branches = 100.0\nrequire_branches = true\n\n[required]\ncrates = [\"radroots_a\"]\n",
   4589         );
   4590         let policy =
   4591             read_coverage_policy(&policy_dir.join("coverage.toml")).expect("parse coverage policy");
   4592         let err = validate_required_coverage_summary_with_policy(&root, &required, &policy)
   4593             .expect_err("row and report mismatch should fail");
   4594         assert!(err.contains("does not match coverage gate report"));
   4595         let _ = fs::remove_dir_all(&root);
   4596     }
   4597 
   4598     #[test]
   4599     fn validate_publish_package_metadata_requires_description() {
   4600         let root = temp_root("publish_metadata");
   4601         fs::create_dir_all(root.join("crates").join("a")).expect("create crate dir");
   4602         fs::write(
   4603             root.join("Cargo.toml"),
   4604             r#"[workspace]
   4605 members = ["crates/a"]
   4606 "#,
   4607         )
   4608         .expect("write workspace manifest");
   4609         fs::write(
   4610             root.join("crates").join("a").join("Cargo.toml"),
   4611             r#"[package]
   4612 name = "radroots_a"
   4613 version = "0.1.0"
   4614 edition = "2024"
   4615 repository = { workspace = true }
   4616 homepage = { workspace = true }
   4617 documentation = "https://docs.rs/radroots_a"
   4618 readme = { workspace = true }
   4619 "#,
   4620         )
   4621         .expect("write package manifest");
   4622         let publish = ["radroots_a".to_string()]
   4623             .into_iter()
   4624             .collect::<BTreeSet<_>>();
   4625         let err =
   4626             validate_publish_package_metadata(&root, &publish).expect_err("missing description");
   4627         assert!(err.contains("package.description"));
   4628         let _ = fs::remove_dir_all(&root);
   4629     }
   4630 
   4631     #[test]
   4632     fn synthetic_workspace_validates_contract_and_release_preflight() {
   4633         let root = create_synthetic_workspace("synthetic_valid");
   4634         let bundle = load_contract_bundle(&root).expect("load synthetic bundle");
   4635         validate_contract_bundle(&bundle).expect("validate synthetic bundle");
   4636         validate_release_preflight(&root).expect("validate synthetic preflight");
   4637         let _ = fs::remove_dir_all(root);
   4638     }
   4639 
   4640     #[test]
   4641     fn helper_functions_cover_error_paths() {
   4642         let empty = collect_unique_set(&["".to_string()], "field").expect_err("empty value");
   4643         assert!(empty.contains("field contains an empty crate name"));
   4644         let duplicate = collect_unique_set(&["a".to_string(), "a".to_string()], "field")
   4645             .expect_err("duplicate value");
   4646         assert!(duplicate.contains("field has duplicate crate a"));
   4647 
   4648         let values = ["b".to_string(), "a".to_string()];
   4649         let set = collect_unique_set(&values, "field").expect("unique values");
   4650         assert_eq!(join_set(&set), "a, b".to_string());
   4651 
   4652         assert!(package_publish_enabled(None));
   4653         assert!(package_publish_enabled(Some(&PackagePublish::Bool(true))));
   4654         assert!(!package_publish_enabled(Some(&PackagePublish::Bool(false))));
   4655         assert!(package_publish_enabled(Some(&PackagePublish::Registries(
   4656             vec!["crates-io".to_string(),]
   4657         ))));
   4658         assert!(!package_publish_enabled(Some(&PackagePublish::Registries(
   4659             Vec::new()
   4660         ))));
   4661 
   4662         let mut package = toml::value::Table::new();
   4663         package.insert("description".to_string(), toml::Value::Integer(42));
   4664         assert!(!package_field_configured(&package, "description"));
   4665 
   4666         assert!(!publish_config_is_public(None));
   4667         assert!(!publish_config_is_public(Some(&PackagePublish::Bool(true))));
   4668         assert!(publish_config_is_public(Some(&PackagePublish::Registries(
   4669             vec!["crates-io".to_string(),]
   4670         ))));
   4671         assert!(!publish_config_is_public(Some(
   4672             &PackagePublish::Registries(vec!["crates-io".to_string(), "mirror".to_string(),])
   4673         )));
   4674         assert!(!publish_config_is_public(Some(
   4675             &PackagePublish::Registries(vec!["mirror".to_string(),])
   4676         )));
   4677 
   4678         assert!(!publish_config_is_non_public(None));
   4679         assert!(!publish_config_is_non_public(Some(&PackagePublish::Bool(
   4680             true
   4681         ))));
   4682         assert!(publish_config_is_non_public(Some(&PackagePublish::Bool(
   4683             false
   4684         ))));
   4685         assert!(!publish_config_is_non_public(Some(
   4686             &PackagePublish::Registries(vec!["crates-io".to_string(),])
   4687         )));
   4688     }
   4689 
   4690     #[test]
   4691     fn release_contract_helpers_cover_classification_and_env_override_paths() {
   4692         let release = ReleaseSection {
   4693             version: "1.0.0".to_string(),
   4694         };
   4695         let empty_order = ReleaseCrateSet { crates: Vec::new() };
   4696 
   4697         let legacy = ReleaseContractFile {
   4698             release: ReleaseSection {
   4699                 version: release.version.clone(),
   4700             },
   4701             classification: ReleaseClassification::default(),
   4702             publish: Some(ReleaseCrateSet {
   4703                 crates: vec!["radroots_public".to_string()],
   4704             }),
   4705             internal: Some(ReleaseCrateSet {
   4706                 crates: vec!["radroots_internal".to_string()],
   4707             }),
   4708             publish_order: ReleaseCrateSet {
   4709                 crates: empty_order.crates.clone(),
   4710             },
   4711         };
   4712         assert!(!legacy.uses_classification());
   4713         assert_eq!(legacy.public_crates(), vec!["radroots_public".to_string()]);
   4714         assert_eq!(
   4715             legacy.internal_crates(),
   4716             vec!["radroots_internal".to_string()]
   4717         );
   4718 
   4719         let empty_legacy = ReleaseContractFile {
   4720             release: ReleaseSection {
   4721                 version: release.version.clone(),
   4722             },
   4723             classification: ReleaseClassification::default(),
   4724             publish: None,
   4725             internal: None,
   4726             publish_order: ReleaseCrateSet {
   4727                 crates: empty_order.crates.clone(),
   4728             },
   4729         };
   4730         assert!(!empty_legacy.uses_classification());
   4731         assert_eq!(empty_legacy.public_crates(), Vec::<String>::new());
   4732         assert_eq!(empty_legacy.internal_crates(), Vec::<String>::new());
   4733 
   4734         let internal = ReleaseContractFile {
   4735             release: ReleaseSection {
   4736                 version: release.version.clone(),
   4737             },
   4738             classification: ReleaseClassification {
   4739                 internal: vec!["radroots_internal_only".to_string()],
   4740                 ..ReleaseClassification::default()
   4741             },
   4742             publish: None,
   4743             internal: None,
   4744             publish_order: ReleaseCrateSet {
   4745                 crates: empty_order.crates.clone(),
   4746             },
   4747         };
   4748         assert!(internal.uses_classification());
   4749 
   4750         let deferred = ReleaseContractFile {
   4751             release: ReleaseSection {
   4752                 version: release.version.clone(),
   4753             },
   4754             classification: ReleaseClassification {
   4755                 deferred: vec!["radroots_deferred".to_string()],
   4756                 ..ReleaseClassification::default()
   4757             },
   4758             publish: None,
   4759             internal: None,
   4760             publish_order: ReleaseCrateSet {
   4761                 crates: empty_order.crates.clone(),
   4762             },
   4763         };
   4764         assert!(deferred.uses_classification());
   4765         assert_eq!(
   4766             deferred.deferred_crates(),
   4767             vec!["radroots_deferred".to_string()]
   4768         );
   4769 
   4770         let retired = ReleaseContractFile {
   4771             release: ReleaseSection {
   4772                 version: release.version.clone(),
   4773             },
   4774             classification: ReleaseClassification {
   4775                 retired: vec!["radroots_retired".to_string()],
   4776                 ..ReleaseClassification::default()
   4777             },
   4778             publish: None,
   4779             internal: None,
   4780             publish_order: ReleaseCrateSet {
   4781                 crates: empty_order.crates.clone(),
   4782             },
   4783         };
   4784         assert!(retired.uses_classification());
   4785         assert_eq!(
   4786             retired.retired_crates(),
   4787             vec!["radroots_retired".to_string()]
   4788         );
   4789 
   4790         let yank_only = ReleaseContractFile {
   4791             release,
   4792             classification: ReleaseClassification {
   4793                 yank_only: vec!["radroots_yank_only".to_string()],
   4794                 ..ReleaseClassification::default()
   4795             },
   4796             publish: None,
   4797             internal: None,
   4798             publish_order: empty_order,
   4799         };
   4800         assert!(yank_only.uses_classification());
   4801         assert_eq!(
   4802             yank_only.yank_only_crates(),
   4803             vec!["radroots_yank_only".to_string()]
   4804         );
   4805 
   4806         let root = create_synthetic_workspace("release_contract_env_override");
   4807         let policy_path = root_release_policy_path(&root);
   4808         let resolved =
   4809             resolve_release_contract_path_with_override(&root, Some(policy_path.clone()))
   4810                 .expect("existing override policy should resolve");
   4811         assert_eq!(resolved, Some(policy_path));
   4812 
   4813         let missing_policy = root.join("missing-release-policy.toml");
   4814         let err = resolve_release_contract_path_with_override(&root, Some(missing_policy.clone()))
   4815             .expect_err("missing env policy should fail");
   4816         assert!(err.contains(RELEASE_POLICY_ENV));
   4817         assert!(err.contains("missing release policy file"));
   4818         assert!(err.contains(&missing_policy.display().to_string()));
   4819 
   4820         let _ = fs::remove_dir_all(&root);
   4821     }
   4822 
   4823     #[test]
   4824     fn workspace_package_manifests_reject_duplicate_package_names() {
   4825         let root = temp_root("workspace_manifest_duplicates");
   4826         write_file(
   4827             &root.join("Cargo.toml"),
   4828             r#"[workspace]
   4829 members = ["crates/a", "crates/b"]
   4830 "#,
   4831         );
   4832         let package_manifest =
   4833             "[package]\nname = \"duplicate\"\nversion = \"0.1.0\"\nedition = \"2024\"\n";
   4834         write_file(
   4835             &root.join("crates").join("a").join("Cargo.toml"),
   4836             package_manifest,
   4837         );
   4838         write_file(
   4839             &root.join("crates").join("b").join("Cargo.toml"),
   4840             package_manifest,
   4841         );
   4842         let err = workspace_package_manifests(&root)
   4843             .expect_err("duplicate package names in manifest map");
   4844         assert!(err.contains("duplicate workspace package name in manifest map"));
   4845         let _ = fs::remove_dir_all(root);
   4846     }
   4847 
   4848     #[test]
   4849     fn coverage_refresh_parsing_and_summary_errors_are_reported() {
   4850         let root = temp_root("coverage_refresh_errors");
   4851         let coverage_dir = root.join("target").join("coverage");
   4852         fs::create_dir_all(&coverage_dir).expect("create coverage dir");
   4853 
   4854         write_file(
   4855             &coverage_dir.join("coverage-refresh.tsv"),
   4856             "crate\tstatus\texec\tfunc\tbranch\tregion\treport\nbad-row\n",
   4857         );
   4858         let bad_row = load_coverage_refresh_rows(&root).expect_err("invalid coverage row");
   4859         assert!(bad_row.contains("at least 7 columns"));
   4860 
   4861         write_file(
   4862             &coverage_dir.join("coverage-refresh.tsv"),
   4863             "crate\tstatus\texec\tfunc\tbranch\tregion\treport\nradroots_a\tpass\tnot-a-number\t100\t100\t100\tfile\n",
   4864         );
   4865         let bad_percent = load_coverage_refresh_rows(&root).expect_err("invalid coverage percent");
   4866         assert!(bad_percent.contains("parse exec"));
   4867 
   4868         write_file(
   4869             &coverage_dir.join("coverage-refresh.tsv"),
   4870             "crate\tstatus\texec\tfunc\tbranch\tregion\treport\nradroots_a\tpass\t100\t100\t100\tnot-a-number\tfile\n",
   4871         );
   4872         let bad_region =
   4873             load_coverage_refresh_rows(&root).expect_err("invalid region coverage percent");
   4874         assert!(bad_region.contains("parse region"));
   4875 
   4876         write_file(
   4877             &coverage_dir.join("coverage-refresh.tsv"),
   4878             "crate\tstatus\texec\tfunc\tbranch\tregion\treport\nradroots_a\tpass\t100\t100\t100\t100\tfile\nradroots_a\tpass\t100\t100\t100\t100\tfile\n",
   4879         );
   4880         let duplicate_row = load_coverage_refresh_rows(&root).expect_err("duplicate coverage row");
   4881         assert!(duplicate_row.contains("duplicate coverage row"));
   4882 
   4883         write_file(
   4884             &coverage_dir.join("coverage-refresh.tsv"),
   4885             "crate\tstatus\texec\tfunc\tbranch\tregion\treport\nradroots_a\tfail\t100\t100\t100\t100\tfile\n",
   4886         );
   4887         let required = ["radroots_a".to_string()]
   4888             .into_iter()
   4889             .collect::<BTreeSet<_>>();
   4890         let non_pass = validate_required_coverage_summary(&root, &required, strict_thresholds())
   4891             .expect_err("non-pass status");
   4892         assert!(non_pass.contains("non-pass status"));
   4893 
   4894         write_file(
   4895             &coverage_dir.join("coverage-refresh.tsv"),
   4896             "crate\tstatus\texec\tfunc\tbranch\tregion\treport\nradroots_a\tpass\t99.9\t100\t100\t100\tfile\n",
   4897         );
   4898         let below_100 = validate_required_coverage_summary(&root, &required, strict_thresholds())
   4899             .expect_err("coverage below 100");
   4900         assert!(below_100.contains("must satisfy coverage policy"));
   4901 
   4902         let missing = ["missing".to_string()].into_iter().collect::<BTreeSet<_>>();
   4903         let missing_err = validate_required_coverage_summary(&root, &missing, strict_thresholds())
   4904             .expect_err("missing required row");
   4905         assert!(missing_err.contains("missing from coverage-refresh.tsv"));
   4906 
   4907         let _ = fs::remove_dir_all(root);
   4908     }
   4909 
   4910     #[test]
   4911     fn enum_extract_and_parse_error_paths_are_reported() {
   4912         let missing = extract_enum_body("pub struct X;", "RadrootsCoreUnitDimension")
   4913             .expect_err("missing enum");
   4914         assert!(missing.contains("missing enum"));
   4915 
   4916         let missing_brace = extract_enum_body(
   4917             "pub enum RadrootsCoreUnitDimension",
   4918             "RadrootsCoreUnitDimension",
   4919         )
   4920         .expect_err("missing opening brace");
   4921         assert!(missing_brace.contains("missing opening brace"));
   4922 
   4923         let missing_close = extract_enum_body(
   4924             "pub enum RadrootsCoreUnitDimension { Count, Mass",
   4925             "RadrootsCoreUnitDimension",
   4926         )
   4927         .expect_err("missing closing brace");
   4928         assert!(missing_close.contains("missing closing brace"));
   4929 
   4930         let variants = parse_enum_variants(
   4931             r#"
   4932             ,
   4933             = 1,
   4934             // skip
   4935             #![cfg(test)]
   4936             Count,
   4937             "#,
   4938         );
   4939         assert_eq!(variants, vec!["Count".to_string()]);
   4940 
   4941         let nested = extract_enum_body(
   4942             "pub enum RadrootsCoreUnitDimension { Count = { 1 }, Mass = 2 }",
   4943             "RadrootsCoreUnitDimension",
   4944         )
   4945         .expect("nested braces in enum body");
   4946         assert!(nested.contains("Count"));
   4947     }
   4948 
   4949     #[test]
   4950     fn coverage_policy_parity_reports_contract_errors() {
   4951         let root = create_synthetic_workspace("coverage_policy_errors");
   4952         let contract_root = root.join("contracts");
   4953         let coverage_root = coverage_root(&contract_root);
   4954 
   4955         write_file(
   4956             &coverage_root.join("coverage.toml"),
   4957             r#"[gate]
   4958 fail_under_exec_lines = 100.0
   4959 fail_under_functions = 100.0
   4960 fail_under_regions = 100.0
   4961 fail_under_branches = 100.0
   4962 require_branches = true
   4963 
   4964 [required]
   4965 crates = []
   4966 "#,
   4967         );
   4968         let empty_required =
   4969             validate_coverage_policy_parity(&root, &contract_root).expect_err("empty required");
   4970         assert!(empty_required.contains("required crates list must not be empty"));
   4971 
   4972         write_file(
   4973             &coverage_root.join("coverage.toml"),
   4974             r#"[gate]
   4975 fail_under_exec_lines = 97.0
   4976 fail_under_functions = 100.0
   4977 fail_under_regions = 100.0
   4978 fail_under_branches = 100.0
   4979 require_branches = true
   4980 
   4981 [required]
   4982 crates = ["radroots_a", "radroots_b"]
   4983 "#,
   4984         );
   4985         let invalid_gate = validate_coverage_policy_parity(&root, &contract_root)
   4986             .expect_err("invalid policy thresholds");
   4987         assert!(invalid_gate.contains("100/100/100/100"));
   4988 
   4989         write_file(
   4990             &coverage_root.join("coverage.toml"),
   4991             r#"[gate]
   4992 fail_under_exec_lines = 100.0
   4993 fail_under_functions = 97.0
   4994 fail_under_regions = 100.0
   4995 fail_under_branches = 100.0
   4996 require_branches = true
   4997 
   4998 [required]
   4999 crates = ["radroots_a", "radroots_b"]
   5000 "#,
   5001         );
   5002         let invalid_functions = validate_coverage_policy_parity(&root, &contract_root)
   5003             .expect_err("invalid function threshold");
   5004         assert!(invalid_functions.contains("100/100/100/100"));
   5005 
   5006         write_file(
   5007             &coverage_root.join("coverage.toml"),
   5008             r#"[gate]
   5009 fail_under_exec_lines = 100.0
   5010 fail_under_functions = 100.0
   5011 fail_under_regions = 97.0
   5012 fail_under_branches = 100.0
   5013 require_branches = true
   5014 
   5015 [required]
   5016 crates = ["radroots_a", "radroots_b"]
   5017 "#,
   5018         );
   5019         let invalid_regions = validate_coverage_policy_parity(&root, &contract_root)
   5020             .expect_err("invalid region threshold");
   5021         assert!(invalid_regions.contains("100/100/100/100"));
   5022 
   5023         write_file(
   5024             &coverage_root.join("coverage.toml"),
   5025             r#"[gate]
   5026 fail_under_exec_lines = 100.0
   5027 fail_under_functions = 100.0
   5028 fail_under_regions = 100.0
   5029 fail_under_branches = 97.0
   5030 require_branches = true
   5031 
   5032 [required]
   5033 crates = ["radroots_a", "radroots_b"]
   5034 "#,
   5035         );
   5036         let invalid_branches = validate_coverage_policy_parity(&root, &contract_root)
   5037             .expect_err("invalid branch threshold");
   5038         assert!(invalid_branches.contains("100/100/100/100"));
   5039 
   5040         write_file(
   5041             &coverage_root.join("coverage.toml"),
   5042             r#"[gate]
   5043 fail_under_exec_lines = 100.0
   5044 fail_under_functions = 100.0
   5045 fail_under_regions = 100.0
   5046 fail_under_branches = 100.0
   5047 require_branches = true
   5048 
   5049 [required]
   5050 crates = ["radroots_a", "radroots_a"]
   5051 "#,
   5052         );
   5053         let duplicate_required = validate_coverage_policy_parity(&root, &contract_root)
   5054             .expect_err("duplicate required crate");
   5055         assert!(duplicate_required.contains("duplicate crate"));
   5056 
   5057         write_file(
   5058             &coverage_root.join("coverage.toml"),
   5059             r#"[gate]
   5060 fail_under_exec_lines = 100.0
   5061 fail_under_functions = 100.0
   5062 fail_under_regions = 100.0
   5063 fail_under_branches = 100.0
   5064 require_branches = false
   5065 
   5066 [required]
   5067 crates = ["radroots_a", "radroots_b"]
   5068 "#,
   5069         );
   5070         let branches_optional = validate_coverage_policy_parity(&root, &contract_root)
   5071             .expect_err("branches must be required");
   5072         assert!(branches_optional.contains("required branches"));
   5073 
   5074         write_file(
   5075             &coverage_root.join("coverage.toml"),
   5076             r#"[gate]
   5077 fail_under_exec_lines = 100.0
   5078 fail_under_functions = 100.0
   5079 fail_under_regions = 100.0
   5080 fail_under_branches = 100.0
   5081 require_branches = true
   5082 
   5083 [required]
   5084 crates = ["radroots_b"]
   5085 "#,
   5086         );
   5087         let missing_workspace = validate_coverage_policy_parity(&root, &contract_root)
   5088             .expect_err("missing workspace crate in policy");
   5089         assert!(missing_workspace.contains("missing workspace crates"));
   5090 
   5091         write_file(
   5092             &coverage_root.join("coverage.toml"),
   5093             r#"[gate]
   5094 fail_under_exec_lines = 100.0
   5095 fail_under_functions = 100.0
   5096 fail_under_regions = 100.0
   5097 fail_under_branches = 100.0
   5098 require_branches = true
   5099 
   5100 [required]
   5101 crates = ["unknown"]
   5102 "#,
   5103         );
   5104         let required_unknown = validate_coverage_policy_parity(&root, &contract_root)
   5105             .expect_err("unknown required crate");
   5106         assert!(required_unknown.contains("includes excluded or unknown crates"));
   5107 
   5108         let _ = fs::remove_dir_all(root);
   5109     }
   5110 
   5111     #[test]
   5112     fn release_publish_policy_reports_contract_errors() {
   5113         let root = create_synthetic_workspace("release_policy_errors");
   5114         let contract_root = root.join("contracts");
   5115         let release_policy_path = root_release_policy_path(&root);
   5116 
   5117         write_file(
   5118             &release_policy_path,
   5119             r#"[release]
   5120 version = ""
   5121 
   5122 [publish]
   5123 crates = ["radroots_a"]
   5124 
   5125 [internal]
   5126 crates = ["radroots_b"]
   5127 
   5128 [publish_order]
   5129 crates = ["radroots_a"]
   5130 "#,
   5131         );
   5132         let empty_version = validate_release_publish_policy(&root, &contract_root, "1.0.0")
   5133             .expect_err("empty release version");
   5134         assert!(empty_version.contains("must not be empty"));
   5135 
   5136         write_file(
   5137             &release_policy_path,
   5138             r#"[release]
   5139 version = "2.0.0"
   5140 
   5141 [publish]
   5142 crates = ["radroots_a"]
   5143 
   5144 [internal]
   5145 crates = ["radroots_b"]
   5146 
   5147 [publish_order]
   5148 crates = ["radroots_a"]
   5149 "#,
   5150         );
   5151         let version_mismatch = validate_release_publish_policy(&root, &contract_root, "1.0.0")
   5152             .expect_err("release version mismatch");
   5153         assert!(version_mismatch.contains("must match contract version"));
   5154 
   5155         write_file(
   5156             &release_policy_path,
   5157             r#"[release]
   5158 version = "1.0.0"
   5159 
   5160 [publish]
   5161 crates = ["radroots_a"]
   5162 
   5163 [internal]
   5164 crates = ["radroots_a"]
   5165 
   5166 [publish_order]
   5167 crates = ["radroots_a"]
   5168 "#,
   5169         );
   5170         let overlap = validate_release_publish_policy(&root, &contract_root, "1.0.0")
   5171             .expect_err("publish/internal overlap");
   5172         assert!(overlap.contains("overlap is not allowed"));
   5173 
   5174         write_file(
   5175             &release_policy_path,
   5176             r#"[release]
   5177 version = "1.0.0"
   5178 
   5179 [publish]
   5180 crates = ["radroots_a"]
   5181 
   5182 [internal]
   5183 crates = []
   5184 
   5185 [publish_order]
   5186 crates = ["radroots_a"]
   5187 "#,
   5188         );
   5189         let missing_workspace = validate_release_publish_policy(&root, &contract_root, "1.0.0")
   5190             .expect_err("missing workspace crate");
   5191         assert!(missing_workspace.contains("missing workspace crates"));
   5192 
   5193         write_file(
   5194             &release_policy_path,
   5195             r#"[release]
   5196 version = "1.0.0"
   5197 
   5198 [publish]
   5199 crates = ["radroots_a"]
   5200 
   5201 [internal]
   5202 crates = ["radroots_b"]
   5203 
   5204 [publish_order]
   5205 crates = []
   5206 "#,
   5207         );
   5208         let missing_publish_order = validate_release_publish_policy(&root, &contract_root, "1.0.0")
   5209             .expect_err("missing publish order entries");
   5210         assert!(missing_publish_order.contains("missing publish crates"));
   5211 
   5212         write_file(
   5213             &release_policy_path,
   5214             r#"[release]
   5215 version = "1.0.0"
   5216 
   5217 [publish]
   5218 crates = ["radroots_a"]
   5219 
   5220 [internal]
   5221 crates = ["radroots_b"]
   5222 
   5223 [publish_order]
   5224 crates = ["radroots_a", "radroots_b"]
   5225 "#,
   5226         );
   5227         let extra_publish_order = validate_release_publish_policy(&root, &contract_root, "1.0.0")
   5228             .expect_err("extra publish order entries");
   5229         assert!(extra_publish_order.contains("non-publish crates"));
   5230 
   5231         write_file(
   5232             &root.join("crates").join("a").join("Cargo.toml"),
   5233             r#"[package]
   5234 name = "radroots_a"
   5235 publish = ["crates-io"]
   5236 version = "0.1.0"
   5237 edition = "2024"
   5238 description = "crate a"
   5239 repository = "https://example.com/a"
   5240 homepage = "https://example.com/a"
   5241 documentation = "https://docs.example.com/a"
   5242 readme = "README"
   5243 
   5244 [dependencies]
   5245 radroots_b = { path = "../b" }
   5246 "#,
   5247         );
   5248         write_file(
   5249             &root.join("crates").join("b").join("Cargo.toml"),
   5250             r#"[package]
   5251 name = "radroots_b"
   5252 version = "0.1.0"
   5253 edition = "2024"
   5254 description = "crate b"
   5255 repository = "https://example.com/b"
   5256 homepage = "https://example.com/b"
   5257 documentation = "https://docs.example.com/b"
   5258 readme = "README"
   5259 "#,
   5260         );
   5261         write_file(
   5262             &release_policy_path,
   5263             r#"[release]
   5264 version = "1.0.0"
   5265 
   5266 [publish]
   5267 crates = ["radroots_a", "radroots_b"]
   5268 
   5269 [internal]
   5270 crates = []
   5271 
   5272 [publish_order]
   5273 crates = ["radroots_a", "radroots_b"]
   5274 "#,
   5275         );
   5276         let dependency_order = validate_release_publish_policy(&root, &contract_root, "1.0.0")
   5277             .expect_err("dependency order violation");
   5278         assert!(dependency_order.contains("must place dependency"));
   5279 
   5280         write_file(
   5281             &release_policy_path,
   5282             r#"[release]
   5283 version = "1.0.0"
   5284 
   5285 [publish]
   5286 crates = ["radroots_a"]
   5287 
   5288 [internal]
   5289 crates = ["radroots_b"]
   5290 
   5291 [publish_order]
   5292 crates = ["radroots_a"]
   5293 "#,
   5294         );
   5295         write_file(
   5296             &root.join("crates").join("b").join("Cargo.toml"),
   5297             r#"[package]
   5298 name = "radroots_b"
   5299 version = "0.1.0"
   5300 edition = "2024"
   5301 publish = false
   5302 "#,
   5303         );
   5304         validate_release_publish_policy(&root, &contract_root, "1.0.0")
   5305             .expect("internal dependency should be ignored in publish ordering");
   5306 
   5307         write_file(
   5308             &root.join("crates").join("a").join("Cargo.toml"),
   5309             r#"[package]
   5310 name = "radroots_a"
   5311 version = "0.1.0"
   5312 edition = "2024"
   5313 publish = false
   5314 "#,
   5315         );
   5316         write_file(
   5317             &release_policy_path,
   5318             r#"[release]
   5319 version = "1.0.0"
   5320 
   5321 [publish]
   5322 crates = ["radroots_a"]
   5323 
   5324 [internal]
   5325 crates = ["radroots_b"]
   5326 
   5327 [publish_order]
   5328 crates = ["radroots_a"]
   5329 "#,
   5330         );
   5331         let publish_flag = validate_release_publish_policy(&root, &contract_root, "1.0.0")
   5332             .expect_err("publish crate must be publishable");
   5333         assert!(publish_flag.contains("must set publish = [\"crates-io\"]"));
   5334 
   5335         write_file(
   5336             &root.join("crates").join("a").join("Cargo.toml"),
   5337             r#"[package]
   5338 name = "radroots_a"
   5339 publish = ["crates-io"]
   5340 version = "0.1.0"
   5341 edition = "2024"
   5342 description = "crate a"
   5343 repository = "https://example.com/a"
   5344 homepage = "https://example.com/a"
   5345 documentation = "https://docs.example.com/a"
   5346 readme = "README"
   5347 "#,
   5348         );
   5349         write_file(
   5350             &root.join("crates").join("b").join("Cargo.toml"),
   5351             r#"[package]
   5352 name = "radroots_b"
   5353 version = "0.1.0"
   5354 edition = "2024"
   5355 "#,
   5356         );
   5357         let internal_flag = validate_release_publish_policy(&root, &contract_root, "1.0.0")
   5358             .expect_err("internal crate must be non-publishable");
   5359         assert!(internal_flag.contains("non-public crate"));
   5360 
   5361         let _ = fs::remove_dir_all(root);
   5362     }
   5363 
   5364     #[test]
   5365     fn validate_contract_bundle_reports_required_field_errors() {
   5366         let root = create_synthetic_workspace("contract_bundle_errors");
   5367 
   5368         let assert_bundle_error = |expected: &str, mutator: fn(&mut ContractBundle)| {
   5369             let mut bundle = load_contract_bundle(&root).expect("load bundle");
   5370             mutator(&mut bundle);
   5371             let err = match validate_contract_bundle(&bundle) {
   5372                 Ok(()) => panic!("expected bundle validation error: {expected}"),
   5373                 Err(err) => err,
   5374             };
   5375             assert!(err.contains(expected), "expected `{expected}` in `{err}`");
   5376         };
   5377 
   5378         assert_bundle_error("contract name is required", |bundle| {
   5379             bundle.manifest.contract.name.clear();
   5380         });
   5381         assert_bundle_error("contract version is required", |bundle| {
   5382             bundle.manifest.contract.version.clear();
   5383         });
   5384         assert_bundle_error("contract source is required", |bundle| {
   5385             bundle.manifest.contract.source.clear();
   5386         });
   5387         assert_bundle_error("surface.model_crates must not be empty", |bundle| {
   5388             bundle.manifest.surface.model_crates.clear();
   5389         });
   5390         assert_bundle_error("surface.algorithm_crates must not be empty", |bundle| {
   5391             bundle.manifest.surface.algorithm_crates.clear();
   5392         });
   5393         assert_bundle_error(
   5394             "surface.internal_replica_crates.storage must be a crate identifier",
   5395             |bundle| {
   5396                 bundle.manifest.surface.internal_replica_crates = Some(InternalReplicaCrates {
   5397                     schema: "radroots_replica_db_schema".to_string(),
   5398                     storage: "crates/replica_db".to_string(),
   5399                     sync: "radroots_replica_sync".to_string(),
   5400                 });
   5401             },
   5402         );
   5403         assert_bundle_error("version.contract.version is required", |bundle| {
   5404             bundle.version.contract.version.clear();
   5405         });
   5406         assert_bundle_error("version.contract.stability is required", |bundle| {
   5407             bundle.version.contract.stability.clear();
   5408         });
   5409         assert_bundle_error("version.semver rules must all be non-empty", |bundle| {
   5410             bundle.version.semver.major_on.clear();
   5411         });
   5412         assert_bundle_error("version.semver rules must all be non-empty", |bundle| {
   5413             bundle.version.semver.minor_on.clear();
   5414         });
   5415         assert_bundle_error("version.semver rules must all be non-empty", |bundle| {
   5416             bundle.version.semver.patch_on.clear();
   5417         });
   5418         assert_bundle_error(
   5419             "compatibility.requires_conformance_pass must be true",
   5420             |bundle| {
   5421                 bundle.version.compatibility.requires_conformance_pass = false;
   5422             },
   5423         );
   5424         assert_bundle_error(
   5425             "compatibility.requires_contract_manifest_diff must be true",
   5426             |bundle| {
   5427                 bundle.version.compatibility.requires_contract_manifest_diff = false;
   5428             },
   5429         );
   5430         assert_bundle_error(
   5431             "compatibility.requires_release_notes must be true",
   5432             |bundle| {
   5433                 bundle.version.compatibility.requires_release_notes = false;
   5434             },
   5435         );
   5436         assert_bundle_error("contract policy flags must all be true", |bundle| {
   5437             bundle.manifest.policy.exclude_internal_workspace_crates = false;
   5438         });
   5439         assert_bundle_error("contract policy flags must all be true", |bundle| {
   5440             bundle.manifest.policy.require_reproducible_exports = false;
   5441         });
   5442         assert_bundle_error("contract policy flags must all be true", |bundle| {
   5443             bundle.manifest.policy.require_conformance_vectors = false;
   5444         });
   5445         assert_bundle_error("contract replica policy flags must all be true", |bundle| {
   5446             bundle.manifest.policy.replica = Some(ReplicaPolicy {
   5447                 forbid_legacy_alias_identifiers: false,
   5448                 require_transport_agnostic_sync_contract: true,
   5449                 require_deterministic_emit_ingest: true,
   5450             });
   5451         });
   5452 
   5453         let _ = fs::remove_dir_all(root);
   5454     }
   5455 
   5456     #[test]
   5457     fn load_contract_bundle_rejects_stale_consumer_sdk_tables() {
   5458         let stale_manifest_root = create_synthetic_workspace("stale_manifest_consumer_sdk");
   5459         let manifest_path = stale_manifest_root.join("contracts").join("manifest.toml");
   5460         let mut manifest = fs::read_to_string(&manifest_path).expect("manifest");
   5461         manifest.push_str(
   5462             r#"
   5463 [consumer_sdk]
   5464 rust_package = "radroots_sdk"
   5465 "#,
   5466         );
   5467         write_file(&manifest_path, &manifest);
   5468         let manifest_err =
   5469             load_contract_bundle(&stale_manifest_root).expect_err("stale manifest table");
   5470         assert!(manifest_err.contains("manifest.toml"));
   5471         assert!(manifest_err.contains("consumer_sdk"));
   5472         let _ = fs::remove_dir_all(stale_manifest_root);
   5473 
   5474         let stale_operations_root = create_synthetic_workspace("stale_operations_consumer_sdk");
   5475         add_operation_contract_files(&stale_operations_root);
   5476         let operations_path = stale_operations_root
   5477             .join("contracts")
   5478             .join("operations.toml");
   5479         let mut operations = fs::read_to_string(&operations_path).expect("operations");
   5480         operations.push_str(
   5481             r#"
   5482 [consumer_sdk]
   5483 rust_package = "radroots_sdk"
   5484 "#,
   5485         );
   5486         write_file(&operations_path, &operations);
   5487         let operations_err =
   5488             load_contract_bundle(&stale_operations_root).expect_err("stale operations table");
   5489         assert!(operations_err.contains("operations.toml"));
   5490         assert!(operations_err.contains("consumer_sdk"));
   5491         let _ = fs::remove_dir_all(stale_operations_root);
   5492     }
   5493 
   5494     #[test]
   5495     fn load_contract_bundle_rejects_legacy_contract_roots() {
   5496         let stale_spec_root = create_synthetic_workspace("stale_spec_root");
   5497         fs::create_dir_all(stale_spec_root.join("spec")).expect("create spec root");
   5498         let spec_err = load_contract_bundle(&stale_spec_root).expect_err("stale spec root");
   5499         assert!(spec_err.contains("legacy contract root"));
   5500         assert!(spec_err.contains("spec"));
   5501         let _ = fs::remove_dir_all(stale_spec_root);
   5502 
   5503         let stale_policy_root = create_synthetic_workspace("stale_policy_root");
   5504         fs::create_dir_all(stale_policy_root.join("policy")).expect("create policy root");
   5505         let policy_err = load_contract_bundle(&stale_policy_root).expect_err("stale policy root");
   5506         assert!(policy_err.contains("legacy contract root"));
   5507         assert!(policy_err.contains("policy"));
   5508         let _ = fs::remove_dir_all(stale_policy_root);
   5509     }
   5510 
   5511     #[test]
   5512     fn validate_contract_bundle_reports_operation_contract_errors() {
   5513         let root = create_synthetic_workspace("operation_contract_bundle_errors");
   5514         add_operation_contract_files(&root);
   5515 
   5516         let assert_bundle_error = |expected: &str, mutator: fn(&mut ContractBundle)| {
   5517             let mut bundle = load_contract_bundle(&root).expect("load bundle");
   5518             mutator(&mut bundle);
   5519             let err = validate_contract_bundle(&bundle).expect_err("bundle validation error");
   5520             assert!(err.contains(expected), "expected `{expected}` in `{err}`");
   5521         };
   5522 
   5523         assert_bundle_error("public.domains must not be empty", |bundle| {
   5524             bundle
   5525                 .operations_manifest
   5526                 .as_mut()
   5527                 .expect("operations manifest")
   5528                 .public
   5529                 .domains
   5530                 .clear();
   5531         });
   5532         let _ = fs::remove_dir_all(root);
   5533     }
   5534 
   5535     #[test]
   5536     fn validate_contract_bundle_requires_real_conformance_assets() {
   5537         let missing_schema_root = create_synthetic_workspace("operation_contract_missing_schema");
   5538         add_operation_contract_files(&missing_schema_root);
   5539         let _ = fs::remove_file(conformance_schema_path(&missing_schema_root));
   5540         let bundle = load_contract_bundle(&missing_schema_root).expect("load bundle");
   5541         let err = validate_contract_bundle(&bundle).expect_err("missing schema should fail");
   5542         assert!(err.contains("vector.schema.json"));
   5543         let _ = fs::remove_dir_all(&missing_schema_root);
   5544 
   5545         let invalid_vector_root = create_synthetic_workspace("operation_contract_invalid_vector");
   5546         add_operation_contract_files(&invalid_vector_root);
   5547         write_file(
   5548             &invalid_vector_root
   5549                 .join("contracts")
   5550                 .join("conformance")
   5551                 .join("vectors")
   5552                 .join("profile")
   5553                 .join("build_draft.v1.json"),
   5554             r#"{
   5555   "suite": "profile",
   5556   "contract_version": "1.0.0",
   5557   "vectors": [
   5558     {
   5559       "id": "profile_build_draft_minimal_001",
   5560       "kind": "profile.build_draft",
   5561       "input": {}
   5562     }
   5563   ]
   5564 }
   5565 "#,
   5566         );
   5567         let bundle = load_contract_bundle(&invalid_vector_root).expect("load bundle");
   5568         let err = validate_contract_bundle(&bundle).expect_err("invalid vector should fail");
   5569         assert!(err.contains("build_draft.v1.json"));
   5570         assert!(err.contains("parse"));
   5571         let _ = fs::remove_dir_all(&invalid_vector_root);
   5572 
   5573         let root = create_synthetic_workspace("operation_contract_vector_path");
   5574         add_operation_contract_files(&root);
   5575         let mut bundle = load_contract_bundle(&root).expect("load bundle");
   5576         bundle
   5577             .operations_manifest
   5578             .as_mut()
   5579             .expect("operations manifest")
   5580             .operations
   5581             .get_mut("profile_build_draft")
   5582             .expect("profile operation")
   5583             .conformance
   5584             .vector = "conformance/vectors/profile/build_draft.v1.json".to_string();
   5585         let err = validate_contract_bundle(&bundle).expect_err("legacy path should fail");
   5586         assert!(err.contains("must live under contracts/conformance/"));
   5587         let _ = fs::remove_dir_all(root);
   5588     }
   5589 
   5590     #[test]
   5591     fn parse_toml_and_publish_flags_report_failures() {
   5592         let missing = temp_root("parse_toml_missing");
   5593         let read_err =
   5594             parse_toml::<WorkspaceCargoManifest>(&missing.join("Cargo.toml")).expect_err("missing");
   5595         assert!(read_err.contains("read"));
   5596         let _ = fs::remove_dir_all(&missing);
   5597 
   5598         let invalid = temp_root("parse_toml_invalid");
   5599         write_file(&invalid.join("Cargo.toml"), "[workspace]\nmembers = [");
   5600         let parse_err = parse_toml::<WorkspaceCargoManifest>(&invalid.join("Cargo.toml"))
   5601             .expect_err("invalid manifest");
   5602         assert!(parse_err.contains("parse"));
   5603         let _ = fs::remove_dir_all(&invalid);
   5604 
   5605         let contract_manifest_missing = temp_root("parse_contract_manifest_missing");
   5606         let contract_manifest_read_err =
   5607             parse_toml::<ContractManifest>(&contract_manifest_missing.join("manifest.toml"))
   5608                 .expect_err("missing contract manifest");
   5609         assert!(contract_manifest_read_err.contains("read"));
   5610         let _ = fs::remove_dir_all(&contract_manifest_missing);
   5611 
   5612         let contract_manifest_invalid = temp_root("parse_contract_manifest_invalid");
   5613         write_file(
   5614             &contract_manifest_invalid.join("manifest.toml"),
   5615             "[contract",
   5616         );
   5617         let contract_manifest_parse_err =
   5618             parse_toml::<ContractManifest>(&contract_manifest_invalid.join("manifest.toml"))
   5619                 .expect_err("invalid contract manifest");
   5620         assert!(contract_manifest_parse_err.contains("parse"));
   5621         let _ = fs::remove_dir_all(&contract_manifest_invalid);
   5622 
   5623         let version_missing = temp_root("parse_version_policy_missing");
   5624         let version_read_err = parse_toml::<VersionPolicy>(&version_missing.join("version.toml"))
   5625             .expect_err("missing version policy");
   5626         assert!(version_read_err.contains("read"));
   5627         let _ = fs::remove_dir_all(&version_missing);
   5628 
   5629         let version_invalid = temp_root("parse_version_policy_invalid");
   5630         write_file(&version_invalid.join("version.toml"), "[version");
   5631         let version_parse_err = parse_toml::<VersionPolicy>(&version_invalid.join("version.toml"))
   5632             .expect_err("invalid version policy");
   5633         assert!(version_parse_err.contains("parse"));
   5634         let _ = fs::remove_dir_all(&version_invalid);
   5635 
   5636         let release_missing = temp_root("parse_release_contract_missing");
   5637         let release_read_err =
   5638             parse_toml::<ReleaseContractFile>(&release_missing.join("publish-set.toml"))
   5639                 .expect_err("missing release contract");
   5640         assert!(release_read_err.contains("read"));
   5641         let _ = fs::remove_dir_all(&release_missing);
   5642 
   5643         let release_invalid = temp_root("parse_release_contract_invalid");
   5644         write_file(&release_invalid.join("publish-set.toml"), "[release");
   5645         let release_parse_err =
   5646             parse_toml::<ReleaseContractFile>(&release_invalid.join("publish-set.toml"))
   5647                 .expect_err("invalid release contract");
   5648         assert!(release_parse_err.contains("parse"));
   5649         let _ = fs::remove_dir_all(&release_invalid);
   5650 
   5651         let operations_missing = temp_root("parse_operations_manifest_missing");
   5652         let operations_read_err =
   5653             parse_toml::<OperationsContractManifest>(&operations_missing.join("operations.toml"))
   5654                 .expect_err("missing operations manifest");
   5655         assert!(operations_read_err.contains("read"));
   5656         let _ = fs::remove_dir_all(&operations_missing);
   5657 
   5658         let operations_invalid = temp_root("parse_operations_manifest_invalid");
   5659         write_file(&operations_invalid.join("operations.toml"), "[operations");
   5660         let operations_parse_err =
   5661             parse_toml::<OperationsContractManifest>(&operations_invalid.join("operations.toml"))
   5662                 .expect_err("invalid operations manifest");
   5663         assert!(operations_parse_err.contains("parse"));
   5664         let _ = fs::remove_dir_all(&operations_invalid);
   5665 
   5666         let dup = temp_root("publish_flags_duplicate");
   5667         write_file(
   5668             &dup.join("Cargo.toml"),
   5669             r#"[workspace]
   5670 members = ["crates/a", "crates/b"]
   5671 "#,
   5672         );
   5673         let member_manifest =
   5674             "[package]\nname = \"duplicate\"\nversion = \"0.1.0\"\nedition = \"2024\"\n";
   5675         write_file(
   5676             &dup.join("crates").join("a").join("Cargo.toml"),
   5677             member_manifest,
   5678         );
   5679         write_file(
   5680             &dup.join("crates").join("b").join("Cargo.toml"),
   5681             member_manifest,
   5682         );
   5683         let dup_err = workspace_package_publish_flags(&dup).expect_err("duplicate publish flags");
   5684         assert!(dup_err.contains("duplicate workspace package name"));
   5685         let _ = fs::remove_dir_all(&dup);
   5686     }
   5687 
   5688     #[test]
   5689     fn workspace_package_records_and_callers_report_member_manifest_errors() {
   5690         let root = temp_root("workspace_package_record_errors");
   5691         write_file(
   5692             &root.join("Cargo.toml"),
   5693             r#"[workspace]
   5694 members = ["crates/a"]
   5695 "#,
   5696         );
   5697 
   5698         let read_err =
   5699             workspace_package_records(&root).expect_err("missing member manifest should fail");
   5700         assert!(read_err.contains("read"));
   5701 
   5702         let names_err = workspace_package_names(&root).expect_err("names should fail");
   5703         assert!(names_err.contains("read"));
   5704         let manifests_err = workspace_package_manifests(&root).expect_err("manifests should fail");
   5705         assert!(manifests_err.contains("read"));
   5706         let flags_err = workspace_package_publish_flags(&root).expect_err("flags should fail");
   5707         assert!(flags_err.contains("read"));
   5708         let deps_err = read_workspace_package_dependencies(&root).expect_err("deps should fail");
   5709         assert!(deps_err.contains("read"));
   5710 
   5711         let publish = ["radroots_a".to_string()]
   5712             .into_iter()
   5713             .collect::<BTreeSet<_>>();
   5714         let publish_err =
   5715             validate_publish_package_metadata(&root, &publish).expect_err("publish metadata");
   5716         assert!(publish_err.contains("read"));
   5717 
   5718         write_file(
   5719             &root.join("crates").join("a").join("Cargo.toml"),
   5720             "[package",
   5721         );
   5722         let parse_value_err =
   5723             workspace_package_records(&root).expect_err("invalid toml should fail");
   5724         assert!(parse_value_err.contains("parse"));
   5725 
   5726         write_file(
   5727             &root.join("crates").join("a").join("Cargo.toml"),
   5728             r#"[workspace]
   5729 resolver = "2"
   5730 "#,
   5731         );
   5732         let parse_package_err =
   5733             workspace_package_records(&root).expect_err("missing package table should fail");
   5734         assert!(parse_package_err.contains("parse"));
   5735 
   5736         let _ = fs::remove_dir_all(&root);
   5737     }
   5738 
   5739     #[test]
   5740     fn workspace_package_manifests_success_and_publish_metadata_duplicate_names() {
   5741         let root = create_synthetic_workspace("workspace_manifest_success");
   5742         let manifests = workspace_package_manifests(&root).expect("workspace manifests");
   5743         assert_eq!(manifests.len(), 2);
   5744         assert!(manifests.contains_key("radroots_a"));
   5745         assert!(manifests.contains_key("radroots_b"));
   5746 
   5747         write_file(
   5748             &root.join("crates").join("b").join("Cargo.toml"),
   5749             r#"[package]
   5750 name = "radroots_a"
   5751 version = "0.1.0"
   5752 edition = "2024"
   5753 description = "crate b duplicate name"
   5754 repository = "https://example.com/b"
   5755 homepage = "https://example.com/b"
   5756 documentation = "https://docs.example.com/b"
   5757 readme = "README"
   5758 publish = false
   5759 "#,
   5760         );
   5761         let publish = ["radroots_a".to_string()]
   5762             .into_iter()
   5763             .collect::<BTreeSet<_>>();
   5764         let duplicate_err =
   5765             validate_publish_package_metadata(&root, &publish).expect_err("duplicate package map");
   5766         assert!(duplicate_err.contains("duplicate workspace package name"));
   5767 
   5768         let _ = fs::remove_dir_all(&root);
   5769     }
   5770 
   5771     #[test]
   5772     fn workspace_package_publish_configs_cover_success_and_duplicate_names() {
   5773         let root = create_synthetic_workspace("workspace_publish_configs");
   5774         let flags = workspace_package_publish_flags(&root).expect("publish flags");
   5775         assert_eq!(flags["radroots_a"], true);
   5776         assert_eq!(flags["radroots_b"], false);
   5777 
   5778         let configs = workspace_package_publish_configs(&root).expect("publish configs");
   5779         assert_eq!(
   5780             configs["radroots_a"],
   5781             Some(PackagePublish::Registries(vec!["crates-io".to_string()]))
   5782         );
   5783         assert_eq!(configs["radroots_b"], Some(PackagePublish::Bool(false)));
   5784 
   5785         write_file(
   5786             &root.join("crates").join("b").join("Cargo.toml"),
   5787             r#"[package]
   5788 name = "radroots_a"
   5789 version = "0.1.0"
   5790 edition = "2024"
   5791 publish = false
   5792 "#,
   5793         );
   5794         let duplicate_err = workspace_package_publish_configs(&root)
   5795             .expect_err("duplicate package name in publish configs");
   5796         assert!(duplicate_err.contains("duplicate workspace package name"));
   5797 
   5798         let _ = fs::remove_dir_all(&root);
   5799     }
   5800 
   5801     #[test]
   5802     fn workspace_package_publish_configs_report_workspace_record_errors() {
   5803         let root = temp_root("workspace_publish_configs_errors");
   5804         let err = workspace_package_publish_configs(&root)
   5805             .expect_err("missing workspace manifest should fail");
   5806         assert!(err.contains("Cargo.toml"));
   5807 
   5808         let _ = fs::remove_dir_all(&root);
   5809     }
   5810 
   5811     #[test]
   5812     fn coverage_release_and_bundle_loaders_report_parse_and_read_errors() {
   5813         let root = create_synthetic_workspace("coverage_release_loader_errors");
   5814         let contract_root = root.join("contracts");
   5815         let coverage_root = coverage_root(&contract_root);
   5816         let release_policy_path = root_release_policy_path(&root);
   5817 
   5818         let missing_workspace = temp_root("coverage_missing_workspace_manifest");
   5819         let policy_workspace_err =
   5820             validate_coverage_policy_parity(&missing_workspace, &contract_root)
   5821                 .expect_err("coverage workspace lookup error");
   5822         assert!(policy_workspace_err.contains("Cargo.toml"));
   5823         let _ = fs::remove_dir_all(&missing_workspace);
   5824 
   5825         let _ = fs::remove_file(coverage_root.join("coverage.toml"));
   5826         let policy_load_err = validate_coverage_policy_parity(&root, &contract_root)
   5827             .expect_err("coverage policy read error");
   5828         assert!(policy_load_err.contains("coverage.toml"));
   5829         write_file(
   5830             &coverage_root.join("coverage.toml"),
   5831             r#"[gate]
   5832 fail_under_exec_lines = 100.0
   5833 fail_under_functions = 100.0
   5834 fail_under_regions = 100.0
   5835 fail_under_branches = 100.0
   5836 require_branches = true
   5837 
   5838 [required]
   5839 crates = ["radroots_a", "radroots_b"]
   5840 "#,
   5841         );
   5842 
   5843         let missing_release = temp_root("release_missing_workspace_manifest");
   5844         write_root_release_policy(
   5845             &missing_release,
   5846             r#"[release]
   5847 version = "1.0.0"
   5848 
   5849 [publish]
   5850 crates = ["radroots_a"]
   5851 
   5852 [internal]
   5853 crates = ["radroots_b"]
   5854 
   5855 [publish_order]
   5856 crates = ["radroots_a"]
   5857 "#,
   5858         );
   5859         let release_workspace_err =
   5860             validate_release_publish_policy(&missing_release, &contract_root, "1.0.0")
   5861                 .expect_err("release workspace read error");
   5862         assert!(release_workspace_err.contains("Cargo.toml"));
   5863         let _ = fs::remove_dir_all(&missing_release);
   5864 
   5865         let _ = fs::remove_file(&release_policy_path);
   5866         let release_load_err = validate_release_publish_policy(&root, &contract_root, "1.0.0")
   5867             .expect_err("release contract read error");
   5868         assert!(release_load_err.contains(ROOT_RELEASE_POLICY_RELATIVE));
   5869 
   5870         write_file(
   5871             &release_policy_path,
   5872             r#"[release]
   5873 version = "1.0.0"
   5874 
   5875 [publish]
   5876 crates = ["radroots_a", "radroots_a"]
   5877 
   5878 [internal]
   5879 crates = ["radroots_b"]
   5880 
   5881 [publish_order]
   5882 crates = ["radroots_a"]
   5883 "#,
   5884         );
   5885         let duplicate_publish = validate_release_publish_policy(&root, &contract_root, "1.0.0")
   5886             .expect_err("duplicate publish crates");
   5887         assert!(duplicate_publish.contains("publish.crates has duplicate crate"));
   5888 
   5889         write_file(
   5890             &release_policy_path,
   5891             r#"[release]
   5892 version = "1.0.0"
   5893 
   5894 [publish]
   5895 crates = ["radroots_a"]
   5896 
   5897 [internal]
   5898 crates = ["radroots_b", "radroots_b"]
   5899 
   5900 [publish_order]
   5901 crates = ["radroots_a"]
   5902 "#,
   5903         );
   5904         let duplicate_internal = validate_release_publish_policy(&root, &contract_root, "1.0.0")
   5905             .expect_err("duplicate internal crates");
   5906         assert!(duplicate_internal.contains("internal.crates has duplicate crate"));
   5907 
   5908         write_file(
   5909             &release_policy_path,
   5910             r#"[release]
   5911 version = "1.0.0"
   5912 
   5913 [publish]
   5914 crates = ["radroots_a"]
   5915 
   5916 [internal]
   5917 crates = ["radroots_b"]
   5918 
   5919 [publish_order]
   5920 crates = ["radroots_a", "radroots_a"]
   5921 "#,
   5922         );
   5923         let duplicate_order = validate_release_publish_policy(&root, &contract_root, "1.0.0")
   5924             .expect_err("duplicate publish order");
   5925         assert!(duplicate_order.contains("publish_order.crates has duplicate crate"));
   5926 
   5927         write_file(
   5928             &release_policy_path,
   5929             r#"[release]
   5930 version = "1.0.0"
   5931 
   5932 [publish]
   5933 crates = ["radroots_a"]
   5934 
   5935 [internal]
   5936 crates = ["radroots_b"]
   5937 
   5938 [publish_order]
   5939 crates = ["radroots_a"]
   5940 "#,
   5941         );
   5942         write_file(
   5943             &root.join("crates").join("a").join("Cargo.toml"),
   5944             "[package",
   5945         );
   5946         let dependency_err = validate_release_publish_policy(&root, &contract_root, "1.0.0")
   5947             .expect_err("workspace dependency parse error");
   5948         assert!(dependency_err.contains("parse"));
   5949 
   5950         let _ = fs::remove_dir_all(&root);
   5951     }
   5952 
   5953     #[test]
   5954     fn load_release_contract_with_override_reports_override_and_missing_policy_errors() {
   5955         let root = create_synthetic_workspace("release_contract_loader_errors");
   5956         let contract_root = root.join("contracts");
   5957 
   5958         let missing_override = root.join("missing-release-policy.toml");
   5959         let override_err = load_release_contract_with_override(
   5960             &root,
   5961             &contract_root,
   5962             Some(missing_override.clone()),
   5963         )
   5964         .expect_err("missing override should fail");
   5965         assert!(override_err.contains(RELEASE_POLICY_ENV));
   5966         assert!(override_err.contains("missing release policy file"));
   5967 
   5968         let _ = fs::remove_file(root_release_policy_path(&root));
   5969         let missing_policy_err = load_release_contract_with_override(&root, &contract_root, None)
   5970             .expect_err("missing release policy should fail");
   5971         assert!(missing_policy_err.contains("release publish policy not found"));
   5972         assert!(missing_policy_err.contains(ROOT_RELEASE_POLICY_RELATIVE));
   5973 
   5974         let _ = fs::remove_dir_all(&root);
   5975     }
   5976 
   5977     #[test]
   5978     fn root_release_policy_preflight_covers_classification_variants() {
   5979         let root = create_synthetic_workspace("root_release_policy_classifications");
   5980         configure_root_release_policy_workspace(&root);
   5981         write_root_release_policy(
   5982             &root,
   5983             r#"[release]
   5984 version = "1.0.0"
   5985 
   5986 [classification]
   5987 public = ["radroots_a"]
   5988 internal = ["radroots_b"]
   5989 deferred = ["radroots_c"]
   5990 retired = ["radroots_d"]
   5991 yank_only = ["radroots_e"]
   5992 
   5993 [publish_order]
   5994 crates = ["radroots_a"]
   5995 "#,
   5996         );
   5997 
   5998         let bundle = load_contract_bundle(&root).expect("load root release policy bundle");
   5999         validate_contract_bundle(&bundle).expect("validate root release policy bundle");
   6000         validate_release_preflight(&root).expect("validate root release policy preflight");
   6001 
   6002         let _ = fs::remove_dir_all(&root);
   6003     }
   6004 
   6005     #[test]
   6006     fn root_release_policy_reports_deferred_retired_and_yank_only_errors() {
   6007         for (label, policy_body, expected) in [
   6008             (
   6009                 "deferred",
   6010                 r#"[release]
   6011 version = "1.0.0"
   6012 
   6013 [classification]
   6014 public = ["radroots_a"]
   6015 internal = ["radroots_b"]
   6016 deferred = ["radroots_c", "radroots_c"]
   6017 retired = ["radroots_d"]
   6018 yank_only = ["radroots_e"]
   6019 
   6020 [publish_order]
   6021 crates = ["radroots_a"]
   6022 "#,
   6023                 "classification.deferred has duplicate crate radroots_c",
   6024             ),
   6025             (
   6026                 "retired",
   6027                 r#"[release]
   6028 version = "1.0.0"
   6029 
   6030 [classification]
   6031 public = ["radroots_a"]
   6032 internal = ["radroots_b"]
   6033 deferred = ["radroots_c"]
   6034 retired = [""]
   6035 yank_only = ["radroots_e"]
   6036 
   6037 [publish_order]
   6038 crates = ["radroots_a"]
   6039 "#,
   6040                 "classification.retired contains an empty crate name",
   6041             ),
   6042             (
   6043                 "yank_only",
   6044                 r#"[release]
   6045 version = "1.0.0"
   6046 
   6047 [classification]
   6048 public = ["radroots_a"]
   6049 internal = ["radroots_b"]
   6050 deferred = ["radroots_c"]
   6051 retired = ["radroots_d"]
   6052 yank_only = ["radroots_e", "radroots_e"]
   6053 
   6054 [publish_order]
   6055 crates = ["radroots_a"]
   6056 "#,
   6057                 "classification.yank_only has duplicate crate radroots_e",
   6058             ),
   6059         ] {
   6060             let root = create_synthetic_workspace(&format!("root_release_policy_{label}_error"));
   6061             configure_root_release_policy_workspace(&root);
   6062             write_root_release_policy(&root, policy_body);
   6063 
   6064             let err = validate_release_publish_policy(&root, &root.join("contracts"), "1.0.0")
   6065                 .expect_err("invalid non-public classification should fail");
   6066             assert!(err.contains(expected), "{label} err: {err}");
   6067 
   6068             let _ = fs::remove_dir_all(&root);
   6069         }
   6070     }
   6071 
   6072     #[test]
   6073     fn validate_release_preflight_reports_each_stage_error() {
   6074         let missing_contract_root = temp_root("preflight_missing_contract");
   6075         let missing_contract_err =
   6076             validate_release_preflight(&missing_contract_root).expect_err("missing contract");
   6077         assert!(missing_contract_err.contains("manifest.toml"));
   6078         let _ = fs::remove_dir_all(&missing_contract_root);
   6079 
   6080         let invalid_bundle = create_synthetic_workspace("preflight_invalid_bundle");
   6081         write_file(
   6082             &invalid_bundle.join("contracts").join("manifest.toml"),
   6083             r#"[contract]
   6084 name = "radroots_contract"
   6085 version = "1.0.0"
   6086 source = "synthetic"
   6087 
   6088 [surface]
   6089 model_crates = ["radroots_a"]
   6090 algorithm_crates = ["radroots_b"]
   6091 
   6092 [policy]
   6093 exclude_internal_workspace_crates = false
   6094 require_reproducible_exports = true
   6095 require_conformance_vectors = true
   6096 "#,
   6097         );
   6098         let invalid_bundle_err =
   6099             validate_release_preflight(&invalid_bundle).expect_err("bundle validation");
   6100         assert!(invalid_bundle_err.contains("contract policy flags must all be true"));
   6101         let _ = fs::remove_dir_all(&invalid_bundle);
   6102 
   6103         let missing_release = create_synthetic_workspace("preflight_missing_release");
   6104         let _ = fs::remove_file(root_release_policy_path(&missing_release));
   6105         let missing_release_err =
   6106             validate_release_preflight(&missing_release).expect_err("missing release");
   6107         assert!(missing_release_err.contains(ROOT_RELEASE_POLICY_RELATIVE));
   6108         let _ = fs::remove_dir_all(&missing_release);
   6109 
   6110         let missing_required = create_synthetic_workspace("preflight_missing_required");
   6111         let _ = fs::remove_file(missing_required.join("contracts").join("coverage.toml"));
   6112         let missing_required_err =
   6113             validate_release_preflight(&missing_required).expect_err("missing required list");
   6114         assert!(missing_required_err.contains("coverage.toml"));
   6115         let _ = fs::remove_dir_all(&missing_required);
   6116 
   6117         let duplicate_publish = create_synthetic_workspace("preflight_duplicate_publish");
   6118         write_file(
   6119             &root_release_policy_path(&duplicate_publish),
   6120             r#"[release]
   6121 version = "1.0.0"
   6122 
   6123 [publish]
   6124 crates = ["radroots_a", "radroots_a"]
   6125 
   6126 [internal]
   6127 crates = ["radroots_b"]
   6128 
   6129 [publish_order]
   6130 crates = ["radroots_a"]
   6131 "#,
   6132         );
   6133         let duplicate_publish_err =
   6134             validate_release_preflight(&duplicate_publish).expect_err("duplicate publish crates");
   6135         assert!(duplicate_publish_err.contains("publish.crates has duplicate crate"));
   6136         let _ = fs::remove_dir_all(&duplicate_publish);
   6137 
   6138         let duplicate_required = create_synthetic_workspace("preflight_duplicate_required");
   6139         write_file(
   6140             &duplicate_required.join("contracts").join("coverage.toml"),
   6141             "[gate]\nfail_under_exec_lines = 100.0\nfail_under_functions = 100.0\nfail_under_regions = 100.0\nfail_under_branches = 100.0\nrequire_branches = true\n\n[required]\ncrates = [\"radroots_a\", \"radroots_a\"]\n",
   6142         );
   6143         let duplicate_required_err =
   6144             validate_release_preflight(&duplicate_required).expect_err("duplicate required crates");
   6145         assert!(duplicate_required_err.contains("duplicate crate"));
   6146         let _ = fs::remove_dir_all(&duplicate_required);
   6147 
   6148         let publish_metadata = create_synthetic_workspace("preflight_publish_metadata");
   6149         write_file(
   6150             &publish_metadata.join("crates").join("a").join("Cargo.toml"),
   6151             r#"[package]
   6152 name = "radroots_a"
   6153 publish = ["crates-io"]
   6154 version = "0.1.0"
   6155 edition = "2024"
   6156 "#,
   6157         );
   6158         let publish_metadata_err =
   6159             validate_release_preflight(&publish_metadata).expect_err("publish metadata validation");
   6160         assert!(publish_metadata_err.contains("must define a non-empty package.description"));
   6161         let _ = fs::remove_dir_all(&publish_metadata);
   6162 
   6163         let missing_coverage_row = create_synthetic_workspace("preflight_missing_coverage_row");
   6164         write_file(
   6165             &missing_coverage_row
   6166                 .join("target")
   6167                 .join("coverage")
   6168                 .join("coverage-refresh.tsv"),
   6169             "crate\tstatus\texec\tfunc\tbranch\tregion\treport\n",
   6170         );
   6171         let missing_coverage_row_err = validate_release_preflight(&missing_coverage_row)
   6172             .expect_err("required coverage refresh row missing");
   6173         assert!(missing_coverage_row_err.contains("missing from coverage-refresh.tsv"));
   6174         let _ = fs::remove_dir_all(&missing_coverage_row);
   6175     }
   6176 
   6177     #[test]
   6178     fn load_contract_bundle_and_validation_report_version_core_and_coverage_errors() {
   6179         let root = create_synthetic_workspace("bundle_version_core_and_coverage_errors");
   6180         write_file(&root.join("contracts").join("version.toml"), "[contract");
   6181         let version_parse_err = load_contract_bundle(&root).expect_err("invalid version file");
   6182         assert!(version_parse_err.contains("version.toml"));
   6183 
   6184         write_file(
   6185             &root.join("contracts").join("version.toml"),
   6186             r#"[contract]
   6187 version = "1.0.0"
   6188 stability = "alpha"
   6189 
   6190 [semver]
   6191 major_on = ["breaking"]
   6192 minor_on = ["feature"]
   6193 patch_on = ["fix"]
   6194 
   6195 [compatibility]
   6196 requires_conformance_pass = true
   6197 requires_contract_manifest_diff = true
   6198 requires_release_notes = true
   6199 "#,
   6200         );
   6201         let bundle = load_contract_bundle(&root).expect("load bundle");
   6202         write_file(
   6203             &root.join("crates").join("core").join("src").join("unit.rs"),
   6204             r#"pub enum RadrootsCoreUnitDimension {
   6205 Mass,
   6206 Count,
   6207 Volume,
   6208 }
   6209 "#,
   6210         );
   6211         let core_err = validate_contract_bundle(&bundle).expect_err("core unit mismatch");
   6212         assert!(core_err.contains("variant order must be"));
   6213 
   6214         write_file(
   6215             &root.join("crates").join("core").join("src").join("unit.rs"),
   6216             r#"pub enum RadrootsCoreUnitDimension {
   6217 Count,
   6218 Mass,
   6219 Volume,
   6220 }
   6221 "#,
   6222         );
   6223         write_file(
   6224             &root.join("contracts").join("coverage.toml"),
   6225             r#"[gate]
   6226 fail_under_exec_lines = 100.0
   6227 fail_under_functions = 100.0
   6228 fail_under_regions = 100.0
   6229 fail_under_branches = 100.0
   6230 require_branches = false
   6231 
   6232 [required]
   6233 crates = ["radroots_a", "radroots_b"]
   6234 "#,
   6235         );
   6236         let policy_err = validate_contract_bundle(&bundle).expect_err("coverage policy validation");
   6237         assert!(policy_err.contains("100/100/100/100"));
   6238 
   6239         let _ = fs::remove_dir_all(&root);
   6240     }
   6241 
   6242     #[test]
   6243     fn coverage_summary_and_core_enum_additional_error_paths() {
   6244         let coverage_root = temp_root("coverage_summary_additional_errors");
   6245         write_file(
   6246             &coverage_root
   6247                 .join("target")
   6248                 .join("coverage")
   6249                 .join("coverage-refresh.tsv"),
   6250             "crate\tstatus\texec\tfunc\tbranch\tregion\treport\nradroots_a\tpass\t100\tbad\t100\t100\tfile\n",
   6251         );
   6252         let func_err = load_coverage_refresh_rows(&coverage_root).expect_err("func parse error");
   6253         assert!(func_err.contains("parse func"));
   6254         write_file(
   6255             &coverage_root
   6256                 .join("target")
   6257                 .join("coverage")
   6258                 .join("coverage-refresh.tsv"),
   6259             "crate\tstatus\texec\tfunc\tbranch\tregion\treport\nradroots_a\tpass\t100\t100\tbad\t100\tfile\n",
   6260         );
   6261         let branch_err =
   6262             load_coverage_refresh_rows(&coverage_root).expect_err("branch parse error");
   6263         assert!(branch_err.contains("parse branch"));
   6264         let _ = fs::remove_dir_all(&coverage_root);
   6265 
   6266         let missing_refresh_root = temp_root("coverage_summary_missing_refresh");
   6267         let required = ["radroots_a".to_string()]
   6268             .into_iter()
   6269             .collect::<BTreeSet<_>>();
   6270         let missing_refresh_err = validate_required_coverage_summary(
   6271             &missing_refresh_root,
   6272             &required,
   6273             strict_thresholds(),
   6274         )
   6275         .expect_err("missing refresh should fail");
   6276         assert!(missing_refresh_err.contains("coverage-refresh.tsv"));
   6277         let _ = fs::remove_dir_all(&missing_refresh_root);
   6278 
   6279         let enum_root = temp_root("core_unit_missing_enum");
   6280         write_file(
   6281             &enum_root
   6282                 .join("crates")
   6283                 .join("core")
   6284                 .join("src")
   6285                 .join("unit.rs"),
   6286             "pub struct NotTheEnum;",
   6287         );
   6288         let enum_err =
   6289             validate_core_unit_dimension_variant_order(&enum_root).expect_err("missing enum");
   6290         assert!(enum_err.contains("missing enum"));
   6291         let _ = fs::remove_dir_all(&enum_root);
   6292     }
   6293 
   6294     #[test]
   6295     fn publish_metadata_and_coverage_refresh_report_missing_paths() {
   6296         let root = temp_root("publish_missing_manifest");
   6297         write_file(
   6298             &root.join("Cargo.toml"),
   6299             r#"[workspace]
   6300 members = ["crates/a"]
   6301 "#,
   6302         );
   6303         write_file(
   6304             &root.join("crates").join("a").join("Cargo.toml"),
   6305             r#"[package]
   6306 name = "radroots_a"
   6307 version = "0.1.0"
   6308 edition = "2024"
   6309 description = "crate a"
   6310 repository = { workspace = true }
   6311 homepage = { workspace = true }
   6312 readme = { workspace = true }
   6313 "#,
   6314         );
   6315         let missing_manifest = ["radroots_b".to_string()]
   6316             .into_iter()
   6317             .collect::<BTreeSet<_>>();
   6318         let missing_err = validate_publish_package_metadata(&root, &missing_manifest)
   6319             .expect_err("missing workspace manifest");
   6320         assert!(missing_err.contains("has no workspace manifest"));
   6321 
   6322         let missing_field = ["radroots_a".to_string()]
   6323             .into_iter()
   6324             .collect::<BTreeSet<_>>();
   6325         let field_err = validate_publish_package_metadata(&root, &missing_field)
   6326             .expect_err("missing configured field");
   6327         assert!(field_err.contains("must configure package.documentation"));
   6328 
   6329         let refresh_missing =
   6330             load_coverage_refresh_rows(&root).expect_err("missing coverage-refresh.tsv");
   6331         assert!(refresh_missing.contains("coverage-refresh.tsv"));
   6332         let _ = fs::remove_dir_all(&root);
   6333     }
   6334 
   6335     #[test]
   6336     fn coverage_refresh_parser_skips_blank_lines() {
   6337         let root = temp_root("coverage_refresh_blank_lines");
   6338         write_file(
   6339             &root
   6340                 .join("target")
   6341                 .join("coverage")
   6342                 .join("coverage-refresh.tsv"),
   6343             "crate\tstatus\texec\tfunc\tbranch\tregion\treport\n\nradroots_a\tpass\t100\t100\t100\t100\tfile\n",
   6344         );
   6345         let rows = load_coverage_refresh_rows(&root).expect("rows");
   6346         assert_eq!(rows.len(), 1);
   6347         assert!(rows.contains_key("radroots_a"));
   6348         let _ = fs::remove_dir_all(&root);
   6349     }
   6350 
   6351     #[test]
   6352     fn core_unit_dimension_validation_reports_missing_and_mismatch() {
   6353         let missing = temp_root("core_unit_missing");
   6354         let missing_err = validate_core_unit_dimension_variant_order(&missing)
   6355             .expect_err("missing unit file should fail");
   6356         assert!(missing_err.contains("unit.rs"));
   6357         let _ = fs::remove_dir_all(&missing);
   6358 
   6359         let mismatch = temp_root("core_unit_mismatch");
   6360         write_file(
   6361             &mismatch
   6362                 .join("crates")
   6363                 .join("core")
   6364                 .join("src")
   6365                 .join("unit.rs"),
   6366             r#"pub enum RadrootsCoreUnitDimension {
   6367 Mass,
   6368 Count,
   6369 Volume,
   6370 }
   6371 "#,
   6372         );
   6373         let mismatch_err = validate_core_unit_dimension_variant_order(&mismatch)
   6374             .expect_err("mismatched enum order should fail");
   6375         assert!(mismatch_err.contains("variant order must be"));
   6376         let _ = fs::remove_dir_all(&mismatch);
   6377     }
   6378 
   6379     #[test]
   6380     fn coverage_and_release_additional_error_branches_are_reported() {
   6381         let root = create_synthetic_workspace("coverage_release_extra_errors");
   6382         let contract_root = root.join("contracts");
   6383         let coverage_root = coverage_root(&contract_root);
   6384         let release_policy_path = root_release_policy_path(&root);
   6385 
   6386         write_file(
   6387             &coverage_root.join("coverage.toml"),
   6388             r#"[gate]
   6389 fail_under_exec_lines = 100.0
   6390 fail_under_functions = 100.0
   6391 fail_under_regions = 100.0
   6392 fail_under_branches = 100.0
   6393 require_branches = true
   6394 
   6395 [required]
   6396 crates = ["radroots_a", "radroots_b", "radroots_extra"]
   6397 "#,
   6398         );
   6399         let coverage_extra = validate_coverage_policy_parity(&root, &contract_root)
   6400             .expect_err("coverage unknown crate");
   6401         assert!(coverage_extra.contains("includes excluded or unknown crates"));
   6402 
   6403         write_file(
   6404             &coverage_root.join("coverage.toml"),
   6405             r#"[gate]
   6406 fail_under_exec_lines = 100.0
   6407 fail_under_functions = 100.0
   6408 fail_under_regions = 100.0
   6409 fail_under_branches = 100.0
   6410 require_branches = true
   6411 
   6412 [required]
   6413 crates = ["radroots_b"]
   6414 "#,
   6415         );
   6416         let required_list_mismatch = validate_coverage_policy_parity(&root, &contract_root)
   6417             .expect_err("required list must match workspace crates");
   6418         assert!(required_list_mismatch.contains("missing workspace crates"));
   6419 
   6420         write_file(
   6421             &release_policy_path,
   6422             r#"[release]
   6423 version = "1.0.0"
   6424 
   6425 [publish]
   6426 crates = ["radroots_a", "radroots_b", "radroots_extra"]
   6427 
   6428 [internal]
   6429 crates = []
   6430 
   6431 [publish_order]
   6432 crates = ["radroots_a", "radroots_b"]
   6433 "#,
   6434         );
   6435         let release_extra = validate_release_publish_policy(&root, &contract_root, "1.0.0")
   6436             .expect_err("release extra crate");
   6437         assert!(release_extra.contains("include unknown crates"));
   6438 
   6439         write_file(
   6440             &release_policy_path,
   6441             r#"[release]
   6442 version = "1.0.0"
   6443 
   6444 [publish]
   6445 crates = ["radroots_a"]
   6446 
   6447 [internal]
   6448 crates = ["radroots_b"]
   6449 
   6450 [publish_order]
   6451 crates = ["radroots_a", "radroots_b"]
   6452 "#,
   6453         );
   6454         let publish_order_extra = validate_release_publish_policy(&root, &contract_root, "1.0.0")
   6455             .expect_err("publish order non-publish crate");
   6456         assert!(publish_order_extra.contains("non-publish crates"));
   6457 
   6458         let _ = fs::remove_dir_all(&root);
   6459     }
   6460 
   6461     #[test]
   6462     fn validate_contract_bundle_reports_release_policy_errors() {
   6463         let release_error_root = create_synthetic_workspace("bundle_release_policy_error");
   6464         write_file(
   6465             &root_release_policy_path(&release_error_root),
   6466             r#"[release]
   6467 version = "1.0.0"
   6468 
   6469 [publish]
   6470 crates = ["radroots_a"]
   6471 
   6472 [internal]
   6473 crates = ["radroots_b"]
   6474 
   6475 [publish_order]
   6476 crates = []
   6477 "#,
   6478         );
   6479         let bundle = load_contract_bundle(&release_error_root).expect("load release error bundle");
   6480         let release_err = validate_contract_bundle(&bundle).expect_err("release policy failure");
   6481         assert!(release_err.contains("publish_order.crates is missing publish crates"));
   6482         let _ = fs::remove_dir_all(&release_error_root);
   6483     }
   6484 }