services_hardening_reconciliation_finalization_contract.rs (4337B)
1 #![forbid(unsafe_code)] 2 3 use rhi::RHI_RECONCILIATION_FINALIZATION_CONTRACT_VERSION; 4 use serde_json::json; 5 6 const CONTRACT: &str = 7 include_str!("../contracts/services_hardening/reconciliation_finalization.v1.json"); 8 const ROOT: &str = include_str!("../src/lib.rs"); 9 const SOURCE: &str = include_str!("../src/reconciliation_finalization.rs"); 10 const MANIFEST: &str = include_str!("../src/reconciliation_manifest.rs"); 11 const README: &str = include_str!("../README"); 12 13 #[test] 14 fn machine_contract_freezes_the_complete_step_195_boundary() { 15 let contract: serde_json::Value = serde_json::from_str(CONTRACT).expect("contract"); 16 assert_eq!( 17 contract["schema"], 18 "radroots.rhi.reconciliation-finalization" 19 ); 20 assert_eq!(contract["schema_version"], 1); 21 assert_eq!( 22 contract["contract_version"], 23 RHI_RECONCILIATION_FINALIZATION_CONTRACT_VERSION 24 ); 25 assert_eq!( 26 contract["private_identity_chain"]["manifest_retains"], 27 json!(["step_190_attempt_id", "step_190_job_id"]) 28 ); 29 assert_eq!( 30 contract["private_identity_chain"]["canonical_manifest_wire_changed"], 31 false 32 ); 33 assert_eq!( 34 contract["preflight_order"], 35 json!([ 36 "writable_host", 37 "sealed_identity_chain", 38 "unexpired_input_lease", 39 "exact_current_lease", 40 "exact_current_dirty_generation_and_policy_digest", 41 "exact_committed_attempt_row" 42 ]) 43 ); 44 assert_eq!(contract["durable_validation"]["mutation"], false); 45 assert_eq!( 46 contract["durable_validation"]["step_199_requirement"], 47 "rerun_same_validator_inside_atomic_finalization_transaction_before_any_write" 48 ); 49 assert_eq!( 50 contract["durable_validation"]["preflight_is_commit_authority"], 51 false 52 ); 53 assert_eq!(contract["effects"]["sqlite_read"], true); 54 assert_eq!(contract["effects"]["sqlite_write"], false); 55 for effect in [ 56 "filesystem", 57 "source_or_relay", 58 "network", 59 "task_spawn", 60 "ambient_clock", 61 "ambient_entropy", 62 "report_or_attestation", 63 "publication", 64 "job_finalization", 65 ] { 66 assert_eq!(contract["effects"][effect], false, "effect {effect}"); 67 } 68 } 69 70 #[test] 71 fn finalization_boundary_is_sealed_identity_bound_and_nonmutating() { 72 assert!(ROOT.contains("mod reconciliation_finalization;")); 73 assert!(!ROOT.contains("pub mod reconciliation_finalization;")); 74 for required in [ 75 "RhiReconciliationFinalizationFence", 76 "RhiReconciliationFinalizationError", 77 "RhiReconciliationFinalizationErrorKind", 78 "RHI_RECONCILIATION_FINALIZATION_CONTRACT_VERSION", 79 ] { 80 assert!(ROOT.contains(required), "root API is missing {required}"); 81 } 82 for required in [ 83 "pub async fn prepare_finalization(", 84 "validate_finalization_fence(", 85 "validate_exact_lease(transaction, lease)", 86 "read_dirty(transaction, identity.trade_id)", 87 "MATCH_COMMITTED_ATTEMPT_SQL", 88 "manifest.attempt_id() != attempt_id(job.id(), job.attempt_count())", 89 "now >= lease.lease_expires()", 90 "evaluation.projection().digest().is_none()", 91 ] { 92 assert!( 93 SOURCE.contains(required), 94 "finalization boundary is missing {required}" 95 ); 96 } 97 for required in [ 98 "attempt_id: RhiReconciliationAttemptId", 99 "job_id: RhiReconciliationJobId", 100 "attempt_id: plan.id()", 101 "job_id: plan.job_id()", 102 ] { 103 assert!( 104 MANIFEST.contains(required), 105 "manifest is missing {required}" 106 ); 107 } 108 for forbidden in [ 109 "INSERT ", 110 "UPDATE ", 111 "DELETE ", 112 "std::fs", 113 "std::net", 114 "tokio::spawn", 115 "SystemTime", 116 "thread_rng", 117 "OsRng", 118 "pub fn new(", 119 "pub const fn new(", 120 ] { 121 assert!( 122 !SOURCE.contains(forbidden), 123 "finalization boundary gained forbidden authority {forbidden}" 124 ); 125 } 126 assert!(README.contains("## Generation-fenced finalization preflight")); 127 assert!(README.contains( 128 "[`reconciliation_finalization.v1.json`](contracts/services_hardening/reconciliation_finalization.v1.json)" 129 )); 130 }