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:
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");
+}