crdt-primitives.md markdown
356 lines 10.4 KB
Raw
sha256:5472be4fece32b606c308fad9d57295ce327955fb2b87b8beec6ea1626050473 Add published YouTube URL to Episode 00 Sonnet 5 10 hours ago

Episode 12 --- CRDT Primitives

Working YouTube title:
The Merge That Never Has A Conflict (And Doesn't Exist Yet)

Thumbnail thought:
no conflict. no wiring.

Target runtime: ~8:00


[0:00--0:20] COLD OPEN

[CAMERA --- Episode 11's closing line, on screen: "what happens when the thing writing commits isn't a person at all."]

GABRIEL:

Before agents --- one more foundation. Every merge you've watched this season needed a human, or an agent playing human, to read two sides and decide. There's a whole other category of merge that never asks anyone anything. Let's build it.

[TITLE CARD --- fast]

CRDT PRIMITIVES

[Music enters.]


[0:20--1:10] THE PROMISE

[CAMERA]

$ muse code cat "muse/domain.py::CRDTPlugin" | head -20
class CRDTPlugin(MuseDomainPlugin, Protocol):
    """join always succeeds:
    - No conflict state ever exists.
    - Any two replicas... converge to the same state, regardless
      of delivery order.
    - Millions of agents can write concurrently without coordination.
    """

GABRIEL VO:

That's the actual docstring, in the actual source. Bold claim. Let's find out if it's true, and then let's find out if it's reachable --- two very different questions, and this episode answers both.


[1:10--3:00] THREE LAWS, ONE SET

[TERMINAL]

$ python3 -c "
from muse.core.crdts.or_set import ORSet
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')

print('A:', sorted(a.elements()))
print('B:', sorted(b.elements()))
print('join(A,B):', sorted(a.join(b).elements()))
print('join(B,A):', sorted(b.join(a).elements()))
"
A: ['draft', 'reviewed']
B: ['needs-tests']
join(A,B): ['needs-tests', 'reviewed']
join(B,A): ['needs-tests', 'reviewed']

GABRIEL:

Two agents. Neither one ever saw the other's write. A added reviewed. B removed draft and added needs-tests. Join them in either order --- identical result. That's not a coincidence, that's the whole point of an OR-Set: commutative by construction.

[beat]

Associativity and idempotency, same primitive:

associative: True   # join(join(A,B),C) == join(A,join(B,C))
idempotent:  True   # join(A,A) == A

GABRIEL VO:

Three lattice laws. Not asserted --- computed, live, on real Python objects. This is the actual math behind "eventual consistency," running in front of you instead of cited from a paper.


[3:00--3:50] TWO MORE SHAPES OF CONVERGENCE

[TERMINAL]

$ python3 -c "
from muse.core.crdts.g_counter import GCounter
total = GCounter().increment('agent-a', 5).join(
        GCounter().increment('agent-b', 3)).join(
        GCounter().increment('agent-c', 2))
print(total.value())
"
10

GABRIEL VO:

A GCounter --- only grows. Three agents, three independent increments, one correct total, no coordination. Good for play counts, view counts, anything that only goes up.

[beat]

$ python3 -c "
from muse.core.crdts.lww_register import LWWRegister
r1 = LWWRegister('Muse Understands Music', 1000, 'agent-a')
r2 = LWWRegister('CRDT Primitives (draft)', 1002, 'agent-b')
print(r1.join(r2).read())
"
CRDT Primitives (draft)

GABRIEL:

Last-writer-wins, timestamp-ordered. Different shape, same lattice guarantee. Muse ships five of these --- GCounter, LWWRegister, OR-Set, an add-wins map, and a sequence CRDT for ordered data. Pick the shape that matches what you're actually modeling.


[3:50--4:40] THE DOMAIN-LEVEL VERSION, CALLED DIRECTLY

[CAMERA]

Individual primitives converging is one thing. A whole domain plugin using them through the real six-method protocol is the actual claim this season has been making. Let's call plugin.join() directly --- the exact function a domain author would implement.

[TERMINAL]

$ python3 -c "
from muse.plugins.scaffold.plugin import ScaffoldPlugin
plugin = ScaffoldPlugin()
joined_ab = plugin.join(a_crdt, b_crdt)   # agent A's and B's label state
joined_ba = plugin.join(b_crdt, a_crdt)
# both decode to the same OR-Set:
print(sorted_labels(joined_ab), sorted_labels(joined_ba))
"
['needs-tests', 'reviewed'] ['needs-tests', 'reviewed']

GABRIEL VO:

Real plugin, real protocol method, order-independent convergence. The CRDTPlugin interface isn't vaporware --- join() genuinely works, exactly as advertised, 163 tests deep including an exhaustive lattice-law stress test.


[4:40--6:20] THE HONEST PART

[CAMERA]

Here's where it gets uncomfortable. Everything you just watched, I called by hand, in Python, directly. Let's see what happens when I do the normal thing --- two branches, a real repo, muse merge.

[TERMINAL]

$ muse init --domain scaffold
$ echo "hello" > README.md && muse commit -m "Initial" --sign

$ muse checkout -b feat/agent-a
$ echo "hello v2" > README.md && muse commit -m "Agent A change" --sign
$ muse switch main
$ muse checkout -b feat/agent-b
$ echo "hello v3" > README.md && muse commit -m "Agent B change" --sign

$ muse switch main
$ muse merge feat/agent-a        # fast-forward, fine
$ muse merge feat/agent-b
{ "status": "conflict", "conflicts": ["README.md"] }

GABRIEL:

A real conflict. On a domain whose plugin has a fully working, fully tested join() method sitting right there. muse merge never called it.

[beat]

I went and checked why.

$ muse code cat "muse/cli/commands/merge.py::_run_merge" | grep -A2 STRATEGY_MAP
# Use STRATEGY_MAP as the single source of truth for routing.
_engine = STRATEGY_MAP.get(strategy or "recursive")

GABRIEL VO:

muse merge picks its strategy from a --strategy flag --- recursive, overlay, snapshot, replay, ours, theirs. It never reads the domain's own schema()["merge_mode"]. crdt_join_snapshots(), the function whose docstring says it "is the CRDT entry point for the muse merge command" --- has zero callers anywhere in the codebase except that docstring.

[beat]

Every primitive is real. The math is real. The plugin interface works when you call it. Nobody wired the last ten feet of pipe.


[6:20--7:10] WHY THIS ISN'T THE SAME AS THE LAST TWO BUGS

[CAMERA]

Episode 09's Harmony bug and Episode 11's MIDI bug were both real functionality quietly producing the wrong answer. This is different --- nothing here produces a wrong answer. muse merge does exactly what --strategy recursive says it should. The CRDT path simply isn't connected to anything a user can reach.

[beat]

That's actually a smaller kind of problem to fix --- one isinstance check and a routing branch in run_merge(), plus a real decision about where vector clocks and CRDT state live in a commit record, which doesn't exist yet either. Filed as staging#204. Not a regression. An unfinished wire.


[7:10--7:45] OUT

[TERMINAL --- fading to black]

GABRIEL VO:

Ten-plus episodes in, and the pattern holds: showing you the real thing, including the parts that aren't finished, is more convincing than hiding them would ever be.

[beat]

Next: the thing that's been quietly true in every episode this season. The author of half these commits was never a person sitting at a keyboard.

[CUT TO BLACK]

musehub.ai


Production Notes

Episode 12 is the season's first "the feature is real but disconnected" finding, distinct in kind from Episode 09 (silently wrong output) and Episode 11 (silently wrong output via bad call ordering). Keep the tone distinct too: not "gotcha," not deflated --- more like finding a fully machined part in a drawer that was never bolted on. The lattice-law demo in the first half has to land as genuinely impressive on its own terms before the reveal, or the episode reads as one long complaint.

Structure Is Deliberate: Build Trust, Then Spend It

Part 1 (primitives) and Part 2 (plugin.join() called directly) exist to earn the right to make the claim in Part 3 land as surprising rather than predictable. If a viewer already suspects "this is probably not wired up" by minute two, the reveal has no weight. Don't foreshadow it.

The Distinction In The Recap (6:20-7:10) Is Not Optional

Viewers who watched Episode 09 and 11 will reflexively read this as "another bug segment." It isn't the same shape, and the season's credibility depends on the audience being able to tell functional bugs (wrong output) apart from integration gaps (right output, missing wire) rather than lumping every finding into one undifferentiated "muse has bugs" bucket. Say the distinction out loud, don't assume it's obvious from context.

Everything Here Is Real

Every primitive call, the plugin.join() call, and the muse merge conflict were run against the actual current build and reproduced twice. staging#204 was filed with exact file/line references (merge.py's STRATEGY_MAP.get(strategy or "recursive"), crdt_join_snapshots()'s zero real callers) before this script was written, not after. Re-run make-crdt-episode12-demo.sh at record time --- if #204 has since been fixed, Part 3 needs to be re-shot as "and here's the fix landing," not silently cut.

The Seed

The viewer arrives thinking:

Three-way merge with Harmony covers the concurrent-editing story. What's CRDT even for here?

They should leave thinking:

The math for zero-coordination convergence already exists inside this tool, tested harder than most of its shipped features. It's one unfinished decision away from being real. What happens once agents --- plural, uncoordinated, fast --- are the primary writers, and everyone's waiting on this exact wire?

That's Episode 13.

File History 1 commit
sha256:5472be4fece32b606c308fad9d57295ce327955fb2b87b8beec6ea1626050473 Add published YouTube URL to Episode 00 Sonnet 5 10 hours ago