code wiki / _hdl_build / nx_estate_inventory.nx

nx_estate_inventory.nx source

↩ module page · 177 lines · 10091 B

1// nx_estate_inventory.nx -- FIRST RUNG of the Nishi Office/Storage suite for andelinwest: a NEVER-LOSE, 2// audit-trailed estate INVENTORY (the will's assets/beneficiaries) on the sovereign append-only content- 3// addressed store (nx_seg_store). Why this reduces EXECUTOR CONFLICT: the store is APPEND-ONLY IMMUTABLE -- 4// every edit is a NEW version and OLD versions are never destroyed (the ADDITIVE law), commits are crash-safe 5// (temp+rename), and reads return ONE authoritative current value. So the executor + heirs get a single, 6// tamper-evident source of truth WITH a complete change history, instead of scattered disputable copies. 7// nx_estate_inventory put <prefix> <asset_id> <description> <value> <beneficiary> 8// nx_estate_inventory get <prefix> <asset_id> 9// nx_estate_inventory history <prefix> <asset_id> (the full audit trail = every version, oldest->newest) 10// prefix = a store path prefix, e.g. knowledge/store/estate-andelinwest-CLIENT- license_tier: ORIGINAL 11import "nx_seg_store.nx" 12const K_MAGIC_8192: i64 = 8192 13const K_MAGIC_65536: i64 = 65536 14 15func ei_puts(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 16func ei_num(v: i64) -> i64 { let bb: *u8=sys_mmap(28); var m: i64=v; if m<0{m=0-m;sys_write(1,"-" as *u8,1)}; let t: *u8=sys_mmap(28); var k: i64=0; if m==0{t[0]=(48 as u8);k=1}; while m>0{t[k]=((48+(m%10)) as u8);m=m/10;k=k+1}; var i: i64=0; while i<k{bb[i]=t[k-1-i];i=i+1}; sys_write(1,bb,k); return 0 } 17func ei_strlen(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n } 18func ei_streq(a: *u8, b: *u8) -> i64 { var i: i64=0; while a[i]!=(0 as u8){ if a[i]!=b[i]{return 0} i=i+1 } if b[i]!=(0 as u8){return 0} return 1 } 19func ei_cat(dst: *u8, off: i64, s: *u8) -> i64 { var i: i64=0; while s[i]!=(0 as u8){ dst[off+i]=s[i]; i=i+1 } return off+i } 20 21// next segment id = the segment COUNT. ss_manifest fills segs[] with name-string POINTERS (not segids), so we 22// must NOT max over them; commits are sequential (each uses the prior count as its id), so count == next id. 23func ei_next_segid(prefix: *u8) -> i64 { 24 let segs: *i64=sys_mmap(8*260) as *i64 25 return ss_manifest(prefix, segs) 26} 27 28// build key "asset:<id>" (NUL-terminated) into kbuf 29func ei_key(kbuf: *u8, id: *u8) -> i64 { 30 var o: i64=ei_cat(kbuf, 0, "asset:" as *u8) 31 o=ei_cat(kbuf, o, id) 32 kbuf[o]=0 as u8 33 return o 34} 35 36// is `id` (idlen bytes) present as a whole line in buf[0..n)? 37func ei_id_present(buf: *u8, n: i64, id: *u8, idlen: i64) -> i64 { 38 var ls: i64=0; var i: i64=0 39 while i<=n { 40 var eol: i64=0 41 if i==n { eol=1 } else { if buf[i]==(10 as u8) { eol=1 } } 42 if eol==1 { 43 if i-ls==idlen { var j: i64=0; var same: i64=1; while j<idlen { if buf[ls+j]!=id[j] { same=0; j=idlen } else { j=j+1 } } if same==1 { return 1 } } 44 ls=i+1 45 } 46 i=i+1 47 } 48 return 0 49} 50 51func main(argc: i64, argv: *i64) -> i64 { 52 if argc<3 { 53 ei_puts("usage: nx_estate_inventory put|get|history|list|export <prefix> ...\n" as *u8) 54 sys_exit(2); return 2 55 } 56 let cmd: *u8=argv[1] as *u8 57 let prefix: *u8=argv[2] as *u8 58 59 if ei_streq(cmd, "put" as *u8)==1 { 60 if argc<7 { ei_puts("usage: put <prefix> <asset_id> <description> <value> <beneficiary>\n" as *u8); sys_exit(2); return 2 } 61 let id: *u8=argv[3] as *u8 62 let kbuf: *u8=sys_mmap(256); ei_key(kbuf, id) 63 // canonical record: description<TAB>value<TAB>beneficiary 64 let vbuf: *u8=sys_mmap(K_MAGIC_8192); var vo: i64=0 65 vo=ei_cat(vbuf, vo, argv[4] as *u8); vbuf[vo]=9 as u8; vo=vo+1 66 vo=ei_cat(vbuf, vo, argv[5] as *u8); vbuf[vo]=9 as u8; vo=vo+1 67 vo=ei_cat(vbuf, vo, argv[6] as *u8) 68 let segid: i64=ei_next_segid(prefix) 69 let w: *i64=ss_begin() 70 ss_add(w, 1, kbuf, vbuf, vo) 71 // maintain "__index__" (newline-separated asset ids) IN THE SAME COMMIT so `list` can enumerate the whole 72 // will inventory atomically -- the asset record and the index advance together (no torn state). 73 let ipo: *i64=sys_mmap(16) as *i64; let ilo: *i64=sys_mmap(16) as *i64 74 let idxbuf: *u8=sys_mmap(K_MAGIC_65536); var ilen: i64=0 75 if ss_get(prefix, "__index__" as *u8, ipo, ilo)>=0 { let src: *u8=ipo[0] as *u8; var c: i64=0; while c<ilo[0] { idxbuf[ilen]=src[c]; ilen=ilen+1; c=c+1 } } 76 let idl: i64=ei_strlen(id) 77 if ei_id_present(idxbuf, ilen, id, idl)==0 { var c2: i64=0; while c2<idl { idxbuf[ilen]=id[c2]; ilen=ilen+1; c2=c2+1 } idxbuf[ilen]=10 as u8; ilen=ilen+1 } 78 ss_add(w, 1, "__index__" as *u8, idxbuf, ilen) 79 let rc: i64=ss_commit(prefix, w, segid) 80 if rc!=0 { ei_puts("ESTATE-PUT-FAIL rc=" as *u8); ei_num(rc); ei_puts("\n" as *u8); sys_exit(1); return 1 } 81 ei_puts("ESTATE-PUT-OK asset=" as *u8); ei_puts(id); ei_puts(" version=" as *u8); ei_num(segid); ei_puts("\n" as *u8) 82 sys_exit(0); return 0 83 } 84 85 if ei_streq(cmd, "get" as *u8)==1 { 86 if argc<4 { ei_puts("usage: get <prefix> <asset_id>\n" as *u8); sys_exit(2); return 2 } 87 let kbuf: *u8=sys_mmap(256); ei_key(kbuf, argv[3] as *u8) 88 let po: *i64=sys_mmap(16) as *i64 89 let lo: *i64=sys_mmap(16) as *i64 90 let rc: i64=ss_get(prefix, kbuf, po, lo) 91 if rc<0 { ei_puts("ESTATE-GET: asset not found\n" as *u8); sys_exit(1); return 1 } 92 ei_puts("ESTATE-ASSET " as *u8); ei_puts(argv[3] as *u8); ei_puts(" = " as *u8) 93 sys_write(1, po[0] as *u8, lo[0]); ei_puts("\n" as *u8) 94 sys_exit(0); return 0 95 } 96 97 if ei_streq(cmd, "history" as *u8)==1 { 98 if argc<4 { ei_puts("usage: history <prefix> <asset_id>\n" as *u8); sys_exit(2); return 2 } 99 let kbuf: *u8=sys_mmap(256); ei_key(kbuf, argv[3] as *u8) 100 let kinds: *i64=sys_mmap(8*260) as *i64 101 let ptrs: *i64=sys_mmap(8*260) as *i64 102 let lens: *i64=sys_mmap(8*260) as *i64 103 let srcs: *i64=sys_mmap(8*260) as *i64 104 let n: i64=ss_scan_all(prefix, kbuf, kinds, ptrs, lens, srcs) 105 ei_puts("ESTATE-HISTORY " as *u8); ei_puts(argv[3] as *u8); ei_puts(" versions=" as *u8); ei_num(n); ei_puts(" (oldest->newest; immutable, never destroyed)\n" as *u8) 106 var i: i64=0 107 while i<n { 108 ei_puts(" v" as *u8); ei_num(i); ei_puts(" seg=" as *u8); ei_num(srcs[i]) 109 if kinds[i]==2 { ei_puts(" [TOMBSTONE/soft-delete]" as *u8) } else { ei_puts(" = " as *u8); sys_write(1, ptrs[i] as *u8, lens[i]) } 110 ei_puts("\n" as *u8) 111 i=i+1 112 } 113 sys_exit(0); return 0 114 } 115 116 if ei_streq(cmd, "list" as *u8)==1 { 117 // the WHOLE will inventory: every asset id (from __index__) with its current authoritative state. 118 let ipo: *i64=sys_mmap(16) as *i64; let ilo: *i64=sys_mmap(16) as *i64 119 if ss_get(prefix, "__index__" as *u8, ipo, ilo)<0 { ei_puts("ESTATE-LIST: (empty inventory)\nESTATE-LIST-OK assets=0\n" as *u8); sys_exit(0); return 0 } 120 let idxp: *u8=ipo[0] as *u8; let idxn: i64=ilo[0] 121 ei_puts("ESTATE-INVENTORY (all assets, current state; desc<TAB>value<TAB>beneficiary):\n" as *u8) 122 var ls: i64=0; var i: i64=0; var cnt: i64=0 123 while i<=idxn { 124 var eol: i64=0 125 if i==idxn { eol=1 } else { if idxp[i]==(10 as u8) { eol=1 } } 126 if eol==1 { 127 if i>ls { 128 let kbuf: *u8=sys_mmap(256); var ko: i64=ei_cat(kbuf, 0, "asset:" as *u8) 129 var c: i64=ls; while c<i { kbuf[ko]=idxp[c]; ko=ko+1; c=c+1 } kbuf[ko]=0 as u8 130 let po: *i64=sys_mmap(16) as *i64; let lo: *i64=sys_mmap(16) as *i64 131 ei_puts(" " as *u8); sys_write(1, ((idxp as i64)+ls) as *u8, i-ls); ei_puts(" = " as *u8) 132 if ss_get(prefix, kbuf, po, lo)>=0 { sys_write(1, po[0] as *u8, lo[0]) } else { ei_puts("(missing)" as *u8) } 133 ei_puts("\n" as *u8); cnt=cnt+1 134 } 135 ls=i+1 136 } 137 i=i+1 138 } 139 ei_puts("ESTATE-LIST-OK assets=" as *u8); ei_num(cnt); ei_puts("\n" as *u8) 140 sys_exit(0); return 0 141 } 142 143 if ei_streq(cmd, "export" as *u8)==1 { 144 // emit a MAIL-MERGE-READY TSV (header + one row per asset) so the inventory directly drives per-heir 145 // document generation (nx_mailmerge). Columns: asset<TAB>description<TAB>value<TAB>beneficiary -- the 146 // stored value is ALREADY description<TAB>value<TAB>beneficiary, so each row = asset-id + TAB + value. 147 let tab: *u8=sys_mmap(1); tab[0]=9 as u8 148 ei_puts("asset" as *u8); sys_write(1,tab,1); ei_puts("description" as *u8); sys_write(1,tab,1); ei_puts("value" as *u8); sys_write(1,tab,1); ei_puts("beneficiary\n" as *u8) 149 let ipo: *i64=sys_mmap(16) as *i64; let ilo: *i64=sys_mmap(16) as *i64 150 if ss_get(prefix, "__index__" as *u8, ipo, ilo)<0 { sys_exit(0); return 0 } 151 let idxp: *u8=ipo[0] as *u8; let idxn: i64=ilo[0] 152 var ls: i64=0; var i: i64=0 153 while i<=idxn { 154 var eol: i64=0 155 if i==idxn { eol=1 } else { if idxp[i]==(10 as u8) { eol=1 } } 156 if eol==1 { 157 if i>ls { 158 let kbuf: *u8=sys_mmap(256); var ko: i64=ei_cat(kbuf, 0, "asset:" as *u8) 159 var c: i64=ls; while c<i { kbuf[ko]=idxp[c]; ko=ko+1; c=c+1 } kbuf[ko]=0 as u8 160 let po: *i64=sys_mmap(16) as *i64; let lo: *i64=sys_mmap(16) as *i64 161 if ss_get(prefix, kbuf, po, lo)>=0 { 162 sys_write(1, ((idxp as i64)+ls) as *u8, i-ls) // asset id 163 sys_write(1, tab, 1) 164 sys_write(1, po[0] as *u8, lo[0]) // stored value = description<TAB>value<TAB>beneficiary 165 ei_puts("\n" as *u8) 166 } 167 } 168 ls=i+1 169 } 170 i=i+1 171 } 172 sys_exit(0); return 0 173 } 174 175 ei_puts("ESTATE: unknown command (put|get|history|list|export)\n" as *u8) 176 sys_exit(2); return 2 177}