lib

Core libraries for Radroots
git clone https://radroots.dev/git/lib.git
Log | Files | Refs | README

commit 1e7dfb72bb40648d84cb33245a898a26cdd8186f
parent 99bc178f53b7dea0d5b839141e7d77fc988dd718
Author: triesap <tyson@radroots.org>
Date:   Mon, 10 Aug 2026 21:04:16 +0000

contracts: reserve service event decisions

- Reserve a collision-free immutable RHI attestation kind and exact digest contract.
- Freeze trade mutation tag cardinality and filter semantics across all five kinds.
- Add deterministic positive and negative conformance decision vectors.
- Verify decision and registry separation with targeted tests and contract validation.

Diffstat:
MAGENTS.md | 5+++++
Acontracts/architecture/decisions/services_hardening_events.v1.json | 118+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Acontracts/conformance/vectors/rhi/evidence_attestation_decision.v1.json | 153+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Acontracts/conformance/vectors/trade/mutation_index_tags_decision.v1.json | 147+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Acrates/event_codec/tests/services_hardening_event_decisions.rs | 256+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 679 insertions(+), 0 deletions(-)

diff --git a/AGENTS.md b/AGENTS.md @@ -22,6 +22,11 @@ This file exists for compatibility with tools that look for AGENTS.md. specifications, decisions, runbooks, and qualification evidence belong under the parent monorepo's `docs/oss/lib/**` authority and must never become a standalone build, test, package, or release input. +- The pre-implementation service-event reservation is + `contracts/architecture/decisions/services_hardening_events.v1.json`. + Service-event source, registry, generated, and consumer work must implement + that exact kind, tag, cardinality, query, and supersession contract; it may + not reinterpret the reservation from current prototype wire behavior. - Current source and tests are implementation evidence. They do not silently override `radroots.crates.release.v1`. - Record any evidence-based plan deviation in diff --git a/contracts/architecture/decisions/services_hardening_events.v1.json b/contracts/architecture/decisions/services_hardening_events.v1.json @@ -0,0 +1,118 @@ +{ + "schema": "radroots.services-hardening.event-decisions.v1", + "contract_version": 1, + "decision_state": "reserved_preimplementation", + "trade_mutation": { + "contract_family": "radroots.trade.mutation-index.v1", + "event_class": "regular_immutable", + "event_kinds": [ + { "mutation_type": "proposal", "kind": 3470, "contract_id": "radroots.trade.proposal.v1" }, + { "mutation_type": "decision", "kind": 3471, "contract_id": "radroots.trade.decision.v1" }, + { "mutation_type": "revision_proposal", "kind": 3472, "contract_id": "radroots.trade.revision_proposal.v1" }, + { "mutation_type": "revision_decision", "kind": 3473, "contract_id": "radroots.trade.revision_decision.v1" }, + { "mutation_type": "cancellation", "kind": 3474, "contract_id": "radroots.trade.cancellation.v1" } + ], + "canonical_tag_order": [ + "contract", + "d:trade", + "x:mutation", + "x:root", + "x:parent_sorted", + "p:buyer", + "p:seller" + ], + "tags": [ + { "name": "contract", "marker": "", "cardinality": "exactly_one", "value": "content_contract_id", "relay_filter": "none" }, + { "name": "d", "marker": "", "cardinality": "exactly_one", "value": "trade_id_lower_hex_32", "relay_filter": "#d" }, + { "name": "x", "marker": "mutation", "cardinality": "exactly_one", "value": "mutation_id_lower_hex_64", "relay_filter": "#x" }, + { "name": "x", "marker": "root", "cardinality": "proposal_zero_other_mutations_exactly_one", "value": "root_mutation_id_lower_hex_64", "relay_filter": "#x" }, + { "name": "x", "marker": "parent", "cardinality": "proposal_zero_other_mutations_one_to_four_sorted_unique", "value": "parent_mutation_id_lower_hex_64", "relay_filter": "#x" }, + { "name": "p", "marker": "", "cardinality": "first_of_exactly_two", "value": "buyer_pubkey_lower_hex_64", "relay_filter": "#p" }, + { "name": "p", "marker": "", "cardinality": "second_of_exactly_two", "value": "seller_pubkey_lower_hex_64", "relay_filter": "#p" } + ], + "filter_contract": { + "trade_id": "kind plus #d", + "mutation_id": "kind plus #x followed by marker verification", + "root_mutation_id": "kind plus #x followed by marker verification", + "party_pubkey": "kind plus #p followed by exact ordered buyer-first and seller-second comparison against canonical content" + }, + "validation": { + "structural_tags_are_derived": true, + "unknown_structural_marker_rejected": true, + "duplicate_or_conflicting_structural_tag_rejected": true, + "caller_structural_tags_forbidden": true, + "legacy_contract_d_p_e_shape_accepted": false + } + }, + "rhi_attestation": { + "contract_id": "radroots.rhi.evidence_attestation.v1", + "kind_constant": "KIND_RHI_EVIDENCE_ATTESTATION", + "kind": 3441, + "event_class": "regular_immutable", + "replaceability": "none", + "content_encoding": "RFC8785_JCS_JSON_UTF8", + "statement_digest": { + "algorithm": "sha256", + "domain_separator_utf8_nul": "radroots:rhi-evidence-attestation-statement:v1", + "payload_fields": [ + "contract_id", + "contract_version", + "issuer_pubkey", + "trade_id", + "claim_mutation_id", + "outcome", + "reason_codes", + "reducer_contract_id", + "reducer_contract_version", + "projection_digest", + "evidence_manifest_digest", + "evidence_policy_digest", + "observed_at_unix_s", + "attestation_method", + "supersedes_report_id", + "supersedes_event_id", + "trade_generation" + ], + "excluded_fields": ["report_id", "statement_digest", "event_id", "signature"], + "formula": "SHA256(domain_separator_utf8 || 0x00 || RFC8785(payload)_utf8)" + }, + "fixed_values": { + "contract_version": 1, + "attestation_method": "signed_evidence_snapshot", + "outcomes": ["valid", "invalid", "indeterminate"] + }, + "canonical_tag_order": [ + "contract", + "d:trade", + "x:claim", + "x:statement", + "t:outcome", + "x:supersedes_report", + "e:supersedes_event" + ], + "tags": [ + { "name": "contract", "marker": "", "cardinality": "exactly_one", "value": "radroots.rhi.evidence_attestation.v1", "relay_filter": "none" }, + { "name": "d", "marker": "", "cardinality": "exactly_one", "value": "trade_id_lower_hex_32", "relay_filter": "#d" }, + { "name": "x", "marker": "claim", "cardinality": "exactly_one", "value": "claim_mutation_id_lower_hex_64", "relay_filter": "#x" }, + { "name": "x", "marker": "statement", "cardinality": "exactly_one", "value": "statement_digest_lower_hex_64", "relay_filter": "#x" }, + { "name": "t", "marker": "", "cardinality": "exactly_one", "value": "radroots:rhi-outcome:<valid|invalid|indeterminate>", "relay_filter": "#t" }, + { "name": "x", "marker": "supersedes_report", "cardinality": "zero_or_one", "value": "superseded_statement_digest_lower_hex_64", "relay_filter": "#x" }, + { "name": "e", "marker": "", "cardinality": "zero_or_one", "value": "superseded_nostr_event_id_lower_hex_64", "relay_filter": "#e" } + ], + "supersession": { + "requires_both_references_or_neither": true, + "report_id_equals_statement_digest": true, + "current_selection": "highest_committed_trade_generation_then_observed_at_then_statement_digest", + "relay_arrival_order_authoritative": false, + "deletion_request_changes_retained_history": false + }, + "validation": { + "author_equals_issuer": true, + "content_is_exact_canonical_report": true, + "structural_tags_are_derived": true, + "duplicate_or_conflicting_structural_tag_rejected": true, + "caller_structural_tags_forbidden": true, + "reason_codes_sorted_unique": true + } + } +} diff --git a/contracts/conformance/vectors/rhi/evidence_attestation_decision.v1.json b/contracts/conformance/vectors/rhi/evidence_attestation_decision.v1.json @@ -0,0 +1,153 @@ +{ + "suite": "rhi_evidence_attestation_decision", + "contract_version": "1.0.0", + "vectors": [ + { + "id": "rhi_evidence_attestation_current_001", + "kind": "rhi.evidence_attestation.valid", + "input": { + "statement_payload": { + "attestation_method": "signed_evidence_snapshot", + "claim_mutation_id": "2222222222222222222222222222222222222222222222222222222222222222", + "contract_id": "radroots.rhi.evidence_attestation.v1", + "contract_version": 1, + "evidence_manifest_digest": "4444444444444444444444444444444444444444444444444444444444444444", + "evidence_policy_digest": "5555555555555555555555555555555555555555555555555555555555555555", + "issuer_pubkey": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "observed_at_unix_s": 1800000000, + "outcome": "indeterminate", + "projection_digest": "6666666666666666666666666666666666666666666666666666666666666666", + "reason_codes": ["required_source_incomplete"], + "reducer_contract_id": "radroots.trade.reducer.v1", + "reducer_contract_version": 1, + "supersedes_event_id": null, + "supersedes_report_id": null, + "trade_generation": 7, + "trade_id": "11111111111111111111111111111111" + } + }, + "expected": { + "kind": 3441, + "event_class": "regular_immutable", + "canonical_statement_payload_utf8": "{\"attestation_method\":\"signed_evidence_snapshot\",\"claim_mutation_id\":\"2222222222222222222222222222222222222222222222222222222222222222\",\"contract_id\":\"radroots.rhi.evidence_attestation.v1\",\"contract_version\":1,\"evidence_manifest_digest\":\"4444444444444444444444444444444444444444444444444444444444444444\",\"evidence_policy_digest\":\"5555555555555555555555555555555555555555555555555555555555555555\",\"issuer_pubkey\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"observed_at_unix_s\":1800000000,\"outcome\":\"indeterminate\",\"projection_digest\":\"6666666666666666666666666666666666666666666666666666666666666666\",\"reason_codes\":[\"required_source_incomplete\"],\"reducer_contract_id\":\"radroots.trade.reducer.v1\",\"reducer_contract_version\":1,\"supersedes_event_id\":null,\"supersedes_report_id\":null,\"trade_generation\":7,\"trade_id\":\"11111111111111111111111111111111\"}", + "statement_digest": "461acfea579481f6aadba47c31abc07eaa700f66abc074b8926ba41266082b44", + "report_id": "461acfea579481f6aadba47c31abc07eaa700f66abc074b8926ba41266082b44", + "canonical_event_content_utf8": "{\"attestation_method\":\"signed_evidence_snapshot\",\"claim_mutation_id\":\"2222222222222222222222222222222222222222222222222222222222222222\",\"contract_id\":\"radroots.rhi.evidence_attestation.v1\",\"contract_version\":1,\"evidence_manifest_digest\":\"4444444444444444444444444444444444444444444444444444444444444444\",\"evidence_policy_digest\":\"5555555555555555555555555555555555555555555555555555555555555555\",\"issuer_pubkey\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"observed_at_unix_s\":1800000000,\"outcome\":\"indeterminate\",\"projection_digest\":\"6666666666666666666666666666666666666666666666666666666666666666\",\"reason_codes\":[\"required_source_incomplete\"],\"reducer_contract_id\":\"radroots.trade.reducer.v1\",\"reducer_contract_version\":1,\"report_id\":\"461acfea579481f6aadba47c31abc07eaa700f66abc074b8926ba41266082b44\",\"statement_digest\":\"461acfea579481f6aadba47c31abc07eaa700f66abc074b8926ba41266082b44\",\"supersedes_event_id\":null,\"supersedes_report_id\":null,\"trade_generation\":7,\"trade_id\":\"11111111111111111111111111111111\"}", + "tags": [ + ["contract", "radroots.rhi.evidence_attestation.v1"], + ["d", "11111111111111111111111111111111"], + ["x", "2222222222222222222222222222222222222222222222222222222222222222", "claim"], + ["x", "461acfea579481f6aadba47c31abc07eaa700f66abc074b8926ba41266082b44", "statement"], + ["t", "radroots:rhi-outcome:indeterminate"] + ] + } + }, + { + "id": "rhi_evidence_attestation_superseding_002", + "kind": "rhi.evidence_attestation.valid", + "input": { + "statement_payload": { + "attestation_method": "signed_evidence_snapshot", + "claim_mutation_id": "2222222222222222222222222222222222222222222222222222222222222222", + "contract_id": "radroots.rhi.evidence_attestation.v1", + "contract_version": 1, + "evidence_manifest_digest": "4444444444444444444444444444444444444444444444444444444444444444", + "evidence_policy_digest": "5555555555555555555555555555555555555555555555555555555555555555", + "issuer_pubkey": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "observed_at_unix_s": 1800000100, + "outcome": "valid", + "projection_digest": "6666666666666666666666666666666666666666666666666666666666666666", + "reason_codes": ["scope_satisfied"], + "reducer_contract_id": "radroots.trade.reducer.v1", + "reducer_contract_version": 1, + "supersedes_event_id": "8888888888888888888888888888888888888888888888888888888888888888", + "supersedes_report_id": "7777777777777777777777777777777777777777777777777777777777777777", + "trade_generation": 8, + "trade_id": "11111111111111111111111111111111" + } + }, + "expected": { + "canonical_statement_payload_utf8": "{\"attestation_method\":\"signed_evidence_snapshot\",\"claim_mutation_id\":\"2222222222222222222222222222222222222222222222222222222222222222\",\"contract_id\":\"radroots.rhi.evidence_attestation.v1\",\"contract_version\":1,\"evidence_manifest_digest\":\"4444444444444444444444444444444444444444444444444444444444444444\",\"evidence_policy_digest\":\"5555555555555555555555555555555555555555555555555555555555555555\",\"issuer_pubkey\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"observed_at_unix_s\":1800000100,\"outcome\":\"valid\",\"projection_digest\":\"6666666666666666666666666666666666666666666666666666666666666666\",\"reason_codes\":[\"scope_satisfied\"],\"reducer_contract_id\":\"radroots.trade.reducer.v1\",\"reducer_contract_version\":1,\"supersedes_event_id\":\"8888888888888888888888888888888888888888888888888888888888888888\",\"supersedes_report_id\":\"7777777777777777777777777777777777777777777777777777777777777777\",\"trade_generation\":8,\"trade_id\":\"11111111111111111111111111111111\"}", + "statement_digest": "61af3caa6a3a14ff7bb026e9f294826d1d1957a5aff3d814156acee9cf0d5807", + "report_id": "61af3caa6a3a14ff7bb026e9f294826d1d1957a5aff3d814156acee9cf0d5807", + "canonical_event_content_utf8": "{\"attestation_method\":\"signed_evidence_snapshot\",\"claim_mutation_id\":\"2222222222222222222222222222222222222222222222222222222222222222\",\"contract_id\":\"radroots.rhi.evidence_attestation.v1\",\"contract_version\":1,\"evidence_manifest_digest\":\"4444444444444444444444444444444444444444444444444444444444444444\",\"evidence_policy_digest\":\"5555555555555555555555555555555555555555555555555555555555555555\",\"issuer_pubkey\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"observed_at_unix_s\":1800000100,\"outcome\":\"valid\",\"projection_digest\":\"6666666666666666666666666666666666666666666666666666666666666666\",\"reason_codes\":[\"scope_satisfied\"],\"reducer_contract_id\":\"radroots.trade.reducer.v1\",\"reducer_contract_version\":1,\"report_id\":\"61af3caa6a3a14ff7bb026e9f294826d1d1957a5aff3d814156acee9cf0d5807\",\"statement_digest\":\"61af3caa6a3a14ff7bb026e9f294826d1d1957a5aff3d814156acee9cf0d5807\",\"supersedes_event_id\":\"8888888888888888888888888888888888888888888888888888888888888888\",\"supersedes_report_id\":\"7777777777777777777777777777777777777777777777777777777777777777\",\"trade_generation\":8,\"trade_id\":\"11111111111111111111111111111111\"}", + "tags": [ + ["contract", "radroots.rhi.evidence_attestation.v1"], + ["d", "11111111111111111111111111111111"], + ["x", "2222222222222222222222222222222222222222222222222222222222222222", "claim"], + ["x", "61af3caa6a3a14ff7bb026e9f294826d1d1957a5aff3d814156acee9cf0d5807", "statement"], + ["t", "radroots:rhi-outcome:valid"], + ["x", "7777777777777777777777777777777777777777777777777777777777777777", "supersedes_report"], + ["e", "8888888888888888888888888888888888888888888888888888888888888888"] + ], + "mutates_prior_report": false + } + }, + { + "id": "rhi_evidence_attestation_wrong_kind_003", + "kind": "rhi.evidence_attestation.invalid", + "input": { "base": "rhi_evidence_attestation_current_001", "kind": 3440 }, + "expected": { "layer": "wire", "error_code": "invalid_attestation_kind" } + }, + { + "id": "rhi_evidence_attestation_wrong_author_004", + "kind": "rhi.evidence_attestation.invalid", + "input": { "base": "rhi_evidence_attestation_current_001", "event_author": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" }, + "expected": { "layer": "wire", "error_code": "issuer_author_mismatch" } + }, + { + "id": "rhi_evidence_attestation_noncanonical_content_005", + "kind": "rhi.evidence_attestation.invalid", + "input": { "base": "rhi_evidence_attestation_current_001", "content_transform": "append_ascii_space" }, + "expected": { "layer": "wire", "error_code": "noncanonical_report_content" } + }, + { + "id": "rhi_evidence_attestation_digest_mismatch_006", + "kind": "rhi.evidence_attestation.invalid", + "input": { "base": "rhi_evidence_attestation_current_001", "statement_digest": "0000000000000000000000000000000000000000000000000000000000000000" }, + "expected": { "layer": "wire", "error_code": "statement_digest_mismatch" } + }, + { + "id": "rhi_evidence_attestation_unknown_outcome_007", + "kind": "rhi.evidence_attestation.invalid", + "input": { "base": "rhi_evidence_attestation_current_001", "outcome": "complete" }, + "expected": { "layer": "wire", "error_code": "invalid_outcome" } + }, + { + "id": "rhi_evidence_attestation_missing_claim_tag_008", + "kind": "rhi.evidence_attestation.invalid", + "input": { "base": "rhi_evidence_attestation_current_001", "remove_tag": ["x", "claim"] }, + "expected": { "layer": "wire", "error_code": "missing_claim_tag" } + }, + { + "id": "rhi_evidence_attestation_duplicate_trade_tag_009", + "kind": "rhi.evidence_attestation.invalid", + "input": { "base": "rhi_evidence_attestation_current_001", "append_tag": ["d", "99999999999999999999999999999999"] }, + "expected": { "layer": "wire", "error_code": "duplicate_trade_tag" } + }, + { + "id": "rhi_evidence_attestation_duplicate_statement_tag_010", + "kind": "rhi.evidence_attestation.invalid", + "input": { "base": "rhi_evidence_attestation_current_001", "append_tag": ["x", "9999999999999999999999999999999999999999999999999999999999999999", "statement"] }, + "expected": { "layer": "wire", "error_code": "duplicate_statement_tag" } + }, + { + "id": "rhi_evidence_attestation_incomplete_supersession_011", + "kind": "rhi.evidence_attestation.invalid", + "input": { "base": "rhi_evidence_attestation_current_001", "supersedes_report_id": "7777777777777777777777777777777777777777777777777777777777777777", "supersedes_event_id": null }, + "expected": { "layer": "wire", "error_code": "incomplete_supersession_reference" } + }, + { + "id": "rhi_evidence_attestation_stale_supersession_012", + "kind": "rhi.evidence_attestation.invalid", + "input": { "base": "rhi_evidence_attestation_superseding_002", "current_trade_generation": 8, "candidate_trade_generation": 7 }, + "expected": { "layer": "admission", "error_code": "stale_trade_generation" } + }, + { + "id": "rhi_evidence_attestation_caller_structural_tag_013", + "kind": "rhi.evidence_attestation.invalid", + "input": { "builder_extra_tags": [["d", "11111111111111111111111111111111"]] }, + "expected": { "layer": "builder", "error_code": "caller_structural_tag_forbidden" } + } + ] +} diff --git a/contracts/conformance/vectors/trade/mutation_index_tags_decision.v1.json b/contracts/conformance/vectors/trade/mutation_index_tags_decision.v1.json @@ -0,0 +1,147 @@ +{ + "suite": "trade_mutation_index_decision", + "contract_version": "1.0.0", + "vectors": [ + { + "id": "trade_mutation_index_all_fields_001", + "kind": "trade.mutation_index_tags.valid", + "input": { + "contract_id": "radroots.trade.revision_proposal.v1", + "trade_id": "11111111111111111111111111111111", + "mutation_id": "2222222222222222222222222222222222222222222222222222222222222222", + "root_mutation_id": "3333333333333333333333333333333333333333333333333333333333333333", + "parent_mutation_ids": [ + "4444444444444444444444444444444444444444444444444444444444444444", + "5555555555555555555555555555555555555555555555555555555555555555" + ], + "buyer_pubkey": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "seller_pubkey": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + }, + "expected": { + "kind": 3472, + "tags": [ + ["contract", "radroots.trade.revision_proposal.v1"], + ["d", "11111111111111111111111111111111"], + ["x", "2222222222222222222222222222222222222222222222222222222222222222", "mutation"], + ["x", "3333333333333333333333333333333333333333333333333333333333333333", "root"], + ["x", "4444444444444444444444444444444444444444444444444444444444444444", "parent"], + ["x", "5555555555555555555555555555555555555555555555555555555555555555", "parent"], + ["p", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"], + ["p", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"] + ] + } + }, + { + "id": "trade_mutation_index_proposal_002", + "kind": "trade.mutation_index_tags.valid", + "input": { + "contract_id": "radroots.trade.proposal.v1", + "root_mutation_id": null, + "parent_mutation_ids": [] + }, + "expected": { + "kind": 3470, + "tag_names_and_semantics": ["contract", "d:trade", "x:mutation", "p:buyer-first", "p:seller-second"] + } + }, + { + "id": "trade_mutation_index_decision_003", + "kind": "trade.mutation_index_tags.valid", + "input": { + "contract_id": "radroots.trade.decision.v1", + "root_mutation_id": "3333333333333333333333333333333333333333333333333333333333333333", + "parent_mutation_ids": ["4444444444444444444444444444444444444444444444444444444444444444"] + }, + "expected": { + "kind": 3471, + "tag_names_and_semantics": ["contract", "d:trade", "x:mutation", "x:root", "x:parent", "p:buyer-first", "p:seller-second"] + } + }, + { + "id": "trade_mutation_index_revision_decision_004", + "kind": "trade.mutation_index_tags.valid", + "input": { + "contract_id": "radroots.trade.revision_decision.v1", + "root_mutation_id": "3333333333333333333333333333333333333333333333333333333333333333", + "parent_mutation_ids": ["4444444444444444444444444444444444444444444444444444444444444444"] + }, + "expected": { + "kind": 3473, + "tag_names_and_semantics": ["contract", "d:trade", "x:mutation", "x:root", "x:parent", "p:buyer-first", "p:seller-second"] + } + }, + { + "id": "trade_mutation_index_cancellation_005", + "kind": "trade.mutation_index_tags.valid", + "input": { + "contract_id": "radroots.trade.cancellation.v1", + "root_mutation_id": "3333333333333333333333333333333333333333333333333333333333333333", + "parent_mutation_ids": ["4444444444444444444444444444444444444444444444444444444444444444"] + }, + "expected": { + "kind": 3474, + "tag_names_and_semantics": ["contract", "d:trade", "x:mutation", "x:root", "x:parent", "p:buyer-first", "p:seller-second"] + } + }, + { + "id": "trade_mutation_index_missing_mutation_006", + "kind": "trade.mutation_index_tags.invalid", + "input": { "base": "trade_mutation_index_all_fields_001", "remove_tag": ["x", "mutation"] }, + "expected": { "layer": "wire", "error_code": "missing_mutation_tag" } + }, + { + "id": "trade_mutation_index_duplicate_trade_007", + "kind": "trade.mutation_index_tags.invalid", + "input": { "base": "trade_mutation_index_all_fields_001", "append_tag": ["d", "99999999999999999999999999999999"] }, + "expected": { "layer": "wire", "error_code": "duplicate_trade_tag" } + }, + { + "id": "trade_mutation_index_proposal_with_root_008", + "kind": "trade.mutation_index_tags.invalid", + "input": { "base": "trade_mutation_index_proposal_002", "append_tag": ["x", "3333333333333333333333333333333333333333333333333333333333333333", "root"] }, + "expected": { "layer": "wire", "error_code": "unexpected_root_tag" } + }, + { + "id": "trade_mutation_index_nonproposal_without_root_009", + "kind": "trade.mutation_index_tags.invalid", + "input": { "base": "trade_mutation_index_all_fields_001", "remove_tag": ["x", "root"] }, + "expected": { "layer": "wire", "error_code": "missing_root_tag" } + }, + { + "id": "trade_mutation_index_unsorted_parents_010", + "kind": "trade.mutation_index_tags.invalid", + "input": { "base": "trade_mutation_index_all_fields_001", "swap_tag_indexes": [4, 5] }, + "expected": { "layer": "wire", "error_code": "noncanonical_parent_order" } + }, + { + "id": "trade_mutation_index_wrong_party_order_011", + "kind": "trade.mutation_index_tags.invalid", + "input": { "base": "trade_mutation_index_all_fields_001", "swap_tag_indexes": [6, 7] }, + "expected": { "layer": "wire", "error_code": "party_tag_order_mismatch" } + }, + { + "id": "trade_mutation_index_legacy_parent_event_tag_012", + "kind": "trade.mutation_index_tags.invalid", + "input": { "base": "trade_mutation_index_all_fields_001", "replace_tag": { "index": 4, "tag": ["e", "4444444444444444444444444444444444444444444444444444444444444444"] } }, + "expected": { "layer": "wire", "error_code": "legacy_parent_event_tag" } + }, + { + "id": "trade_mutation_index_caller_structural_tag_013", + "kind": "trade.mutation_index_tags.invalid", + "input": { "builder_extra_tags": [["d", "11111111111111111111111111111111"]] }, + "expected": { "layer": "builder", "error_code": "caller_structural_tag_forbidden" } + }, + { + "id": "trade_mutation_index_proposal_with_parent_014", + "kind": "trade.mutation_index_tags.invalid", + "input": { "base": "trade_mutation_index_proposal_002", "append_tag": ["x", "4444444444444444444444444444444444444444444444444444444444444444", "parent"] }, + "expected": { "layer": "wire", "error_code": "unexpected_parent_tag" } + }, + { + "id": "trade_mutation_index_nonproposal_without_parent_015", + "kind": "trade.mutation_index_tags.invalid", + "input": { "base": "trade_mutation_index_all_fields_001", "remove_tags": [["x", "parent"]] }, + "expected": { "layer": "wire", "error_code": "missing_parent_tag" } + } + ] +} diff --git a/crates/event_codec/tests/services_hardening_event_decisions.rs b/crates/event_codec/tests/services_hardening_event_decisions.rs @@ -0,0 +1,256 @@ +#![forbid(unsafe_code)] + +use serde_json::Value; +use sha2::{Digest, Sha256}; +use std::collections::BTreeSet; + +const DECISION: &str = + include_str!("../../../contracts/architecture/decisions/services_hardening_events.v1.json"); +const REGISTRY: &str = + include_str!("../../../contracts/event_store/event_contract_registry_v7.inventory.json"); +const TRADE_VECTORS: &str = include_str!( + "../../../contracts/conformance/vectors/trade/mutation_index_tags_decision.v1.json" +); +const RHI_VECTORS: &str = include_str!( + "../../../contracts/conformance/vectors/rhi/evidence_attestation_decision.v1.json" +); + +fn json(source: &str) -> Value { + serde_json::from_str(source).expect("services-hardening machine contract must be valid JSON") +} + +fn strings(value: &Value, field: &str) -> Vec<String> { + value[field] + .as_array() + .expect("field must be an array") + .iter() + .map(|entry| entry.as_str().expect("entry must be a string").to_owned()) + .collect() +} + +fn error_codes(vectors: &Value) -> BTreeSet<String> { + vectors["vectors"] + .as_array() + .expect("vector list") + .iter() + .filter_map(|vector| vector["expected"]["error_code"].as_str()) + .map(str::to_owned) + .collect() +} + +fn verify_attestation_digest_vector(vector: &Value) -> String { + let canonical_payload = vector["expected"]["canonical_statement_payload_utf8"] + .as_str() + .expect("canonical statement payload"); + assert_eq!( + serde_json::to_string(&vector["input"]["statement_payload"]).unwrap(), + canonical_payload + ); + let mut hasher = Sha256::new(); + hasher.update(b"radroots:rhi-evidence-attestation-statement:v1\0"); + hasher.update(canonical_payload.as_bytes()); + let digest = hex::encode(hasher.finalize()); + assert_eq!(vector["expected"]["statement_digest"], digest); + assert_eq!(vector["expected"]["report_id"], digest); + let canonical_event = vector["expected"]["canonical_event_content_utf8"] + .as_str() + .expect("canonical event content"); + let mut event_content = json(canonical_event); + assert_eq!(event_content["report_id"], digest); + assert_eq!(event_content["statement_digest"], digest); + let event_object = event_content.as_object_mut().expect("report object"); + event_object.remove("report_id"); + event_object.remove("statement_digest"); + assert_eq!( + serde_json::to_string(&event_content).unwrap(), + canonical_payload + ); + digest +} + +#[test] +fn services_hardening_event_decision_reserves_unique_exact_kinds() { + let decision = json(DECISION); + assert_eq!( + decision["schema"], + "radroots.services-hardening.event-decisions.v1" + ); + assert_eq!(decision["decision_state"], "reserved_preimplementation"); + + let expected_trade = BTreeSet::from([3470_u64, 3471, 3472, 3473, 3474]); + let trade = decision["trade_mutation"]["event_kinds"] + .as_array() + .expect("trade event kinds"); + let actual_trade = trade + .iter() + .map(|entry| entry["kind"].as_u64().expect("numeric kind")) + .collect::<BTreeSet<_>>(); + assert_eq!(actual_trade, expected_trade); + + let registry = json(REGISTRY); + let registered = registry["kind_contracts"] + .as_array() + .expect("registry kind contracts") + .iter() + .map(|entry| entry["kind"].as_u64().expect("registered numeric kind")) + .collect::<Vec<_>>(); + for kind in expected_trade { + assert!(registered.contains(&kind), "trade kind {kind} must exist"); + } + let attestation_kind = decision["rhi_attestation"]["kind"] + .as_u64() + .expect("attestation kind"); + assert_eq!(attestation_kind, 3441); + assert!( + !registered.contains(&attestation_kind), + "reserved attestation kind must not collide with a registered kind" + ); +} + +#[test] +fn services_hardening_trade_tag_cardinality_and_query_contract_is_exact() { + let decision = json(DECISION); + let trade = &decision["trade_mutation"]; + assert_eq!(trade["event_class"], "regular_immutable"); + assert_eq!( + strings(trade, "canonical_tag_order"), + [ + "contract", + "d:trade", + "x:mutation", + "x:root", + "x:parent_sorted", + "p:buyer", + "p:seller", + ] + ); + let tags = trade["tags"].as_array().expect("trade tags"); + assert_eq!(tags.len(), 7); + assert_eq!(tags[1]["cardinality"], "exactly_one"); + assert_eq!(tags[2]["cardinality"], "exactly_one"); + assert_eq!( + tags[3]["cardinality"], + "proposal_zero_other_mutations_exactly_one" + ); + assert_eq!( + tags[4]["cardinality"], + "proposal_zero_other_mutations_one_to_four_sorted_unique" + ); + assert_eq!(tags[5]["cardinality"], "first_of_exactly_two"); + assert_eq!(tags[6]["cardinality"], "second_of_exactly_two"); + assert_eq!( + trade["validation"]["legacy_contract_d_p_e_shape_accepted"], + false + ); + + let vectors = json(TRADE_VECTORS); + let first = &vectors["vectors"][0]; + assert_eq!(first["expected"]["kind"], 3472); + assert_eq!( + first["expected"]["tags"] + .as_array() + .expect("exact tags") + .len(), + 8 + ); + assert_eq!(first["expected"]["tags"][1].as_array().unwrap().len(), 2); + assert_eq!(first["expected"]["tags"][6].as_array().unwrap().len(), 2); + assert_eq!(first["expected"]["tags"][7].as_array().unwrap().len(), 2); + let kinds = vectors["vectors"] + .as_array() + .expect("trade decision vectors") + .iter() + .filter_map(|vector| vector["expected"]["kind"].as_u64()) + .collect::<BTreeSet<_>>(); + assert_eq!(kinds, BTreeSet::from([3470, 3471, 3472, 3473, 3474])); + assert_eq!( + error_codes(&vectors), + BTreeSet::from([ + "caller_structural_tag_forbidden".to_owned(), + "duplicate_trade_tag".to_owned(), + "legacy_parent_event_tag".to_owned(), + "missing_parent_tag".to_owned(), + "missing_mutation_tag".to_owned(), + "missing_root_tag".to_owned(), + "noncanonical_parent_order".to_owned(), + "party_tag_order_mismatch".to_owned(), + "unexpected_parent_tag".to_owned(), + "unexpected_root_tag".to_owned(), + ]) + ); +} + +#[test] +fn services_hardening_attestation_is_immutable_and_fully_bound() { + let decision = json(DECISION); + let attestation = &decision["rhi_attestation"]; + assert_eq!(attestation["kind"], 3441); + assert_eq!(attestation["event_class"], "regular_immutable"); + assert_eq!(attestation["replaceability"], "none"); + assert_eq!(attestation["content_encoding"], "RFC8785_JCS_JSON_UTF8"); + assert_eq!( + attestation["fixed_values"]["attestation_method"], + "signed_evidence_snapshot" + ); + assert_eq!( + strings(attestation, "canonical_tag_order"), + [ + "contract", + "d:trade", + "x:claim", + "x:statement", + "t:outcome", + "x:supersedes_report", + "e:supersedes_event", + ] + ); + assert_eq!( + attestation["supersession"]["requires_both_references_or_neither"], + true + ); + assert_eq!( + attestation["supersession"]["report_id_equals_statement_digest"], + true + ); + assert_eq!( + attestation["supersession"]["relay_arrival_order_authoritative"], + false + ); + + let vectors = json(RHI_VECTORS); + let positive = &vectors["vectors"][0]; + assert_eq!(positive["expected"]["kind"], 3441); + verify_attestation_digest_vector(positive); + assert_eq!(positive["expected"]["tags"][1].as_array().unwrap().len(), 2); + assert_eq!(positive["expected"]["tags"][4].as_array().unwrap().len(), 2); + assert_eq!( + vectors["vectors"][1]["expected"]["mutates_prior_report"], + false + ); + verify_attestation_digest_vector(&vectors["vectors"][1]); + assert_eq!( + vectors["vectors"][1]["expected"]["tags"][6] + .as_array() + .unwrap() + .len(), + 2 + ); + assert_eq!( + error_codes(&vectors), + BTreeSet::from([ + "caller_structural_tag_forbidden".to_owned(), + "duplicate_statement_tag".to_owned(), + "duplicate_trade_tag".to_owned(), + "incomplete_supersession_reference".to_owned(), + "invalid_attestation_kind".to_owned(), + "invalid_outcome".to_owned(), + "issuer_author_mismatch".to_owned(), + "missing_claim_tag".to_owned(), + "noncanonical_report_content".to_owned(), + "stale_trade_generation".to_owned(), + "statement_digest_mismatch".to_owned(), + ]) + ); + let stale = &vectors["vectors"][11]; + assert_eq!(stale["expected"]["layer"], "admission"); +}