rhi

Coordinated trade for connected markets
git clone https://radroots.dev/git/rhi.git
Log | Files | Refs | README | LICENSE

services_hardening_reconciliation_reducer_contract.rs (4638B)


      1 #![forbid(unsafe_code)]
      2 
      3 use rhi::RHI_RECONCILIATION_REDUCER_CONTRACT_VERSION;
      4 use serde_json::json;
      5 
      6 const CONTRACT: &str =
      7     include_str!("../contracts/services_hardening/reconciliation_reducer.v1.json");
      8 const ROOT: &str = include_str!("../src/lib.rs");
      9 const SOURCE: &str = include_str!("../src/reconciliation_reducer.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_193_boundary() {
     15     let contract: serde_json::Value = serde_json::from_str(CONTRACT).expect("contract");
     16     assert_eq!(contract["schema"], "radroots.rhi.reconciliation-reducer");
     17     assert_eq!(contract["schema_version"], 1);
     18     assert_eq!(
     19         contract["contract_version"],
     20         RHI_RECONCILIATION_REDUCER_CONTRACT_VERSION
     21     );
     22     assert_eq!(
     23         contract["input"]["authority"],
     24         "sealed_confirmed_reconciliation_manifest_only"
     25     );
     26     assert_eq!(contract["input"]["maximum_mutations"], 65_536);
     27     assert_eq!(
     28         contract["input"]["maximum_canonical_content_bytes"],
     29         134_217_728
     30     );
     31     assert_eq!(
     32         contract["input"]["evidence_state"],
     33         json!({
     34             "missing": "missing",
     35             "partial": "query_partial",
     36             "scope_satisfied": "complete",
     37             "unsupported": "unsupported_version"
     38         })
     39     );
     40     assert_eq!(
     41         contract["shared_reducer"]["contract_id"],
     42         "radroots.trade.reducer.v1"
     43     );
     44     assert_eq!(
     45         contract["projection_digest"]["ordered_fields"],
     46         json!([
     47             "rhi_reducer_contract_version_u32_be",
     48             "shared_reducer_contract_id_length_u64_be",
     49             "shared_reducer_contract_id_utf8",
     50             "shared_reducer_contract_version_u16_be",
     51             "evidence_manifest_digest",
     52             "evidence_policy_digest",
     53             "shared_projection_digest"
     54         ])
     55     );
     56     assert_eq!(contract["effects"]["sqlite"], false);
     57     assert_eq!(contract["effects"]["source_or_relay"], false);
     58     assert_eq!(contract["effects"]["ambient_clock"], false);
     59     assert_eq!(contract["effects"]["ambient_entropy"], false);
     60     assert_eq!(
     61         contract["result"]["shared_projection_digest_available"],
     62         "optional_fail_closed_for_outcome"
     63     );
     64     assert_eq!(
     65         contract["result"]["rhi_projection_digest_available"],
     66         "optional_fail_closed_for_outcome"
     67     );
     68     assert_eq!(
     69         contract["result"]["outcome_owner"],
     70         "reconciliation_outcome.v1.json"
     71     );
     72 }
     73 
     74 #[test]
     75 fn reducer_boundary_is_sealed_redacted_and_effect_free() {
     76     assert!(ROOT.contains("mod reconciliation_reducer;"));
     77     assert!(!ROOT.contains("pub mod reconciliation_reducer;"));
     78     for required in [
     79         "RhiReconciliationProjection",
     80         "RhiReconciliationReducerError",
     81         "RhiReconciliationReducerErrorKind",
     82         "RHI_RECONCILIATION_REDUCER_CONTRACT_VERSION",
     83         "reduce_rhi_reconciliation_manifest",
     84     ] {
     85         assert!(ROOT.contains(required), "root API is missing {required}");
     86     }
     87     for required in [
     88         "trade_mutation_from_canonical_content",
     89         "reduce_trade_records(input)",
     90         "PROJECTION_DIGEST_DOMAIN",
     91         "manifest.digest()",
     92         "inner.evidence_policy_digest()",
     93         "decode_lower_hex_32(shared.projection_digest())",
     94         "RHI_REDUCER_MAXIMUM_MUTATION_MATERIAL_BYTES",
     95     ] {
     96         assert!(SOURCE.contains(required), "reducer is missing {required}");
     97     }
     98     assert!(!SOURCE.contains("fn shared_projection(&self)"));
     99     for required in [
    100         "reducer_mutations: Box<[RhiReducerMutationMaterial]>",
    101         "BTreeMap::<[u8; 32], RhiReducerMutationMaterial>::new()",
    102         "RHI_REDUCER_MAXIMUM_MUTATION_MATERIAL_BYTES: usize = 134_217_728",
    103         "canonical_content: Arc<[u8]>",
    104         "canonical_content: fact.record.canonical_content.clone()",
    105     ] {
    106         assert!(
    107             MANIFEST.contains(required),
    108             "manifest reducer material is missing {required}"
    109         );
    110     }
    111     for forbidden in [
    112         "sqlx::",
    113         "std::fs",
    114         "std::net",
    115         "tokio::",
    116         "SystemTime",
    117         "thread_rng",
    118         "OsRng",
    119         "pub fn new(",
    120         "pub const fn new(",
    121         "pub fn persist",
    122     ] {
    123         assert!(
    124             !SOURCE.contains(forbidden),
    125             "reducer gained forbidden authority {forbidden}"
    126         );
    127     }
    128     assert!(README.contains("## Pure reconciliation reducer"));
    129     assert!(README.contains(
    130         "[`reconciliation_reducer.v1.json`](contracts/services_hardening/reconciliation_reducer.v1.json)"
    131     ));
    132 }