package_boundary.rs (76246B)
1 #![forbid(unsafe_code)] 2 3 const MANIFEST: &str = include_str!("../Cargo.toml"); 4 const README: &str = include_str!("../README"); 5 const AGENTS: &str = include_str!("../AGENTS.md"); 6 const ROOT: &str = include_str!("../src/lib.rs"); 7 const MAIN: &str = include_str!("../src/main.rs"); 8 const ADMIN: &str = include_str!("../src/admin_v1.rs"); 9 const DOCTOR: &str = include_str!("../src/doctor_v1.rs"); 10 const OPERATIONS: &str = include_str!("../src/operations_v1.rs"); 11 const STATUS: &str = include_str!("../src/status_v1.rs"); 12 const PROCESS_RESULT: &str = include_str!("../src/process_result_v1.rs"); 13 const OPERATOR_CONTRACT: &str = 14 include_str!("../contracts/services_hardening/operator_contract.v1.json"); 15 const STATUS_CONTRACT: &str = include_str!("../contracts/services_hardening/status_cache.v1.json"); 16 const OPERATIONS_CONTRACT: &str = 17 include_str!("../contracts/services_hardening/tcp_operations.v1.json"); 18 const ADMIN_IDENTITY_OFFLINE_CONTRACT: &str = 19 include_str!("../contracts/services_hardening/admin_identity_offline.v1.json"); 20 const ADMIN_WAVE_QUALIFICATION_CONTRACT: &str = 21 include_str!("../contracts/services_hardening/admin_wave_qualification.v1.json"); 22 const ADAPTERS: &str = include_str!("../src/adapters/mod.rs"); 23 const NOSTR_ADAPTERS: &str = include_str!("../src/adapters/nostr/mod.rs"); 24 const FEATURES: &str = include_str!("../src/features/mod.rs"); 25 const RUNTIME_ADAPTERS: &str = include_str!("../src/runtime_adapters.rs"); 26 const RUNTIME_ADAPTER_CONTRACT: &str = 27 include_str!("../contracts/services_hardening/runtime_adapters.v1.json"); 28 const RUNTIME_FOUNDATION: &str = include_str!("../src/runtime_foundation.rs"); 29 const PRESENCE_DESIRED: &str = include_str!("../src/presence_desired.rs"); 30 const PRESENCE_DESIRED_CONTRACT: &str = 31 include_str!("../contracts/services_hardening/presence_desired_state.v1.json"); 32 const PRESENCE_PUBLICATION: &str = include_str!("../src/presence_publication.rs"); 33 const PRESENCE_PUBLICATION_CONTRACT: &str = 34 include_str!("../contracts/services_hardening/presence_publication.v1.json"); 35 const PUBLICATION: &str = include_str!("../src/publication.rs"); 36 const PUBLICATION_ATTEMPT: &str = include_str!("../src/publication_attempt.rs"); 37 const PUBLICATION_ATTEMPT_CONTRACT: &str = 38 include_str!("../contracts/services_hardening/publication_attempt_evidence.v1.json"); 39 const PUBLICATION_EXECUTION: &str = include_str!("../src/publication_execution.rs"); 40 const PUBLICATION_EXECUTION_CONTRACT: &str = 41 include_str!("../contracts/services_hardening/publication_execution.v1.json"); 42 const PUBLICATION_WAVE_QUALIFICATION_CONTRACT: &str = 43 include_str!("../contracts/services_hardening/publication_wave_qualification.v1.json"); 44 const FAILURE_QUALIFICATION_CONTRACT: &str = 45 include_str!("../contracts/services_hardening/failure_qualification.v1.json"); 46 const PROCESS_QUALIFICATION_CONTRACT: &str = 47 include_str!("../contracts/services_hardening/process_qualification.v1.json"); 48 const PROCESS_QUALIFICATION_TESTS: &str = include_str!("services_hardening_process.rs"); 49 const RUNTIME_GRAPH: &str = include_str!("../src/runtime_graph.rs"); 50 const PUBLICATION_CONTRACT: &str = 51 include_str!("../contracts/services_hardening/publication_outbox.v1.json"); 52 const PUBLICATION_SUBMISSION: &str = include_str!("../src/publication_submission.rs"); 53 const PUBLICATION_SUBMISSION_CONTRACT: &str = 54 include_str!("../contracts/services_hardening/publication_submission.v1.json"); 55 const RECONCILIATION_ATTEMPTS: &str = include_str!("../src/reconciliation_attempt.rs"); 56 const RECONCILIATION_COMMIT: &str = include_str!("../src/reconciliation_commit.rs"); 57 const RECONCILIATION_ATTESTATION: &str = include_str!("../src/reconciliation_attestation.rs"); 58 const RECONCILIATION_FINALIZATION: &str = include_str!("../src/reconciliation_finalization.rs"); 59 const RECONCILIATION_FINALIZATION_COMMIT: &str = 60 include_str!("../src/reconciliation_finalization_commit.rs"); 61 const RECONCILIATION_MANIFEST: &str = include_str!("../src/reconciliation_manifest.rs"); 62 const RECONCILIATION_REDUCER: &str = include_str!("../src/reconciliation_reducer.rs"); 63 const RECONCILIATION_JOBS: &str = include_str!("../src/reconciliation_job.rs"); 64 const RECONCILIATION_REPLAY: &str = include_str!("../src/reconciliation_replay.rs"); 65 const RECONCILIATION_ATTEMPT_CONTRACT: &str = 66 include_str!("../contracts/services_hardening/reconciliation_attempts.v1.json"); 67 const RECONCILIATION_REPLAY_CONTRACT: &str = 68 include_str!("../contracts/services_hardening/reconciliation_replay.v1.json"); 69 const RECONCILIATION_COMMIT_CONTRACT: &str = 70 include_str!("../contracts/services_hardening/reconciliation_commit.v1.json"); 71 const RECONCILIATION_ATTESTATION_CONTRACT: &str = 72 include_str!("../contracts/services_hardening/reconciliation_attestation.v1.json"); 73 const RECONCILIATION_FINALIZATION_CONTRACT: &str = 74 include_str!("../contracts/services_hardening/reconciliation_finalization.v1.json"); 75 const RECONCILIATION_FINALIZATION_COMMIT_CONTRACT: &str = 76 include_str!("../contracts/services_hardening/reconciliation_finalization_commit.v1.json"); 77 const RECONCILIATION_MANIFEST_CONTRACT: &str = 78 include_str!("../contracts/services_hardening/reconciliation_manifest.v1.json"); 79 const RECONCILIATION_REDUCER_CONTRACT: &str = 80 include_str!("../contracts/services_hardening/reconciliation_reducer.v1.json"); 81 const RECONCILIATION_OUTCOME_CONTRACT: &str = 82 include_str!("../contracts/services_hardening/reconciliation_outcome.v1.json"); 83 const RUNTIME_FOUNDATION_CONTRACT: &str = 84 include_str!("../contracts/services_hardening/runtime_foundation.v1.json"); 85 const TRADE_INGEST_CONTRACT: &str = 86 include_str!("../contracts/services_hardening/trade_ingest.v1.json"); 87 const TRADE_EVIDENCE_PERSISTENCE_CONTRACT: &str = 88 include_str!("../contracts/services_hardening/trade_evidence_persistence.v1.json"); 89 const TRADE_SOURCE_INGEST_CONTRACT: &str = 90 include_str!("../contracts/services_hardening/trade_source_ingest.v1.json"); 91 const STATE_HOST: &str = include_str!("../src/state_host.rs"); 92 const PUBLIC_API: &str = include_str!("../contracts/api_baselines/rhi.txt"); 93 const SOURCES: &[&str] = &[ 94 include_str!("../src/adapters/nostr/event.rs"), 95 include_str!("../src/admin_v1.rs"), 96 include_str!("../src/cli_v1.rs"), 97 include_str!("../src/config_v1.rs"), 98 include_str!("../src/doctor_v1.rs"), 99 include_str!("../src/features/trade_agreement_attestation.rs"), 100 include_str!("../src/identity_credential.rs"), 101 include_str!("../src/identity_envelope.rs"), 102 include_str!("../src/operations_v1.rs"), 103 include_str!("../src/presence_desired.rs"), 104 include_str!("../src/presence_publication.rs"), 105 include_str!("../src/process_result_v1.rs"), 106 include_str!("../src/publication.rs"), 107 include_str!("../src/publication_attempt.rs"), 108 include_str!("../src/publication_execution.rs"), 109 include_str!("../src/publication_submission.rs"), 110 include_str!("../src/reconciliation_attempt.rs"), 111 include_str!("../src/reconciliation_attestation.rs"), 112 include_str!("../src/reconciliation_commit.rs"), 113 include_str!("../src/reconciliation_finalization.rs"), 114 include_str!("../src/reconciliation_finalization_commit.rs"), 115 include_str!("../src/reconciliation_job.rs"), 116 include_str!("../src/reconciliation_manifest.rs"), 117 include_str!("../src/reconciliation_reducer.rs"), 118 include_str!("../src/reconciliation_replay.rs"), 119 include_str!("../src/runtime_context.rs"), 120 include_str!("../src/runtime_adapters.rs"), 121 include_str!("../src/runtime_foundation.rs"), 122 include_str!("../src/source_ingest.rs"), 123 include_str!("../src/state_catalog.rs"), 124 include_str!("../src/state_config.rs"), 125 include_str!("../src/state_host.rs"), 126 include_str!("../src/state_maintenance.rs"), 127 include_str!("../src/state_metadata.rs"), 128 include_str!("../src/state_repository.rs"), 129 include_str!("../src/state_trade.rs"), 130 include_str!("../src/status_v1.rs"), 131 include_str!("../src/trade_ingest.rs"), 132 ]; 133 134 #[test] 135 fn state_initialization_uses_only_governed_directory_and_sqlite_authority() { 136 for required in [ 137 "ServiceSqliteInitializer", 138 "ServiceSqliteInitializerFuture", 139 ".state_directory_plan()", 140 ".and_then(|plan| plan.provision())", 141 "initialize_database(", 142 ] { 143 assert!( 144 STATE_HOST.contains(required), 145 "state initialization is missing `{required}`" 146 ); 147 } 148 for forbidden in [ 149 "PathBuf", 150 "use sqlx::", 151 "SqliteConnectOptions", 152 "ConnectOptions", 153 "create_dir_all", 154 "try_exists", 155 ] { 156 assert!( 157 !STATE_HOST.contains(forbidden), 158 "state initialization regained `{forbidden}`" 159 ); 160 } 161 } 162 163 #[test] 164 fn package_identity_is_standalone_and_non_publishable() { 165 assert!(MANIFEST.contains("name = \"rhi\"")); 166 assert!(MANIFEST.contains("repository = \"https://github.com/radrootslabs/rhi\"")); 167 assert!(MANIFEST.contains("readme = \"README\"")); 168 assert!(MANIFEST.contains("publish = false")); 169 for forbidden in [ 170 "path = \"../", 171 "path = \"../../", 172 "enterprise/", 173 "ops/", 174 "foundation/", 175 ] { 176 assert!( 177 !MANIFEST.contains(forbidden), 178 "standalone package retains forbidden dependency surface {forbidden}" 179 ); 180 } 181 } 182 183 #[test] 184 fn shared_runtime_contracts_are_curated_without_exposing_implementation_authority() { 185 for forbidden in [ 186 "pub use radroots_service_sqlite", 187 "pub mod service_host", 188 "pub mod service_sqlite", 189 "sqlx::Pool", 190 "sqlx::SqliteConnection", 191 "SystemEntropy", 192 "SystemMonotonicClock", 193 "SystemWallClock", 194 "TaskSupervisor", 195 "pub use radroots_service_host::CancellationToken", 196 ] { 197 assert!( 198 !ROOT.contains(forbidden), 199 "RHI public root exposes private host implementation {forbidden}" 200 ); 201 } 202 assert!(!PUBLIC_API.contains("radroots_service_host::HostError")); 203 assert!(!PUBLIC_API.contains("radroots_service_host::TaskSupervisor")); 204 } 205 206 #[test] 207 fn state_catalog_module_is_private_and_root_api_is_curated() { 208 for module in [ 209 "adapters", 210 "admin_v1", 211 "cli_v1", 212 "config_v1", 213 "doctor_v1", 214 "features", 215 "identity_credential", 216 "identity_envelope", 217 "operations_v1", 218 "presence_desired", 219 "presence_publication", 220 "process_result_v1", 221 "publication", 222 "publication_attempt", 223 "publication_execution", 224 "publication_submission", 225 "reconciliation_attempt", 226 "reconciliation_attestation", 227 "reconciliation_commit", 228 "reconciliation_finalization", 229 "reconciliation_finalization_commit", 230 "reconciliation_job", 231 "reconciliation_manifest", 232 "reconciliation_reducer", 233 "reconciliation_replay", 234 "runtime_context", 235 "runtime_adapters", 236 "runtime_foundation", 237 "source_ingest", 238 "state_catalog", 239 "state_config", 240 "state_host", 241 "state_maintenance", 242 "state_metadata", 243 "state_repository", 244 "state_trade", 245 "status_v1", 246 "trade_ingest", 247 ] { 248 assert!( 249 ROOT.contains(&format!("mod {module};")), 250 "RHI root is missing private module {module}" 251 ); 252 assert!( 253 !ROOT.contains(&format!("pub mod {module};")), 254 "RHI root exposes module {module}" 255 ); 256 } 257 assert!(ADAPTERS.contains("pub(crate) mod nostr;")); 258 assert!(NOSTR_ADAPTERS.contains("pub(crate) mod event;")); 259 assert!(FEATURES.contains("pub(crate) mod trade_agreement_attestation;")); 260 assert!(ROOT.contains("#![doc = include_str!(\"../README\")]")); 261 for required in [ 262 "NostrEventAdapter", 263 "TradeAgreementAttestationPolicy", 264 "TradeAgreementAttestationErrorKind", 265 "rhi_migration_catalog", 266 "rhi_schema_catalog", 267 "validate_rhi_state_catalogs", 268 "RhiStateCatalogError", 269 "RhiRuntimeAdapters", 270 "RhiPublicationAuthority", 271 "RhiPresenceDesiredAuthority", 272 "RhiPresenceDesiredCommitOutcome", 273 "RhiPresenceDesiredErrorKind", 274 "RhiPresenceDesiredState", 275 "validate_rhi_presence_desired_authority", 276 "RHI_PRESENCE_DESIRED_CONTRACT_VERSION", 277 "RhiExactPresenceSink", 278 "RhiPreparedPresenceAttempt", 279 "RhiPresenceAttemptCommit", 280 "RhiPresenceAttemptOutcome", 281 "RhiPresenceLease", 282 "RhiPresenceLeaseOwner", 283 "RhiPresenceOutboxState", 284 "RhiPresencePublicationErrorKind", 285 "RhiPresenceTargetState", 286 "RhiSignedPresenceDocument", 287 "RhiSignedPresenceDocuments", 288 "build_rhi_signed_presence_documents", 289 "validate_rhi_signed_presence_documents", 290 "RHI_PRESENCE_PUBLICATION_CONTRACT_VERSION", 291 "RhiAdminRoute", 292 "RhiAdminRequestDocument", 293 "RhiAdminResponseDocument", 294 "RhiAdminHandler", 295 "RhiAdminRouter", 296 "RhiAdminServer", 297 "RhiBoundAdminServer", 298 "build_rhi_admin_router", 299 "RhiCliPrimaryAuthorityV1", 300 "RhiCliOfflineOperationV1", 301 "RhiCliAdminOperationV1", 302 "RhiCliExecutionPlanV1", 303 "plan_rhi_cli_v1", 304 "RhiDoctorCheckId", 305 "RhiDoctorCheckDefinition", 306 "RhiDoctorCheckResult", 307 "RhiDoctorReport", 308 "RhiDoctorProbe", 309 "run_rhi_doctor", 310 "rhi_doctor_check_definitions", 311 "RhiProcessResult", 312 "RhiStatusPublisher", 313 "RhiStatusReader", 314 "RhiStatusSnapshot", 315 "RhiStatusObservationV1", 316 "RhiProviderStatusV1", 317 "RhiEvidenceTransportStatusV1", 318 "RhiReconciliationStatusV1", 319 "RhiPublicationStatusV1", 320 "RhiPresenceStatusV1", 321 "rhi_status_cache", 322 "RhiOperationsServer", 323 "RhiBoundOperationsServer", 324 "RhiOperationsCancellationToken", 325 "RhiOperationsErrorKind", 326 "RhiPublicationErrorKind", 327 "RhiPublicationMode", 328 "RhiPublicationRetryPolicy", 329 "RhiPublicationTarget", 330 "RHI_PUBLICATION_CONTRACT_VERSION", 331 "RhiPublicationAttemptEvidence", 332 "RhiPublicationAttemptEvidenceErrorKind", 333 "RhiPublicationAttemptId", 334 "RhiPublicationAttemptOutcome", 335 "RhiPublicationTargetState", 336 "RhiPublicationUnixMilliseconds", 337 "RHI_PUBLICATION_ATTEMPT_EVIDENCE_CONTRACT_VERSION", 338 "RHI_PUBLICATION_ATTEMPT_NUMBER_MAXIMUM", 339 "RHI_PUBLICATION_TARGET_ORDINAL_MAXIMUM", 340 "RhiExactPublicationSink", 341 "RhiPreparedPublicationAttempt", 342 "RhiPublicationAttemptCommit", 343 "RhiPublicationExecutionErrorKind", 344 "RhiPublicationLease", 345 "RhiPublicationLeaseOwner", 346 "RhiPublicationOutboxState", 347 "RhiPublicationRetryDelayMilliseconds", 348 "RHI_PUBLICATION_EXECUTION_CONTRACT_VERSION", 349 "RhiCommittedPublication", 350 "RhiPublicationOutboxId", 351 "RhiPublicationSubmissionErrorKind", 352 "RHI_PUBLICATION_SUBMISSION_CONTRACT_VERSION", 353 "RhiReconciliationAttemptPlan", 354 "RhiReconciliationSourceRequest", 355 "RhiReconciliationSourceResult", 356 "RhiReconciliationAttemptResults", 357 "RhiReconciliationSourceCommitOutcome", 358 "RhiReconciliationCommitErrorKind", 359 "RhiSignedEvidenceAttestation", 360 "RhiEvidenceAttestationSupersession", 361 "RhiReconciliationAttestationErrorKind", 362 "RHI_RECONCILIATION_ATTESTATION_CONTRACT_VERSION", 363 "RHI_RECONCILIATION_SIGNED_ATTESTATION_MAX_BYTES", 364 "build_rhi_signed_evidence_attestation", 365 "RhiReconciliationFinalizationFence", 366 "RhiReconciliationFinalizationErrorKind", 367 "RHI_RECONCILIATION_FINALIZATION_CONTRACT_VERSION", 368 "RhiReconciliationFinalizationCommitOutcome", 369 "RhiReconciliationFinalizationCommitErrorKind", 370 "RHI_RECONCILIATION_FINALIZATION_COMMIT_CONTRACT_VERSION", 371 "RhiReconciliationManifest", 372 "RhiReconciliationManifestErrorKind", 373 "RhiReconciliationScopePrerequisites", 374 "RhiReconciliationProjection", 375 "RhiReconciliationEvaluation", 376 "RhiReconciliationCoverage", 377 "RhiReconciliationOutcome", 378 "RhiReconciliationReasonCode", 379 "RHI_RECONCILIATION_OUTCOME_CONTRACT_VERSION", 380 "RhiReconciliationReducerErrorKind", 381 "evaluate_rhi_reconciliation_claim", 382 "reduce_rhi_reconciliation_manifest", 383 "RhiReconciliationSourceReplayPlan", 384 "RhiReconciliationSourceReplay", 385 "RhiReconciliationJobPolicy", 386 "RhiReconciliationLease", 387 "RhiTimeEntropyAdapters", 388 "RhiTransportAdapters", 389 "RhiCredentialAccess", 390 "RhiIdentityAccess", 391 "RhiRuntimeFoundation", 392 "RhiRuntimeReadiness", 393 "open_rhi_runtime_foundation", 394 "apply_rhi_configuration", 395 "RhiConfigApplyOutcome", 396 "WallClock", 397 "MonotonicClock", 398 "EntropySource", 399 "EntropyError", 400 "WallClockError", 401 "MonotonicClockError", 402 "admit_rhi_trade_mutation_event", 403 "RhiTradeMutationAdmissionLimits", 404 "RhiAdmittedTradeMutationEvent", 405 "RhiTradeEvidencePersistenceError", 406 "RhiTradeEvidencePersistenceErrorKind", 407 "RhiTradeEvidencePersistenceOutcome", 408 "RhiTradeSourceObservation", 409 "RHI_TRADE_EVIDENCE_PERSISTENCE_CONTRACT_VERSION", 410 "ingest_rhi_trade_source", 411 "RhiTradeDirtyGeneration", 412 "RhiTradeSourceAttempt", 413 "RhiTradeSourceCompletion", 414 "RhiTradeSourceCursor", 415 "RhiTradeSourceIngestError", 416 "RhiTradeSourceIngestErrorKind", 417 "RhiTradeSourceIngestOutcome", 418 "RHI_TRADE_SOURCE_INGEST_CONTRACT_VERSION", 419 "RHI_TRADE_SOURCE_RESULT_MAX_BYTES", 420 "RHI_TRADE_SOURCE_RESULT_MAX_EVENTS", 421 ] { 422 assert!( 423 ROOT.contains(required), 424 "RHI root API is missing {required}" 425 ); 426 } 427 428 let public_modules = PUBLIC_API 429 .lines() 430 .filter(|line| line.starts_with("pub mod ")) 431 .collect::<Vec<_>>(); 432 assert_eq!(public_modules, ["pub mod rhi"]); 433 assert!(PUBLIC_API.contains("pub struct rhi::NostrEventAdapter<'a>")); 434 assert!(PUBLIC_API.contains("pub struct rhi::TradeAgreementAttestationError")); 435 assert!(PUBLIC_API.contains("pub struct rhi::RhiPresenceDesiredAuthority")); 436 assert!(PUBLIC_API.contains("pub struct rhi::RhiPresenceDesiredState")); 437 assert!(PUBLIC_API.contains("pub enum rhi::RhiPresenceDesiredErrorKind")); 438 assert!(PUBLIC_API.contains("pub struct rhi::RhiSignedPresenceDocument")); 439 assert!(PUBLIC_API.contains("pub enum rhi::RhiPresencePublicationErrorKind")); 440 assert!(PUBLIC_API.contains("pub struct rhi::RhiCliExecutionPlanV1")); 441 assert!(PUBLIC_API.contains( 442 "pub const fn rhi::plan_rhi_cli_v1(&rhi::RhiCliInvocationV1) -> rhi::RhiCliExecutionPlanV1" 443 )); 444 assert!(!PUBLIC_API.contains("rhi::adapters::")); 445 assert!(!PUBLIC_API.contains("rhi::features::")); 446 assert!(!PUBLIC_API.contains("rhi::runtime_adapters::")); 447 assert!(!PUBLIC_API.contains("rhi::publication::")); 448 assert!(!PUBLIC_API.contains("rhi::publication_attempt::")); 449 assert!(!PUBLIC_API.contains("rhi::publication_execution::")); 450 assert!(!PUBLIC_API.contains("rhi::publication_submission::")); 451 assert!(!PUBLIC_API.contains("rhi::presence_publication::")); 452 assert!(!PUBLIC_API.contains("rhi::admin_v1::")); 453 assert!(!PUBLIC_API.contains("rhi::cli_v1::")); 454 assert!(!PUBLIC_API.contains("rhi::doctor_v1::")); 455 assert!(!PUBLIC_API.contains("rhi::operations_v1::")); 456 assert!(!PUBLIC_API.contains("rhi::process_result_v1::")); 457 assert!(!PUBLIC_API.contains("rhi::status_v1::")); 458 } 459 460 #[test] 461 fn step212_status_and_tcp_operations_are_passive_closed_and_dependency_neutral() { 462 let status_contract: serde_json::Value = 463 serde_json::from_str(STATUS_CONTRACT).expect("status contract"); 464 let operations_contract: serde_json::Value = 465 serde_json::from_str(OPERATIONS_CONTRACT).expect("operations contract"); 466 assert_eq!(status_contract["schema"], "radroots.rhi.status-cache.v1"); 467 assert_eq!(status_contract["step"], 212); 468 assert_eq!(status_contract["read"]["fresh_probe"], false); 469 assert_eq!( 470 operations_contract["schema"], 471 "radroots.rhi.tcp-operations.v1" 472 ); 473 assert_eq!(operations_contract["step"], 212); 474 assert_eq!(operations_contract["route_registration_extension"], false); 475 476 for required in [ 477 "CachedServiceStatePublisher<RhiCachedStatus>", 478 "pub struct RhiStatusPublisher", 479 "pub struct RhiStatusReader", 480 "pub struct RhiStatusSnapshot", 481 "pub fn rhi_status_cache(", 482 "status.to_bounded_json()", 483 "reconciliation: RhiReconciliationStatusV1", 484 "publication: RhiPublicationStatusV1", 485 "presence: RhiPresenceStatusV1", 486 "RHI_STATUS_REASON_CODE_COUNT: usize = 13", 487 "radroots_rhi_service_phase", 488 "radroots_rhi_service_ready", 489 ] { 490 assert!(STATUS.contains(required), "status is missing {required}"); 491 } 492 for required in [ 493 "HostOperationsServer::new(listener, status.operations_cache())", 494 "RhiOperationsCancellationToken", 495 "HostOperationsTransportLimits::new(values)", 496 "HeaderLimitBelowParserFloor", 497 ] { 498 assert!( 499 OPERATIONS.contains(required), 500 "operations is missing {required}" 501 ); 502 } 503 for forbidden in [ 504 "sqlx::", 505 "std::fs::", 506 "tokio::spawn", 507 "spawn_blocking", 508 "SystemTime", 509 "std::env::", 510 "provider.execute", 511 "source.fetch", 512 "relay.connect", 513 "route(", 514 "Router", 515 ] { 516 assert!(!STATUS.contains(forbidden), "status gained {forbidden}"); 517 assert!( 518 !OPERATIONS.contains(forbidden), 519 "operations gained {forbidden}" 520 ); 521 } 522 assert!(PUBLIC_API.contains("impl core::clone::Clone for rhi::RhiStatusReader")); 523 assert!(!PUBLIC_API.contains("impl core::clone::Clone for rhi::RhiStatusPublisher")); 524 assert!(!PUBLIC_API.contains("impl core::clone::Clone for rhi::RhiStatusSnapshot")); 525 for forbidden in [ 526 "radroots_service_host::OperationsServer", 527 "radroots_service_host::BoundOperationsServer", 528 "radroots_service_host::CachedServiceState", 529 "radroots_service_host::BoundedMetricsSnapshot", 530 ] { 531 assert!(!PUBLIC_API.contains(forbidden)); 532 } 533 for required in [ 534 "## Passive lifecycle status and TCP operations", 535 "exactly HTTP/1.1 `GET /livez`, `GET /readyz`, and `GET /metrics`", 536 "Requests perform no SQLite", 537 "status_cache.v1.json", 538 "tcp_operations.v1.json", 539 ] { 540 assert!(README.contains(required), "README is missing {required}"); 541 } 542 } 543 544 #[test] 545 fn doctor_and_process_results_are_closed_bounded_and_process_safe() { 546 let contract: serde_json::Value = 547 serde_json::from_str(OPERATOR_CONTRACT).expect("operator contract"); 548 assert_eq!(contract["doctor"]["contract_version"], 1); 549 assert_eq!(contract["doctor"]["execution"], "ordered"); 550 assert_eq!(contract["doctor"]["checks"].as_array().unwrap().len(), 15); 551 assert_eq!(contract["doctor"]["report_max_utf8_bytes"], 8_192); 552 assert_eq!(contract["doctor"]["required_fail_or_timeout_exit"], 6); 553 assert_eq!(contract["doctor"]["detached_probe_work"], false); 554 assert_eq!(contract["exit_codes"].as_array().unwrap().len(), 7); 555 556 for required in [ 557 "pub const RHI_DOCTOR_CHECK_COUNT: usize = 15", 558 "pub const RHI_DOCTOR_REPORT_MAX_UTF8_BYTES: usize = 8_192", 559 "tokio::time::timeout(", 560 "probe.probe(definition)", 561 "Ok(RhiDoctorObservation::Skipped) if !definition.required", 562 "RhiDoctorCheckStatus::Timeout", 563 "canonical_json: Box<[u8]>", 564 ".field(\"canonical_json\", &\"[redacted]\")", 565 ] { 566 assert!(DOCTOR.contains(required), "doctor is missing {required}"); 567 } 568 for forbidden in [ 569 "std::fs", 570 "std::net", 571 "sqlx::", 572 "tokio::spawn", 573 "thread::spawn", 574 "SystemTime", 575 "serde_json::Value", 576 "pub fn into_inner", 577 ] { 578 assert!( 579 !DOCTOR.contains(forbidden), 580 "doctor orchestrator gained forbidden authority {forbidden}" 581 ); 582 } 583 for required in [ 584 "pub enum RhiProcessResult", 585 "Self::Success => 0", 586 "Self::DoctorRequiredCheckFailed => 6", 587 "pub const fn code(self) -> &'static str", 588 ] { 589 assert!( 590 PROCESS_RESULT.contains(required), 591 "process result is missing {required}" 592 ); 593 } 594 assert!(MAIN.contains("parse_rhi_cli_v1_from(std::env::args_os())")); 595 assert!(MAIN.contains("RhiProcessResult::InputOrConfiguration")); 596 assert!(MAIN.contains("execute_rhi_cli_v1_with_signal_source")); 597 assert!(MAIN.contains("eprintln!(\"{}\", RhiLogRecord::process_result(result))")); 598 for forbidden in ["{error}", "{error:?}", "process::exit", "tokio::runtime"] { 599 assert!( 600 !MAIN.contains(forbidden), 601 "binary exposes forbidden process behavior {forbidden}" 602 ); 603 } 604 assert!( 605 MANIFEST.contains( 606 "tokio = { version = \"1\", default-features = false, features = [\"io-util\", \"macros\", \"net\", \"rt-multi-thread\", \"signal\", \"sync\", \"time\"] }" 607 ) 608 ); 609 assert!(MANIFEST.contains( 610 "serde = { version = \"1\", default-features = false, features = [\"derive\"] }" 611 )); 612 } 613 614 #[test] 615 fn active_admin_boundary_hides_shared_transport_authority() { 616 for required in [ 617 "pub struct RhiAdminRouter", 618 "pub struct RhiAdminServer", 619 "pub struct RhiBoundAdminServer", 620 "pub trait RhiAdminHandler", 621 "pub const COMMON: [Self; 7]", 622 "pub const DOMAIN: [Self; 13]", 623 "pub const ALL: [Self; 20]", 624 "pub const ACTIVE: [Self; 20]", 625 ] { 626 assert!( 627 ADMIN.contains(required), 628 "missing common admin boundary `{required}`" 629 ); 630 } 631 let offline: serde_json::Value = 632 serde_json::from_str(ADMIN_IDENTITY_OFFLINE_CONTRACT).expect("offline identity contract"); 633 assert_eq!(offline["final_inventory"]["route_count"], 20); 634 assert_eq!(offline["final_inventory"]["model_count"], 33); 635 assert_eq!(offline["identity_rotation"]["unix_admin_mutation"], false); 636 let qualification: serde_json::Value = serde_json::from_str(ADMIN_WAVE_QUALIFICATION_CONTRACT) 637 .expect("admin wave qualification contract"); 638 assert_eq!(qualification["step"], 209); 639 assert_eq!(qualification["wave"], "130-b"); 640 assert_eq!(qualification["final_inventory"]["route_count"], 20); 641 assert_eq!(qualification["final_inventory"]["model_count"], 33); 642 for forbidden in ["IdentityRekey", "IdentityReplace"] { 643 assert!(!ADMIN.contains(forbidden)); 644 assert!(!PUBLIC_API.contains(forbidden)); 645 } 646 for forbidden in [ 647 "pub fn into_inner", 648 "pub fn router", 649 "pub fn listener", 650 "pub use radroots_service_host::AdminRouter", 651 "pub use radroots_service_host::AdminServer", 652 "pub use serde_json::Value", 653 ] { 654 assert!(!ROOT.contains(forbidden), "public root leaks `{forbidden}`"); 655 assert!( 656 !PUBLIC_API.contains(forbidden), 657 "API baseline leaks `{forbidden}`" 658 ); 659 } 660 } 661 662 #[test] 663 fn presence_desired_state_is_config_bound_durable_and_effect_free() { 664 let contract: serde_json::Value = 665 serde_json::from_str(PRESENCE_DESIRED_CONTRACT).expect("presence-desired-state contract"); 666 assert_eq!(contract["schema"], "radroots.rhi.presence-desired-state"); 667 assert_eq!(contract["contract_version"], 1); 668 assert_eq!(contract["authority"]["maximum_targets"], 32); 669 assert_eq!(contract["durable_state"]["write_class"], "compare_and_swap"); 670 assert_eq!(contract["durable_state"]["rows"], "exactly_zero_or_one"); 671 assert_eq!(contract["effects"]["network"], false); 672 assert_eq!(contract["effects"]["relay_io"], false); 673 for required in [ 674 "pub fn validate_rhi_presence_desired_authority(", 675 "require_current_config(transaction, authority).await?", 676 "LIMIT 1", 677 "LIMIT 2", 678 "ServiceSqliteTransactionErrorKind::CommitOutcomeUnknown", 679 ] { 680 assert!( 681 PRESENCE_DESIRED.contains(required), 682 "presence desired-state boundary is missing {required}" 683 ); 684 } 685 for forbidden in [ 686 "SystemTime", 687 "OsRng", 688 "thread_rng", 689 "tokio::spawn", 690 "std::net", 691 "EventSink", 692 "sign_nostr_event", 693 ] { 694 assert!( 695 !PRESENCE_DESIRED.contains(forbidden), 696 "presence desired-state boundary gained forbidden authority {forbidden}" 697 ); 698 } 699 assert!(!ROOT.contains("pub mod presence_desired")); 700 assert!(!PUBLIC_API.contains("rhi::presence_desired::")); 701 } 702 703 #[test] 704 fn presence_publication_is_typed_verified_durable_and_exact_byte_only() { 705 let contract: serde_json::Value = 706 serde_json::from_str(PRESENCE_PUBLICATION_CONTRACT).expect("presence-publication contract"); 707 assert_eq!(contract["schema"], "radroots.rhi.presence-publication"); 708 assert_eq!(contract["schema_version"], 1); 709 assert_eq!(contract["contract_version"], 1); 710 assert_eq!(contract["step"], 205); 711 assert_eq!(contract["durable_workflow"]["schema_version"], 10); 712 assert_eq!( 713 contract["durable_workflow"]["exact_signed_bytes_committed_before_io"], 714 true 715 ); 716 assert_eq!( 717 contract["durable_workflow"]["target_submitted_committed_before_io"], 718 true 719 ); 720 assert_eq!( 721 contract["durable_workflow"]["remote_io_inside_sql_transaction"], 722 false 723 ); 724 assert_eq!( 725 contract["durable_workflow"]["commit_outcome_unknown"], 726 "caller_retains_sealed_exact_bytes_and_rereads_exact_identity_before_retry" 727 ); 728 assert_eq!( 729 contract["construction"]["validation_input"], 730 "sealed_documents_and_public_desired_authority_only" 731 ); 732 assert_eq!( 733 contract["resource_bounds"]["maximum_signed_event_bytes"], 734 32_768 735 ); 736 assert_eq!( 737 contract["resource_bounds"]["maximum_attempts_per_target"], 738 100 739 ); 740 assert_eq!( 741 contract["resource_bounds"]["maximum_authored_unix_seconds"], 742 i64::MAX 743 ); 744 for required in [ 745 "AuthoredProfile::new(PROFILE_NAME)", 746 "ApplicationHandlerSpec::new(APPLICATION_HANDLER_KINDS.to_vec())", 747 "validate_signed_document(", 748 "pub fn validate_rhi_signed_presence_documents(\n documents: &RhiSignedPresenceDocuments,\n authority: &RhiPresenceDesiredAuthority,\n)", 749 "verify_id(&event)", 750 "verify(&event)", 751 "pub trait RhiExactPresenceSink: Send + Sync", 752 "pub async fn commit_signed_presence(\n &self,\n documents: &RhiSignedPresenceDocuments,", 753 "pub async fn claim_next_presence(", 754 "pub async fn prepare_next_presence_target(", 755 "pub async fn record_presence_outcome(", 756 "pub async fn recover_one_expired_presence(", 757 "pub async fn execute_next_presence(", 758 "state = 'submitted'", 759 "INSERT INTO presence_attempts", 760 "sink.submit_exact(&prepared).await", 761 "ServiceSqliteTransactionErrorKind::CommitOutcomeUnknown", 762 ] { 763 assert!( 764 PRESENCE_PUBLICATION.contains(required), 765 "presence publication is missing {required}" 766 ); 767 } 768 for forbidden in [ 769 "SystemTime", 770 "thread_rng", 771 "OsRng", 772 "tokio::spawn", 773 "std::net", 774 "std::fs", 775 "SqliteConnection", 776 "SqlitePool", 777 "EventSink", 778 ] { 779 assert!( 780 !PRESENCE_PUBLICATION.contains(forbidden), 781 "presence publication gained forbidden authority {forbidden}" 782 ); 783 } 784 assert!(!ROOT.contains("pub mod presence_publication")); 785 assert!(!PUBLIC_API.contains("rhi::presence_publication::")); 786 } 787 788 #[test] 789 fn publication_authority_is_config_derived_sealed_and_effect_free() { 790 let contract: serde_json::Value = 791 serde_json::from_str(PUBLICATION_CONTRACT).expect("publication contract"); 792 assert_eq!(contract["schema"], "radroots.rhi.publication-outbox"); 793 assert_eq!(contract["schema_version"], 1); 794 assert_eq!(contract["state_schema_version"], 7); 795 assert_eq!(contract["effects"]["sqlite_query_or_mutation"], false); 796 assert_eq!(contract["effects"]["relay_or_network"], false); 797 for required in [ 798 "pub fn from_config(config: &RhiConfigDocumentV1)", 799 "RhiPublicationMode::Required", 800 "RhiPublicationMode::Disabled", 801 "target_set_digest(&targets)?", 802 "authority_digest(", 803 ] { 804 assert!( 805 PUBLICATION.contains(required), 806 "publication authority is missing {required}" 807 ); 808 } 809 for forbidden in [ 810 "sqlx::", 811 "std::fs", 812 "std::net", 813 "tokio::", 814 "SystemTime", 815 "thread_rng", 816 "OsRng", 817 ] { 818 assert!( 819 !PUBLICATION.contains(forbidden), 820 "publication authority gained forbidden effect {forbidden}" 821 ); 822 } 823 } 824 825 #[test] 826 fn committed_publication_is_bounded_exact_and_never_reconstructed() { 827 let contract: serde_json::Value = serde_json::from_str(PUBLICATION_SUBMISSION_CONTRACT) 828 .expect("publication-submission contract"); 829 assert_eq!(contract["schema"], "radroots.rhi.publication-submission"); 830 assert_eq!(contract["contract_version"], 1); 831 assert_eq!(contract["source"]["maximum_signed_event_bytes"], 32_768); 832 assert_eq!(contract["retry_and_recovery"]["parse_event"], false); 833 assert_eq!(contract["retry_and_recovery"]["reserialize_event"], false); 834 assert_eq!(contract["retry_and_recovery"]["resign_event"], false); 835 for required in [ 836 "pub async fn read_committed_publication(", 837 "READ_COMMITTED_PUBLICATION_SQL", 838 "length(event.canonical_event_json) BETWEEN 1 AND 32768", 839 "Sha256::digest(&exact_signed_event_bytes)", 840 "pub const fn exact_signed_event_bytes(&self) -> &[u8]", 841 ] { 842 assert!( 843 PUBLICATION_SUBMISSION.contains(required), 844 "committed publication is missing {required}" 845 ); 846 } 847 for forbidden in [ 848 "serde_json", 849 "Nip01EventWire", 850 "SignedEvent", 851 "sign_nostr_event", 852 "EventSink", 853 "std::net", 854 "tokio::spawn", 855 "SystemTime", 856 "pub(crate) fn from_committed_parts", 857 ] { 858 assert!( 859 !PUBLICATION_SUBMISSION.contains(forbidden), 860 "committed publication gained reconstruction or I/O authority {forbidden}" 861 ); 862 } 863 assert!(!ROOT.contains("pub mod publication_submission")); 864 assert!(!PUBLIC_API.contains("rhi::publication_submission::")); 865 } 866 867 #[test] 868 fn publication_attempt_evidence_is_closed_bounded_and_effect_free() { 869 let contract: serde_json::Value = 870 serde_json::from_str(PUBLICATION_ATTEMPT_CONTRACT).expect("publication-attempt contract"); 871 assert_eq!( 872 contract["schema"], 873 "radroots.rhi.publication-attempt-evidence" 874 ); 875 assert_eq!(contract["contract_version"], 1); 876 assert_eq!(contract["bounds"]["target_ordinal"]["maximum"], 31); 877 assert_eq!(contract["bounds"]["attempt_number"]["maximum"], 100); 878 assert_eq!( 879 contract["evidence"]["result_code"], 880 "exact_closed_outcome_code" 881 ); 882 assert_eq!(contract["effects"]["sqlite_read_or_mutation"], false); 883 assert_eq!(contract["effects"]["relay_or_network"], false); 884 for required in [ 885 "pub enum RhiPublicationTargetState", 886 "pub enum RhiPublicationAttemptOutcome", 887 "pub struct RhiPublicationAttemptEvidence", 888 "publication.outbox_id()", 889 "publication.event_sha256()", 890 "RHI_PUBLICATION_TARGET_ORDINAL_MAXIMUM", 891 "RHI_PUBLICATION_ATTEMPT_NUMBER_MAXIMUM", 892 ] { 893 assert!( 894 PUBLICATION_ATTEMPT.contains(required), 895 "publication-attempt evidence is missing {required}" 896 ); 897 } 898 for forbidden in [ 899 "sqlx::", 900 "serde_json", 901 "EventSink", 902 "SystemTime", 903 "std::fs", 904 "std::net", 905 "tokio::spawn", 906 ] { 907 assert!( 908 !PUBLICATION_ATTEMPT.contains(forbidden), 909 "publication-attempt evidence gained forbidden authority {forbidden}" 910 ); 911 } 912 assert!(!ROOT.contains("pub mod publication_attempt")); 913 assert!(!PUBLIC_API.contains("rhi::publication_attempt::")); 914 } 915 916 #[test] 917 fn publication_execution_is_sqlx_owned_exact_byte_and_fail_closed() { 918 let contract: serde_json::Value = serde_json::from_str(PUBLICATION_EXECUTION_CONTRACT) 919 .expect("publication-execution contract"); 920 assert_eq!(contract["schema"], "radroots.rhi.publication-execution"); 921 assert_eq!(contract["contract_version"], 1); 922 assert_eq!( 923 contract["storage_authority"], 924 "single_service_sqlite_host_sqlx_transactions" 925 ); 926 assert_eq!( 927 contract["claim"]["authority"], 928 "exact_current_required_authority_and_target_set" 929 ); 930 assert_eq!(contract["attempt"]["remote_io_outside_transaction"], true); 931 assert_eq!(contract["exact_byte_sink"]["parse"], false); 932 assert_eq!(contract["exact_byte_sink"]["reserialize"], false); 933 assert_eq!( 934 contract["cancellation_and_recovery"]["after_durable_submitted"], 935 "unknown_until_independent_evidence" 936 ); 937 for required in [ 938 "pub trait RhiExactPublicationSink: Send + Sync", 939 "pub async fn claim_next_publication(", 940 "pub async fn prepare_next_publication_target(", 941 "pub async fn record_publication_outcome(", 942 "pub async fn recover_one_expired_publication(", 943 "pub async fn execute_next_publication(", 944 "read_committed(transaction, lease.outbox.id)", 945 "state = 'submitted'", 946 "INSERT INTO publication_attempts", 947 "ServiceSqliteTransactionErrorKind::CommitOutcomeUnknown", 948 ] { 949 assert!( 950 PUBLICATION_EXECUTION.contains(required), 951 "publication execution is missing {required}" 952 ); 953 } 954 for forbidden in [ 955 "radroots_event_codec", 956 "Nip01EventWire", 957 "DeliveryPayload", 958 "EventSink", 959 "serde_json", 960 "SystemTime", 961 "thread_rng", 962 "OsRng", 963 "tokio::spawn", 964 "SqliteConnection", 965 "SqlitePool", 966 ] { 967 assert!( 968 !PUBLICATION_EXECUTION.contains(forbidden), 969 "publication execution gained forbidden authority {forbidden}" 970 ); 971 } 972 assert!(!ROOT.contains("pub mod publication_execution")); 973 assert!(!PUBLIC_API.contains("rhi::publication_execution::")); 974 let qualification: serde_json::Value = 975 serde_json::from_str(PUBLICATION_WAVE_QUALIFICATION_CONTRACT) 976 .expect("publication-wave qualification contract"); 977 assert_eq!(qualification["step"], 203); 978 assert_eq!(qualification["state_schema_version"], 8); 979 assert_eq!( 980 qualification["invariants"]["production_failpoint_surface"], 981 false 982 ); 983 } 984 985 #[test] 986 fn reconciliation_attestation_is_typed_signed_verified_and_effect_free() { 987 let contract: serde_json::Value = serde_json::from_str(RECONCILIATION_ATTESTATION_CONTRACT) 988 .expect("reconciliation-attestation contract"); 989 assert_eq!( 990 contract["schema"], 991 "radroots.rhi.reconciliation-attestation" 992 ); 993 assert_eq!(contract["contract_version"], 1); 994 assert_eq!(contract["event"]["kind"], 3_441); 995 assert_eq!(contract["effects"]["sqlite"], false); 996 assert_eq!(contract["effects"]["publication"], false); 997 for required in [ 998 "RadrootsRhiEvidenceReportV1::new(", 999 "AuthoredEventBody::from_rhi_evidence_attestation(", 1000 "AuthoredEventPlan::bind(", 1001 "sign_nostr_event(unsigned, auxiliary)", 1002 "Nip01EventWire::parse_json_unverified_with_limits(", 1003 "verify_id(&event)", 1004 "verify(&event)", 1005 "rhi_evidence_attestation_from_event(&event)", 1006 "validate_against_manifest(manifest)", 1007 ] { 1008 assert!( 1009 RECONCILIATION_ATTESTATION.contains(required), 1010 "reconciliation attestation is missing {required}" 1011 ); 1012 } 1013 for forbidden in ["sqlx::", "std::fs", "std::net", "tokio::", "SystemTime"] { 1014 assert!( 1015 !RECONCILIATION_ATTESTATION.contains(forbidden), 1016 "reconciliation attestation gained forbidden authority {forbidden}" 1017 ); 1018 } 1019 assert!(!ROOT.contains("pub mod reconciliation_attestation")); 1020 assert!(!PUBLIC_API.contains("rhi::reconciliation_attestation::")); 1021 } 1022 1023 #[test] 1024 fn reconciliation_commit_is_atomic_bounded_and_sealed() { 1025 let contract: serde_json::Value = serde_json::from_str(RECONCILIATION_COMMIT_CONTRACT) 1026 .expect("reconciliation-commit contract"); 1027 assert_eq!(contract["schema"], "radroots.rhi.reconciliation-commit"); 1028 assert_eq!(contract["contract_version"], 1); 1029 assert_eq!(contract["state_schema_version"], 6); 1030 assert_eq!(contract["effects"]["source_or_relay"], false); 1031 for required in [ 1032 ".take(plan.requests().len().saturating_add(1))", 1033 "validate_exact_lease(transaction, lease)", 1034 "reconcile_existing(transaction, &plan, &parts)", 1035 "SOURCE_INVENTORY_DIGEST_DOMAIN", 1036 "accepted_inventory_sha256", 1037 "advance_dirty_generation(", 1038 "write_checkpoint(", 1039 "committed_cursor_evidence(", 1040 ] { 1041 assert!( 1042 RECONCILIATION_COMMIT.contains(required), 1043 "reconciliation commit is missing {required}" 1044 ); 1045 } 1046 assert!(!ROOT.contains("pub mod reconciliation_commit")); 1047 assert!(!PUBLIC_API.contains("rhi::reconciliation_commit::")); 1048 } 1049 1050 #[test] 1051 fn reconciliation_finalization_is_attempt_bound_nonmutating_and_revalidated() { 1052 let contract: serde_json::Value = serde_json::from_str(RECONCILIATION_FINALIZATION_CONTRACT) 1053 .expect("reconciliation-finalization contract"); 1054 assert_eq!( 1055 contract["schema"], 1056 "radroots.rhi.reconciliation-finalization" 1057 ); 1058 assert_eq!(contract["contract_version"], 1); 1059 assert_eq!(contract["effects"]["sqlite_read"], true); 1060 assert_eq!(contract["effects"]["sqlite_write"], false); 1061 assert_eq!( 1062 contract["durable_validation"]["preflight_is_commit_authority"], 1063 false 1064 ); 1065 for required in [ 1066 "pub async fn prepare_finalization(", 1067 "validate_finalization_fence(", 1068 "validate_exact_lease(transaction, lease)", 1069 "read_dirty(transaction, identity.trade_id)", 1070 "MATCH_COMMITTED_ATTEMPT_SQL", 1071 "attempt_id(job.id(), job.attempt_count())", 1072 ] { 1073 assert!( 1074 RECONCILIATION_FINALIZATION.contains(required), 1075 "reconciliation finalization is missing {required}" 1076 ); 1077 } 1078 for forbidden in [ 1079 "INSERT ", 1080 "UPDATE ", 1081 "DELETE ", 1082 "tokio::spawn", 1083 "SystemTime", 1084 ] { 1085 assert!( 1086 !RECONCILIATION_FINALIZATION.contains(forbidden), 1087 "reconciliation finalization gained forbidden authority {forbidden}" 1088 ); 1089 } 1090 assert!(!ROOT.contains("pub mod reconciliation_finalization")); 1091 assert!(!PUBLIC_API.contains("rhi::reconciliation_finalization::")); 1092 } 1093 1094 #[test] 1095 fn reconciliation_finalization_commit_is_atomic_idempotent_and_effect_bounded() { 1096 let contract: serde_json::Value = 1097 serde_json::from_str(RECONCILIATION_FINALIZATION_COMMIT_CONTRACT) 1098 .expect("reconciliation-finalization-commit contract"); 1099 assert_eq!( 1100 contract["schema"], 1101 "radroots.rhi.reconciliation-finalization-commit" 1102 ); 1103 assert_eq!(contract["contract_version"], 1); 1104 assert_eq!(contract["transaction"]["count"], 1); 1105 assert_eq!(contract["effects"]["network"], false); 1106 for required in [ 1107 "pub async fn commit_finalization(", 1108 "reconcile_existing(transaction, record)", 1109 "validate_finalization_identity(transaction, record.lease, record.identity, record.now)", 1110 "validate_source_inventory(transaction, record)", 1111 "validate_advanced_checkpoints(transaction, record)", 1112 "validate_supersession(transaction, record)", 1113 "COMPLETE_JOB_SQL", 1114 ] { 1115 assert!( 1116 RECONCILIATION_FINALIZATION_COMMIT.contains(required), 1117 "atomic finalization is missing {required}" 1118 ); 1119 } 1120 for forbidden in ["tokio::spawn", "SystemTime", "std::fs", "reqwest"] { 1121 assert!( 1122 !RECONCILIATION_FINALIZATION_COMMIT.contains(forbidden), 1123 "atomic finalization gained forbidden authority {forbidden}" 1124 ); 1125 } 1126 assert!(!ROOT.contains("pub mod reconciliation_finalization_commit")); 1127 assert!(!PUBLIC_API.contains("rhi::reconciliation_finalization_commit::")); 1128 } 1129 1130 #[test] 1131 fn reconciliation_manifest_is_canonical_sealed_and_effect_free() { 1132 let contract: serde_json::Value = serde_json::from_str(RECONCILIATION_MANIFEST_CONTRACT) 1133 .expect("reconciliation-manifest contract"); 1134 assert_eq!(contract["schema"], "radroots.rhi.reconciliation-manifest"); 1135 assert_eq!(contract["contract_version"], 1); 1136 assert_eq!( 1137 contract["construction_authority"], 1138 "confirmed_step_190_commit_outcome_only" 1139 ); 1140 assert_eq!(contract["effects"]["sqlite"], false); 1141 for required in [ 1142 "RadrootsTradeEvidenceManifestV1::new(", 1143 "SOURCE_RESULT_DIGEST_DOMAIN", 1144 "PROVENANCE_DIGEST_DOMAIN", 1145 "committed_inventory_digest(part)", 1146 "pub fn into_evidence_manifest(", 1147 ] { 1148 assert!( 1149 RECONCILIATION_MANIFEST.contains(required), 1150 "reconciliation manifest is missing {required}" 1151 ); 1152 } 1153 for forbidden in ["sqlx::", "std::fs", "std::net", "tokio::", "SystemTime"] { 1154 assert!( 1155 !RECONCILIATION_MANIFEST.contains(forbidden), 1156 "reconciliation manifest gained forbidden authority {forbidden}" 1157 ); 1158 } 1159 assert!(!ROOT.contains("pub mod reconciliation_manifest")); 1160 assert!(!PUBLIC_API.contains("rhi::reconciliation_manifest::")); 1161 } 1162 1163 #[test] 1164 fn reconciliation_reducer_is_manifest_bound_sealed_and_effect_free() { 1165 let contract: serde_json::Value = serde_json::from_str(RECONCILIATION_REDUCER_CONTRACT) 1166 .expect("reconciliation-reducer contract"); 1167 assert_eq!(contract["schema"], "radroots.rhi.reconciliation-reducer"); 1168 assert_eq!(contract["contract_version"], 1); 1169 assert_eq!(contract["input"]["maximum_mutations"], 65_536); 1170 assert_eq!( 1171 contract["input"]["maximum_canonical_content_bytes"], 1172 134_217_728 1173 ); 1174 assert_eq!(contract["effects"]["sqlite"], false); 1175 for required in [ 1176 "trade_mutation_from_canonical_content", 1177 "reduce_trade_records(input)", 1178 "PROJECTION_DIGEST_DOMAIN", 1179 "manifest.digest()", 1180 "inner.evidence_policy_digest()", 1181 "pub fn reduce_rhi_reconciliation_manifest(", 1182 "RHI_REDUCER_MAXIMUM_MUTATION_MATERIAL_BYTES", 1183 ] { 1184 assert!( 1185 RECONCILIATION_REDUCER.contains(required), 1186 "reconciliation reducer is missing {required}" 1187 ); 1188 } 1189 for forbidden in ["sqlx::", "std::fs", "std::net", "tokio::", "SystemTime"] { 1190 assert!( 1191 !RECONCILIATION_REDUCER.contains(forbidden), 1192 "reconciliation reducer gained forbidden authority {forbidden}" 1193 ); 1194 } 1195 assert!(!ROOT.contains("pub mod reconciliation_reducer")); 1196 assert!(!PUBLIC_API.contains("rhi::reconciliation_reducer::")); 1197 assert!(!PUBLIC_API.contains("RhiReconciliationProjection::shared_projection(&self)")); 1198 } 1199 1200 #[test] 1201 fn reconciliation_outcome_is_projection_bound_total_and_effect_free() { 1202 let contract: serde_json::Value = serde_json::from_str(RECONCILIATION_OUTCOME_CONTRACT) 1203 .expect("reconciliation-outcome contract"); 1204 assert_eq!(contract["schema"], "radroots.rhi.reconciliation-outcome"); 1205 assert_eq!(contract["contract_version"], 1); 1206 assert_eq!(contract["coverage"].as_array().expect("coverage").len(), 4); 1207 assert_eq!(contract["outcome"].as_array().expect("outcome").len(), 3); 1208 assert_eq!(contract["reason_inventory"]["cardinality"], 1); 1209 assert_eq!(contract["effects"]["sqlite"], false); 1210 for required in [ 1211 "pub fn evaluate_rhi_reconciliation_claim(", 1212 "RhiReconciliationEvaluation", 1213 "RhiReconciliationReasonCode", 1214 "classify_evaluation(facts)", 1215 "projection: RhiReconciliationProjection", 1216 "claim_mutation_id: MutationId", 1217 ] { 1218 assert!( 1219 RECONCILIATION_REDUCER.contains(required), 1220 "reconciliation outcome is missing {required}" 1221 ); 1222 } 1223 for forbidden in [ 1224 "sqlx::", 1225 "std::fs", 1226 "std::net", 1227 "tokio::", 1228 "SystemTime", 1229 "caller_supplied_outcome", 1230 ] { 1231 assert!( 1232 !RECONCILIATION_REDUCER.contains(forbidden), 1233 "reconciliation outcome gained forbidden authority {forbidden}" 1234 ); 1235 } 1236 assert!(!PUBLIC_API.contains("rhi::reconciliation_reducer::")); 1237 assert!(!PUBLIC_API.contains("RhiReconciliationEvaluation {")); 1238 } 1239 1240 #[test] 1241 fn public_errors_are_crate_owned_redacted_and_source_free() { 1242 let production = SOURCES.join("\n"); 1243 assert!(!production.contains("fn source(")); 1244 for forbidden in [ 1245 "source: std::io::Error", 1246 "source: sqlx::Error", 1247 "source: serde_json::Error", 1248 "source: toml::de::Error", 1249 "source: url::ParseError", 1250 ] { 1251 assert!( 1252 !production.contains(forbidden), 1253 "raw error source `{forbidden}` escaped" 1254 ); 1255 } 1256 for forbidden in [ 1257 "serde_json::Error", 1258 "radroots_event::trade::TradeProtocolError", 1259 "sqlx::Error", 1260 "std::io::Error", 1261 "thiserror::", 1262 ] { 1263 assert!( 1264 !PUBLIC_API.contains(forbidden), 1265 "reviewed API exposes dependency error `{forbidden}`" 1266 ); 1267 } 1268 let public_error_count = PUBLIC_API 1269 .lines() 1270 .filter(|line| line.starts_with("pub struct rhi::") && line.ends_with("Error")) 1271 .count(); 1272 assert_eq!(public_error_count, 39); 1273 } 1274 1275 #[test] 1276 fn failure_qualification_is_source_locked_bounded_and_nonexpansive() { 1277 let contract: serde_json::Value = serde_json::from_str(FAILURE_QUALIFICATION_CONTRACT) 1278 .expect("failure qualification contract"); 1279 assert_eq!(contract["schema"], "radroots.rhi.failure-qualification.v1"); 1280 assert_eq!(contract["step"], 214); 1281 assert_eq!(contract["service"], "rhi"); 1282 assert_eq!( 1283 contract["source_lock"]["lib_revision"], 1284 "053d0c750bf9cd683c6ea37cefe7e79617ba629f" 1285 ); 1286 assert_eq!(contract["resource_bounds"]["source_result_events"], 4_096); 1287 assert_eq!( 1288 contract["resource_bounds"]["source_result_bytes"], 1289 8_388_608 1290 ); 1291 assert_eq!(contract["resource_bounds"]["reconciliation_queue"], 65_536); 1292 assert_eq!(contract["resource_bounds"]["publication_queue"], 65_536); 1293 assert_eq!(contract["invariants"]["malformed_history_repaired"], false); 1294 assert_eq!( 1295 contract["invariants"]["sqlx_is_only_high_level_sqlite_authority"], 1296 true 1297 ); 1298 assert_eq!( 1299 contract["invariants"]["production_failpoint_surface"], 1300 false 1301 ); 1302 } 1303 1304 #[test] 1305 fn process_qualification_is_actual_bounded_and_wave_closed() { 1306 let contract: serde_json::Value = serde_json::from_str(PROCESS_QUALIFICATION_CONTRACT) 1307 .expect("process qualification contract"); 1308 assert_eq!(contract["schema"], "radroots.rhi.process-qualification.v1"); 1309 assert_eq!(contract["step"], 215); 1310 assert_eq!(contract["service"], "rhi"); 1311 assert_eq!(contract["binary"], "rhi"); 1312 assert_eq!(contract["bounds"]["parallel_inspection_processes"], 8); 1313 assert_eq!(contract["bounds"]["soak_iterations"], 32); 1314 assert_eq!( 1315 contract["component_qualification"]["sha256"], 1316 "f05da8e559f463f99c67c3c7e22eafa57935be91fb0094f2aa2f98a58544b8b9" 1317 ); 1318 assert_eq!(contract["invariants"]["actual_executable_required"], true); 1319 assert_eq!( 1320 contract["invariants"]["production_failpoint_surface"], 1321 false 1322 ); 1323 assert_eq!(contract["invariants"]["test_environment_selector"], false); 1324 for name in contract["actual_process_corpus"] 1325 .as_array() 1326 .expect("actual process corpus") 1327 { 1328 let name = name.as_str().expect("process test name"); 1329 assert!( 1330 PROCESS_QUALIFICATION_TESTS.contains(&format!("fn {name}(")), 1331 "missing actual-process test {name}" 1332 ); 1333 } 1334 for forbidden in ["RHI_TEST_", "RADROOTS_TEST_", "FAILPOINT"] { 1335 assert!(!MAIN.contains(forbidden)); 1336 assert!(!RUNTIME_GRAPH.contains(forbidden)); 1337 } 1338 assert!(!PROCESS_QUALIFICATION_TESTS.contains("std::env::var")); 1339 } 1340 1341 #[test] 1342 fn reconciliation_attempts_are_exact_bounded_and_effect_free() { 1343 let contract: serde_json::Value = serde_json::from_str(RECONCILIATION_ATTEMPT_CONTRACT) 1344 .expect("reconciliation-attempt contract"); 1345 assert_eq!(contract["schema"], "radroots.rhi.reconciliation-attempts"); 1346 assert_eq!(contract["contract_version"], 1); 1347 assert_eq!(contract["state_schema_version"], 5); 1348 assert_eq!(contract["plan"]["source_count_maximum"], 16); 1349 assert_eq!(contract["plan"]["result_event_maximum"], 4_096); 1350 assert_eq!( 1351 contract["plan"]["result_original_event_bytes_maximum"], 1352 8_388_608 1353 ); 1354 assert_eq!( 1355 contract["result"]["inventory_ingestion_bound"], 1356 "configured_source_count_plus_one" 1357 ); 1358 assert_eq!(contract["effects"]["sqlite"], false); 1359 assert_eq!(contract["effects"]["source_or_relay"], false); 1360 for required in [ 1361 "state_metadata::evidence_policy_digest(normalized)", 1362 ".take(plan.requests.len().saturating_add(1))", 1363 "RhiTradeSourceCompletion::IncompleteTimeout", 1364 "RhiReconciliationSourceSelectorDigest", 1365 ] { 1366 assert!( 1367 RECONCILIATION_ATTEMPTS.contains(required), 1368 "attempt boundary is missing {required}" 1369 ); 1370 } 1371 for forbidden in [ 1372 "sqlx::", 1373 "std::fs", 1374 "std::net", 1375 "tokio::", 1376 "SystemTime", 1377 "thread_rng", 1378 "OsRng", 1379 "RhiTradeSourceCursor", 1380 ] { 1381 assert!( 1382 !RECONCILIATION_ATTEMPTS.contains(forbidden), 1383 "attempt boundary gained forbidden authority {forbidden}" 1384 ); 1385 } 1386 assert!(!ROOT.contains("pub mod reconciliation_attempt")); 1387 assert!(!PUBLIC_API.contains("rhi::reconciliation_attempt::")); 1388 } 1389 1390 #[test] 1391 fn reconciliation_replay_is_overlap_safe_bounded_and_effect_free() { 1392 let contract: serde_json::Value = serde_json::from_str(RECONCILIATION_REPLAY_CONTRACT) 1393 .expect("reconciliation-replay contract"); 1394 assert_eq!(contract["schema"], "radroots.rhi.reconciliation-replay"); 1395 assert_eq!(contract["contract_version"], 1); 1396 assert_eq!(contract["state_schema_version"], 5); 1397 assert_eq!(contract["cursor"]["equal_timestamp_safe"], true); 1398 assert_eq!( 1399 contract["cursor"]["input"], 1400 "sealed_step_190_committed_cursor_evidence" 1401 ); 1402 assert_eq!( 1403 contract["cursor"]["eligible_only_for"], 1404 "complete_and_strictly_after_prior_cursor" 1405 ); 1406 assert_eq!( 1407 contract["inventory"]["input_ingestion_bound"], 1408 "request_maximum_events_plus_one" 1409 ); 1410 assert_eq!( 1411 contract["inventory"]["first_provenance"], 1412 "earliest_injected_observation_time_retained" 1413 ); 1414 assert_eq!(contract["effects"]["sqlite"], false); 1415 assert_eq!(contract["effects"]["source_or_relay"], false); 1416 for required in [ 1417 ".take(maximum_events.saturating_add(1))", 1418 "saturating_sub(overlap_seconds)", 1419 "RhiReconciliationReplayErrorKind::MutationConflict", 1420 "RhiReconciliationReplayErrorKind::SignedEventConflict", 1421 "RhiReconciliationSourceCursorEvidence", 1422 "cursor_scope_matches(", 1423 ] { 1424 assert!( 1425 RECONCILIATION_REPLAY.contains(required), 1426 "replay boundary is missing {required}" 1427 ); 1428 } 1429 for forbidden in [ 1430 "sqlx::", 1431 "std::fs", 1432 "std::net", 1433 "tokio::", 1434 "SystemTime", 1435 "thread_rng", 1436 "OsRng", 1437 ] { 1438 assert!( 1439 !RECONCILIATION_REPLAY.contains(forbidden), 1440 "replay boundary gained forbidden authority {forbidden}" 1441 ); 1442 } 1443 assert!(!ROOT.contains("pub mod reconciliation_replay")); 1444 assert!(!PUBLIC_API.contains("rhi::reconciliation_replay::")); 1445 } 1446 1447 #[test] 1448 fn trade_source_ingest_is_exact_bounded_generation_fenced_and_sealed() { 1449 let contract: serde_json::Value = 1450 serde_json::from_str(TRADE_SOURCE_INGEST_CONTRACT).expect("trade-source ingest contract"); 1451 assert_eq!(contract["schema"], "radroots.rhi.trade-source-ingest.v1"); 1452 assert_eq!(contract["contract_version"], 1); 1453 assert_eq!(contract["source"]["kind"], "nostr_relay"); 1454 assert_eq!( 1455 contract["source"]["selector"]["kinds"], 1456 serde_json::json!([3470, 3471, 3472, 3473, 3474]) 1457 ); 1458 assert_eq!(contract["source"]["selector"]["exact_tag"], "#d"); 1459 assert_eq!(contract["source"]["page_events_maximum"], 1_000); 1460 assert_eq!(contract["source"]["result_events_maximum"], 4_096); 1461 assert_eq!( 1462 contract["source"]["result_original_event_bytes_maximum"], 1463 8_388_608 1464 ); 1465 assert_eq!( 1466 contract["completion"]["complete"], 1467 "exact_target_eose_before_deadline" 1468 ); 1469 assert_eq!( 1470 contract["admission"]["deduplicate_by"], 1471 serde_json::json!(["verified_event_id", "verified_event_signature"]) 1472 ); 1473 assert_eq!( 1474 contract["checkpoint"]["scope"], 1475 serde_json::json!([ 1476 "source_id", 1477 "selector_id", 1478 "evidence_policy_sha256", 1479 "trade_id" 1480 ]) 1481 ); 1482 assert_eq!(contract["checkpoint"]["equal_timestamp_safe"], true); 1483 assert_eq!( 1484 contract["dirty_generation"]["do_not_advance_when"], 1485 serde_json::json!([ 1486 "rejected_event", 1487 "duplicate_event", 1488 "repeated_source_observation", 1489 "operational_retry" 1490 ]) 1491 ); 1492 assert_eq!( 1493 contract["transaction"]["source_fetch_inside_transaction"], 1494 false 1495 ); 1496 1497 let source = include_str!("../src/source_ingest.rs"); 1498 for required in [ 1499 "with_kinds(EVENT_KINDS.to_vec())", 1500 "with_exact_tag_value('d', trade_id.to_hex())", 1501 "with_since_unix_seconds(since)", 1502 "admit_rhi_trade_mutation_event(", 1503 "read_checkpoint(transaction", 1504 "read_dirty(transaction", 1505 "compare_cursor(current.cursor, candidate).is_lt()", 1506 "new_relevant_evidence", 1507 ] { 1508 assert!( 1509 source.contains(required), 1510 "source ingest is missing {required}" 1511 ); 1512 } 1513 for forbidden in [ 1514 "pub fn host(", 1515 "pub fn sqlite_host(", 1516 "SystemTime", 1517 "std::fs", 1518 "std::net", 1519 "tokio::spawn", 1520 ] { 1521 assert!( 1522 !source.contains(forbidden), 1523 "source ingest gained forbidden authority {forbidden}" 1524 ); 1525 } 1526 assert!(!ROOT.contains("pub mod source_ingest")); 1527 assert!(!PUBLIC_API.contains("rhi::source_ingest::")); 1528 } 1529 1530 #[test] 1531 fn trade_ingest_is_sealed_bounded_verified_and_effect_free() { 1532 let contract: serde_json::Value = 1533 serde_json::from_str(TRADE_INGEST_CONTRACT).expect("trade-ingest contract"); 1534 assert_eq!(contract["schema"], "radroots.rhi.trade-ingest.v1"); 1535 assert_eq!(contract["contract_version"], 1); 1536 assert_eq!(contract["wire"]["original_wire_cap_before_parse"], true); 1537 assert_eq!(contract["wire"]["duplicate_fields"], "reject"); 1538 assert_eq!(contract["authored_time"]["default"], "none"); 1539 assert_eq!(contract["verification"]["event_id"], "recomputed_and_exact"); 1540 assert_eq!( 1541 contract["verification"]["signature"], 1542 "bip340_schnorr_verified" 1543 ); 1544 assert_eq!(contract["effects"]["filesystem"], false); 1545 assert_eq!(contract["effects"]["sqlite"], false); 1546 assert_eq!(contract["effects"]["network"], false); 1547 assert_eq!( 1548 contract["persistence_contract"], 1549 "contracts/services_hardening/trade_evidence_persistence.v1.json" 1550 ); 1551 1552 let source = include_str!("../src/trade_ingest.rs"); 1553 for required in [ 1554 "preflight_wire(source, limits)?", 1555 "verify_id(&event)", 1556 "verify(&event)", 1557 "trade_mutation_from_event(&event)", 1558 "original: original.into()", 1559 ] { 1560 assert!( 1561 source.contains(required), 1562 "trade ingest is missing {required}" 1563 ); 1564 } 1565 for forbidden in [ 1566 "sqlx::", 1567 "std::fs", 1568 "std::net", 1569 "tokio::", 1570 "SystemTime", 1571 "process::", 1572 ] { 1573 assert!( 1574 !source.contains(forbidden), 1575 "trade ingest gained effect authority {forbidden}" 1576 ); 1577 } 1578 assert!(!ROOT.contains("pub mod trade_ingest")); 1579 assert!(!PUBLIC_API.contains("rhi::trade_ingest::")); 1580 } 1581 1582 #[test] 1583 fn trade_evidence_persistence_is_typed_atomic_and_sealed() { 1584 let contract: serde_json::Value = serde_json::from_str(TRADE_EVIDENCE_PERSISTENCE_CONTRACT) 1585 .expect("trade-evidence persistence contract"); 1586 assert_eq!( 1587 contract["schema"], 1588 "radroots.rhi.trade-evidence-persistence.v1" 1589 ); 1590 assert_eq!(contract["contract_version"], 1); 1591 assert_eq!(contract["transaction"], "one_governed_sqlx_transaction"); 1592 assert_eq!(contract["effects"]["checkpoint"], false); 1593 assert_eq!(contract["effects"]["dirty_generation"], false); 1594 assert_eq!( 1595 contract["facts"]["signed_event"]["identity"], 1596 serde_json::json!(["verified_event_id", "verified_event_signature"]) 1597 ); 1598 1599 let source = include_str!("../src/state_trade.rs"); 1600 for required in [ 1601 "pub async fn persist_trade_evidence", 1602 "RhiAdmittedTradeMutationEvent", 1603 "RhiTradeSourceObservation", 1604 ".transaction(move |transaction|", 1605 "ON CONFLICT (event_id, event_signature) DO NOTHING", 1606 ] { 1607 assert!( 1608 source.contains(required), 1609 "trade evidence persistence is missing {required}" 1610 ); 1611 } 1612 for forbidden in [ 1613 "pub fn host(", 1614 "pub fn into_parts(", 1615 "pub fn event_signature_bytes(", 1616 "SystemTime", 1617 "std::fs", 1618 "std::net", 1619 "checkpoint", 1620 "dirty_generation", 1621 ] { 1622 assert!( 1623 !source.contains(forbidden), 1624 "trade evidence persistence gained forbidden authority {forbidden}" 1625 ); 1626 } 1627 assert!(!ROOT.contains("pub mod state_trade")); 1628 assert!(!PUBLIC_API.contains("rhi::state_trade::")); 1629 assert!(!PUBLIC_API.contains("sqlx::")); 1630 } 1631 1632 #[test] 1633 fn runtime_foundation_is_existing_only_passive_and_process_neutral() { 1634 let contract: serde_json::Value = 1635 serde_json::from_str(RUNTIME_FOUNDATION_CONTRACT).expect("runtime foundation contract"); 1636 assert_eq!(contract["schema"], "radroots.rhi.runtime-foundation"); 1637 assert_eq!(contract["schema_version"], 1); 1638 assert_eq!(contract["state_open"]["initialize_if_missing"], false); 1639 assert_eq!( 1640 contract["state_open"]["durable_configuration_binding_required"], 1641 true 1642 ); 1643 assert_eq!(contract["transport"]["invoked_during_foundation"], false); 1644 assert_eq!(contract["task_ownership"]["task_handles_exposed"], false); 1645 for required in [ 1646 "open_rhi_state_read_write_from_config", 1647 "RhiIdentityEnvelopeBinding::from_configuration", 1648 ".identity_credential()", 1649 "startup_readiness(&configuration)", 1650 ] { 1651 assert!(RUNTIME_FOUNDATION.contains(required)); 1652 } 1653 for forbidden in [ 1654 "tokio::runtime", 1655 "tokio::signal", 1656 "signal_hook", 1657 "tracing_subscriber", 1658 "std::process::exit", 1659 ".fetch(", 1660 ".subscribe(", 1661 ".deliver(", 1662 ] { 1663 assert!(!RUNTIME_FOUNDATION.contains(forbidden)); 1664 } 1665 } 1666 1667 #[test] 1668 fn runtime_adapter_boundary_is_exact_bounded_and_process_neutral() { 1669 let contract: serde_json::Value = 1670 serde_json::from_str(RUNTIME_ADAPTER_CONTRACT).expect("runtime adapter contract"); 1671 assert_eq!(contract["schema"], "radroots.rhi.runtime-adapters"); 1672 assert_eq!(contract["schema_version"], 1); 1673 assert_eq!(contract["contract_version"], 1); 1674 assert_eq!(contract["jitter"]["inclusive_maximum"], 3_600_000); 1675 assert_eq!(contract["jitter"]["maximum_entropy_draws"], 16); 1676 assert_eq!(contract["jitter"]["wall_clock_derived"], false); 1677 assert_eq!(contract["transport"]["evidence_fetch"], "EventSource"); 1678 assert_eq!( 1679 contract["transport"]["evidence_subscription"], 1680 "EventSubscriber" 1681 ); 1682 assert_eq!(contract["transport"]["publication"], "EventSink"); 1683 assert_eq!( 1684 contract["identity"]["order"], 1685 serde_json::json!(["credential", "encrypted_identity"]) 1686 ); 1687 assert_eq!(contract["identity"]["fallback"], false); 1688 assert_eq!(contract["identity"]["generation"], false); 1689 assert_eq!(contract["tasks"]["join_owned"], true); 1690 assert_eq!(contract["tasks"]["handles_exposed"], false); 1691 1692 for required in [ 1693 "Arc<dyn WallClock>", 1694 "Arc<dyn MonotonicClock>", 1695 "Arc<dyn EntropySource>", 1696 "Arc<dyn EventSource>", 1697 "Arc<dyn EventSubscriber>", 1698 "Arc<dyn EventSink>", 1699 "TaskSupervisor", 1700 "RHI_RUNTIME_JITTER_MAX_MILLISECONDS: u64 = 3_600_000", 1701 "RHI_RUNTIME_JITTER_MAX_ENTROPY_DRAWS: usize = 16", 1702 "u128::from(u64::from_be_bytes(bytes)) * u128::from(range)", 1703 "low >= rejection_threshold", 1704 "resolve_rhi_wrapping_credential(runtime, binding)", 1705 "open_rhi_encrypted_identity(binding, credential)", 1706 ] { 1707 assert!( 1708 RUNTIME_ADAPTERS.contains(required), 1709 "runtime adapter boundary is missing {required}" 1710 ); 1711 } 1712 for forbidden in [ 1713 "tokio::runtime::Runtime", 1714 "tokio::runtime::Builder", 1715 "tokio::signal", 1716 "signal_hook", 1717 "tracing_subscriber", 1718 "std::process::exit", 1719 "tokio::spawn", 1720 "std::thread::spawn", 1721 "SystemTime::now", 1722 "subsec_nanos", 1723 "rand::", 1724 ] { 1725 assert!( 1726 !RUNTIME_ADAPTERS.contains(forbidden), 1727 "runtime adapter boundary contains forbidden authority {forbidden}" 1728 ); 1729 } 1730 assert!(MANIFEST.contains("radroots_transport =")); 1731 assert!(MANIFEST.contains("default-features = false, features = [\"std\"]")); 1732 } 1733 1734 #[test] 1735 fn readme_freezes_the_root_only_boundary_and_exact_baseline() { 1736 for required in [ 1737 "## Public API boundary", 1738 "one curated crate-root API", 1739 "public errors use RHI-owned stable classifications", 1740 "shared clock and entropy traits and their source-free error values", 1741 "failures into stable RHI classifications", 1742 "```compile_fail", 1743 "[RHI API baseline](contracts/api_baselines/rhi.txt)", 1744 "[`trade_ingest.v1.json`](contracts/services_hardening/trade_ingest.v1.json)", 1745 "[`trade_evidence_persistence.v1.json`](contracts/services_hardening/trade_evidence_persistence.v1.json)", 1746 "## Bounded relay-source ingestion", 1747 "[`trade_source_ingest.v1.json`](contracts/services_hardening/trade_source_ingest.v1.json)", 1748 "## Durable reconciliation jobs", 1749 "[`reconciliation_jobs.v1.json`](contracts/services_hardening/reconciliation_jobs.v1.json)", 1750 "## Bounded reconciliation source attempts", 1751 "[`reconciliation_attempts.v1.json`](contracts/services_hardening/reconciliation_attempts.v1.json)", 1752 "## Overlap-safe reconciliation replay", 1753 "[`reconciliation_replay.v1.json`](contracts/services_hardening/reconciliation_replay.v1.json)", 1754 "## Atomic reconciliation result commit", 1755 "[`reconciliation_commit.v1.json`](contracts/services_hardening/reconciliation_commit.v1.json)", 1756 "## Immutable reconciliation manifest", 1757 "[`reconciliation_manifest.v1.json`](contracts/services_hardening/reconciliation_manifest.v1.json)", 1758 "## Pure reconciliation reducer", 1759 "[`reconciliation_reducer.v1.json`](contracts/services_hardening/reconciliation_reducer.v1.json)", 1760 "binds the promoted shared `radroots.trade.reducer.v1`", 1761 "[`reconciliation_outcome.v1.json`](contracts/services_hardening/reconciliation_outcome.v1.json)", 1762 "## Generation-fenced finalization preflight", 1763 "[`reconciliation_finalization.v1.json`](contracts/services_hardening/reconciliation_finalization.v1.json)", 1764 "Step 199 must rerun the same validator inside the final", 1765 "## Atomic reconciliation finalization commit", 1766 "[`reconciliation_finalization_commit.v1.json`](contracts/services_hardening/reconciliation_finalization_commit.v1.json)", 1767 "An exact retry returns", 1768 "Disabled publication creates no outbox or target row", 1769 "## Canonical signed reconciliation attestation", 1770 "[`reconciliation_attestation.v1.json`](contracts/services_hardening/reconciliation_attestation.v1.json)", 1771 "## Explicit publication authority and durable schema", 1772 "## Deterministic durable presence intent", 1773 "[`presence_desired_state.v1.json`](contracts/services_hardening/presence_desired_state.v1.json)", 1774 "## Durable exact-byte presence publication", 1775 "[`presence_publication.v1.json`](contracts/services_hardening/presence_publication.v1.json)", 1776 "Expired work from a", 1777 "superseded desired generation is recorded as `unknown`", 1778 "unknown commit result can be reconciled by replaying the same retained bytes", 1779 "[`publication_outbox.v1.json`](contracts/services_hardening/publication_outbox.v1.json)", 1780 "## Bounded publication attempt evidence", 1781 "[`publication_attempt_evidence.v1.json`](contracts/services_hardening/publication_attempt_evidence.v1.json)", 1782 "## Durable exact-byte publication execution", 1783 "[`publication_execution.v1.json`](contracts/services_hardening/publication_execution.v1.json)", 1784 "[`publication_wave_qualification.v1.json`](contracts/services_hardening/publication_wave_qualification.v1.json)", 1785 "The event body and exact kind-3441 structural tags", 1786 "without rebuilding, reserializing, or", 1787 "Coverage is exactly `Missing`, `Partial`, `ScopeSatisfied`, or `Unsupported`", 1788 "Missing, partial, unsupported,", 1789 "The Step 192 integration-wave qualification proves that concurrent exact", 1790 "lost-success retry converges after close/reopen", 1791 "inventory terminates at configured source count plus one before mutation", 1792 "configured queue capacity is enforced beneath a fixed 65,536-job", 1793 "from an unexpired claimed job lease", 1794 "can be omitted, duplicated, reordered, or appended beyond", 1795 "Planning and result validation are pure and perform no", 1796 "SQLite, source, relay, network, filesystem, task, clock, or entropy operation", 1797 "No ambient clock or entropy is read", 1798 "Only exact-target EOSE before the deadline is complete", 1799 "4,096 distinct signed-event identities (event ID plus signature) and 8 MiB", 1800 "observation, and operational retry do not", 1801 "schema-v6 immutable", 1802 "schema-v7 immutable report, signed-event,", 1803 "The schema-v7", 1804 "catalog is frozen by Step 198", 1805 "one canonical mutation", 1806 "every distinct valid signed", 1807 "does not advance reconciliation checkpoints or dirty generation", 1808 "## Injected runtime adapters", 1809 "whole-second wall UTC", 1810 "process-local monotonic time", 1811 "exact v1 maximum of 3,600,000", 1812 "fails closed after sixteen rejected entropy draws", 1813 "never derived from wall-clock", 1814 "Constructing the adapter set performs no clock read", 1815 "no signal handler, Tokio runtime, logger, or process-exit policy", 1816 "[`runtime_adapters.v1.json`](contracts/services_hardening/runtime_adapters.v1.json)", 1817 "## Existing-state runtime foundation", 1818 "opens only an already initialized database", 1819 "No evidence source, live subscription, or publication sink is", 1820 "[`runtime_foundation.v1.json`](contracts/services_hardening/runtime_foundation.v1.json)", 1821 "at most 1,024 consecutive generations", 1822 "never stores raw TOML, paths, relay URLs, credential", 1823 "## Unix-admin boundary", 1824 "seven common RHI routes", 1825 "thirteen reconciliation, job, source", 1826 "cursors use canonical base64url without padding", 1827 "Step 208 removes the two never-registered live identity rekey/replace routes", 1828 "20-route/33-model inventory", 1829 "[`admin_common.v1.json`](contracts/services_hardening/admin_common.v1.json)", 1830 "[`admin_domain.v1.json`](contracts/services_hardening/admin_domain.v1.json)", 1831 "[`admin_identity_offline.v1.json`](contracts/services_hardening/admin_identity_offline.v1.json)", 1832 "[`admin_wave_qualification.v1.json`](contracts/services_hardening/admin_wave_qualification.v1.json)", 1833 "## Bounded active doctor and stable process results", 1834 "governed fifteen checks in exact contract order", 1835 "Required failure or timeout returns exit code `6`", 1836 "no\ndetached probe work is permitted", 1837 ] { 1838 assert!(README.contains(required), "README is missing {required}"); 1839 } 1840 for forbidden in [ 1841 "SystemTime", 1842 "thread_rng", 1843 "OsRng", 1844 "pub mod reconciliation_job", 1845 ] { 1846 assert!( 1847 !RECONCILIATION_JOBS.contains(forbidden), 1848 "reconciliation jobs expose forbidden authority {forbidden}" 1849 ); 1850 } 1851 for required in [ 1852 "Keep every implementation module private", 1853 "contracts/api_baselines/rhi.txt", 1854 "Public errors must use RHI-owned stable classifications", 1855 "no raw dependency-owned source chain", 1856 "Compose those dependencies only through the sealed runtime-adapter boundary", 1857 "exposes no task handle or concrete transport handle", 1858 "admit_rhi_trade_mutation_event", 1859 "Persist each canonical", 1860 "independently signed Nostr event", 1861 "Commit a signed finalization only through the sealed attempt repository", 1862 "Build service-profile and application-handler presence only through the", 1863 "Preserve the\n caller's sealed exact-byte capability", 1864 "Recover an expired stale", 1865 "Step 211 freezes the exact fifteen-check doctor inventory", 1866 ] { 1867 assert!(AGENTS.contains(required), "AGENTS is missing {required}"); 1868 } 1869 } 1870 1871 #[test] 1872 fn human_verification_contract_routes_checks_and_records_nix_outputs() { 1873 for required in [ 1874 "cargo extbuild doctor", 1875 "cargo extbuild run -- cargo fmt --all --check", 1876 "cargo extbuild run -- cargo check --workspace --all-targets --locked", 1877 "cargo extbuild run -- cargo test --workspace --all-targets --locked", 1878 "cargo extbuild run -- cargo clippy --workspace --all-targets --locked -- -D warnings", 1879 "The flake exposes the RHI package, application, checks, and development shell", 1880 "unsigned OCI\nderivation for `x86_64-linux`", 1881 ] { 1882 assert!(README.contains(required), "README is missing {required}"); 1883 } 1884 for forbidden in ["nix run", "nix develop", "nix build", "nix flake"] { 1885 assert!( 1886 !README.contains(forbidden), 1887 "README retains forbidden active Nix command {forbidden}" 1888 ); 1889 } 1890 }