"""Regenerate tests/fixtures/crdt/merge_fixtures.json from the canonical reference (vault/crdt.py). Run: uv run python tests/fixtures/crdt/_generate.py The emitted JSON is the *golden* G1 fixture corpus (ADR-0180 / ADR-0196 gate G1). Changing the canonical form in vault/crdt.py changes these hashes; the contract tests pin them, so a golden diff is a reviewed, deliberate act. Versor components use only exactly-f32-representable, exactly-JSON-representable values (integers, signed zeros, halves) so the corpus round-trips with zero float ambiguity. NaN / signed-zero *bit*-distinctness is exercised in-code in test_crdt_content_ordering.py, not here. """ from __future__ import annotations import json import sys from pathlib import Path _REPO_ROOT = Path(__file__).resolve().parents[3] sys.path.insert(0, str(_REPO_ROOT)) from vault.crdt import ( # noqa: E402 # pyright: ignore[reportMissingImports] VERSOR_COMPONENTS, ArenaEntry, Delta, canonical_bytes, delta_hash, merge_kernel, ) _OUT = Path(__file__).resolve().parent / "merge_fixtures.json" # Rust parity fixture lives under core-rs/tests/fixtures/ (a *subdir* of tests/, # so cargo does not compile it as a standalone integration-test target). _RUST_OUT = _REPO_ROOT / "core-rs" / "tests" / "fixtures" / "crdt_parity_expected.rs" def versor(**components: float) -> list[float]: """Build a 32-float versor; unset indices default to 0.0.""" v = [0.0] * VERSOR_COMPONENTS for idx, value in components.items(): v[int(idx.lstrip("c"))] = value return v def entry(versor_vals: list[float], provenance: bytes) -> ArenaEntry: return ArenaEntry.of(versor_vals, provenance) def encode_entry(e: ArenaEntry) -> dict: return {"versor": list(e.versor), "provenance_hex": e.provenance.hex()} def encode_delta_input(entries: list[ArenaEntry]) -> list[dict]: return [encode_entry(e) for e in entries] def build_cases() -> list[dict]: cases: list[dict] = [] def add(name: str, description: str, delta_entry_lists: list[list[ArenaEntry]]): deltas = [Delta.from_entries(es) for es in delta_entry_lists] merged = merge_kernel(deltas) cases.append( { "name": name, "description": description, "input_deltas": [encode_delta_input(es) for es in delta_entry_lists], "expected_merged_entries": [encode_entry(e) for e in merged.entries], "expected_canonical_bytes_hex": canonical_bytes(merged).hex(), "expected_delta_hash": delta_hash(merged), } ) # 1 — single entry, single delta. add( "single_entry", "One delta, one entry: identity of the canonical form.", [[entry(versor(c0=1.0), b"a")]], ) # 2 — duplicate byte-identical entries collapse (idempotence at entry level). add( "dedup_within_delta", "Byte-identical entries collapse to one (join idempotence).", [[entry(versor(c0=1.0), b"a"), entry(versor(c0=1.0), b"a")]], ) # 3 — same versor, distinct provenance: BOTH retained (no over-dedup). add( "distinct_provenance_retained", "Same versor under different provenance are distinct content.", [[entry(versor(c5=2.0), b"left"), entry(versor(c5=2.0), b"right")]], ) # 4 — three deltas merged; corpus pins the canonical (content-sorted) result. add( "three_delta_merge", "Union of three deltas, content-sorted and deduped.", [ [entry(versor(c1=3.0), b"z"), entry(versor(c0=1.0), b"a")], [entry(versor(c2=2.0), b"m"), entry(versor(c0=1.0), b"a")], [entry(versor(c10=5.0), b"q")], ], ) # 5 — signed-zero is distinct content (+0.0 bits != -0.0 bits). add( "signed_zero_distinct", "+0.0 and -0.0 have distinct bit patterns -> distinct entries.", [[entry(versor(c0=0.0), b"p"), entry(versor(c0=-0.0), b"p")]], ) return cases def write_rust_fixtures(cases: list[dict]) -> None: """Emit the Rust-side expected canonical_bytes hex so core-rs/tests can assert byte-parity without a JSON parser dependency. Python stays the single source of truth.""" lines = [ "// @generated by tests/fixtures/crdt/_generate.py — DO NOT EDIT.", "// Expected canonical_bytes hex per case (mirrors merge_fixtures.json):", "// the Python-canonical Delta-CRDT G1 contract (ADR-0180 / ADR-0196)", "// the Rust substrate must reproduce byte-for-byte.", "// (include!d mid-module, so plain // comments — not //! — are required.)", "", "pub const EXPECTED_CANONICAL_BYTES_HEX: &[(&str, &str)] = &[", ] for case in cases: lines.append( f' ("{case["name"]}", "{case["expected_canonical_bytes_hex"]}"),' ) lines.append("];") _RUST_OUT.parent.mkdir(parents=True, exist_ok=True) _RUST_OUT.write_text("\n".join(lines) + "\n") def main() -> None: corpus = { "_comment": ( "Golden Delta-CRDT fixture corpus (ADR-0180 / ADR-0196 gate G1). " "Regenerate with: uv run python tests/fixtures/crdt/_generate.py" ), "versor_components": VERSOR_COMPONENTS, "cases": build_cases(), } _OUT.write_text(json.dumps(corpus, indent=2, sort_keys=False) + "\n") write_rust_fixtures(corpus["cases"]) print(f"wrote {_OUT} ({len(corpus['cases'])} cases)") print(f"wrote {_RUST_OUT}") for case in corpus["cases"]: print(f" {case['name']:30s} hash={case['expected_delta_hash'][:16]}…") if __name__ == "__main__": main()