From a210bd5292a9f3ca89ceea2fc2428e48f0016e7a Mon Sep 17 00:00:00 2001 From: Aleksey Safonov <55020240+safal207@users.noreply.github.com> Date: Wed, 22 Jul 2026 07:57:56 +0300 Subject: [PATCH 01/12] feat: define causal-temporal transition graph --- .../causal-temporal/graph.json | 157 ++++++++++++++++++ 1 file changed, 157 insertions(+) create mode 100644 conformance/guardrail-decision-v1/causal-temporal/graph.json diff --git a/conformance/guardrail-decision-v1/causal-temporal/graph.json b/conformance/guardrail-decision-v1/causal-temporal/graph.json new file mode 100644 index 0000000..f237299 --- /dev/null +++ b/conformance/guardrail-decision-v1/causal-temporal/graph.json @@ -0,0 +1,157 @@ +{ + "schema": "proofpath.causal-temporal-graph.v0.1", + "canonicalization": "utf8-json-sort-keys-no-whitespace-v0.1", + "axes": { + "origin": { + "initial": "UNCOMMITTED", + "states": [ + "UNCOMMITTED", + "COMMITTED", + "REPRODUCIBLE", + "INVALID" + ] + }, + "freshness": { + "initial": "UNKNOWN", + "states": [ + "UNKNOWN", + "FRESH", + "STALE" + ] + }, + "temporal": { + "initial": "UNANCHORED", + "states": [ + "UNANCHORED", + "PENDING", + "ANCHORED", + "UNAVAILABLE", + "INVALID" + ] + } + }, + "transitions": [ + { + "event_type": "COMMIT_SOURCE_HASH", + "axis": "origin", + "from": [ + "UNCOMMITTED" + ], + "to": "COMMITTED", + "evidence_required": true + }, + { + "event_type": "VERIFY_SOURCE_SNAPSHOT", + "axis": "origin", + "from": [ + "COMMITTED" + ], + "to": "REPRODUCIBLE", + "evidence_required": true + }, + { + "event_type": "INVALIDATE_SOURCE_ORIGIN", + "axis": "origin", + "from": [ + "UNCOMMITTED", + "COMMITTED", + "REPRODUCIBLE" + ], + "to": "INVALID", + "evidence_required": true + }, + { + "event_type": "CHECK_SOURCE_FRESH", + "axis": "freshness", + "from": [ + "UNKNOWN", + "FRESH", + "STALE" + ], + "to": "FRESH", + "evidence_required": true + }, + { + "event_type": "CHECK_SOURCE_STALE", + "axis": "freshness", + "from": [ + "UNKNOWN", + "FRESH", + "STALE" + ], + "to": "STALE", + "evidence_required": true + }, + { + "event_type": "SUBMIT_OTS", + "axis": "temporal", + "from": [ + "UNANCHORED", + "UNAVAILABLE" + ], + "to": "PENDING", + "evidence_required": true + }, + { + "event_type": "VERIFY_OTS_PENDING", + "axis": "temporal", + "from": [ + "UNANCHORED", + "PENDING", + "UNAVAILABLE" + ], + "to": "PENDING", + "evidence_required": true + }, + { + "event_type": "VERIFY_OTS_SUCCESS", + "axis": "temporal", + "from": [ + "UNANCHORED", + "PENDING", + "UNAVAILABLE" + ], + "to": "ANCHORED", + "evidence_required": true, + "required_fields": [ + "temporal_bound.bitcoin_block_height", + "temporal_bound.attested_before" + ] + }, + { + "event_type": "REVERIFY_OTS_SUCCESS", + "axis": "temporal", + "from": [ + "ANCHORED" + ], + "to": "ANCHORED", + "evidence_required": true, + "required_fields": [ + "temporal_bound.bitcoin_block_height", + "temporal_bound.attested_before" + ] + }, + { + "event_type": "VERIFY_OTS_UNAVAILABLE", + "axis": "temporal", + "from": [ + "UNANCHORED", + "PENDING", + "UNAVAILABLE" + ], + "to": "UNAVAILABLE", + "evidence_required": true + }, + { + "event_type": "VERIFY_OTS_INVALID", + "axis": "temporal", + "from": [ + "UNANCHORED", + "PENDING", + "UNAVAILABLE" + ], + "to": "INVALID", + "evidence_required": true + } + ] +} \ No newline at end of file From 325bb5292e33db413fc001411e471073b86dab01 Mon Sep 17 00:00:00 2001 From: Aleksey Safonov <55020240+safal207@users.noreply.github.com> Date: Wed, 22 Jul 2026 07:58:11 +0300 Subject: [PATCH 02/12] test: add causal-temporal graph verifier --- scripts/check_causal_temporal_graph.py | 200 +++++++++++++++++++++++++ 1 file changed, 200 insertions(+) create mode 100644 scripts/check_causal_temporal_graph.py diff --git a/scripts/check_causal_temporal_graph.py b/scripts/check_causal_temporal_graph.py new file mode 100644 index 0000000..1aa3b27 --- /dev/null +++ b/scripts/check_causal_temporal_graph.py @@ -0,0 +1,200 @@ +#!/usr/bin/env python3 +"""Validate causal-temporal transition traces for one immutable subject hash.""" + +from __future__ import annotations + +import argparse +import hashlib +import json +import re +import sys +from datetime import datetime +from pathlib import Path +from typing import Any, Sequence + +HASH_RE = re.compile(r"^sha256:[0-9a-f]{64}$") + + +def canonical_bytes(value: Any) -> bytes: + return json.dumps( + value, + sort_keys=True, + separators=(",", ":"), + ensure_ascii=False, + ).encode("utf-8") + + +def recompute_event_id(event: dict[str, Any]) -> str: + preimage = {key: value for key, value in event.items() if key != "event_id"} + return "sha256:" + hashlib.sha256(canonical_bytes(preimage)).hexdigest() + + +def parse_time(value: str) -> datetime: + if value.endswith("Z"): + value = value[:-1] + "+00:00" + return datetime.fromisoformat(value) + + +def get_dotted(value: dict[str, Any], path: str) -> Any: + current: Any = value + for part in path.split("."): + if not isinstance(current, dict) or part not in current: + raise KeyError(path) + current = current[part] + return current + + +def initial_state(graph: dict[str, Any]) -> dict[str, str]: + return {name: spec["initial"] for name, spec in graph["axes"].items()} + + +def validate_graph(graph: dict[str, Any]) -> None: + axes = graph["axes"] + for axis, spec in axes.items(): + states = spec["states"] + if len(states) != len(set(states)): + raise ValueError(f"duplicate state on axis {axis}") + if spec["initial"] not in states: + raise ValueError(f"initial state missing on axis {axis}") + + event_types: set[str] = set() + for transition in graph["transitions"]: + event_type = transition["event_type"] + if event_type in event_types: + raise ValueError(f"duplicate event_type: {event_type}") + event_types.add(event_type) + axis = transition["axis"] + if axis not in axes: + raise ValueError(f"unknown axis: {axis}") + allowed = set(axes[axis]["states"]) + if not set(transition["from"]).issubset(allowed): + raise ValueError(f"unknown from-state in {event_type}") + if transition["to"] not in allowed: + raise ValueError(f"unknown to-state in {event_type}") + + +def fail(code: str, seq: int | None = None) -> dict[str, Any]: + result: dict[str, Any] = {"ok": False, "error": code} + if seq is not None: + result["seq"] = seq + return result + + +def verify_trace(graph: dict[str, Any], case: dict[str, Any]) -> dict[str, Any]: + transitions = {item["event_type"]: item for item in graph["transitions"]} + axes = graph["axes"] + expected_axes = set(axes) + current = initial_state(graph) + previous_id: str | None = None + previous_time: datetime | None = None + subject_hash = case["subject_hash"] + + if not HASH_RE.fullmatch(subject_hash): + return fail("INVALID_SUBJECT_HASH") + + events = case["events"] + for index, event in enumerate(events): + seq = event.get("seq") + if seq != index: + return fail("SEQUENCE_GAP_OR_DUPLICATE", index) + + if event.get("parent_event_id") != previous_id: + return fail("PARENT_EVENT_MISMATCH", index) + + if event.get("subject_hash") != subject_hash: + return fail("SUBJECT_HASH_DRIFT", index) + + event_id = event.get("event_id") + if not isinstance(event_id, str) or event_id != recompute_event_id(event): + return fail("EVENT_ID_MISMATCH", index) + + try: + observed_at = parse_time(event["observed_at"]) + except (KeyError, TypeError, ValueError): + return fail("INVALID_OBSERVED_AT", index) + if previous_time is not None and observed_at < previous_time: + return fail("OBSERVED_AT_REGRESSION", index) + + before = event.get("state_before") + after = event.get("state_after") + if not isinstance(before, dict) or not isinstance(after, dict): + return fail("INVALID_STATE_VECTOR", index) + if set(before) != expected_axes or set(after) != expected_axes: + return fail("STATE_VECTOR_AXES_MISMATCH", index) + for axis, spec in axes.items(): + if before[axis] not in spec["states"] or after[axis] not in spec["states"]: + return fail("UNKNOWN_STATE", index) + + if before != current: + return fail("STATE_BEFORE_MISMATCH", index) + + transition = transitions.get(event.get("event_type")) + if transition is None: + return fail("UNDECLARED_TRANSITION", index) + + axis = transition["axis"] + if before[axis] not in transition["from"] or after[axis] != transition["to"]: + return fail("ILLEGAL_AXIS_TRANSITION", index) + + for untouched_axis in expected_axes - {axis}: + if before[untouched_axis] != after[untouched_axis]: + return fail("UNDECLARED_AXIS_MUTATION", index) + + if transition.get("evidence_required") and not event.get("evidence_ref"): + return fail("MISSING_TRANSITION_EVIDENCE", index) + + for required_path in transition.get("required_fields", []): + try: + required_value = get_dotted(event, required_path) + except KeyError: + return fail("MISSING_REQUIRED_TRANSITION_FIELD", index) + if required_value in (None, ""): + return fail("MISSING_REQUIRED_TRANSITION_FIELD", index) + + current = after + previous_id = event_id + previous_time = observed_at + + return { + "ok": True, + "error": None, + "final_state": current, + "terminal_event_id": previous_id, + "event_count": len(events), + } + + +def main(argv: Sequence[str] | None = None) -> int: + parser = argparse.ArgumentParser() + parser.add_argument("graph", type=Path) + parser.add_argument("vectors", type=Path) + args = parser.parse_args(sys.argv[1:] if argv is None else argv) + + graph = json.loads(args.graph.read_text(encoding="utf-8")) + vectors = json.loads(args.vectors.read_text(encoding="utf-8")) + validate_graph(graph) + + failures = 0 + for case in vectors["cases"]: + actual = verify_trace(graph, case) + expected = case["expected"] + projection = {key: actual.get(key) for key in expected} + if projection != expected: + failures += 1 + print(f"FAIL {case['name']}") + print(" expected:", json.dumps(expected, sort_keys=True)) + print(" actual: ", json.dumps(projection, sort_keys=True)) + else: + outcome = "PASS" if actual["ok"] else actual["error"] + print(f"PASS {case['name']} -> {outcome}") + + if failures: + print(f"\nCausal-temporal graph conformance failed: {failures}") + return 1 + + print(f"\nCausal-temporal graph conformance passed: {len(vectors['cases'])}") + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) From 6b44e4a738ca8810068ec70209b47840a846eb9e Mon Sep 17 00:00:00 2001 From: Aleksey Safonov <55020240+safal207@users.noreply.github.com> Date: Wed, 22 Jul 2026 07:59:19 +0300 Subject: [PATCH 03/12] test: add causal-temporal transition vectors --- .../causal-temporal/vectors.json | 407 ++++++++++++++++++ 1 file changed, 407 insertions(+) create mode 100644 conformance/guardrail-decision-v1/causal-temporal/vectors.json diff --git a/conformance/guardrail-decision-v1/causal-temporal/vectors.json b/conformance/guardrail-decision-v1/causal-temporal/vectors.json new file mode 100644 index 0000000..29b4558 --- /dev/null +++ b/conformance/guardrail-decision-v1/causal-temporal/vectors.json @@ -0,0 +1,407 @@ +{ + "schema": "proofpath.causal-temporal-vectors.v0.1", + "cases": [ + { + "name": "valid-full-causal-chain", + "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "events": [ + { + "seq": 0, + "parent_event_id": null, + "event_type": "COMMIT_SOURCE_HASH", + "state_before": { + "origin": "UNCOMMITTED", + "freshness": "UNKNOWN", + "temporal": "UNANCHORED" + }, + "state_after": { + "origin": "COMMITTED", + "freshness": "UNKNOWN", + "temporal": "UNANCHORED" + }, + "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "evidence_ref": "evidence:source-hash", + "observed_at": "2026-07-22T04:00:00Z", + "event_id": "sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962" + }, + { + "seq": 1, + "parent_event_id": "sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962", + "event_type": "VERIFY_SOURCE_SNAPSHOT", + "state_before": { + "origin": "COMMITTED", + "freshness": "UNKNOWN", + "temporal": "UNANCHORED" + }, + "state_after": { + "origin": "REPRODUCIBLE", + "freshness": "UNKNOWN", + "temporal": "UNANCHORED" + }, + "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "evidence_ref": "evidence:snapshot", + "observed_at": "2026-07-22T04:01:00Z", + "event_id": "sha256:f7325b13c1b69f4482ff2f743210e33a3d2c50e6f83fa4993a3a2b764cb680e0" + }, + { + "seq": 2, + "parent_event_id": "sha256:f7325b13c1b69f4482ff2f743210e33a3d2c50e6f83fa4993a3a2b764cb680e0", + "event_type": "CHECK_SOURCE_FRESH", + "state_before": { + "origin": "REPRODUCIBLE", + "freshness": "UNKNOWN", + "temporal": "UNANCHORED" + }, + "state_after": { + "origin": "REPRODUCIBLE", + "freshness": "FRESH", + "temporal": "UNANCHORED" + }, + "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "evidence_ref": "evidence:live-fetch", + "observed_at": "2026-07-22T04:02:00Z", + "event_id": "sha256:cd424af268762cc38b46a9b3bc14ebe51a8c615082847bae9100620c15525065" + }, + { + "seq": 3, + "parent_event_id": "sha256:cd424af268762cc38b46a9b3bc14ebe51a8c615082847bae9100620c15525065", + "event_type": "SUBMIT_OTS", + "state_before": { + "origin": "REPRODUCIBLE", + "freshness": "FRESH", + "temporal": "UNANCHORED" + }, + "state_after": { + "origin": "REPRODUCIBLE", + "freshness": "FRESH", + "temporal": "PENDING" + }, + "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "evidence_ref": "evidence:ots-proof-pending", + "observed_at": "2026-07-22T04:03:00Z", + "event_id": "sha256:5110d0131c3fe5eea49865ea467ed229c48f75763c5e50c1c6776db6d5cb7a18" + }, + { + "seq": 4, + "parent_event_id": "sha256:5110d0131c3fe5eea49865ea467ed229c48f75763c5e50c1c6776db6d5cb7a18", + "event_type": "VERIFY_OTS_SUCCESS", + "state_before": { + "origin": "REPRODUCIBLE", + "freshness": "FRESH", + "temporal": "PENDING" + }, + "state_after": { + "origin": "REPRODUCIBLE", + "freshness": "FRESH", + "temporal": "ANCHORED" + }, + "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "evidence_ref": "evidence:ots-verification", + "observed_at": "2026-07-22T05:00:00Z", + "temporal_bound": { + "kind": "not_later_than", + "bitcoin_block_height": 900001, + "attested_before": "2026-07-22T04:55:00Z" + }, + "event_id": "sha256:d2db1fff41daa5b2656e72d0be097963d23085347059287b7fc2a43a5d58c8e8" + } + ], + "expected": { + "ok": true, + "error": null, + "final_state": { + "origin": "REPRODUCIBLE", + "freshness": "FRESH", + "temporal": "ANCHORED" + }, + "event_count": 5 + } + }, + { + "name": "valid-staleness-does-not-erase-temporal-anchor", + "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "events": [ + { + "seq": 0, + "parent_event_id": null, + "event_type": "COMMIT_SOURCE_HASH", + "state_before": { + "origin": "UNCOMMITTED", + "freshness": "UNKNOWN", + "temporal": "UNANCHORED" + }, + "state_after": { + "origin": "COMMITTED", + "freshness": "UNKNOWN", + "temporal": "UNANCHORED" + }, + "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "evidence_ref": "evidence:source-hash", + "observed_at": "2026-07-22T04:00:00Z", + "event_id": "sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962" + }, + { + "seq": 1, + "parent_event_id": "sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962", + "event_type": "VERIFY_SOURCE_SNAPSHOT", + "state_before": { + "origin": "COMMITTED", + "freshness": "UNKNOWN", + "temporal": "UNANCHORED" + }, + "state_after": { + "origin": "REPRODUCIBLE", + "freshness": "UNKNOWN", + "temporal": "UNANCHORED" + }, + "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "evidence_ref": "evidence:snapshot", + "observed_at": "2026-07-22T04:01:00Z", + "event_id": "sha256:f7325b13c1b69f4482ff2f743210e33a3d2c50e6f83fa4993a3a2b764cb680e0" + }, + { + "seq": 2, + "parent_event_id": "sha256:f7325b13c1b69f4482ff2f743210e33a3d2c50e6f83fa4993a3a2b764cb680e0", + "event_type": "CHECK_SOURCE_FRESH", + "state_before": { + "origin": "REPRODUCIBLE", + "freshness": "UNKNOWN", + "temporal": "UNANCHORED" + }, + "state_after": { + "origin": "REPRODUCIBLE", + "freshness": "FRESH", + "temporal": "UNANCHORED" + }, + "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "evidence_ref": "evidence:live-fetch", + "observed_at": "2026-07-22T04:02:00Z", + "event_id": "sha256:cd424af268762cc38b46a9b3bc14ebe51a8c615082847bae9100620c15525065" + }, + { + "seq": 3, + "parent_event_id": "sha256:cd424af268762cc38b46a9b3bc14ebe51a8c615082847bae9100620c15525065", + "event_type": "SUBMIT_OTS", + "state_before": { + "origin": "REPRODUCIBLE", + "freshness": "FRESH", + "temporal": "UNANCHORED" + }, + "state_after": { + "origin": "REPRODUCIBLE", + "freshness": "FRESH", + "temporal": "PENDING" + }, + "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "evidence_ref": "evidence:ots-proof-pending", + "observed_at": "2026-07-22T04:03:00Z", + "event_id": "sha256:5110d0131c3fe5eea49865ea467ed229c48f75763c5e50c1c6776db6d5cb7a18" + }, + { + "seq": 4, + "parent_event_id": "sha256:5110d0131c3fe5eea49865ea467ed229c48f75763c5e50c1c6776db6d5cb7a18", + "event_type": "VERIFY_OTS_SUCCESS", + "state_before": { + "origin": "REPRODUCIBLE", + "freshness": "FRESH", + "temporal": "PENDING" + }, + "state_after": { + "origin": "REPRODUCIBLE", + "freshness": "FRESH", + "temporal": "ANCHORED" + }, + "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "evidence_ref": "evidence:ots-verification", + "observed_at": "2026-07-22T05:00:00Z", + "temporal_bound": { + "kind": "not_later_than", + "bitcoin_block_height": 900001, + "attested_before": "2026-07-22T04:55:00Z" + }, + "event_id": "sha256:d2db1fff41daa5b2656e72d0be097963d23085347059287b7fc2a43a5d58c8e8" + }, + { + "seq": 5, + "parent_event_id": "sha256:d2db1fff41daa5b2656e72d0be097963d23085347059287b7fc2a43a5d58c8e8", + "event_type": "CHECK_SOURCE_STALE", + "state_before": { + "origin": "REPRODUCIBLE", + "freshness": "FRESH", + "temporal": "ANCHORED" + }, + "state_after": { + "origin": "REPRODUCIBLE", + "freshness": "STALE", + "temporal": "ANCHORED" + }, + "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "evidence_ref": "evidence:changed-live-source", + "observed_at": "2026-07-22T06:00:00Z", + "event_id": "sha256:ad51fba53c659be72b76720ba569754368e5af51666d054e13490c3fc5e0be8d" + } + ], + "expected": { + "ok": true, + "error": null, + "final_state": { + "origin": "REPRODUCIBLE", + "freshness": "STALE", + "temporal": "ANCHORED" + }, + "event_count": 6 + } + }, + { + "name": "reject-undeclared-transition", + "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "events": [ + { + "seq": 0, + "parent_event_id": null, + "event_type": "COMMIT_SOURCE_HASH", + "state_before": {"origin":"UNCOMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"}, + "state_after": {"origin":"COMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"}, + "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "evidence_ref": "evidence:source-hash", + "observed_at": "2026-07-22T04:00:00Z", + "event_id": "sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962" + }, + { + "seq": 1, + "parent_event_id": "sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962", + "event_type": "VERIFY_SOURCE_SNAPSHOT", + "state_before": {"origin":"COMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"}, + "state_after": {"origin":"REPRODUCIBLE","freshness":"UNKNOWN","temporal":"UNANCHORED"}, + "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "evidence_ref": "evidence:snapshot", + "observed_at": "2026-07-22T04:01:00Z", + "event_id": "sha256:f7325b13c1b69f4482ff2f743210e33a3d2c50e6f83fa4993a3a2b764cb680e0" + }, + { + "seq": 2, + "parent_event_id": "sha256:f7325b13c1b69f4482ff2f743210e33a3d2c50e6f83fa4993a3a2b764cb680e0", + "event_type": "CHECK_SOURCE_FRESH", + "state_before": {"origin":"REPRODUCIBLE","freshness":"UNKNOWN","temporal":"UNANCHORED"}, + "state_after": {"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"UNANCHORED"}, + "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "evidence_ref": "evidence:live-fetch", + "observed_at": "2026-07-22T04:02:00Z", + "event_id": "sha256:cd424af268762cc38b46a9b3bc14ebe51a8c615082847bae9100620c15525065" + }, + { + "seq": 3, + "parent_event_id": "sha256:cd424af268762cc38b46a9b3bc14ebe51a8c615082847bae9100620c15525065", + "event_type": "ROLLBACK_TIME", + "state_before": {"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"UNANCHORED"}, + "state_after": {"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"PENDING"}, + "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "evidence_ref": "evidence:ots-proof-pending", + "observed_at": "2026-07-22T04:03:00Z", + "event_id": "sha256:6ff11df1dff007030a9ce5bec1915612235cfb4e8a2677dcc09ea18019dfd93b" + } + ], + "expected": {"ok":false,"error":"UNDECLARED_TRANSITION"} + }, + { + "name": "reject-sequence-gap", + "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "events": [ + { + "seq": 0,"parent_event_id":null,"event_type":"COMMIT_SOURCE_HASH","state_before":{"origin":"UNCOMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"COMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:source-hash","observed_at":"2026-07-22T04:00:00Z","event_id":"sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962" + }, + { + "seq": 1,"parent_event_id":"sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962","event_type":"VERIFY_SOURCE_SNAPSHOT","state_before":{"origin":"COMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"REPRODUCIBLE","freshness":"UNKNOWN","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:snapshot","observed_at":"2026-07-22T04:01:00Z","event_id":"sha256:f7325b13c1b69f4482ff2f743210e33a3d2c50e6f83fa4993a3a2b764cb680e0" + }, + { + "seq": 3,"parent_event_id":"sha256:f7325b13c1b69f4482ff2f743210e33a3d2c50e6f83fa4993a3a2b764cb680e0","event_type":"CHECK_SOURCE_FRESH","state_before":{"origin":"REPRODUCIBLE","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:live-fetch","observed_at":"2026-07-22T04:02:00Z","event_id":"sha256:cd424af268762cc38b46a9b3bc14ebe51a8c615082847bae9100620c15525065" + } + ], + "expected": {"ok":false,"error":"SEQUENCE_GAP_OR_DUPLICATE"} + }, + { + "name":"reject-parent-mismatch", + "subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "events":[ + {"seq":0,"parent_event_id":null,"event_type":"COMMIT_SOURCE_HASH","state_before":{"origin":"UNCOMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"COMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:source-hash","observed_at":"2026-07-22T04:00:00Z","event_id":"sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962"}, + {"seq":1,"parent_event_id":"sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962","event_type":"VERIFY_SOURCE_SNAPSHOT","state_before":{"origin":"COMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"REPRODUCIBLE","freshness":"UNKNOWN","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:snapshot","observed_at":"2026-07-22T04:01:00Z","event_id":"sha256:f7325b13c1b69f4482ff2f743210e33a3d2c50e6f83fa4993a3a2b764cb680e0"}, + {"seq":2,"parent_event_id":"sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb","event_type":"CHECK_SOURCE_FRESH","state_before":{"origin":"REPRODUCIBLE","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:live-fetch","observed_at":"2026-07-22T04:02:00Z","event_id":"sha256:cd424af268762cc38b46a9b3bc14ebe51a8c615082847bae9100620c15525065"} + ], + "expected":{"ok":false,"error":"PARENT_EVENT_MISMATCH"} + }, + { + "name":"reject-subject-hash-drift", + "subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "events":[ + {"seq":0,"parent_event_id":null,"event_type":"COMMIT_SOURCE_HASH","state_before":{"origin":"UNCOMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"COMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:source-hash","observed_at":"2026-07-22T04:00:00Z","event_id":"sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962"}, + {"seq":1,"parent_event_id":"sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962","event_type":"VERIFY_SOURCE_SNAPSHOT","state_before":{"origin":"COMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"REPRODUCIBLE","freshness":"UNKNOWN","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:snapshot","observed_at":"2026-07-22T04:01:00Z","event_id":"sha256:f7325b13c1b69f4482ff2f743210e33a3d2c50e6f83fa4993a3a2b764cb680e0"}, + {"seq":2,"parent_event_id":"sha256:f7325b13c1b69f4482ff2f743210e33a3d2c50e6f83fa4993a3a2b764cb680e0","event_type":"CHECK_SOURCE_FRESH","state_before":{"origin":"REPRODUCIBLE","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"UNANCHORED"},"subject_hash":"sha256:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc","evidence_ref":"evidence:live-fetch","observed_at":"2026-07-22T04:02:00Z","event_id":"sha256:cd424af268762cc38b46a9b3bc14ebe51a8c615082847bae9100620c15525065"} + ], + "expected":{"ok":false,"error":"SUBJECT_HASH_DRIFT"} + }, + { + "name":"reject-observed-time-regression", + "subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "events":[ + {"seq":0,"parent_event_id":null,"event_type":"COMMIT_SOURCE_HASH","state_before":{"origin":"UNCOMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"COMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:source-hash","observed_at":"2026-07-22T04:00:00Z","event_id":"sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962"}, + {"seq":1,"parent_event_id":"sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962","event_type":"VERIFY_SOURCE_SNAPSHOT","state_before":{"origin":"COMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"REPRODUCIBLE","freshness":"UNKNOWN","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:snapshot","observed_at":"2026-07-22T04:01:00Z","event_id":"sha256:f7325b13c1b69f4482ff2f743210e33a3d2c50e6f83fa4993a3a2b764cb680e0"}, + {"seq":2,"parent_event_id":"sha256:f7325b13c1b69f4482ff2f743210e33a3d2c50e6f83fa4993a3a2b764cb680e0","event_type":"CHECK_SOURCE_FRESH","state_before":{"origin":"REPRODUCIBLE","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:live-fetch","observed_at":"2026-07-22T03:59:00Z","event_id":"sha256:026a17b297db14f38ea985504d17cc8bc089b05de5ac875d686ce8fe3d339eea"} + ], + "expected":{"ok":false,"error":"OBSERVED_AT_REGRESSION"} + }, + { + "name":"reject-missing-transition-evidence", + "subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "events":[ + {"seq":0,"parent_event_id":null,"event_type":"COMMIT_SOURCE_HASH","state_before":{"origin":"UNCOMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"COMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:source-hash","observed_at":"2026-07-22T04:00:00Z","event_id":"sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962"}, + {"seq":1,"parent_event_id":"sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962","event_type":"VERIFY_SOURCE_SNAPSHOT","state_before":{"origin":"COMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"REPRODUCIBLE","freshness":"UNKNOWN","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:snapshot","observed_at":"2026-07-22T04:01:00Z","event_id":"sha256:f7325b13c1b69f4482ff2f743210e33a3d2c50e6f83fa4993a3a2b764cb680e0"}, + {"seq":2,"parent_event_id":"sha256:f7325b13c1b69f4482ff2f743210e33a3d2c50e6f83fa4993a3a2b764cb680e0","event_type":"CHECK_SOURCE_FRESH","state_before":{"origin":"REPRODUCIBLE","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"","observed_at":"2026-07-22T04:02:00Z","event_id":"sha256:c28ec1f1491aa01646fe97f5755fe868d2cd2d12c3bcba9e86ae1d961449a93b"} + ], + "expected":{"ok":false,"error":"MISSING_TRANSITION_EVIDENCE"} + }, + { + "name":"reject-undeclared-axis-mutation", + "subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "events":[ + {"seq":0,"parent_event_id":null,"event_type":"COMMIT_SOURCE_HASH","state_before":{"origin":"UNCOMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"COMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:source-hash","observed_at":"2026-07-22T04:00:00Z","event_id":"sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962"}, + {"seq":1,"parent_event_id":"sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962","event_type":"VERIFY_SOURCE_SNAPSHOT","state_before":{"origin":"COMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"REPRODUCIBLE","freshness":"UNKNOWN","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:snapshot","observed_at":"2026-07-22T04:01:00Z","event_id":"sha256:f7325b13c1b69f4482ff2f743210e33a3d2c50e6f83fa4993a3a2b764cb680e0"}, + {"seq":2,"parent_event_id":"sha256:f7325b13c1b69f4482ff2f743210e33a3d2c50e6f83fa4993a3a2b764cb680e0","event_type":"CHECK_SOURCE_FRESH","state_before":{"origin":"REPRODUCIBLE","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"INVALID","freshness":"FRESH","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:live-fetch","observed_at":"2026-07-22T04:02:00Z","event_id":"sha256:fa8d7b8dd2867ec70caad6d33bf7b24713e5085dbaac24265c635ecf56ce3896"} + ], + "expected":{"ok":false,"error":"UNDECLARED_AXIS_MUTATION"} + }, + { + "name":"reject-event-id-tamper", + "subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "events":[ + {"seq":0,"parent_event_id":null,"event_type":"COMMIT_SOURCE_HASH","state_before":{"origin":"UNCOMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"COMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:source-hash","observed_at":"2026-07-22T04:00:00Z","event_id":"sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962"}, + {"seq":1,"parent_event_id":"sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962","event_type":"VERIFY_SOURCE_SNAPSHOT","state_before":{"origin":"COMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"REPRODUCIBLE","freshness":"UNKNOWN","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:snapshot","observed_at":"2026-07-22T04:01:00Z","event_id":"sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"} + ], + "expected":{"ok":false,"error":"EVENT_ID_MISMATCH"} + }, + { + "name":"reject-temporal-regression-after-anchor", + "subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "events":[ + {"seq":0,"parent_event_id":null,"event_type":"COMMIT_SOURCE_HASH","state_before":{"origin":"UNCOMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"COMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:source-hash","observed_at":"2026-07-22T04:00:00Z","event_id":"sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962"}, + {"seq":1,"parent_event_id":"sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962","event_type":"VERIFY_SOURCE_SNAPSHOT","state_before":{"origin":"COMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"REPRODUCIBLE","freshness":"UNKNOWN","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:snapshot","observed_at":"2026-07-22T04:01:00Z","event_id":"sha256:f7325b13c1b69f4482ff2f743210e33a3d2c50e6f83fa4993a3a2b764cb680e0"}, + {"seq":2,"parent_event_id":"sha256:f7325b13c1b69f4482ff2f743210e33a3d2c50e6f83fa4993a3a2b764cb680e0","event_type":"CHECK_SOURCE_FRESH","state_before":{"origin":"REPRODUCIBLE","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:live-fetch","observed_at":"2026-07-22T04:02:00Z","event_id":"sha256:cd424af268762cc38b46a9b3bc14ebe51a8c615082847bae9100620c15525065"}, + {"seq":3,"parent_event_id":"sha256:cd424af268762cc38b46a9b3bc14ebe51a8c615082847bae9100620c15525065","event_type":"SUBMIT_OTS","state_before":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"UNANCHORED"},"state_after":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"PENDING"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:ots-proof-pending","observed_at":"2026-07-22T04:03:00Z","event_id":"sha256:5110d0131c3fe5eea49865ea467ed229c48f75763c5e50c1c6776db6d5cb7a18"}, + {"seq":4,"parent_event_id":"sha256:5110d0131c3fe5eea49865ea467ed229c48f75763c5e50c1c6776db6d5cb7a18","event_type":"VERIFY_OTS_SUCCESS","state_before":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"PENDING"},"state_after":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"ANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:ots-verification","observed_at":"2026-07-22T05:00:00Z","temporal_bound":{"kind":"not_later_than","bitcoin_block_height":900001,"attested_before":"2026-07-22T04:55:00Z"},"event_id":"sha256:d2db1fff41daa5b2656e72d0be097963d23085347059287b7fc2a43a5d58c8e8"}, + {"seq":5,"parent_event_id":"sha256:d2db1fff41daa5b2656e72d0be097963d23085347059287b7fc2a43a5d58c8e8","event_type":"SUBMIT_OTS","state_before":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"ANCHORED"},"state_after":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"PENDING"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:new-submit","observed_at":"2026-07-22T06:00:00Z","event_id":"sha256:37235730a1d9e3b4cca169353864a9388f18559027d3b0571749eab7f855c4f0"} + ], + "expected":{"ok":false,"error":"ILLEGAL_AXIS_TRANSITION"} + }, + { + "name":"reject-anchor-without-temporal-bound", + "subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "events":[ + {"seq":0,"parent_event_id":null,"event_type":"COMMIT_SOURCE_HASH","state_before":{"origin":"UNCOMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"COMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:source-hash","observed_at":"2026-07-22T04:00:00Z","event_id":"sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962"}, + {"seq":1,"parent_event_id":"sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962","event_type":"VERIFY_SOURCE_SNAPSHOT","state_before":{"origin":"COMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"REPRODUCIBLE","freshness":"UNKNOWN","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:snapshot","observed_at":"2026-07-22T04:01:00Z","event_id":"sha256:f7325b13c1b69f4482ff2f743210e33a3d2c50e6f83fa4993a3a2b764cb680e0"}, + {"seq":2,"parent_event_id":"sha256:f7325b13c1b69f4482ff2f743210e33a3d2c50e6f83fa4993a3a2b764cb680e0","event_type":"CHECK_SOURCE_FRESH","state_before":{"origin":"REPRODUCIBLE","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:live-fetch","observed_at":"2026-07-22T04:02:00Z","event_id":"sha256:cd424af268762cc38b46a9b3bc14ebe51a8c615082847bae9100620c15525065"}, + {"seq":3,"parent_event_id":"sha256:cd424af268762cc38b46a9b3bc14ebe51a8c615082847bae9100620c15525065","event_type":"SUBMIT_OTS","state_before":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"UNANCHORED"},"state_after":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"PENDING"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:ots-proof-pending","observed_at":"2026-07-22T04:03:00Z","event_id":"sha256:5110d0131c3fe5eea49865ea467ed229c48f75763c5e50c1c6776db6d5cb7a18"}, + {"seq":4,"parent_event_id":"sha256:5110d0131c3fe5eea49865ea467ed229c48f75763c5e50c1c6776db6d5cb7a18","event_type":"VERIFY_OTS_SUCCESS","state_before":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"PENDING"},"state_after":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"ANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:ots-verification","observed_at":"2026-07-22T05:00:00Z","event_id":"sha256:f5da26f3d199b71759c12dde17a33cf1cb56044ad09d7746d5abac3ec71d6b9c"} + ], + "expected":{"ok":false,"error":"MISSING_REQUIRED_TRANSITION_FIELD"} + } + ] +} \ No newline at end of file From a1ad49385ff388bd92991f8cf6bd8fb34b75a745 Mon Sep 17 00:00:00 2001 From: Aleksey Safonov <55020240+safal207@users.noreply.github.com> Date: Wed, 22 Jul 2026 07:59:48 +0300 Subject: [PATCH 04/12] docs: add causal-temporal transition graph --- docs/CAUSAL_TEMPORAL_TRANSITION_GRAPH.md | 201 +++++++++++++++++++++++ 1 file changed, 201 insertions(+) create mode 100644 docs/CAUSAL_TEMPORAL_TRANSITION_GRAPH.md diff --git a/docs/CAUSAL_TEMPORAL_TRANSITION_GRAPH.md b/docs/CAUSAL_TEMPORAL_TRANSITION_GRAPH.md new file mode 100644 index 0000000..02a07ef --- /dev/null +++ b/docs/CAUSAL_TEMPORAL_TRANSITION_GRAPH.md @@ -0,0 +1,201 @@ +# Causal-temporal transition graph + +Status: **experimental stacked profile** +Depends on: `proofpath.temporal-anchor.ots.v0.1` + +## Purpose + +A provenance hash, a live-source check, and a Bitcoin temporal anchor answer +different questions. Combining them into one scalar status loses causality and +can produce false regressions. This profile represents one immutable subject as +a product state: + +```text +S(t) = (origin(t), freshness(t), temporal(t)) +``` + +- `origin` answers whether the historical bytes are committed and reproducible; +- `freshness` answers whether a current source still matches those bytes; +- `temporal` answers whether the exact bytes have an independently verified time upper bound. + +A source can therefore be both `STALE` and `ANCHORED`: the live page changed, +but the historical bytes remain reproducible and were proven to exist before a +Bitcoin block. Those facts must not overwrite each other. + +## Full causal chain + +```mermaid +flowchart LR + A[Knowledge source bytes] -->|COMMIT_SOURCE_HASH| B[Origin: COMMITTED] + B -->|VERIFY_SOURCE_SNAPSHOT| C[Origin: REPRODUCIBLE] + C -->|CHECK_SOURCE_FRESH| D[Freshness: FRESH] + C -->|CHECK_SOURCE_STALE| E[Freshness: STALE] + + C -->|SUBMIT_OTS| F[Temporal: PENDING] + F -->|VERIFY_OTS_SUCCESS| G[Temporal: ANCHORED] + F -->|VERIFY_OTS_UNAVAILABLE| H[Temporal: UNAVAILABLE] + F -->|VERIFY_OTS_INVALID| I[Temporal: INVALID] + + G --> J[Bitcoin block height] + J --> K[External upper bound: bytes existed no later than block time] + + D -. live source changes .-> E + G -. preserved independently .-> E +``` + +## Independent state axes + +### Origin axis + +```mermaid +stateDiagram-v2 + [*] --> UNCOMMITTED + UNCOMMITTED --> COMMITTED: COMMIT_SOURCE_HASH + COMMITTED --> REPRODUCIBLE: VERIFY_SOURCE_SNAPSHOT + UNCOMMITTED --> INVALID: INVALIDATE_SOURCE_ORIGIN + COMMITTED --> INVALID: INVALIDATE_SOURCE_ORIGIN + REPRODUCIBLE --> INVALID: INVALIDATE_SOURCE_ORIGIN +``` + +### Freshness axis + +```mermaid +stateDiagram-v2 + [*] --> UNKNOWN + UNKNOWN --> FRESH: CHECK_SOURCE_FRESH + UNKNOWN --> STALE: CHECK_SOURCE_STALE + FRESH --> FRESH: CHECK_SOURCE_FRESH + FRESH --> STALE: CHECK_SOURCE_STALE + STALE --> STALE: CHECK_SOURCE_STALE + STALE --> FRESH: CHECK_SOURCE_FRESH +``` + +Freshness can change as the live source changes. It does not rewrite the frozen +snapshot or remove an existing temporal anchor. + +### Temporal axis + +```mermaid +stateDiagram-v2 + [*] --> UNANCHORED + UNANCHORED --> PENDING: SUBMIT_OTS + UNAVAILABLE --> PENDING: SUBMIT_OTS + UNANCHORED --> PENDING: VERIFY_OTS_PENDING + PENDING --> PENDING: VERIFY_OTS_PENDING + UNAVAILABLE --> PENDING: VERIFY_OTS_PENDING + UNANCHORED --> ANCHORED: VERIFY_OTS_SUCCESS + PENDING --> ANCHORED: VERIFY_OTS_SUCCESS + UNAVAILABLE --> ANCHORED: VERIFY_OTS_SUCCESS + ANCHORED --> ANCHORED: REVERIFY_OTS_SUCCESS + UNANCHORED --> UNAVAILABLE: VERIFY_OTS_UNAVAILABLE + PENDING --> UNAVAILABLE: VERIFY_OTS_UNAVAILABLE + UNAVAILABLE --> UNAVAILABLE: VERIFY_OTS_UNAVAILABLE + UNANCHORED --> INVALID: VERIFY_OTS_INVALID + PENDING --> INVALID: VERIFY_OTS_INVALID + UNAVAILABLE --> INVALID: VERIFY_OTS_INVALID +``` + +There is intentionally no `ANCHORED → PENDING`, `ANCHORED → UNAVAILABLE`, or +`ANCHORED → INVALID` transition for the same exact subject bytes. A later failed +verification attempt is a new observation; it cannot erase a previously +verified historical fact. A contradiction must be recorded separately and +investigated rather than silently rolling back the state. + +## Event record + +Each transition is an append-only causal event: + +```json +{ + "seq": 4, + "parent_event_id": "sha256:...", + "event_type": "VERIFY_OTS_SUCCESS", + "state_before": { + "origin": "REPRODUCIBLE", + "freshness": "FRESH", + "temporal": "PENDING" + }, + "state_after": { + "origin": "REPRODUCIBLE", + "freshness": "FRESH", + "temporal": "ANCHORED" + }, + "subject_hash": "sha256:...", + "evidence_ref": "evidence:ots-verification", + "observed_at": "2026-07-22T05:00:00Z", + "temporal_bound": { + "kind": "not_later_than", + "bitcoin_block_height": 900001, + "attested_before": "2026-07-22T04:55:00Z" + }, + "event_id": "sha256:..." +} +``` + +`event_id` is SHA-256 over compact, sorted-key UTF-8 JSON of every event member +except `event_id` itself. `parent_event_id` creates the causal chain. + +## Time semantics + +The graph intentionally carries two different time concepts: + +- `observed_at` orders local observations inside one trace. It is operational metadata and remains dependent on the observer clock. +- `temporal_bound.attested_before` is an externally verified upper bound derived from an OTS proof and Bitcoin block. It does not claim the exact creation time. + +`issued_at` is not used to prove temporal precedence. A self-declared timestamp +may be useful metadata, but it cannot replace the external bound. + +## Mechanical invariants + +The checker rejects a trace when any of these invariants fails: + +1. `seq` starts at zero and has no gaps or duplicates; +2. every `parent_event_id` equals the previous recomputed `event_id`; +3. every event recomputes to its declared `event_id`; +4. `subject_hash` never changes inside one trace; +5. `observed_at` never moves backward inside one trace; +6. `state_before` equals the prior event's `state_after`; +7. the event type is declared in the graph; +8. only the transition's declared axis may change; +9. the axis transition must be explicitly allowed; +10. required transition evidence must be present; +11. a successful temporal anchor must carry block height and external upper bound. + +## Deviation signals + +| Deviation | Checker signal | +| --- | --- | +| Missing or duplicate sequence | `SEQUENCE_GAP_OR_DUPLICATE` | +| Broken causal parent | `PARENT_EVENT_MISMATCH` | +| Event bytes modified | `EVENT_ID_MISMATCH` | +| Different subject inserted into trace | `SUBJECT_HASH_DRIFT` | +| Observer time moved backward | `OBSERVED_AT_REGRESSION` | +| State does not continue from prior event | `STATE_BEFORE_MISMATCH` | +| Unknown event type | `UNDECLARED_TRANSITION` | +| Forbidden state move | `ILLEGAL_AXIS_TRANSITION` | +| A transition changes another axis | `UNDECLARED_AXIS_MUTATION` | +| Evidence omitted | `MISSING_TRANSITION_EVIDENCE` | +| Anchor omits block/time bound | `MISSING_REQUIRED_TRANSITION_FIELD` | + +## Supersession boundary + +Re-extracting changed source bytes creates a new `subject_hash` and therefore a +new trace. It must not mutate the prior trace. A separate record may connect the +new trace with `supersedes_trace_ref`, but each trace remains independently +recomputable. + +This rule distinguishes: + +```text +same subject + new observation → append event to existing trace +new subject bytes → create new trace and link by supersession +``` + +## Scope boundary + +This profile proves transition consistency for recorded events. It does not +prove that every real-world event was recorded. Completeness requires an +independent boundary or seal that commits to the expected event count or time +window. The graph catches mutation, gaps inside the held chain, illegal moves, +and semantic drift; it cannot detect an entirely omitted unsealed suffix by +itself. From 61b9ee889c23e902bfe296fd286c20b4ab9451f9 Mon Sep 17 00:00:00 2001 From: Aleksey Safonov <55020240+safal207@users.noreply.github.com> Date: Wed, 22 Jul 2026 08:00:45 +0300 Subject: [PATCH 05/12] test: add sealed causal trace completeness --- scripts/check_causal_temporal_graph.py | 40 ++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/scripts/check_causal_temporal_graph.py b/scripts/check_causal_temporal_graph.py index 1aa3b27..411d672 100644 --- a/scripts/check_causal_temporal_graph.py +++ b/scripts/check_causal_temporal_graph.py @@ -29,6 +29,11 @@ def recompute_event_id(event: dict[str, Any]) -> str: return "sha256:" + hashlib.sha256(canonical_bytes(preimage)).hexdigest() +def recompute_seal_id(seal: dict[str, Any]) -> str: + preimage = {key: value for key, value in seal.items() if key != "seal_id"} + return "sha256:" + hashlib.sha256(canonical_bytes(preimage)).hexdigest() + + def parse_time(value: str) -> datetime: if value.endswith("Z"): value = value[:-1] + "+00:00" @@ -80,7 +85,12 @@ def fail(code: str, seq: int | None = None) -> dict[str, Any]: return result -def verify_trace(graph: dict[str, Any], case: dict[str, Any]) -> dict[str, Any]: +def verify_trace( + graph: dict[str, Any], + case: dict[str, Any], + *, + require_seal: bool = False, +) -> dict[str, Any]: transitions = {item["event_type"]: item for item in graph["transitions"]} axes = graph["axes"] expected_axes = set(axes) @@ -155,6 +165,28 @@ def verify_trace(graph: dict[str, Any], case: dict[str, Any]) -> dict[str, Any]: previous_id = event_id previous_time = observed_at + seal = case.get("seal") + if require_seal and seal is None: + return fail("TRACE_SEAL_MISSING") + + if seal is not None: + if not isinstance(seal, dict): + return fail("INVALID_TRACE_SEAL") + if seal.get("seal_id") != recompute_seal_id(seal): + return fail("TRACE_SEAL_ID_MISMATCH") + if seal.get("subject_hash") != subject_hash: + return fail("TRACE_SEAL_SUBJECT_MISMATCH") + if seal.get("total_events") != len(events): + return fail("TRACE_TOTAL_MISMATCH") + if seal.get("terminal_event_id") != previous_id: + return fail("TRACE_TERMINAL_EVENT_MISMATCH") + try: + sealed_at = parse_time(seal["sealed_at"]) + except (KeyError, TypeError, ValueError): + return fail("INVALID_SEALED_AT") + if previous_time is not None and sealed_at < previous_time: + return fail("SEALED_AT_REGRESSION") + return { "ok": True, "error": None, @@ -176,7 +208,11 @@ def main(argv: Sequence[str] | None = None) -> int: failures = 0 for case in vectors["cases"]: - actual = verify_trace(graph, case) + actual = verify_trace( + graph, + case, + require_seal=bool(vectors.get("require_seal", False)), + ) expected = case["expected"] projection = {key: actual.get(key) for key in expected} if projection != expected: From 21f3997aa70407157fd5c37babccd7dd66868bcb Mon Sep 17 00:00:00 2001 From: Aleksey Safonov <55020240+safal207@users.noreply.github.com> Date: Wed, 22 Jul 2026 08:01:30 +0300 Subject: [PATCH 06/12] test: add sealed trace completeness vectors --- .../causal-temporal/sealed-vectors.json | 171 ++++++++++++++++++ 1 file changed, 171 insertions(+) create mode 100644 conformance/guardrail-decision-v1/causal-temporal/sealed-vectors.json diff --git a/conformance/guardrail-decision-v1/causal-temporal/sealed-vectors.json b/conformance/guardrail-decision-v1/causal-temporal/sealed-vectors.json new file mode 100644 index 0000000..38df63e --- /dev/null +++ b/conformance/guardrail-decision-v1/causal-temporal/sealed-vectors.json @@ -0,0 +1,171 @@ +{ + "schema": "proofpath.causal-temporal-sealed-vectors.v0.1", + "require_seal": true, + "cases": [ + { + "name": "valid-sealed-trace", + "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "events": [ + { + "seq": 0, + "parent_event_id": null, + "event_type": "COMMIT_SOURCE_HASH", + "state_before": {"origin":"UNCOMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"}, + "state_after": {"origin":"COMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"}, + "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "evidence_ref": "evidence:source-hash", + "observed_at": "2026-07-22T04:00:00Z", + "event_id": "sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962" + }, + { + "seq": 1, + "parent_event_id": "sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962", + "event_type": "VERIFY_SOURCE_SNAPSHOT", + "state_before": {"origin":"COMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"}, + "state_after": {"origin":"REPRODUCIBLE","freshness":"UNKNOWN","temporal":"UNANCHORED"}, + "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "evidence_ref": "evidence:snapshot", + "observed_at": "2026-07-22T04:01:00Z", + "event_id": "sha256:f7325b13c1b69f4482ff2f743210e33a3d2c50e6f83fa4993a3a2b764cb680e0" + }, + { + "seq": 2, + "parent_event_id": "sha256:f7325b13c1b69f4482ff2f743210e33a3d2c50e6f83fa4993a3a2b764cb680e0", + "event_type": "CHECK_SOURCE_FRESH", + "state_before": {"origin":"REPRODUCIBLE","freshness":"UNKNOWN","temporal":"UNANCHORED"}, + "state_after": {"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"UNANCHORED"}, + "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "evidence_ref": "evidence:live-fetch", + "observed_at": "2026-07-22T04:02:00Z", + "event_id": "sha256:cd424af268762cc38b46a9b3bc14ebe51a8c615082847bae9100620c15525065" + }, + { + "seq": 3, + "parent_event_id": "sha256:cd424af268762cc38b46a9b3bc14ebe51a8c615082847bae9100620c15525065", + "event_type": "SUBMIT_OTS", + "state_before": {"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"UNANCHORED"}, + "state_after": {"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"PENDING"}, + "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "evidence_ref": "evidence:ots-proof-pending", + "observed_at": "2026-07-22T04:03:00Z", + "event_id": "sha256:5110d0131c3fe5eea49865ea467ed229c48f75763c5e50c1c6776db6d5cb7a18" + }, + { + "seq": 4, + "parent_event_id": "sha256:5110d0131c3fe5eea49865ea467ed229c48f75763c5e50c1c6776db6d5cb7a18", + "event_type": "VERIFY_OTS_SUCCESS", + "state_before": {"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"PENDING"}, + "state_after": {"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"ANCHORED"}, + "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "evidence_ref": "evidence:ots-verification", + "observed_at": "2026-07-22T05:00:00Z", + "temporal_bound": {"kind":"not_later_than","bitcoin_block_height":900001,"attested_before":"2026-07-22T04:55:00Z"}, + "event_id": "sha256:d2db1fff41daa5b2656e72d0be097963d23085347059287b7fc2a43a5d58c8e8" + } + ], + "seal": { + "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "total_events": 5, + "terminal_event_id": "sha256:d2db1fff41daa5b2656e72d0be097963d23085347059287b7fc2a43a5d58c8e8", + "sealed_at": "2026-07-22T05:01:00Z", + "seal_id": "sha256:cc765068061e280cf3ae88fef87b655d48ed2a8ee9523daa18cccb446780d5d5" + }, + "expected": {"ok":true,"error":null,"event_count":5} + }, + { + "name": "reject-dropped-tail-against-seal", + "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "events": [ + { + "seq": 0,"parent_event_id":null,"event_type":"COMMIT_SOURCE_HASH","state_before":{"origin":"UNCOMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"COMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:source-hash","observed_at":"2026-07-22T04:00:00Z","event_id":"sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962" + }, + { + "seq": 1,"parent_event_id":"sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962","event_type":"VERIFY_SOURCE_SNAPSHOT","state_before":{"origin":"COMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"REPRODUCIBLE","freshness":"UNKNOWN","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:snapshot","observed_at":"2026-07-22T04:01:00Z","event_id":"sha256:f7325b13c1b69f4482ff2f743210e33a3d2c50e6f83fa4993a3a2b764cb680e0" + }, + { + "seq": 2,"parent_event_id":"sha256:f7325b13c1b69f4482ff2f743210e33a3d2c50e6f83fa4993a3a2b764cb680e0","event_type":"CHECK_SOURCE_FRESH","state_before":{"origin":"REPRODUCIBLE","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:live-fetch","observed_at":"2026-07-22T04:02:00Z","event_id":"sha256:cd424af268762cc38b46a9b3bc14ebe51a8c615082847bae9100620c15525065" + }, + { + "seq": 3,"parent_event_id":"sha256:cd424af268762cc38b46a9b3bc14ebe51a8c615082847bae9100620c15525065","event_type":"SUBMIT_OTS","state_before":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"UNANCHORED"},"state_after":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"PENDING"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:ots-proof-pending","observed_at":"2026-07-22T04:03:00Z","event_id":"sha256:5110d0131c3fe5eea49865ea467ed229c48f75763c5e50c1c6776db6d5cb7a18" + } + ], + "seal": { + "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "total_events": 5, + "terminal_event_id": "sha256:d2db1fff41daa5b2656e72d0be097963d23085347059287b7fc2a43a5d58c8e8", + "sealed_at": "2026-07-22T05:01:00Z", + "seal_id": "sha256:cc765068061e280cf3ae88fef87b655d48ed2a8ee9523daa18cccb446780d5d5" + }, + "expected": {"ok":false,"error":"TRACE_TOTAL_MISMATCH"} + }, + { + "name": "reject-missing-trace-seal", + "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "events": [ + {"seq":0,"parent_event_id":null,"event_type":"COMMIT_SOURCE_HASH","state_before":{"origin":"UNCOMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"COMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:source-hash","observed_at":"2026-07-22T04:00:00Z","event_id":"sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962"}, + {"seq":1,"parent_event_id":"sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962","event_type":"VERIFY_SOURCE_SNAPSHOT","state_before":{"origin":"COMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"REPRODUCIBLE","freshness":"UNKNOWN","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:snapshot","observed_at":"2026-07-22T04:01:00Z","event_id":"sha256:f7325b13c1b69f4482ff2f743210e33a3d2c50e6f83fa4993a3a2b764cb680e0"}, + {"seq":2,"parent_event_id":"sha256:f7325b13c1b69f4482ff2f743210e33a3d2c50e6f83fa4993a3a2b764cb680e0","event_type":"CHECK_SOURCE_FRESH","state_before":{"origin":"REPRODUCIBLE","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:live-fetch","observed_at":"2026-07-22T04:02:00Z","event_id":"sha256:cd424af268762cc38b46a9b3bc14ebe51a8c615082847bae9100620c15525065"}, + {"seq":3,"parent_event_id":"sha256:cd424af268762cc38b46a9b3bc14ebe51a8c615082847bae9100620c15525065","event_type":"SUBMIT_OTS","state_before":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"UNANCHORED"},"state_after":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"PENDING"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:ots-proof-pending","observed_at":"2026-07-22T04:03:00Z","event_id":"sha256:5110d0131c3fe5eea49865ea467ed229c48f75763c5e50c1c6776db6d5cb7a18"}, + {"seq":4,"parent_event_id":"sha256:5110d0131c3fe5eea49865ea467ed229c48f75763c5e50c1c6776db6d5cb7a18","event_type":"VERIFY_OTS_SUCCESS","state_before":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"PENDING"},"state_after":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"ANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:ots-verification","observed_at":"2026-07-22T05:00:00Z","temporal_bound":{"kind":"not_later_than","bitcoin_block_height":900001,"attested_before":"2026-07-22T04:55:00Z"},"event_id":"sha256:d2db1fff41daa5b2656e72d0be097963d23085347059287b7fc2a43a5d58c8e8"} + ], + "expected": {"ok":false,"error":"TRACE_SEAL_MISSING"} + }, + { + "name": "reject-tampered-seal-id", + "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "events": [ + {"seq":0,"parent_event_id":null,"event_type":"COMMIT_SOURCE_HASH","state_before":{"origin":"UNCOMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"COMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:source-hash","observed_at":"2026-07-22T04:00:00Z","event_id":"sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962"}, + {"seq":1,"parent_event_id":"sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962","event_type":"VERIFY_SOURCE_SNAPSHOT","state_before":{"origin":"COMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"REPRODUCIBLE","freshness":"UNKNOWN","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:snapshot","observed_at":"2026-07-22T04:01:00Z","event_id":"sha256:f7325b13c1b69f4482ff2f743210e33a3d2c50e6f83fa4993a3a2b764cb680e0"}, + {"seq":2,"parent_event_id":"sha256:f7325b13c1b69f4482ff2f743210e33a3d2c50e6f83fa4993a3a2b764cb680e0","event_type":"CHECK_SOURCE_FRESH","state_before":{"origin":"REPRODUCIBLE","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:live-fetch","observed_at":"2026-07-22T04:02:00Z","event_id":"sha256:cd424af268762cc38b46a9b3bc14ebe51a8c615082847bae9100620c15525065"}, + {"seq":3,"parent_event_id":"sha256:cd424af268762cc38b46a9b3bc14ebe51a8c615082847bae9100620c15525065","event_type":"SUBMIT_OTS","state_before":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"UNANCHORED"},"state_after":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"PENDING"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:ots-proof-pending","observed_at":"2026-07-22T04:03:00Z","event_id":"sha256:5110d0131c3fe5eea49865ea467ed229c48f75763c5e50c1c6776db6d5cb7a18"}, + {"seq":4,"parent_event_id":"sha256:5110d0131c3fe5eea49865ea467ed229c48f75763c5e50c1c6776db6d5cb7a18","event_type":"VERIFY_OTS_SUCCESS","state_before":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"PENDING"},"state_after":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"ANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:ots-verification","observed_at":"2026-07-22T05:00:00Z","temporal_bound":{"kind":"not_later_than","bitcoin_block_height":900001,"attested_before":"2026-07-22T04:55:00Z"},"event_id":"sha256:d2db1fff41daa5b2656e72d0be097963d23085347059287b7fc2a43a5d58c8e8"} + ], + "seal": { + "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "total_events": 5, + "terminal_event_id": "sha256:d2db1fff41daa5b2656e72d0be097963d23085347059287b7fc2a43a5d58c8e8", + "sealed_at": "2026-07-22T05:01:00Z", + "seal_id": "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" + }, + "expected": {"ok":false,"error":"TRACE_SEAL_ID_MISMATCH"} + }, + { + "name": "reject-terminal-event-mismatch", + "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "events": [ + {"seq":0,"parent_event_id":null,"event_type":"COMMIT_SOURCE_HASH","state_before":{"origin":"UNCOMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"COMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:source-hash","observed_at":"2026-07-22T04:00:00Z","event_id":"sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962"}, + {"seq":1,"parent_event_id":"sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962","event_type":"VERIFY_SOURCE_SNAPSHOT","state_before":{"origin":"COMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"REPRODUCIBLE","freshness":"UNKNOWN","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:snapshot","observed_at":"2026-07-22T04:01:00Z","event_id":"sha256:f7325b13c1b69f4482ff2f743210e33a3d2c50e6f83fa4993a3a2b764cb680e0"}, + {"seq":2,"parent_event_id":"sha256:f7325b13c1b69f4482ff2f743210e33a3d2c50e6f83fa4993a3a2b764cb680e0","event_type":"CHECK_SOURCE_FRESH","state_before":{"origin":"REPRODUCIBLE","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:live-fetch","observed_at":"2026-07-22T04:02:00Z","event_id":"sha256:cd424af268762cc38b46a9b3bc14ebe51a8c615082847bae9100620c15525065"}, + {"seq":3,"parent_event_id":"sha256:cd424af268762cc38b46a9b3bc14ebe51a8c615082847bae9100620c15525065","event_type":"SUBMIT_OTS","state_before":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"UNANCHORED"},"state_after":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"PENDING"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:ots-proof-pending","observed_at":"2026-07-22T04:03:00Z","event_id":"sha256:5110d0131c3fe5eea49865ea467ed229c48f75763c5e50c1c6776db6d5cb7a18"}, + {"seq":4,"parent_event_id":"sha256:5110d0131c3fe5eea49865ea467ed229c48f75763c5e50c1c6776db6d5cb7a18","event_type":"VERIFY_OTS_SUCCESS","state_before":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"PENDING"},"state_after":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"ANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:ots-verification","observed_at":"2026-07-22T05:00:00Z","temporal_bound":{"kind":"not_later_than","bitcoin_block_height":900001,"attested_before":"2026-07-22T04:55:00Z"},"event_id":"sha256:d2db1fff41daa5b2656e72d0be097963d23085347059287b7fc2a43a5d58c8e8"} + ], + "seal": { + "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "total_events": 5, + "terminal_event_id": "sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "sealed_at": "2026-07-22T05:01:00Z", + "seal_id": "sha256:9b9589c627097265e4b5781cf882274866f9e2d0092a8119ff9d540116b3bb4d" + }, + "expected": {"ok":false,"error":"TRACE_TERMINAL_EVENT_MISMATCH"} + }, + { + "name": "reject-sealed-at-regression", + "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "events": [ + {"seq":0,"parent_event_id":null,"event_type":"COMMIT_SOURCE_HASH","state_before":{"origin":"UNCOMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"COMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:source-hash","observed_at":"2026-07-22T04:00:00Z","event_id":"sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962"}, + {"seq":1,"parent_event_id":"sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962","event_type":"VERIFY_SOURCE_SNAPSHOT","state_before":{"origin":"COMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"REPRODUCIBLE","freshness":"UNKNOWN","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:snapshot","observed_at":"2026-07-22T04:01:00Z","event_id":"sha256:f7325b13c1b69f4482ff2f743210e33a3d2c50e6f83fa4993a3a2b764cb680e0"}, + {"seq":2,"parent_event_id":"sha256:f7325b13c1b69f4482ff2f743210e33a3d2c50e6f83fa4993a3a2b764cb680e0","event_type":"CHECK_SOURCE_FRESH","state_before":{"origin":"REPRODUCIBLE","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:live-fetch","observed_at":"2026-07-22T04:02:00Z","event_id":"sha256:cd424af268762cc38b46a9b3bc14ebe51a8c615082847bae9100620c15525065"}, + {"seq":3,"parent_event_id":"sha256:cd424af268762cc38b46a9b3bc14ebe51a8c615082847bae9100620c15525065","event_type":"SUBMIT_OTS","state_before":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"UNANCHORED"},"state_after":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"PENDING"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:ots-proof-pending","observed_at":"2026-07-22T04:03:00Z","event_id":"sha256:5110d0131c3fe5eea49865ea467ed229c48f75763c5e50c1c6776db6d5cb7a18"}, + {"seq":4,"parent_event_id":"sha256:5110d0131c3fe5eea49865ea467ed229c48f75763c5e50c1c6776db6d5cb7a18","event_type":"VERIFY_OTS_SUCCESS","state_before":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"PENDING"},"state_after":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"ANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:ots-verification","observed_at":"2026-07-22T05:00:00Z","temporal_bound":{"kind":"not_later_than","bitcoin_block_height":900001,"attested_before":"2026-07-22T04:55:00Z"},"event_id":"sha256:d2db1fff41daa5b2656e72d0be097963d23085347059287b7fc2a43a5d58c8e8"} + ], + "seal": { + "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "total_events": 5, + "terminal_event_id": "sha256:d2db1fff41daa5b2656e72d0be097963d23085347059287b7fc2a43a5d58c8e8", + "sealed_at": "2026-07-22T04:59:00Z", + "seal_id": "sha256:46cd731531de9f9dfa8799e06bad9a6816f7f7db6592a5188ab04ac6bf9e932f" + }, + "expected": {"ok":false,"error":"SEALED_AT_REGRESSION"} + } + ] +} \ No newline at end of file From c548753b6975c4939125668bf54ef63ab8a324dc Mon Sep 17 00:00:00 2001 From: Aleksey Safonov <55020240+safal207@users.noreply.github.com> Date: Wed, 22 Jul 2026 08:01:39 +0300 Subject: [PATCH 07/12] docs: add causal graph conformance runbook --- .../causal-temporal/README.md | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 conformance/guardrail-decision-v1/causal-temporal/README.md diff --git a/conformance/guardrail-decision-v1/causal-temporal/README.md b/conformance/guardrail-decision-v1/causal-temporal/README.md new file mode 100644 index 0000000..7632248 --- /dev/null +++ b/conformance/guardrail-decision-v1/causal-temporal/README.md @@ -0,0 +1,61 @@ +# Causal-temporal transition conformance + +This corpus verifies a product-state graph for one immutable subject hash across +three independent axes: + +- origin: `UNCOMMITTED → COMMITTED → REPRODUCIBLE`; +- freshness: `UNKNOWN ↔ FRESH ↔ STALE`; +- temporal: `UNANCHORED → PENDING → ANCHORED` with bounded failure states. + +The design prevents one fact from overwriting another. A source can be stale +while its historical bytes remain reproducible and temporally anchored. + +## Run + +```bash +python3 scripts/check_causal_temporal_graph.py \ + conformance/guardrail-decision-v1/causal-temporal/graph.json \ + conformance/guardrail-decision-v1/causal-temporal/vectors.json + +python3 scripts/check_causal_temporal_graph.py \ + conformance/guardrail-decision-v1/causal-temporal/graph.json \ + conformance/guardrail-decision-v1/causal-temporal/sealed-vectors.json +``` + +Expected results: + +```text +Causal-temporal graph conformance passed: 12 +Causal-temporal graph conformance passed: 6 +``` + +## What the unsealed corpus catches + +- illegal or undeclared transitions; +- sequence gaps and duplicates; +- broken parent links; +- event-byte mutation; +- subject-hash drift; +- local observation-time regression; +- undeclared mutation of a second state axis; +- missing evidence; +- temporal-anchor success without block/time bounds; +- attempted `ANCHORED → PENDING` rollback. + +## What the sealed corpus adds + +A trace seal commits to: + +```text +subject_hash + total_events + terminal_event_id + sealed_at +``` + +This catches a silently dropped suffix inside the declared boundary. Without a +seal, a complete-looking prefix cannot prove that no tail was removed. + +## Scope + +The checker validates the consistency and bounded completeness of recorded +events. It cannot prove that the chosen seal boundary corresponds to every +real-world event that should have happened; boundary governance remains a +separate concern. From 76f8ad5723719c94181e7f5930de376fe1e48b19 Mon Sep 17 00:00:00 2001 From: Aleksey Safonov <55020240+safal207@users.noreply.github.com> Date: Wed, 22 Jul 2026 08:02:01 +0300 Subject: [PATCH 08/12] docs: define causal trace seal --- docs/CAUSAL_TEMPORAL_TRACE_SEAL.md | 63 ++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 docs/CAUSAL_TEMPORAL_TRACE_SEAL.md diff --git a/docs/CAUSAL_TEMPORAL_TRACE_SEAL.md b/docs/CAUSAL_TEMPORAL_TRACE_SEAL.md new file mode 100644 index 0000000..f352753 --- /dev/null +++ b/docs/CAUSAL_TEMPORAL_TRACE_SEAL.md @@ -0,0 +1,63 @@ +# Causal-temporal trace seal + +Status: **experimental completeness sidecar** +Companion to: `proofpath.causal-temporal-graph.v0.1` + +## Why a seal is needed + +A parent-linked hash chain exposes mutation and an omitted event in the middle. +It cannot, by itself, distinguish a complete chain from a prefix whose entire +tail was removed. A trace seal closes that bounded-completeness gap by declaring +where the trace ends. + +## Seal shape + +```json +{ + "subject_hash": "sha256:...", + "total_events": 5, + "terminal_event_id": "sha256:...", + "sealed_at": "2026-07-22T05:01:00Z", + "seal_id": "sha256:..." +} +``` + +`seal_id` is SHA-256 over compact sorted-key UTF-8 JSON of all members except +`seal_id`. + +## Verification + +A sealed trace is accepted only when: + +1. the seal itself recomputes; +2. `subject_hash` equals the trace subject; +3. `total_events` equals the held event count; +4. `terminal_event_id` equals the last recomputed event ID; +5. `sealed_at` is not earlier than the final `observed_at`. + +The checker returns explicit signals: + +- `TRACE_SEAL_MISSING`; +- `TRACE_SEAL_ID_MISMATCH`; +- `TRACE_SEAL_SUBJECT_MISMATCH`; +- `TRACE_TOTAL_MISMATCH`; +- `TRACE_TERMINAL_EVENT_MISMATCH`; +- `INVALID_SEALED_AT`; +- `SEALED_AT_REGRESSION`. + +## Causal boundary + +A seal proves completeness only relative to the boundary it declares. It does +not prove that a producer chose the correct real-world boundary or recorded all +external events before sealing. Governance of who may seal, when sealing is +required, and how seals are externally witnessed remains a separate layer. + +For stronger temporal evidence, the seal bytes themselves may be submitted to +the OpenTimestamps profile. That produces two independent guarantees: + +```text +trace seal → bounded event completeness +OTS proof → seal bytes existed no later than a Bitcoin block +``` + +Neither guarantee substitutes for the other. From 9e1292c6fd4df6838f4bea2a46963325c2b398c8 Mon Sep 17 00:00:00 2001 From: Aleksey Safonov <55020240+safal207@users.noreply.github.com> Date: Wed, 22 Jul 2026 08:02:09 +0300 Subject: [PATCH 09/12] ci: verify causal-temporal graph and seal --- .../causal-temporal-transition-graph.yml | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 .github/workflows/causal-temporal-transition-graph.yml diff --git a/.github/workflows/causal-temporal-transition-graph.yml b/.github/workflows/causal-temporal-transition-graph.yml new file mode 100644 index 0000000..c1dae6d --- /dev/null +++ b/.github/workflows/causal-temporal-transition-graph.yml @@ -0,0 +1,43 @@ +name: Causal-temporal transition graph + +on: + pull_request: + paths: + - "scripts/check_causal_temporal_graph.py" + - "conformance/guardrail-decision-v1/causal-temporal/**" + - "docs/CAUSAL_TEMPORAL_TRANSITION_GRAPH.md" + - "docs/CAUSAL_TEMPORAL_TRACE_SEAL.md" + - ".github/workflows/causal-temporal-transition-graph.yml" + push: + branches: + - main + paths: + - "scripts/check_causal_temporal_graph.py" + - "conformance/guardrail-decision-v1/causal-temporal/**" + - "docs/CAUSAL_TEMPORAL_TRANSITION_GRAPH.md" + - "docs/CAUSAL_TEMPORAL_TRACE_SEAL.md" + - ".github/workflows/causal-temporal-transition-graph.yml" + +permissions: + contents: read + +jobs: + conformance: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + persist-credentials: false + - uses: actions/setup-python@v5 + with: + python-version: "3.12" + - name: Validate causal transition vectors + run: | + python3 scripts/check_causal_temporal_graph.py \ + conformance/guardrail-decision-v1/causal-temporal/graph.json \ + conformance/guardrail-decision-v1/causal-temporal/vectors.json + - name: Validate sealed trace completeness + run: | + python3 scripts/check_causal_temporal_graph.py \ + conformance/guardrail-decision-v1/causal-temporal/graph.json \ + conformance/guardrail-decision-v1/causal-temporal/sealed-vectors.json From b887deaf5579ebf564db4de9a5789863af4d239b Mon Sep 17 00:00:00 2001 From: Aleksey Safonov <55020240+safal207@users.noreply.github.com> Date: Wed, 22 Jul 2026 08:04:48 +0300 Subject: [PATCH 10/12] refactor: derive causal vectors from canonical base trace --- scripts/check_causal_temporal_graph.py | 63 ++++++++++++++++++++++---- 1 file changed, 53 insertions(+), 10 deletions(-) diff --git a/scripts/check_causal_temporal_graph.py b/scripts/check_causal_temporal_graph.py index 411d672..6973287 100644 --- a/scripts/check_causal_temporal_graph.py +++ b/scripts/check_causal_temporal_graph.py @@ -4,6 +4,7 @@ from __future__ import annotations import argparse +import copy import hashlib import json import re @@ -34,6 +35,55 @@ def recompute_seal_id(seal: dict[str, Any]) -> str: return "sha256:" + hashlib.sha256(canonical_bytes(preimage)).hexdigest() +def _path_parts(path: str) -> list[str | int]: + return [int(part) if part.isdigit() else part for part in path.split(".")] + + +def _resolve_parent(root: Any, path: str) -> tuple[Any, str | int]: + parts = _path_parts(path) + if not parts: + raise ValueError("empty mutation path") + current = root + for part in parts[:-1]: + current = current[part] + return current, parts[-1] + + +def materialize_case(vectors: dict[str, Any], case: dict[str, Any]) -> dict[str, Any]: + if "events" in case: + return case + if "base_trace" not in vectors: + raise ValueError(f"case {case.get('name')} has no events and no base_trace") + + materialized = copy.deepcopy(vectors["base_trace"]) + materialized["name"] = case["name"] + materialized["expected"] = case["expected"] + + for mutation in case.get("mutations", []): + op = mutation["op"] + if op == "set": + parent, key = _resolve_parent(materialized, mutation["path"]) + parent[key] = copy.deepcopy(mutation["value"]) + elif op == "delete": + parent, key = _resolve_parent(materialized, mutation["path"]) + del parent[key] + elif op == "append_event": + materialized["events"].append(copy.deepcopy(mutation["value"])) + elif op == "truncate_events": + materialized["events"] = materialized["events"][: int(mutation["count"])] + elif op == "recompute_event_id": + index = int(mutation["index"]) + materialized["events"][index]["event_id"] = recompute_event_id( + materialized["events"][index] + ) + elif op == "recompute_seal_id": + materialized["seal"]["seal_id"] = recompute_seal_id(materialized["seal"]) + else: + raise ValueError(f"unknown mutation op: {op}") + + return materialized + + def parse_time(value: str) -> datetime: if value.endswith("Z"): value = value[:-1] + "+00:00" @@ -104,13 +154,10 @@ def verify_trace( events = case["events"] for index, event in enumerate(events): - seq = event.get("seq") - if seq != index: + if event.get("seq") != index: return fail("SEQUENCE_GAP_OR_DUPLICATE", index) - if event.get("parent_event_id") != previous_id: return fail("PARENT_EVENT_MISMATCH", index) - if event.get("subject_hash") != subject_hash: return fail("SUBJECT_HASH_DRIFT", index) @@ -134,25 +181,21 @@ def verify_trace( for axis, spec in axes.items(): if before[axis] not in spec["states"] or after[axis] not in spec["states"]: return fail("UNKNOWN_STATE", index) - if before != current: return fail("STATE_BEFORE_MISMATCH", index) transition = transitions.get(event.get("event_type")) if transition is None: return fail("UNDECLARED_TRANSITION", index) - axis = transition["axis"] if before[axis] not in transition["from"] or after[axis] != transition["to"]: return fail("ILLEGAL_AXIS_TRANSITION", index) - for untouched_axis in expected_axes - {axis}: if before[untouched_axis] != after[untouched_axis]: return fail("UNDECLARED_AXIS_MUTATION", index) if transition.get("evidence_required") and not event.get("evidence_ref"): return fail("MISSING_TRANSITION_EVIDENCE", index) - for required_path in transition.get("required_fields", []): try: required_value = get_dotted(event, required_path) @@ -168,7 +211,6 @@ def verify_trace( seal = case.get("seal") if require_seal and seal is None: return fail("TRACE_SEAL_MISSING") - if seal is not None: if not isinstance(seal, dict): return fail("INVALID_TRACE_SEAL") @@ -207,7 +249,8 @@ def main(argv: Sequence[str] | None = None) -> int: validate_graph(graph) failures = 0 - for case in vectors["cases"]: + for case_spec in vectors["cases"]: + case = materialize_case(vectors, case_spec) actual = verify_trace( graph, case, From fbea854e3664de9a3773d7b891b83beca7120c6f Mon Sep 17 00:00:00 2001 From: Aleksey Safonov <55020240+safal207@users.noreply.github.com> Date: Wed, 22 Jul 2026 08:05:11 +0300 Subject: [PATCH 11/12] test: compact causal transition vectors --- .../causal-temporal/vectors.json | 485 +++++------------- 1 file changed, 129 insertions(+), 356 deletions(-) diff --git a/conformance/guardrail-decision-v1/causal-temporal/vectors.json b/conformance/guardrail-decision-v1/causal-temporal/vectors.json index 29b4558..b501d99 100644 --- a/conformance/guardrail-decision-v1/causal-temporal/vectors.json +++ b/conformance/guardrail-decision-v1/causal-temporal/vectors.json @@ -1,407 +1,180 @@ { - "schema": "proofpath.causal-temporal-vectors.v0.1", + "schema": "proofpath.causal-temporal-vectors.v0.2", + "base_trace": { + "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "events": [ + { + "seq": 0, + "parent_event_id": null, + "event_type": "COMMIT_SOURCE_HASH", + "state_before": {"origin":"UNCOMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"}, + "state_after": {"origin":"COMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"}, + "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "evidence_ref": "evidence:source-hash", + "observed_at": "2026-07-22T04:00:00Z", + "event_id": "sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962" + }, + { + "seq": 1, + "parent_event_id": "sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962", + "event_type": "VERIFY_SOURCE_SNAPSHOT", + "state_before": {"origin":"COMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"}, + "state_after": {"origin":"REPRODUCIBLE","freshness":"UNKNOWN","temporal":"UNANCHORED"}, + "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "evidence_ref": "evidence:snapshot", + "observed_at": "2026-07-22T04:01:00Z", + "event_id": "sha256:f7325b13c1b69f4482ff2f743210e33a3d2c50e6f83fa4993a3a2b764cb680e0" + }, + { + "seq": 2, + "parent_event_id": "sha256:f7325b13c1b69f4482ff2f743210e33a3d2c50e6f83fa4993a3a2b764cb680e0", + "event_type": "CHECK_SOURCE_FRESH", + "state_before": {"origin":"REPRODUCIBLE","freshness":"UNKNOWN","temporal":"UNANCHORED"}, + "state_after": {"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"UNANCHORED"}, + "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "evidence_ref": "evidence:live-fetch", + "observed_at": "2026-07-22T04:02:00Z", + "event_id": "sha256:cd424af268762cc38b46a9b3bc14ebe51a8c615082847bae9100620c15525065" + }, + { + "seq": 3, + "parent_event_id": "sha256:cd424af268762cc38b46a9b3bc14ebe51a8c615082847bae9100620c15525065", + "event_type": "SUBMIT_OTS", + "state_before": {"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"UNANCHORED"}, + "state_after": {"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"PENDING"}, + "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "evidence_ref": "evidence:ots-proof-pending", + "observed_at": "2026-07-22T04:03:00Z", + "event_id": "sha256:5110d0131c3fe5eea49865ea467ed229c48f75763c5e50c1c6776db6d5cb7a18" + }, + { + "seq": 4, + "parent_event_id": "sha256:5110d0131c3fe5eea49865ea467ed229c48f75763c5e50c1c6776db6d5cb7a18", + "event_type": "VERIFY_OTS_SUCCESS", + "state_before": {"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"PENDING"}, + "state_after": {"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"ANCHORED"}, + "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "evidence_ref": "evidence:ots-verification", + "observed_at": "2026-07-22T05:00:00Z", + "temporal_bound": {"kind":"not_later_than","bitcoin_block_height":900001,"attested_before":"2026-07-22T04:55:00Z"}, + "event_id": "sha256:d2db1fff41daa5b2656e72d0be097963d23085347059287b7fc2a43a5d58c8e8" + } + ] + }, "cases": [ { "name": "valid-full-causal-chain", - "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "events": [ - { - "seq": 0, - "parent_event_id": null, - "event_type": "COMMIT_SOURCE_HASH", - "state_before": { - "origin": "UNCOMMITTED", - "freshness": "UNKNOWN", - "temporal": "UNANCHORED" - }, - "state_after": { - "origin": "COMMITTED", - "freshness": "UNKNOWN", - "temporal": "UNANCHORED" - }, - "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "evidence_ref": "evidence:source-hash", - "observed_at": "2026-07-22T04:00:00Z", - "event_id": "sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962" - }, - { - "seq": 1, - "parent_event_id": "sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962", - "event_type": "VERIFY_SOURCE_SNAPSHOT", - "state_before": { - "origin": "COMMITTED", - "freshness": "UNKNOWN", - "temporal": "UNANCHORED" - }, - "state_after": { - "origin": "REPRODUCIBLE", - "freshness": "UNKNOWN", - "temporal": "UNANCHORED" - }, - "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "evidence_ref": "evidence:snapshot", - "observed_at": "2026-07-22T04:01:00Z", - "event_id": "sha256:f7325b13c1b69f4482ff2f743210e33a3d2c50e6f83fa4993a3a2b764cb680e0" - }, - { - "seq": 2, - "parent_event_id": "sha256:f7325b13c1b69f4482ff2f743210e33a3d2c50e6f83fa4993a3a2b764cb680e0", - "event_type": "CHECK_SOURCE_FRESH", - "state_before": { - "origin": "REPRODUCIBLE", - "freshness": "UNKNOWN", - "temporal": "UNANCHORED" - }, - "state_after": { - "origin": "REPRODUCIBLE", - "freshness": "FRESH", - "temporal": "UNANCHORED" - }, - "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "evidence_ref": "evidence:live-fetch", - "observed_at": "2026-07-22T04:02:00Z", - "event_id": "sha256:cd424af268762cc38b46a9b3bc14ebe51a8c615082847bae9100620c15525065" - }, - { - "seq": 3, - "parent_event_id": "sha256:cd424af268762cc38b46a9b3bc14ebe51a8c615082847bae9100620c15525065", - "event_type": "SUBMIT_OTS", - "state_before": { - "origin": "REPRODUCIBLE", - "freshness": "FRESH", - "temporal": "UNANCHORED" - }, - "state_after": { - "origin": "REPRODUCIBLE", - "freshness": "FRESH", - "temporal": "PENDING" - }, - "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "evidence_ref": "evidence:ots-proof-pending", - "observed_at": "2026-07-22T04:03:00Z", - "event_id": "sha256:5110d0131c3fe5eea49865ea467ed229c48f75763c5e50c1c6776db6d5cb7a18" - }, - { - "seq": 4, - "parent_event_id": "sha256:5110d0131c3fe5eea49865ea467ed229c48f75763c5e50c1c6776db6d5cb7a18", - "event_type": "VERIFY_OTS_SUCCESS", - "state_before": { - "origin": "REPRODUCIBLE", - "freshness": "FRESH", - "temporal": "PENDING" - }, - "state_after": { - "origin": "REPRODUCIBLE", - "freshness": "FRESH", - "temporal": "ANCHORED" - }, - "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "evidence_ref": "evidence:ots-verification", - "observed_at": "2026-07-22T05:00:00Z", - "temporal_bound": { - "kind": "not_later_than", - "bitcoin_block_height": 900001, - "attested_before": "2026-07-22T04:55:00Z" - }, - "event_id": "sha256:d2db1fff41daa5b2656e72d0be097963d23085347059287b7fc2a43a5d58c8e8" - } - ], "expected": { "ok": true, "error": null, - "final_state": { - "origin": "REPRODUCIBLE", - "freshness": "FRESH", - "temporal": "ANCHORED" - }, + "final_state": {"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"ANCHORED"}, "event_count": 5 } }, { "name": "valid-staleness-does-not-erase-temporal-anchor", - "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "events": [ - { - "seq": 0, - "parent_event_id": null, - "event_type": "COMMIT_SOURCE_HASH", - "state_before": { - "origin": "UNCOMMITTED", - "freshness": "UNKNOWN", - "temporal": "UNANCHORED" - }, - "state_after": { - "origin": "COMMITTED", - "freshness": "UNKNOWN", - "temporal": "UNANCHORED" - }, - "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "evidence_ref": "evidence:source-hash", - "observed_at": "2026-07-22T04:00:00Z", - "event_id": "sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962" - }, - { - "seq": 1, - "parent_event_id": "sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962", - "event_type": "VERIFY_SOURCE_SNAPSHOT", - "state_before": { - "origin": "COMMITTED", - "freshness": "UNKNOWN", - "temporal": "UNANCHORED" - }, - "state_after": { - "origin": "REPRODUCIBLE", - "freshness": "UNKNOWN", - "temporal": "UNANCHORED" - }, - "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "evidence_ref": "evidence:snapshot", - "observed_at": "2026-07-22T04:01:00Z", - "event_id": "sha256:f7325b13c1b69f4482ff2f743210e33a3d2c50e6f83fa4993a3a2b764cb680e0" - }, - { - "seq": 2, - "parent_event_id": "sha256:f7325b13c1b69f4482ff2f743210e33a3d2c50e6f83fa4993a3a2b764cb680e0", - "event_type": "CHECK_SOURCE_FRESH", - "state_before": { - "origin": "REPRODUCIBLE", - "freshness": "UNKNOWN", - "temporal": "UNANCHORED" - }, - "state_after": { - "origin": "REPRODUCIBLE", - "freshness": "FRESH", - "temporal": "UNANCHORED" - }, - "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "evidence_ref": "evidence:live-fetch", - "observed_at": "2026-07-22T04:02:00Z", - "event_id": "sha256:cd424af268762cc38b46a9b3bc14ebe51a8c615082847bae9100620c15525065" - }, - { - "seq": 3, - "parent_event_id": "sha256:cd424af268762cc38b46a9b3bc14ebe51a8c615082847bae9100620c15525065", - "event_type": "SUBMIT_OTS", - "state_before": { - "origin": "REPRODUCIBLE", - "freshness": "FRESH", - "temporal": "UNANCHORED" - }, - "state_after": { - "origin": "REPRODUCIBLE", - "freshness": "FRESH", - "temporal": "PENDING" - }, - "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "evidence_ref": "evidence:ots-proof-pending", - "observed_at": "2026-07-22T04:03:00Z", - "event_id": "sha256:5110d0131c3fe5eea49865ea467ed229c48f75763c5e50c1c6776db6d5cb7a18" - }, - { - "seq": 4, - "parent_event_id": "sha256:5110d0131c3fe5eea49865ea467ed229c48f75763c5e50c1c6776db6d5cb7a18", - "event_type": "VERIFY_OTS_SUCCESS", - "state_before": { - "origin": "REPRODUCIBLE", - "freshness": "FRESH", - "temporal": "PENDING" - }, - "state_after": { - "origin": "REPRODUCIBLE", - "freshness": "FRESH", - "temporal": "ANCHORED" - }, - "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "evidence_ref": "evidence:ots-verification", - "observed_at": "2026-07-22T05:00:00Z", - "temporal_bound": { - "kind": "not_later_than", - "bitcoin_block_height": 900001, - "attested_before": "2026-07-22T04:55:00Z" - }, - "event_id": "sha256:d2db1fff41daa5b2656e72d0be097963d23085347059287b7fc2a43a5d58c8e8" - }, - { - "seq": 5, - "parent_event_id": "sha256:d2db1fff41daa5b2656e72d0be097963d23085347059287b7fc2a43a5d58c8e8", - "event_type": "CHECK_SOURCE_STALE", - "state_before": { - "origin": "REPRODUCIBLE", - "freshness": "FRESH", - "temporal": "ANCHORED" - }, - "state_after": { - "origin": "REPRODUCIBLE", - "freshness": "STALE", - "temporal": "ANCHORED" - }, - "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "evidence_ref": "evidence:changed-live-source", - "observed_at": "2026-07-22T06:00:00Z", - "event_id": "sha256:ad51fba53c659be72b76720ba569754368e5af51666d054e13490c3fc5e0be8d" - } + "mutations": [ + { + "op": "append_event", + "value": { + "seq": 5, + "parent_event_id": "sha256:d2db1fff41daa5b2656e72d0be097963d23085347059287b7fc2a43a5d58c8e8", + "event_type": "CHECK_SOURCE_STALE", + "state_before": {"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"ANCHORED"}, + "state_after": {"origin":"REPRODUCIBLE","freshness":"STALE","temporal":"ANCHORED"}, + "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "evidence_ref": "evidence:changed-live-source", + "observed_at": "2026-07-22T06:00:00Z" + } + }, + {"op":"recompute_event_id","index":5} ], "expected": { "ok": true, "error": null, - "final_state": { - "origin": "REPRODUCIBLE", - "freshness": "STALE", - "temporal": "ANCHORED" - }, + "final_state": {"origin":"REPRODUCIBLE","freshness":"STALE","temporal":"ANCHORED"}, "event_count": 6 } }, { "name": "reject-undeclared-transition", - "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "events": [ - { - "seq": 0, - "parent_event_id": null, - "event_type": "COMMIT_SOURCE_HASH", - "state_before": {"origin":"UNCOMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"}, - "state_after": {"origin":"COMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"}, - "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "evidence_ref": "evidence:source-hash", - "observed_at": "2026-07-22T04:00:00Z", - "event_id": "sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962" - }, - { - "seq": 1, - "parent_event_id": "sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962", - "event_type": "VERIFY_SOURCE_SNAPSHOT", - "state_before": {"origin":"COMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"}, - "state_after": {"origin":"REPRODUCIBLE","freshness":"UNKNOWN","temporal":"UNANCHORED"}, - "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "evidence_ref": "evidence:snapshot", - "observed_at": "2026-07-22T04:01:00Z", - "event_id": "sha256:f7325b13c1b69f4482ff2f743210e33a3d2c50e6f83fa4993a3a2b764cb680e0" - }, - { - "seq": 2, - "parent_event_id": "sha256:f7325b13c1b69f4482ff2f743210e33a3d2c50e6f83fa4993a3a2b764cb680e0", - "event_type": "CHECK_SOURCE_FRESH", - "state_before": {"origin":"REPRODUCIBLE","freshness":"UNKNOWN","temporal":"UNANCHORED"}, - "state_after": {"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"UNANCHORED"}, - "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "evidence_ref": "evidence:live-fetch", - "observed_at": "2026-07-22T04:02:00Z", - "event_id": "sha256:cd424af268762cc38b46a9b3bc14ebe51a8c615082847bae9100620c15525065" - }, - { - "seq": 3, - "parent_event_id": "sha256:cd424af268762cc38b46a9b3bc14ebe51a8c615082847bae9100620c15525065", - "event_type": "ROLLBACK_TIME", - "state_before": {"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"UNANCHORED"}, - "state_after": {"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"PENDING"}, - "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "evidence_ref": "evidence:ots-proof-pending", - "observed_at": "2026-07-22T04:03:00Z", - "event_id": "sha256:6ff11df1dff007030a9ce5bec1915612235cfb4e8a2677dcc09ea18019dfd93b" - } + "mutations": [ + {"op":"set","path":"events.3.event_type","value":"ROLLBACK_TIME"}, + {"op":"recompute_event_id","index":3} ], "expected": {"ok":false,"error":"UNDECLARED_TRANSITION"} }, { "name": "reject-sequence-gap", - "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "events": [ - { - "seq": 0,"parent_event_id":null,"event_type":"COMMIT_SOURCE_HASH","state_before":{"origin":"UNCOMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"COMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:source-hash","observed_at":"2026-07-22T04:00:00Z","event_id":"sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962" - }, - { - "seq": 1,"parent_event_id":"sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962","event_type":"VERIFY_SOURCE_SNAPSHOT","state_before":{"origin":"COMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"REPRODUCIBLE","freshness":"UNKNOWN","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:snapshot","observed_at":"2026-07-22T04:01:00Z","event_id":"sha256:f7325b13c1b69f4482ff2f743210e33a3d2c50e6f83fa4993a3a2b764cb680e0" - }, - { - "seq": 3,"parent_event_id":"sha256:f7325b13c1b69f4482ff2f743210e33a3d2c50e6f83fa4993a3a2b764cb680e0","event_type":"CHECK_SOURCE_FRESH","state_before":{"origin":"REPRODUCIBLE","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:live-fetch","observed_at":"2026-07-22T04:02:00Z","event_id":"sha256:cd424af268762cc38b46a9b3bc14ebe51a8c615082847bae9100620c15525065" - } - ], + "mutations": [{"op":"set","path":"events.2.seq","value":3}], "expected": {"ok":false,"error":"SEQUENCE_GAP_OR_DUPLICATE"} }, { - "name":"reject-parent-mismatch", - "subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "events":[ - {"seq":0,"parent_event_id":null,"event_type":"COMMIT_SOURCE_HASH","state_before":{"origin":"UNCOMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"COMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:source-hash","observed_at":"2026-07-22T04:00:00Z","event_id":"sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962"}, - {"seq":1,"parent_event_id":"sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962","event_type":"VERIFY_SOURCE_SNAPSHOT","state_before":{"origin":"COMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"REPRODUCIBLE","freshness":"UNKNOWN","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:snapshot","observed_at":"2026-07-22T04:01:00Z","event_id":"sha256:f7325b13c1b69f4482ff2f743210e33a3d2c50e6f83fa4993a3a2b764cb680e0"}, - {"seq":2,"parent_event_id":"sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb","event_type":"CHECK_SOURCE_FRESH","state_before":{"origin":"REPRODUCIBLE","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:live-fetch","observed_at":"2026-07-22T04:02:00Z","event_id":"sha256:cd424af268762cc38b46a9b3bc14ebe51a8c615082847bae9100620c15525065"} - ], - "expected":{"ok":false,"error":"PARENT_EVENT_MISMATCH"} + "name": "reject-parent-mismatch", + "mutations": [{"op":"set","path":"events.2.parent_event_id","value":"sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"}], + "expected": {"ok":false,"error":"PARENT_EVENT_MISMATCH"} }, { - "name":"reject-subject-hash-drift", - "subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "events":[ - {"seq":0,"parent_event_id":null,"event_type":"COMMIT_SOURCE_HASH","state_before":{"origin":"UNCOMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"COMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:source-hash","observed_at":"2026-07-22T04:00:00Z","event_id":"sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962"}, - {"seq":1,"parent_event_id":"sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962","event_type":"VERIFY_SOURCE_SNAPSHOT","state_before":{"origin":"COMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"REPRODUCIBLE","freshness":"UNKNOWN","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:snapshot","observed_at":"2026-07-22T04:01:00Z","event_id":"sha256:f7325b13c1b69f4482ff2f743210e33a3d2c50e6f83fa4993a3a2b764cb680e0"}, - {"seq":2,"parent_event_id":"sha256:f7325b13c1b69f4482ff2f743210e33a3d2c50e6f83fa4993a3a2b764cb680e0","event_type":"CHECK_SOURCE_FRESH","state_before":{"origin":"REPRODUCIBLE","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"UNANCHORED"},"subject_hash":"sha256:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc","evidence_ref":"evidence:live-fetch","observed_at":"2026-07-22T04:02:00Z","event_id":"sha256:cd424af268762cc38b46a9b3bc14ebe51a8c615082847bae9100620c15525065"} - ], - "expected":{"ok":false,"error":"SUBJECT_HASH_DRIFT"} + "name": "reject-subject-hash-drift", + "mutations": [{"op":"set","path":"events.2.subject_hash","value":"sha256:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"}], + "expected": {"ok":false,"error":"SUBJECT_HASH_DRIFT"} }, { - "name":"reject-observed-time-regression", - "subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "events":[ - {"seq":0,"parent_event_id":null,"event_type":"COMMIT_SOURCE_HASH","state_before":{"origin":"UNCOMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"COMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:source-hash","observed_at":"2026-07-22T04:00:00Z","event_id":"sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962"}, - {"seq":1,"parent_event_id":"sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962","event_type":"VERIFY_SOURCE_SNAPSHOT","state_before":{"origin":"COMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"REPRODUCIBLE","freshness":"UNKNOWN","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:snapshot","observed_at":"2026-07-22T04:01:00Z","event_id":"sha256:f7325b13c1b69f4482ff2f743210e33a3d2c50e6f83fa4993a3a2b764cb680e0"}, - {"seq":2,"parent_event_id":"sha256:f7325b13c1b69f4482ff2f743210e33a3d2c50e6f83fa4993a3a2b764cb680e0","event_type":"CHECK_SOURCE_FRESH","state_before":{"origin":"REPRODUCIBLE","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:live-fetch","observed_at":"2026-07-22T03:59:00Z","event_id":"sha256:026a17b297db14f38ea985504d17cc8bc089b05de5ac875d686ce8fe3d339eea"} + "name": "reject-observed-time-regression", + "mutations": [ + {"op":"set","path":"events.2.observed_at","value":"2026-07-22T03:59:00Z"}, + {"op":"recompute_event_id","index":2} ], - "expected":{"ok":false,"error":"OBSERVED_AT_REGRESSION"} + "expected": {"ok":false,"error":"OBSERVED_AT_REGRESSION"} }, { - "name":"reject-missing-transition-evidence", - "subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "events":[ - {"seq":0,"parent_event_id":null,"event_type":"COMMIT_SOURCE_HASH","state_before":{"origin":"UNCOMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"COMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:source-hash","observed_at":"2026-07-22T04:00:00Z","event_id":"sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962"}, - {"seq":1,"parent_event_id":"sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962","event_type":"VERIFY_SOURCE_SNAPSHOT","state_before":{"origin":"COMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"REPRODUCIBLE","freshness":"UNKNOWN","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:snapshot","observed_at":"2026-07-22T04:01:00Z","event_id":"sha256:f7325b13c1b69f4482ff2f743210e33a3d2c50e6f83fa4993a3a2b764cb680e0"}, - {"seq":2,"parent_event_id":"sha256:f7325b13c1b69f4482ff2f743210e33a3d2c50e6f83fa4993a3a2b764cb680e0","event_type":"CHECK_SOURCE_FRESH","state_before":{"origin":"REPRODUCIBLE","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"","observed_at":"2026-07-22T04:02:00Z","event_id":"sha256:c28ec1f1491aa01646fe97f5755fe868d2cd2d12c3bcba9e86ae1d961449a93b"} + "name": "reject-missing-transition-evidence", + "mutations": [ + {"op":"set","path":"events.2.evidence_ref","value":""}, + {"op":"recompute_event_id","index":2} ], - "expected":{"ok":false,"error":"MISSING_TRANSITION_EVIDENCE"} + "expected": {"ok":false,"error":"MISSING_TRANSITION_EVIDENCE"} }, { - "name":"reject-undeclared-axis-mutation", - "subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "events":[ - {"seq":0,"parent_event_id":null,"event_type":"COMMIT_SOURCE_HASH","state_before":{"origin":"UNCOMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"COMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:source-hash","observed_at":"2026-07-22T04:00:00Z","event_id":"sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962"}, - {"seq":1,"parent_event_id":"sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962","event_type":"VERIFY_SOURCE_SNAPSHOT","state_before":{"origin":"COMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"REPRODUCIBLE","freshness":"UNKNOWN","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:snapshot","observed_at":"2026-07-22T04:01:00Z","event_id":"sha256:f7325b13c1b69f4482ff2f743210e33a3d2c50e6f83fa4993a3a2b764cb680e0"}, - {"seq":2,"parent_event_id":"sha256:f7325b13c1b69f4482ff2f743210e33a3d2c50e6f83fa4993a3a2b764cb680e0","event_type":"CHECK_SOURCE_FRESH","state_before":{"origin":"REPRODUCIBLE","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"INVALID","freshness":"FRESH","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:live-fetch","observed_at":"2026-07-22T04:02:00Z","event_id":"sha256:fa8d7b8dd2867ec70caad6d33bf7b24713e5085dbaac24265c635ecf56ce3896"} + "name": "reject-undeclared-axis-mutation", + "mutations": [ + {"op":"set","path":"events.2.state_after.origin","value":"INVALID"}, + {"op":"recompute_event_id","index":2} ], - "expected":{"ok":false,"error":"UNDECLARED_AXIS_MUTATION"} + "expected": {"ok":false,"error":"UNDECLARED_AXIS_MUTATION"} }, { - "name":"reject-event-id-tamper", - "subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "events":[ - {"seq":0,"parent_event_id":null,"event_type":"COMMIT_SOURCE_HASH","state_before":{"origin":"UNCOMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"COMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:source-hash","observed_at":"2026-07-22T04:00:00Z","event_id":"sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962"}, - {"seq":1,"parent_event_id":"sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962","event_type":"VERIFY_SOURCE_SNAPSHOT","state_before":{"origin":"COMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"REPRODUCIBLE","freshness":"UNKNOWN","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:snapshot","observed_at":"2026-07-22T04:01:00Z","event_id":"sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"} - ], - "expected":{"ok":false,"error":"EVENT_ID_MISMATCH"} + "name": "reject-event-id-tamper", + "mutations": [{"op":"set","path":"events.1.event_id","value":"sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"}], + "expected": {"ok":false,"error":"EVENT_ID_MISMATCH"} }, { - "name":"reject-temporal-regression-after-anchor", - "subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "events":[ - {"seq":0,"parent_event_id":null,"event_type":"COMMIT_SOURCE_HASH","state_before":{"origin":"UNCOMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"COMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:source-hash","observed_at":"2026-07-22T04:00:00Z","event_id":"sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962"}, - {"seq":1,"parent_event_id":"sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962","event_type":"VERIFY_SOURCE_SNAPSHOT","state_before":{"origin":"COMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"REPRODUCIBLE","freshness":"UNKNOWN","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:snapshot","observed_at":"2026-07-22T04:01:00Z","event_id":"sha256:f7325b13c1b69f4482ff2f743210e33a3d2c50e6f83fa4993a3a2b764cb680e0"}, - {"seq":2,"parent_event_id":"sha256:f7325b13c1b69f4482ff2f743210e33a3d2c50e6f83fa4993a3a2b764cb680e0","event_type":"CHECK_SOURCE_FRESH","state_before":{"origin":"REPRODUCIBLE","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:live-fetch","observed_at":"2026-07-22T04:02:00Z","event_id":"sha256:cd424af268762cc38b46a9b3bc14ebe51a8c615082847bae9100620c15525065"}, - {"seq":3,"parent_event_id":"sha256:cd424af268762cc38b46a9b3bc14ebe51a8c615082847bae9100620c15525065","event_type":"SUBMIT_OTS","state_before":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"UNANCHORED"},"state_after":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"PENDING"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:ots-proof-pending","observed_at":"2026-07-22T04:03:00Z","event_id":"sha256:5110d0131c3fe5eea49865ea467ed229c48f75763c5e50c1c6776db6d5cb7a18"}, - {"seq":4,"parent_event_id":"sha256:5110d0131c3fe5eea49865ea467ed229c48f75763c5e50c1c6776db6d5cb7a18","event_type":"VERIFY_OTS_SUCCESS","state_before":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"PENDING"},"state_after":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"ANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:ots-verification","observed_at":"2026-07-22T05:00:00Z","temporal_bound":{"kind":"not_later_than","bitcoin_block_height":900001,"attested_before":"2026-07-22T04:55:00Z"},"event_id":"sha256:d2db1fff41daa5b2656e72d0be097963d23085347059287b7fc2a43a5d58c8e8"}, - {"seq":5,"parent_event_id":"sha256:d2db1fff41daa5b2656e72d0be097963d23085347059287b7fc2a43a5d58c8e8","event_type":"SUBMIT_OTS","state_before":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"ANCHORED"},"state_after":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"PENDING"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:new-submit","observed_at":"2026-07-22T06:00:00Z","event_id":"sha256:37235730a1d9e3b4cca169353864a9388f18559027d3b0571749eab7f855c4f0"} + "name": "reject-temporal-regression-after-anchor", + "mutations": [ + { + "op": "append_event", + "value": { + "seq": 5, + "parent_event_id": "sha256:d2db1fff41daa5b2656e72d0be097963d23085347059287b7fc2a43a5d58c8e8", + "event_type": "SUBMIT_OTS", + "state_before": {"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"ANCHORED"}, + "state_after": {"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"PENDING"}, + "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "evidence_ref": "evidence:new-submit", + "observed_at": "2026-07-22T06:00:00Z" + } + }, + {"op":"recompute_event_id","index":5} ], - "expected":{"ok":false,"error":"ILLEGAL_AXIS_TRANSITION"} + "expected": {"ok":false,"error":"ILLEGAL_AXIS_TRANSITION"} }, { - "name":"reject-anchor-without-temporal-bound", - "subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "events":[ - {"seq":0,"parent_event_id":null,"event_type":"COMMIT_SOURCE_HASH","state_before":{"origin":"UNCOMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"COMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:source-hash","observed_at":"2026-07-22T04:00:00Z","event_id":"sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962"}, - {"seq":1,"parent_event_id":"sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962","event_type":"VERIFY_SOURCE_SNAPSHOT","state_before":{"origin":"COMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"REPRODUCIBLE","freshness":"UNKNOWN","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:snapshot","observed_at":"2026-07-22T04:01:00Z","event_id":"sha256:f7325b13c1b69f4482ff2f743210e33a3d2c50e6f83fa4993a3a2b764cb680e0"}, - {"seq":2,"parent_event_id":"sha256:f7325b13c1b69f4482ff2f743210e33a3d2c50e6f83fa4993a3a2b764cb680e0","event_type":"CHECK_SOURCE_FRESH","state_before":{"origin":"REPRODUCIBLE","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:live-fetch","observed_at":"2026-07-22T04:02:00Z","event_id":"sha256:cd424af268762cc38b46a9b3bc14ebe51a8c615082847bae9100620c15525065"}, - {"seq":3,"parent_event_id":"sha256:cd424af268762cc38b46a9b3bc14ebe51a8c615082847bae9100620c15525065","event_type":"SUBMIT_OTS","state_before":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"UNANCHORED"},"state_after":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"PENDING"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:ots-proof-pending","observed_at":"2026-07-22T04:03:00Z","event_id":"sha256:5110d0131c3fe5eea49865ea467ed229c48f75763c5e50c1c6776db6d5cb7a18"}, - {"seq":4,"parent_event_id":"sha256:5110d0131c3fe5eea49865ea467ed229c48f75763c5e50c1c6776db6d5cb7a18","event_type":"VERIFY_OTS_SUCCESS","state_before":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"PENDING"},"state_after":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"ANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:ots-verification","observed_at":"2026-07-22T05:00:00Z","event_id":"sha256:f5da26f3d199b71759c12dde17a33cf1cb56044ad09d7746d5abac3ec71d6b9c"} + "name": "reject-anchor-without-temporal-bound", + "mutations": [ + {"op":"delete","path":"events.4.temporal_bound"}, + {"op":"recompute_event_id","index":4} ], - "expected":{"ok":false,"error":"MISSING_REQUIRED_TRANSITION_FIELD"} + "expected": {"ok":false,"error":"MISSING_REQUIRED_TRANSITION_FIELD"} } ] } \ No newline at end of file From 871cf964bfbb7e41a33081ae92f9f3f43a8afcc8 Mon Sep 17 00:00:00 2001 From: Aleksey Safonov <55020240+safal207@users.noreply.github.com> Date: Wed, 22 Jul 2026 08:05:28 +0300 Subject: [PATCH 12/12] test: compact sealed trace vectors --- .../causal-temporal/sealed-vectors.json | 218 +++++++----------- 1 file changed, 78 insertions(+), 140 deletions(-) diff --git a/conformance/guardrail-decision-v1/causal-temporal/sealed-vectors.json b/conformance/guardrail-decision-v1/causal-temporal/sealed-vectors.json index 38df63e..048974d 100644 --- a/conformance/guardrail-decision-v1/causal-temporal/sealed-vectors.json +++ b/conformance/guardrail-decision-v1/causal-temporal/sealed-vectors.json @@ -1,170 +1,108 @@ { - "schema": "proofpath.causal-temporal-sealed-vectors.v0.1", + "schema": "proofpath.causal-temporal-sealed-vectors.v0.2", "require_seal": true, + "base_trace": { + "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "events": [ + { + "seq": 0, + "parent_event_id": null, + "event_type": "COMMIT_SOURCE_HASH", + "state_before": {"origin":"UNCOMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"}, + "state_after": {"origin":"COMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"}, + "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "evidence_ref": "evidence:source-hash", + "observed_at": "2026-07-22T04:00:00Z", + "event_id": "sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962" + }, + { + "seq": 1, + "parent_event_id": "sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962", + "event_type": "VERIFY_SOURCE_SNAPSHOT", + "state_before": {"origin":"COMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"}, + "state_after": {"origin":"REPRODUCIBLE","freshness":"UNKNOWN","temporal":"UNANCHORED"}, + "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "evidence_ref": "evidence:snapshot", + "observed_at": "2026-07-22T04:01:00Z", + "event_id": "sha256:f7325b13c1b69f4482ff2f743210e33a3d2c50e6f83fa4993a3a2b764cb680e0" + }, + { + "seq": 2, + "parent_event_id": "sha256:f7325b13c1b69f4482ff2f743210e33a3d2c50e6f83fa4993a3a2b764cb680e0", + "event_type": "CHECK_SOURCE_FRESH", + "state_before": {"origin":"REPRODUCIBLE","freshness":"UNKNOWN","temporal":"UNANCHORED"}, + "state_after": {"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"UNANCHORED"}, + "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "evidence_ref": "evidence:live-fetch", + "observed_at": "2026-07-22T04:02:00Z", + "event_id": "sha256:cd424af268762cc38b46a9b3bc14ebe51a8c615082847bae9100620c15525065" + }, + { + "seq": 3, + "parent_event_id": "sha256:cd424af268762cc38b46a9b3bc14ebe51a8c615082847bae9100620c15525065", + "event_type": "SUBMIT_OTS", + "state_before": {"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"UNANCHORED"}, + "state_after": {"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"PENDING"}, + "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "evidence_ref": "evidence:ots-proof-pending", + "observed_at": "2026-07-22T04:03:00Z", + "event_id": "sha256:5110d0131c3fe5eea49865ea467ed229c48f75763c5e50c1c6776db6d5cb7a18" + }, + { + "seq": 4, + "parent_event_id": "sha256:5110d0131c3fe5eea49865ea467ed229c48f75763c5e50c1c6776db6d5cb7a18", + "event_type": "VERIFY_OTS_SUCCESS", + "state_before": {"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"PENDING"}, + "state_after": {"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"ANCHORED"}, + "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "evidence_ref": "evidence:ots-verification", + "observed_at": "2026-07-22T05:00:00Z", + "temporal_bound": {"kind":"not_later_than","bitcoin_block_height":900001,"attested_before":"2026-07-22T04:55:00Z"}, + "event_id": "sha256:d2db1fff41daa5b2656e72d0be097963d23085347059287b7fc2a43a5d58c8e8" + } + ], + "seal": { + "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "total_events": 5, + "terminal_event_id": "sha256:d2db1fff41daa5b2656e72d0be097963d23085347059287b7fc2a43a5d58c8e8", + "sealed_at": "2026-07-22T05:01:00Z", + "seal_id": "sha256:cc765068061e280cf3ae88fef87b655d48ed2a8ee9523daa18cccb446780d5d5" + } + }, "cases": [ { "name": "valid-sealed-trace", - "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "events": [ - { - "seq": 0, - "parent_event_id": null, - "event_type": "COMMIT_SOURCE_HASH", - "state_before": {"origin":"UNCOMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"}, - "state_after": {"origin":"COMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"}, - "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "evidence_ref": "evidence:source-hash", - "observed_at": "2026-07-22T04:00:00Z", - "event_id": "sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962" - }, - { - "seq": 1, - "parent_event_id": "sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962", - "event_type": "VERIFY_SOURCE_SNAPSHOT", - "state_before": {"origin":"COMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"}, - "state_after": {"origin":"REPRODUCIBLE","freshness":"UNKNOWN","temporal":"UNANCHORED"}, - "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "evidence_ref": "evidence:snapshot", - "observed_at": "2026-07-22T04:01:00Z", - "event_id": "sha256:f7325b13c1b69f4482ff2f743210e33a3d2c50e6f83fa4993a3a2b764cb680e0" - }, - { - "seq": 2, - "parent_event_id": "sha256:f7325b13c1b69f4482ff2f743210e33a3d2c50e6f83fa4993a3a2b764cb680e0", - "event_type": "CHECK_SOURCE_FRESH", - "state_before": {"origin":"REPRODUCIBLE","freshness":"UNKNOWN","temporal":"UNANCHORED"}, - "state_after": {"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"UNANCHORED"}, - "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "evidence_ref": "evidence:live-fetch", - "observed_at": "2026-07-22T04:02:00Z", - "event_id": "sha256:cd424af268762cc38b46a9b3bc14ebe51a8c615082847bae9100620c15525065" - }, - { - "seq": 3, - "parent_event_id": "sha256:cd424af268762cc38b46a9b3bc14ebe51a8c615082847bae9100620c15525065", - "event_type": "SUBMIT_OTS", - "state_before": {"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"UNANCHORED"}, - "state_after": {"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"PENDING"}, - "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "evidence_ref": "evidence:ots-proof-pending", - "observed_at": "2026-07-22T04:03:00Z", - "event_id": "sha256:5110d0131c3fe5eea49865ea467ed229c48f75763c5e50c1c6776db6d5cb7a18" - }, - { - "seq": 4, - "parent_event_id": "sha256:5110d0131c3fe5eea49865ea467ed229c48f75763c5e50c1c6776db6d5cb7a18", - "event_type": "VERIFY_OTS_SUCCESS", - "state_before": {"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"PENDING"}, - "state_after": {"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"ANCHORED"}, - "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "evidence_ref": "evidence:ots-verification", - "observed_at": "2026-07-22T05:00:00Z", - "temporal_bound": {"kind":"not_later_than","bitcoin_block_height":900001,"attested_before":"2026-07-22T04:55:00Z"}, - "event_id": "sha256:d2db1fff41daa5b2656e72d0be097963d23085347059287b7fc2a43a5d58c8e8" - } - ], - "seal": { - "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "total_events": 5, - "terminal_event_id": "sha256:d2db1fff41daa5b2656e72d0be097963d23085347059287b7fc2a43a5d58c8e8", - "sealed_at": "2026-07-22T05:01:00Z", - "seal_id": "sha256:cc765068061e280cf3ae88fef87b655d48ed2a8ee9523daa18cccb446780d5d5" - }, "expected": {"ok":true,"error":null,"event_count":5} }, { "name": "reject-dropped-tail-against-seal", - "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "events": [ - { - "seq": 0,"parent_event_id":null,"event_type":"COMMIT_SOURCE_HASH","state_before":{"origin":"UNCOMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"COMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:source-hash","observed_at":"2026-07-22T04:00:00Z","event_id":"sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962" - }, - { - "seq": 1,"parent_event_id":"sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962","event_type":"VERIFY_SOURCE_SNAPSHOT","state_before":{"origin":"COMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"REPRODUCIBLE","freshness":"UNKNOWN","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:snapshot","observed_at":"2026-07-22T04:01:00Z","event_id":"sha256:f7325b13c1b69f4482ff2f743210e33a3d2c50e6f83fa4993a3a2b764cb680e0" - }, - { - "seq": 2,"parent_event_id":"sha256:f7325b13c1b69f4482ff2f743210e33a3d2c50e6f83fa4993a3a2b764cb680e0","event_type":"CHECK_SOURCE_FRESH","state_before":{"origin":"REPRODUCIBLE","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:live-fetch","observed_at":"2026-07-22T04:02:00Z","event_id":"sha256:cd424af268762cc38b46a9b3bc14ebe51a8c615082847bae9100620c15525065" - }, - { - "seq": 3,"parent_event_id":"sha256:cd424af268762cc38b46a9b3bc14ebe51a8c615082847bae9100620c15525065","event_type":"SUBMIT_OTS","state_before":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"UNANCHORED"},"state_after":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"PENDING"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:ots-proof-pending","observed_at":"2026-07-22T04:03:00Z","event_id":"sha256:5110d0131c3fe5eea49865ea467ed229c48f75763c5e50c1c6776db6d5cb7a18" - } - ], - "seal": { - "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "total_events": 5, - "terminal_event_id": "sha256:d2db1fff41daa5b2656e72d0be097963d23085347059287b7fc2a43a5d58c8e8", - "sealed_at": "2026-07-22T05:01:00Z", - "seal_id": "sha256:cc765068061e280cf3ae88fef87b655d48ed2a8ee9523daa18cccb446780d5d5" - }, + "mutations": [{"op":"truncate_events","count":4}], "expected": {"ok":false,"error":"TRACE_TOTAL_MISMATCH"} }, { "name": "reject-missing-trace-seal", - "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "events": [ - {"seq":0,"parent_event_id":null,"event_type":"COMMIT_SOURCE_HASH","state_before":{"origin":"UNCOMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"COMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:source-hash","observed_at":"2026-07-22T04:00:00Z","event_id":"sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962"}, - {"seq":1,"parent_event_id":"sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962","event_type":"VERIFY_SOURCE_SNAPSHOT","state_before":{"origin":"COMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"REPRODUCIBLE","freshness":"UNKNOWN","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:snapshot","observed_at":"2026-07-22T04:01:00Z","event_id":"sha256:f7325b13c1b69f4482ff2f743210e33a3d2c50e6f83fa4993a3a2b764cb680e0"}, - {"seq":2,"parent_event_id":"sha256:f7325b13c1b69f4482ff2f743210e33a3d2c50e6f83fa4993a3a2b764cb680e0","event_type":"CHECK_SOURCE_FRESH","state_before":{"origin":"REPRODUCIBLE","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:live-fetch","observed_at":"2026-07-22T04:02:00Z","event_id":"sha256:cd424af268762cc38b46a9b3bc14ebe51a8c615082847bae9100620c15525065"}, - {"seq":3,"parent_event_id":"sha256:cd424af268762cc38b46a9b3bc14ebe51a8c615082847bae9100620c15525065","event_type":"SUBMIT_OTS","state_before":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"UNANCHORED"},"state_after":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"PENDING"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:ots-proof-pending","observed_at":"2026-07-22T04:03:00Z","event_id":"sha256:5110d0131c3fe5eea49865ea467ed229c48f75763c5e50c1c6776db6d5cb7a18"}, - {"seq":4,"parent_event_id":"sha256:5110d0131c3fe5eea49865ea467ed229c48f75763c5e50c1c6776db6d5cb7a18","event_type":"VERIFY_OTS_SUCCESS","state_before":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"PENDING"},"state_after":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"ANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:ots-verification","observed_at":"2026-07-22T05:00:00Z","temporal_bound":{"kind":"not_later_than","bitcoin_block_height":900001,"attested_before":"2026-07-22T04:55:00Z"},"event_id":"sha256:d2db1fff41daa5b2656e72d0be097963d23085347059287b7fc2a43a5d58c8e8"} - ], + "mutations": [{"op":"delete","path":"seal"}], "expected": {"ok":false,"error":"TRACE_SEAL_MISSING"} }, { "name": "reject-tampered-seal-id", - "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "events": [ - {"seq":0,"parent_event_id":null,"event_type":"COMMIT_SOURCE_HASH","state_before":{"origin":"UNCOMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"COMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:source-hash","observed_at":"2026-07-22T04:00:00Z","event_id":"sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962"}, - {"seq":1,"parent_event_id":"sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962","event_type":"VERIFY_SOURCE_SNAPSHOT","state_before":{"origin":"COMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"REPRODUCIBLE","freshness":"UNKNOWN","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:snapshot","observed_at":"2026-07-22T04:01:00Z","event_id":"sha256:f7325b13c1b69f4482ff2f743210e33a3d2c50e6f83fa4993a3a2b764cb680e0"}, - {"seq":2,"parent_event_id":"sha256:f7325b13c1b69f4482ff2f743210e33a3d2c50e6f83fa4993a3a2b764cb680e0","event_type":"CHECK_SOURCE_FRESH","state_before":{"origin":"REPRODUCIBLE","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:live-fetch","observed_at":"2026-07-22T04:02:00Z","event_id":"sha256:cd424af268762cc38b46a9b3bc14ebe51a8c615082847bae9100620c15525065"}, - {"seq":3,"parent_event_id":"sha256:cd424af268762cc38b46a9b3bc14ebe51a8c615082847bae9100620c15525065","event_type":"SUBMIT_OTS","state_before":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"UNANCHORED"},"state_after":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"PENDING"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:ots-proof-pending","observed_at":"2026-07-22T04:03:00Z","event_id":"sha256:5110d0131c3fe5eea49865ea467ed229c48f75763c5e50c1c6776db6d5cb7a18"}, - {"seq":4,"parent_event_id":"sha256:5110d0131c3fe5eea49865ea467ed229c48f75763c5e50c1c6776db6d5cb7a18","event_type":"VERIFY_OTS_SUCCESS","state_before":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"PENDING"},"state_after":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"ANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:ots-verification","observed_at":"2026-07-22T05:00:00Z","temporal_bound":{"kind":"not_later_than","bitcoin_block_height":900001,"attested_before":"2026-07-22T04:55:00Z"},"event_id":"sha256:d2db1fff41daa5b2656e72d0be097963d23085347059287b7fc2a43a5d58c8e8"} - ], - "seal": { - "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "total_events": 5, - "terminal_event_id": "sha256:d2db1fff41daa5b2656e72d0be097963d23085347059287b7fc2a43a5d58c8e8", - "sealed_at": "2026-07-22T05:01:00Z", - "seal_id": "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" - }, + "mutations": [{"op":"set","path":"seal.seal_id","value":"sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"}], "expected": {"ok":false,"error":"TRACE_SEAL_ID_MISMATCH"} }, { "name": "reject-terminal-event-mismatch", - "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "events": [ - {"seq":0,"parent_event_id":null,"event_type":"COMMIT_SOURCE_HASH","state_before":{"origin":"UNCOMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"COMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:source-hash","observed_at":"2026-07-22T04:00:00Z","event_id":"sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962"}, - {"seq":1,"parent_event_id":"sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962","event_type":"VERIFY_SOURCE_SNAPSHOT","state_before":{"origin":"COMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"REPRODUCIBLE","freshness":"UNKNOWN","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:snapshot","observed_at":"2026-07-22T04:01:00Z","event_id":"sha256:f7325b13c1b69f4482ff2f743210e33a3d2c50e6f83fa4993a3a2b764cb680e0"}, - {"seq":2,"parent_event_id":"sha256:f7325b13c1b69f4482ff2f743210e33a3d2c50e6f83fa4993a3a2b764cb680e0","event_type":"CHECK_SOURCE_FRESH","state_before":{"origin":"REPRODUCIBLE","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:live-fetch","observed_at":"2026-07-22T04:02:00Z","event_id":"sha256:cd424af268762cc38b46a9b3bc14ebe51a8c615082847bae9100620c15525065"}, - {"seq":3,"parent_event_id":"sha256:cd424af268762cc38b46a9b3bc14ebe51a8c615082847bae9100620c15525065","event_type":"SUBMIT_OTS","state_before":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"UNANCHORED"},"state_after":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"PENDING"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:ots-proof-pending","observed_at":"2026-07-22T04:03:00Z","event_id":"sha256:5110d0131c3fe5eea49865ea467ed229c48f75763c5e50c1c6776db6d5cb7a18"}, - {"seq":4,"parent_event_id":"sha256:5110d0131c3fe5eea49865ea467ed229c48f75763c5e50c1c6776db6d5cb7a18","event_type":"VERIFY_OTS_SUCCESS","state_before":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"PENDING"},"state_after":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"ANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:ots-verification","observed_at":"2026-07-22T05:00:00Z","temporal_bound":{"kind":"not_later_than","bitcoin_block_height":900001,"attested_before":"2026-07-22T04:55:00Z"},"event_id":"sha256:d2db1fff41daa5b2656e72d0be097963d23085347059287b7fc2a43a5d58c8e8"} + "mutations": [ + {"op":"set","path":"seal.terminal_event_id","value":"sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"}, + {"op":"recompute_seal_id"} ], - "seal": { - "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "total_events": 5, - "terminal_event_id": "sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", - "sealed_at": "2026-07-22T05:01:00Z", - "seal_id": "sha256:9b9589c627097265e4b5781cf882274866f9e2d0092a8119ff9d540116b3bb4d" - }, "expected": {"ok":false,"error":"TRACE_TERMINAL_EVENT_MISMATCH"} }, { "name": "reject-sealed-at-regression", - "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "events": [ - {"seq":0,"parent_event_id":null,"event_type":"COMMIT_SOURCE_HASH","state_before":{"origin":"UNCOMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"COMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:source-hash","observed_at":"2026-07-22T04:00:00Z","event_id":"sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962"}, - {"seq":1,"parent_event_id":"sha256:829330b6c5b60e3774d6c55fe174092ae5ba0406198e93ff8efc17d77fc73962","event_type":"VERIFY_SOURCE_SNAPSHOT","state_before":{"origin":"COMMITTED","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"REPRODUCIBLE","freshness":"UNKNOWN","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:snapshot","observed_at":"2026-07-22T04:01:00Z","event_id":"sha256:f7325b13c1b69f4482ff2f743210e33a3d2c50e6f83fa4993a3a2b764cb680e0"}, - {"seq":2,"parent_event_id":"sha256:f7325b13c1b69f4482ff2f743210e33a3d2c50e6f83fa4993a3a2b764cb680e0","event_type":"CHECK_SOURCE_FRESH","state_before":{"origin":"REPRODUCIBLE","freshness":"UNKNOWN","temporal":"UNANCHORED"},"state_after":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"UNANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:live-fetch","observed_at":"2026-07-22T04:02:00Z","event_id":"sha256:cd424af268762cc38b46a9b3bc14ebe51a8c615082847bae9100620c15525065"}, - {"seq":3,"parent_event_id":"sha256:cd424af268762cc38b46a9b3bc14ebe51a8c615082847bae9100620c15525065","event_type":"SUBMIT_OTS","state_before":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"UNANCHORED"},"state_after":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"PENDING"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:ots-proof-pending","observed_at":"2026-07-22T04:03:00Z","event_id":"sha256:5110d0131c3fe5eea49865ea467ed229c48f75763c5e50c1c6776db6d5cb7a18"}, - {"seq":4,"parent_event_id":"sha256:5110d0131c3fe5eea49865ea467ed229c48f75763c5e50c1c6776db6d5cb7a18","event_type":"VERIFY_OTS_SUCCESS","state_before":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"PENDING"},"state_after":{"origin":"REPRODUCIBLE","freshness":"FRESH","temporal":"ANCHORED"},"subject_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","evidence_ref":"evidence:ots-verification","observed_at":"2026-07-22T05:00:00Z","temporal_bound":{"kind":"not_later_than","bitcoin_block_height":900001,"attested_before":"2026-07-22T04:55:00Z"},"event_id":"sha256:d2db1fff41daa5b2656e72d0be097963d23085347059287b7fc2a43a5d58c8e8"} + "mutations": [ + {"op":"set","path":"seal.sealed_at","value":"2026-07-22T04:59:00Z"}, + {"op":"recompute_seal_id"} ], - "seal": { - "subject_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "total_events": 5, - "terminal_event_id": "sha256:d2db1fff41daa5b2656e72d0be097963d23085347059287b7fc2a43a5d58c8e8", - "sealed_at": "2026-07-22T04:59:00Z", - "seal_id": "sha256:46cd731531de9f9dfa8799e06bad9a6816f7f7db6592a5188ab04ac6bf9e932f" - }, "expected": {"ok":false,"error":"SEALED_AT_REGRESSION"} } ]