rhi

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

services_hardening_failure_qualification.rs (9674B)


      1 #![forbid(unsafe_code)]
      2 
      3 use std::collections::BTreeSet;
      4 
      5 use serde_json::Value;
      6 
      7 const CONTRACT: &str =
      8     include_str!("../contracts/services_hardening/failure_qualification.v1.json");
      9 const MANIFEST: &str = include_str!("../Cargo.toml");
     10 const README: &str = include_str!("../README");
     11 const AGENTS: &str = include_str!("../AGENTS.md");
     12 const COMPONENT_TESTS: &[&str] = &[
     13     include_str!("services_hardening_config_contract.rs"),
     14     include_str!("services_hardening_config_lifecycle.rs"),
     15     include_str!("services_hardening_state_resilience.rs"),
     16     include_str!("services_hardening_state_host.rs"),
     17     include_str!("services_hardening_reconciliation_jobs.rs"),
     18     include_str!("services_hardening_presence_publication.rs"),
     19     include_str!("services_hardening_source_ingest.rs"),
     20     include_str!("services_hardening_runtime_foundation.rs"),
     21     include_str!("services_hardening_doctor.rs"),
     22     include_str!("package_boundary.rs"),
     23 ];
     24 
     25 #[test]
     26 fn contract_freezes_the_exact_failure_qualification_corpus() {
     27     let contract: Value = serde_json::from_str(CONTRACT).expect("failure qualification contract");
     28     assert_eq!(
     29         contract
     30             .as_object()
     31             .expect("qualification object")
     32             .keys()
     33             .map(String::as_str)
     34             .collect::<BTreeSet<_>>(),
     35         BTreeSet::from([
     36             "component_corpus",
     37             "contract_version",
     38             "deferred",
     39             "invariants",
     40             "resource_bounds",
     41             "schema",
     42             "schema_version",
     43             "service",
     44             "source_lock",
     45             "source_locked_shared_sqlite_corpus",
     46             "step",
     47         ])
     48     );
     49     assert_eq!(contract["schema"], "radroots.rhi.failure-qualification.v1");
     50     assert_eq!(contract["schema_version"], 1);
     51     assert_eq!(contract["contract_version"], 1);
     52     assert_eq!(contract["step"], 214);
     53     assert_eq!(contract["service"], "rhi");
     54     assert_eq!(
     55         contract["source_lock"],
     56         serde_json::json!({
     57             "schema": "radroots.service.source-lock.v2",
     58             "lib_revision": "053d0c750bf9cd683c6ea37cefe7e79617ba629f"
     59         })
     60     );
     61     assert_eq!(
     62         contract["resource_bounds"],
     63         serde_json::json!({
     64             "configuration_document_utf8_bytes": 1_048_576,
     65             "source_result_events": 4_096,
     66             "source_result_bytes": 8_388_608,
     67             "reconciliation_queue": 65_536,
     68             "publication_queue": 65_536,
     69             "doctor_checks": 15
     70         })
     71     );
     72     assert_eq!(
     73         contract["component_corpus"],
     74         serde_json::json!({
     75             "resource_and_backlog": [
     76                 "exact_resource_boundaries_and_safe_defaults_are_frozen",
     77                 "source_results_enforce_deadline_outcome_and_exact_resource_bounds",
     78                 "commit_inventory_bounds_infinite_iterators_before_any_mutation",
     79                 "publication_queue_capacity_is_checked_before_finalization_mutation",
     80                 "configured_result_bound_retains_admitted_evidence_without_checkpoint",
     81                 "public_inputs_have_exact_bounds_and_diagnostics_are_redacted"
     82             ],
     83             "disk_and_durable_state": [
     84                 "backup_integrity_and_offline_restore_obey_one_exact_rhi_authority",
     85                 "maintenance_boundary_is_sealed_source_free_and_sqlx_owned",
     86                 "initialize_is_create_new_and_both_existing_open_modes_close_explicitly"
     87             ],
     88             "corruption_and_malformed_history": [
     89                 "semantically_conflicting_but_structurally_valid_history_fails_closed",
     90                 "exact_open_rejects_unexpected_migration_history_without_repair",
     91                 "publication_schema_rejects_null_state_holes_and_accepted_target_mutation",
     92                 "schema_v8_scans_historical_nullable_job_state_and_installs_permanent_guards"
     93             ],
     94             "cancellation_outage_and_recovery": [
     95                 "cancelled_blocked_commit_has_no_effect_and_exact_retry_succeeds",
     96                 "cancelled_submitted_attempt_recovers_unknown_and_retries_exact_bytes_after_reopen",
     97                 "exact_bytes_are_durable_before_io_and_unknown_recovery_retries_unchanged",
     98                 "incomplete_and_unsupported_results_never_advance_checkpoint_or_dirty_generation",
     99                 "missing_state_fails_before_identity_or_transport_access",
    100                 "identity_failure_after_state_open_releases_authority_without_transport_access",
    101                 "failures_schedule_exact_jitter_and_the_final_attempt_exhausts",
    102                 "signed_attestation_fails_closed_when_injected_entropy_is_unavailable",
    103                 "required_timeout_drops_work_and_remaining_checks_continue_in_order"
    104             ],
    105             "safe_error_posture": [
    106                 "configuration_lifecycle_surface_is_sealed_and_redacted",
    107                 "attempt_and_public_diagnostics_are_bounded_and_redacted",
    108                 "report_debug_and_public_errors_retain_no_sensitive_values",
    109                 "public_errors_are_crate_owned_redacted_and_source_free"
    110             ]
    111         })
    112     );
    113     assert_eq!(
    114         contract["invariants"],
    115         serde_json::json!({
    116             "bounded_ingestion_before_mutation": true,
    117             "atomic_commit_or_no_effect": true,
    118             "cancellation_retry_safe": true,
    119             "durable_unknown_recovered_before_retry": true,
    120             "malformed_history_repaired": false,
    121             "corruption_fails_closed": true,
    122             "sqlx_is_only_high_level_sqlite_authority": true,
    123             "production_failpoint_surface": false,
    124             "test_environment_selector": false,
    125             "public_errors_source_free": true,
    126             "diagnostics_path_secret_free": true
    127         })
    128     );
    129     assert_eq!(
    130         contract["deferred"],
    131         serde_json::json!([
    132             "actual_process_and_bounded_soak_step_215",
    133             "native_release_artifacts_step_216",
    134             "rcld_promotion_step_217",
    135             "parent_pin_alignment_step_217",
    136             "nix",
    137             "oci",
    138             "signing",
    139             "publication",
    140             "deployment"
    141         ])
    142     );
    143 }
    144 
    145 #[test]
    146 fn every_component_contract_entry_names_an_executable_test() {
    147     let contract: Value = serde_json::from_str(CONTRACT).expect("failure qualification contract");
    148     let sources = COMPONENT_TESTS.join("\n");
    149     let corpus = contract["component_corpus"]
    150         .as_object()
    151         .expect("component corpus");
    152     assert_eq!(
    153         corpus.keys().map(String::as_str).collect::<BTreeSet<_>>(),
    154         BTreeSet::from([
    155             "cancellation_outage_and_recovery",
    156             "corruption_and_malformed_history",
    157             "disk_and_durable_state",
    158             "resource_and_backlog",
    159             "safe_error_posture",
    160         ])
    161     );
    162     for (category, tests) in corpus {
    163         let tests = tests.as_array().expect("test-name array");
    164         assert!(!tests.is_empty(), "empty qualification category {category}");
    165         for test in tests {
    166             let test = test.as_str().expect("test name");
    167             assert!(
    168                 sources.contains(&format!("fn {test}(")),
    169                 "qualification entry {category}/{test} has no executable test"
    170             );
    171         }
    172     }
    173 }
    174 
    175 #[test]
    176 fn historical_source_lock_binds_the_shared_sqlite_failure_corpus() {
    177     let contract: Value = serde_json::from_str(CONTRACT).expect("failure qualification contract");
    178     let revision = contract["source_lock"]["lib_revision"]
    179         .as_str()
    180         .expect("Lib revision");
    181     assert_eq!(revision, "053d0c750bf9cd683c6ea37cefe7e79617ba629f");
    182     assert!(MANIFEST.contains(
    183         "radroots_service_sqlite = { git = \"https://github.com/radrootslabs/lib\", rev = \"055096853fca95e15d0f813d33a14aca13be3881\""
    184     ));
    185     assert_eq!(
    186         contract["source_locked_shared_sqlite_corpus"],
    187         serde_json::json!([
    188             "minimum_policy_and_strict_numeric_serde_are_bounded",
    189             "injected_values_classify_exact_boundary_and_propagate_failure",
    190             "physical_corruption_and_query_failure_remain_redacted_and_typed",
    191             "missing_extra_reordered_newer_and_corrupt_history_fail_closed",
    192             "oversized_corrupt_history_is_bounded_before_decode",
    193             "every_initialization_durability_edge_fails_once_and_rolls_back",
    194             "transaction_durability_edges_preserve_exact_commit_semantics",
    195             "backup_durability_edges_fail_once_clean_exact_stage_and_recover",
    196             "close_durability_edges_are_once_only_retryable_or_terminal",
    197             "every_marker_and_restore_durability_edge_is_wired_once",
    198             "sigkill_restore_boundaries_recover_exact_topologies_and_preserve_permissions"
    199         ])
    200     );
    201     assert!(!MANIFEST.contains("rusqlite"));
    202 }
    203 
    204 #[test]
    205 fn human_boundary_is_explicit_and_does_not_preclaim_later_steps() {
    206     for required in [
    207         "## Failure-resilience qualification",
    208         "[`failure_qualification.v1.json`](contracts/services_hardening/failure_qualification.v1.json)",
    209         "actual-process and\nbounded-soak qualification remains Step 215 ownership",
    210         "native release\nartifacts remain Step 216 ownership",
    211         "promotion and parent-pin alignment\nremain Step 217 ownership",
    212     ] {
    213         assert!(README.contains(required), "README is missing {required}");
    214     }
    215     for required in [
    216         "Step 214 freezes the failure-resilience qualification corpus",
    217         "Do not add a second SQLite authority",
    218         "Step 215\n  alone owns actual-process and bounded-soak qualification",
    219     ] {
    220         assert!(AGENTS.contains(required), "AGENTS is missing {required}");
    221     }
    222 }