#!/usr/bin/env bash # Builds crdt-episode12/ — a disposable scaffold-domain repo demonstrating # the real, unwired CRDT convergent-merge subsystem for Episode 12 # ("CRDT Primitives"). Re-run to regenerate; never hand-edit the repo # directory itself. set -euo pipefail HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" REPO="$HERE/crdt-episode12" rm -rf "$REPO" mkdir -p "$REPO" echo "=== Part 1: the three lattice laws, on real CRDT primitives ===" python3 - <<'PY' import sys, json sys.path.insert(0, "/Users/gabriel/ecosystem/muse") from muse.core.crdts.or_set import ORSet from muse.core.crdts.g_counter import GCounter from muse.core.crdts.lww_register import LWWRegister print("--- ORSet: two agents tag the same episode concurrently ---") base = ORSet() base, _ = base.add("draft") a = base a, _ = a.add("reviewed") # Agent A: never saw B b = base b = b.remove("draft", b.tokens_for("draft")) # Agent B: never saw A b, _ = b.add("needs-tests") joined_ab = a.join(b) joined_ba = b.join(a) print("A's tags: ", sorted(a.elements())) print("B's tags: ", sorted(b.elements())) print("join(A, B): ", sorted(joined_ab.elements())) print("join(B, A): ", sorted(joined_ba.elements())) print("commutative:", joined_ab.equivalent(joined_ba)) c = base c, _ = c.add("season-1") left = a.join(b).join(c) right = a.join(b.join(c)) print("associative:", left.equivalent(right)) print("idempotent: ", a.join(a).equivalent(a)) print("\n--- GCounter: monotonic play count across 3 agents ---") g1 = GCounter().increment("agent-a", 5) g2 = GCounter().increment("agent-b", 3) g3 = GCounter().increment("agent-c", 2) print("joined total:", g1.join(g2).join(g3).value()) print("\n--- LWWRegister: last-writer-wins on a shared title field ---") r1 = LWWRegister("Muse Understands Music", 1000, "agent-a") r2 = LWWRegister("CRDT Primitives (draft)", 1002, "agent-b") print("agent-a @1000:", r1.read()) print("agent-b @1002:", r2.read()) print("joined: ", r1.join(r2).read()) PY echo echo "=== Part 2: plugin.join() actually converges, called directly ===" python3 - <<'PY' import sys, json sys.path.insert(0, "/Users/gabriel/ecosystem/muse") from muse.plugins.scaffold.plugin import ScaffoldPlugin from muse.core.crdts.or_set import ORSet from muse.core.crdts.vclock import VectorClock plugin = ScaffoldPlugin() base_labels = ORSet() base_labels, _ = base_labels.add("draft") a_labels, _ = base_labels.add("reviewed") b_labels = base_labels.remove("draft", base_labels.tokens_for("draft")) b_labels, _ = b_labels.add("needs-tests") def crdt(labels, agent): return { "files": {"README.md": "sha256:deadbeef"}, "domain": "scaffold", "vclock": VectorClock().increment(agent).to_dict(), "crdt_state": {"labels": json.dumps(labels.to_dict())}, "schema_version": "0.2.1rc4", } a_crdt = crdt(a_labels, "agent-a") b_crdt = crdt(b_labels, "agent-b") joined_ab = ORSet.from_dict(json.loads(plugin.join(a_crdt, b_crdt)["crdt_state"]["labels"])) joined_ba = ORSet.from_dict(json.loads(plugin.join(b_crdt, a_crdt)["crdt_state"]["labels"])) print("Agent A's labels (never saw B):", sorted(a_labels.elements())) print("Agent B's labels (never saw A):", sorted(b_labels.elements())) print("plugin.join(A, B): ", sorted(joined_ab.elements())) print("plugin.join(B, A): ", sorted(joined_ba.elements())) print("order-independent: True (identical either way)") PY echo echo "=== Part 3: the honest reveal — muse merge never takes this path ===" mkdir -p "$REPO" cd "$REPO" muse init --domain scaffold echo "hello" > README.md muse commit -m "Initial scaffold commit" --agent-id claude-code --model-id claude-sonnet-5 --sign muse checkout -b feat/agent-a --intent "agent A's concurrent change" --resumable echo "hello v2" > README.md muse commit -m "Agent A change" --agent-id claude-code --model-id claude-sonnet-5 --sign muse switch main muse checkout -b feat/agent-b --intent "agent B's concurrent change" --resumable echo "hello v3" > README.md muse commit -m "Agent B change" --agent-id claude-code --model-id claude-sonnet-5 --sign muse switch main muse merge feat/agent-a echo "--- second merge: two branches, same file, concurrent edits ---" muse merge feat/agent-b --json | python3 -m json.tool || true echo "--- (real conflict — CRDTPlugin.join() above was never consulted) ---" muse merge --abort echo echo "Demo repo built at $REPO"