services_hardening_reconciliation_manifest_contract.rs (6131B)
1 #![forbid(unsafe_code)] 2 3 use rhi::RHI_RECONCILIATION_MANIFEST_CONTRACT_VERSION; 4 use serde_json::json; 5 6 const CONTRACT: &str = 7 include_str!("../contracts/services_hardening/reconciliation_manifest.v1.json"); 8 const ROOT: &str = include_str!("../src/lib.rs"); 9 const SOURCE: &str = include_str!("../src/reconciliation_manifest.rs"); 10 const COMMIT: &str = include_str!("../src/reconciliation_commit.rs"); 11 const README: &str = include_str!("../README"); 12 13 #[test] 14 fn machine_contract_freezes_the_complete_step_191_boundary() { 15 let contract: serde_json::Value = serde_json::from_str(CONTRACT).expect("contract"); 16 assert_eq!(contract["schema"], "radroots.rhi.reconciliation-manifest"); 17 assert_eq!(contract["schema_version"], 1); 18 assert_eq!( 19 contract["contract_version"], 20 RHI_RECONCILIATION_MANIFEST_CONTRACT_VERSION 21 ); 22 assert_eq!( 23 contract["construction_authority"], 24 "confirmed_step_190_commit_outcome_only" 25 ); 26 assert_eq!( 27 contract["shared_manifest"]["contract_id"], 28 "radroots.trade.evidence-manifest.v1" 29 ); 30 assert_eq!(contract["shared_manifest"]["source_count_maximum"], 16); 31 assert_eq!( 32 contract["shared_manifest"]["observation_count_maximum"], 33 65_536 34 ); 35 assert_eq!( 36 contract["identity"]["source_selector_digest"], 37 "bound_inside_each_source_result_digest" 38 ); 39 assert_eq!( 40 contract["source_result_digest"]["ordered_fields"], 41 json!([ 42 "attempt_id", 43 "canonical_source_ordinal_u32_be", 44 "request_id", 45 "framed_source_id_utf8", 46 "trade_id", 47 "required_flag", 48 "evidence_policy_digest", 49 "source_selector_digest", 50 "replay_id", 51 "framed_detailed_completion_code_utf8", 52 "started_at_unix_ms_u64_be", 53 "finished_at_unix_ms_u64_be", 54 "accepted_event_count_u32_be", 55 "accepted_event_bytes_u64_be", 56 "step_190_accepted_inventory_digest", 57 "duplicate_observation_count_u32_be", 58 "optional_first_observed_at_unix_s", 59 "optional_prior_cursor", 60 "overlap_seconds_u64_be", 61 "inclusive_since_unix_s_u64_be", 62 "optional_cursor_candidate", 63 "checkpoint_eligible_flag" 64 ]) 65 ); 66 assert_eq!(contract["effects"]["sqlite"], false); 67 assert_eq!(contract["effects"]["ambient_clock"], false); 68 assert_eq!(contract["effects"]["ambient_entropy"], false); 69 assert_eq!( 70 contract["private_reducer_material"]["construction"], 71 "deduplicated_from_confirmed_step_190_canonical_mutation_content" 72 ); 73 assert_eq!( 74 contract["private_reducer_material"]["canonical_manifest_wire_changed"], 75 false 76 ); 77 assert_eq!( 78 contract["private_reducer_material"]["maximum_canonical_content_bytes"], 79 134_217_728 80 ); 81 assert_eq!( 82 contract["private_reducer_material"]["outcome_owner"], 83 "reconciliation_outcome.v1.json" 84 ); 85 assert_eq!( 86 contract["private_finalization_identity"]["attempt_id"], 87 "exact_step_190_committed_attempt_id" 88 ); 89 assert_eq!( 90 contract["private_finalization_identity"]["job_id"], 91 "exact_step_190_claimed_job_id" 92 ); 93 assert_eq!( 94 contract["private_finalization_identity"]["canonical_manifest_wire_changed"], 95 false 96 ); 97 assert!( 98 !contract["deferred"] 99 .as_array() 100 .expect("deferred inventory") 101 .contains(&json!("lineage_reducer")) 102 ); 103 assert!( 104 !contract["deferred"] 105 .as_array() 106 .expect("deferred inventory") 107 .contains(&json!("coverage_and_outcome_projection")) 108 ); 109 } 110 111 #[test] 112 fn manifest_boundary_is_sealed_canonical_redacted_and_effect_free() { 113 assert!(ROOT.contains("mod reconciliation_manifest;")); 114 assert!(!ROOT.contains("pub mod reconciliation_manifest;")); 115 for required in [ 116 "RhiReconciliationManifest", 117 "RhiReconciliationManifestError", 118 "RhiReconciliationManifestErrorKind", 119 "RhiReconciliationScopePrerequisites", 120 "RHI_RECONCILIATION_MANIFEST_CONTRACT_VERSION", 121 ] { 122 assert!(ROOT.contains(required), "root API is missing {required}"); 123 } 124 for required in [ 125 "RadrootsTradeEvidenceManifestV1::new(", 126 "SOURCE_RESULT_DIGEST_DOMAIN", 127 "PROVENANCE_DIGEST_DOMAIN", 128 "SOURCE_SELECTOR", 129 "committed_inventory_digest(part)", 130 "RadrootsTradeSignedEventDigestV1::sha256(&record.canonical_event_json)", 131 "self.manifest_material", 132 "i64::try_from(observed_at.get())", 133 "pub const fn shared_manifest_contract_id(&self)", 134 "pub const fn shared_manifest_contract_version(&self)", 135 "attempt_id: plan.id()", 136 "job_id: plan.job_id()", 137 ] { 138 assert!( 139 SOURCE.contains(required), 140 "manifest boundary is missing {required}" 141 ); 142 } 143 assert!(COMMIT.contains("let manifest_material = committed_manifest_material(&plan, &parts)")); 144 assert!(COMMIT.contains("manifest_material,")); 145 assert!( 146 COMMIT 147 .find("let manifest_material = committed_manifest_material(&plan, &parts)") 148 .expect("pure manifest derivation") 149 < COMMIT 150 .find(".transaction(move |transaction|") 151 .expect("transaction boundary") 152 ); 153 for forbidden in [ 154 "sqlx::", 155 "std::fs", 156 "std::net", 157 "tokio::", 158 "SystemTime", 159 "thread_rng", 160 "OsRng", 161 "from_canonical_bytes", 162 "pub fn new(", 163 "pub const fn new(", 164 "pub fn persist", 165 ] { 166 assert!( 167 !SOURCE.contains(forbidden), 168 "manifest boundary gained forbidden authority {forbidden}" 169 ); 170 } 171 assert!(README.contains("## Immutable reconciliation manifest")); 172 assert!(README.contains( 173 "[`reconciliation_manifest.v1.json`](contracts/services_hardening/reconciliation_manifest.v1.json)" 174 )); 175 }