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}