code wiki / _hdl_build / nx_role_store_migrate.nx

nx_role_store_migrate.nx source

↩ module page · 122 lines · 5824 B

1// nx_role_store_migrate.nx -- MIGRATE the knowledge/roles/*.tsv files into the SOVEREIGN seg-store 2// (knowledge/store/roles-*, via nx_role_store). Operator 2026-06-22: "migrate and get rid of these tsvs just 3// nishi ecosystem." Reads each legacy .tsv, seeds its rows into the matching channel in ONE batched commit 4// (1 segment), then reads EVERY row back and byte-compares to the source line -> GREEN only if every source 5// row is present byte-exact. IDEMPOTENT (rule#10): a channel is seeded only when EMPTY (count==0); once seeded 6// (and possibly evolved by live appends) a re-run writes nothing and still verifies. ADDITIVE (rule#13): the 7// .tsv files are not touched here -- retirement to knowledge/_retired_tsv/ is a separate, post-verify step. 8// pm_coord.tsv -> pmcoord engineer_queue.tsv -> engineerq doctor_queue.tsv -> doctorq engineer_ledger.tsv -> engineerl 9// expect_exit: 0 license_tier: ORIGINAL 10import "nx_role_store.nx" 11import "nx_seg_store.nx" 12import "nx_syscalls.nx" 13const K_MAGIC_4096: i64 = 4096 14 15func mw(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 16func mn(v: i64) -> i64 { let b: *u8=sys_mmap(28); let e: i64=rs_itoa(b,v); sys_write(1,b,e); return 0 } 17 18// migrate ONE legacy tsv into a channel. counts source rows into tot[0], byte-verified rows into ver[0], 19// and channels freshly-seeded this run into wro[0]. Returns 0. 20func mig_one(ch: *u8, tsvpath: *u8, tot: *i64, ver: *i64, wro: *i64) -> i64 { 21 let szp: *i64 = sys_mmap(16) as *i64 22 let buf: *u8 = ss_readall(tsvpath, szp) 23 let sz: i64 = szp[0] 24 mw(" channel " as *u8); mw(ch); mw(" <- " as *u8); mw(tsvpath); mw(" ") 25 26 // SOURCE RETIRED: once the legacy .tsv has been moved to _retired_tsv/, the store is the SSOT. Verify the 27 // channel is self-consistent (every row reads back) so this migration stays idempotent-GREEN post-retirement. 28 if sz <= 0 { 29 let cntr: i64 = rs_count(ch) 30 mw("(source retired/absent; channel rows=" as *u8); mn(cntr); mw(") " as *u8) 31 let pqr: *i64 = sys_mmap(16) as *i64; let lqr: *i64 = sys_mmap(16) as *i64 32 var ir: i64 = 0 33 while ir < cntr { tot[0] = tot[0] + 1; if rs_get_seq(ch, ir, pqr, lqr) == 1 { ver[0] = ver[0] + 1 } ir = ir + 1 } 34 mw("verified=" as *u8); mn(cntr); mw("\n" as *u8) 35 return 0 36 } 37 38 // collect non-empty line (ptr,len) pairs -- the value is the line MINUS its trailing newline 39 let lp: *i64 = sys_mmap(8 * K_MAGIC_4096) as *i64 40 let ll: *i64 = sys_mmap(8 * K_MAGIC_4096) as *i64 41 var k: i64 = 0 42 if sz > 0 { 43 var i: i64 = 0 44 var ls: i64 = 0 45 while i <= sz { 46 var nl: i64 = 0 47 if i >= sz { nl = 1 } else { if buf[i] == (10 as u8) { nl = 1 } } 48 if nl == 1 { 49 let len: i64 = i - ls 50 if len > 0 { if k < K_MAGIC_4096 { lp[k] = (buf as i64) + ls; ll[k] = len; k = k + 1 } } 51 ls = i + 1 52 } 53 i = i + 1 54 } 55 } 56 mw("rows=" as *u8); mn(k) 57 58 let existing: i64 = rs_count(ch) 59 // SEED only when empty -- protects any live-evolved rows from being clobbered on re-run 60 if existing == 0 { if k > 0 { 61 let lk: i64 = rs_lock() 62 let w: *i64 = ss_begin() 63 var j: i64 = 0 64 while j < k { 65 let rk: *u8 = sys_mmap(128); rs_key(ch, j, rk) 66 ss_add(w, 1, rk, lp[j] as *u8, ll[j]) 67 j = j + 1 68 } 69 let nk: *u8 = sys_mmap(128); rs_nkey(ch, nk) 70 let cb: *u8 = sys_mmap(32); let cl: i64 = rs_itoa(cb, k) 71 ss_add(w, 1, nk, cb, cl) 72 ss_commit(RS_PREFIX, w, rs_seg_next()) 73 rs_unlock(lk) 74 wro[0] = wro[0] + 1 75 mw(" SEEDED" as *u8) 76 } } else { mw(" (already-present count=" as *u8); mn(existing); mw(")" as *u8) } 77 78 // VERIFY: each source row reads back byte-exact from the store 79 let pq: *i64 = sys_mmap(16) as *i64 80 let lq: *i64 = sys_mmap(16) as *i64 81 var vok: i64 = 0 82 var j2: i64 = 0 83 while j2 < k { 84 tot[0] = tot[0] + 1 85 if rs_get_seq(ch, j2, pq, lq) == 1 { 86 if lq[0] == ll[j2] { 87 let a: *u8 = pq[0] as *u8 88 let b2: *u8 = lp[j2] as *u8 89 var eq: i64 = 1 90 var x: i64 = 0 91 while x < lq[0] { if a[x] != b2[x] { eq = 0 } x = x + 1 } 92 if eq == 1 { vok = vok + 1; ver[0] = ver[0] + 1 } 93 } 94 } 95 j2 = j2 + 1 96 } 97 mw(" verified=" as *u8); mn(vok); mw("/" as *u8); mn(k); mw("\n" as *u8) 98 return 0 99} 100 101func main() -> i64 { 102 mw("=== nx_role_store_migrate: knowledge/roles/*.tsv -> sovereign seg-store (knowledge/store/roles-*) ===\n" as *u8) 103 let tot: *i64 = sys_mmap(16) as *i64; tot[0] = 0 104 let ver: *i64 = sys_mmap(16) as *i64; ver[0] = 0 105 let wro: *i64 = sys_mmap(16) as *i64; wro[0] = 0 106 107 mig_one("pmcoord" as *u8, "knowledge/roles/pm_coord.tsv" as *u8, tot, ver, wro) 108 mig_one("engineerq" as *u8, "knowledge/roles/engineer_queue.tsv" as *u8, tot, ver, wro) 109 mig_one("doctorq" as *u8, "knowledge/roles/doctor_queue.tsv" as *u8, tot, ver, wro) 110 mig_one("engineerl" as *u8, "knowledge/roles/engineer_ledger.tsv" as *u8, tot, ver, wro) 111 112 mw("\n source_rows=" as *u8); mn(tot[0]); mw(" verified_in_store=" as *u8); mn(ver[0]) 113 mw(" channels_seeded_this_run=" as *u8); mn(wro[0]); mw(" segcount=" as *u8); mn(rs_segcount()) 114 mw("\n store=knowledge/store/roles- (NO TSV)\n" as *u8) 115 116 if ver[0] == tot[0] { if tot[0] > 0 { 117 mw("ROLE-STORE-MIGRATE verdict=GREEN (every legacy roles/*.tsv row is byte-exact in the seg-store)\n" as *u8) 118 sys_exit(0); return 0 119 } } 120 mw("ROLE-STORE-MIGRATE verdict=RED (source rows not fully verified in the store)\n" as *u8) 121 sys_exit(1); return 1 122}