code wiki / _hdl_build / nx_crdt_sync_gate.nx

nx_crdt_sync_gate.nx source

↩ module page · 113 lines · 6603 B

1// nx_crdt_sync_gate.nx -- proves the CRDT SYNC merge on the exact friction scenario: a shared base doc, TWO actors 2// make DIFFERENT concurrent edits (one inserts mid-doc, one appends), they exchange op-logs, and BOTH converge to a 3// document containing BOTH edits -- where naive last-writer-wins (git save-the-file / a lock) loses one and diverges. 4// This is the operational fix for "two Claude sessions edited the same file". license_tier: ORIGINAL expect_exit: 0 5import "nx_syscalls.nx" 6import "nx_crdt_seq.nx" 7import "nx_lamport_clock.nx" 8import "nx_crdt_sync.nx" 9 10func hw(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 11func pn(v: i64) -> i64 { let b: *u8=sys_mmap(32) as *u8; var x: i64=v; var ng: i64=0; if x<0{ng=1;x=0-x} var i: i64=31; if x==0{b[i]=48 as u8;i=i-1} while x>0{b[i]=(48+x%10) as u8;x=x/10;i=i-1} if ng==1{b[i]=45 as u8;i=i-1} sys_write(1,(b as i64+i+1) as *u8,31-i); return 0 } 12func hs(s: *u8, n: i64) -> i64 { sys_write(1, s, n); return 0 } 13func bufeq(a: *u8, an: i64, b: *u8, bn: i64) -> i64 { 14 if an != bn { return 0 } 15 var i: i64 = 0 16 while i < an { if a[i] != b[i] { return 0 } i = i + 1 } 17 return 1 18} 19func has(a: *u8, an: i64, c: i64) -> i64 { 20 var i: i64 = 0 21 while i < an { if (a[i] as i64) == c { return 1 } i = i + 1 } 22 return 0 23} 24func str2(a: *u8, an: i64, c0: i64, c1: i64) -> i64 { 25 if an != 2 { return 0 } 26 if (a[0] as i64) != c0 { return 0 } 27 if (a[1] as i64) != c1 { return 0 } 28 return 1 29} 30func str3(a: *u8, an: i64, c0: i64, c1: i64, c2: i64) -> i64 { 31 if an != 3 { return 0 } 32 if (a[0] as i64) != c0 { return 0 } 33 if (a[1] as i64) != c1 { return 0 } 34 if (a[2] as i64) != c2 { return 0 } 35 return 1 36} 37func str4(a: *u8, an: i64, c0: i64, c1: i64, c2: i64, c3: i64) -> i64 { 38 if an != 4 { return 0 } 39 if (a[0] as i64) != c0 { return 0 } 40 if (a[1] as i64) != c1 { return 0 } 41 if (a[2] as i64) != c2 { return 0 } 42 if (a[3] as i64) != c3 { return 0 } 43 return 1 44} 45 46func main() -> i64 { 47 hw("=== nx_crdt_sync_gate -- two agents edit one doc concurrently; CRDT merges both, git loses one ===\n" as *u8) 48 var fails: i64 = 0 49 50 // BASE (actor 0): 'A'=65 then 'C'=67 -> "AC"; ids A=(1,0) C=(2,0) 51 let base: *i64 = seq_new() 52 let baseLog: *i64 = oplog_new() 53 let clkBase: *i64 = lc_new(0) 54 sync_insert(base, baseLog, clkBase, 65, 0-1, 0-1) 55 sync_insert(base, baseLog, clkBase, 67, 1, 0) 56 let bufBase: *u8 = sys_mmap(64); let lBase: i64 = seq_materialize(base, bufBase) 57 hw(" base="); hs(bufBase, lBase); hw("\n" as *u8) 58 var t1: i64 = 0 59 if str2(bufBase, lBase, 65, 67) == 1 { t1 = 1 } 60 if t1 == 1 { hw("T1 PASS base doc 'AC'\n" as *u8) } else { fails=fails+1; hw("T1 FAIL base\n" as *u8) } 61 62 // FORK: two replicas each apply the base op-log 63 let docA: *i64 = seq_new(); let clkA: *i64 = lc_new(1); sync_apply_log(docA, clkA, baseLog); let logA: *i64 = oplog_new() 64 let docB: *i64 = seq_new(); let clkB: *i64 = lc_new(2); sync_apply_log(docB, clkB, baseLog); let logB: *i64 = oplog_new() 65 66 // CONCURRENT edits: A inserts 'B'=66 after A(1,0) [mid-doc]; B inserts 'D'=68 after C(2,0) [append] 67 sync_insert(docA, logA, clkA, 66, 1, 0) 68 sync_insert(docB, logB, clkB, 68, 2, 0) 69 let aPre: *u8 = sys_mmap(64); let laPre: i64 = seq_materialize(docA, aPre) 70 let bPre: *u8 = sys_mmap(64); let lbPre: i64 = seq_materialize(docB, bPre) 71 hw(" pre-sync replicaA="); hs(aPre, laPre); hw(" replicaB="); hs(bPre, lbPre); hw(" (DIVERGED = the collision)\n" as *u8) 72 var t2: i64 = 0 73 if str3(aPre, laPre, 65, 66, 67) == 1 { if str3(bPre, lbPre, 65, 67, 68) == 1 { if bufeq(aPre, laPre, bPre, lbPre) == 0 { t2 = 1 } } } 74 if t2 == 1 { hw("T2 PASS each replica saw only its own edit -> ABC vs ACD (the git collision state)\n" as *u8) } else { fails=fails+1; hw("T2 FAIL\n" as *u8) } 75 76 // SYNC: exchange op-logs (each applies the other's) 77 sync_apply_log(docA, clkA, logB) 78 sync_apply_log(docB, clkB, logA) 79 let aPost: *u8 = sys_mmap(64); let laPost: i64 = seq_materialize(docA, aPost) 80 let bPost: *u8 = sys_mmap(64); let lbPost: i64 = seq_materialize(docB, bPost) 81 hw(" post-sync replicaA="); hs(aPost, laPost); hw(" replicaB="); hs(bPost, lbPost); hw("\n" as *u8) 82 var t3: i64 = 0 83 if bufeq(aPost, laPost, bPost, lbPost) == 1 { if str4(aPost, laPost, 65, 66, 67, 68) == 1 { t3 = 1 } } 84 if t3 == 1 { hw("T3 PASS both replicas CONVERGE to 'ABCD' after exchanging op-logs\n" as *u8) } else { fails=fails+1; hw("T3 FAIL convergence\n" as *u8) } 85 86 var t4: i64 = 0 87 if laPost == 4 { if has(aPost, laPost, 66) == 1 { if has(aPost, laPost, 68) == 1 { t4 = 1 } } } 88 if t4 == 1 { hw("T4 PASS NO edit lost -- BOTH concurrent edits present (B and D)\n" as *u8) } else { fails=fails+1; hw("T4 FAIL an edit lost\n" as *u8) } 89 90 // NEG CONTROL: naive last-writer-wins (git save-the-file / a lock) keeps ONE version -> len 3 (loss) + it diverged 91 var t5: i64 = 0 92 if laPre == 3 { if lbPre == 3 { if bufeq(aPre, laPre, bPre, lbPre) == 0 { if laPost > laPre { t5 = 1 } } } } 93 if t5 == 1 { hw("T5 PASS neg-control BITES: naive LWW keeps 1 version (len 3<4 = an edit LOST) and diverged; the CRDT did not\n" as *u8) } else { fails=fails+1; hw("T5 FAIL neg-control\n" as *u8) } 94 95 // ARTIFACT 96 let rep: *u8 = sys_mmap(2048) 97 var q: i64 = 0 98 var s: *u8 = "NISHI CRDT SYNC -- V-COLLAB rung 2 (composes nx_crdt_seq + nx_lamport_clock). Two actors edit one base doc 'AC' concurrently: A inserts B mid-doc, B appends D. They exchange op-logs and BOTH converge to 'ABCD' -- both edits kept, zero collision, zero loss.\n" as *u8 99 var k: i64 = 0 100 while s[k] != (0 as u8) { rep[q] = s[k]; q = q + 1; k = k + 1 } 101 s = "Neg-control: naive last-writer-wins (a lock / git save-the-file) keeps only one version (len 3) and diverges = the exact 'file modified since read' collision. This op-log sync is the operational fix; next = a peer sync transport + wiring the real edit surface through it.\n" as *u8 102 k = 0 103 while s[k] != (0 as u8) { rep[q] = s[k]; q = q + 1; k = k + 1 } 104 rep[q] = 0 as u8 105 let fd: i64 = sys_openat_wr("knowledge/nx_crdt_sync.txt\x00" as *u8, 0x1a4) 106 sys_write(fd, rep, q); sys_close(fd) 107 hw("T6 artifact -> knowledge/nx_crdt_sync.txt ("); pn(q); hw(" bytes)\n" as *u8) 108 109 if fails == 0 { hw("NX-CRDT-SYNC GREEN -- concurrent multi-agent edits merge with zero loss; git-model neg-control loses+diverges\n" as *u8); sys_exit(0); return 0 } 110 hw("NX-CRDT-SYNC RED fails="); pn(fails); hw("\n" as *u8) 111 sys_exit(1) 112 return 1 113}