nx_matter_lib.nx source
↩ module page · 187 lines · 6511 B
1// nx_matter_lib.nx -- Nishi Office: Matter/Client SPINE (F502) core lib.
2// Client/matter/party records on the append-only immutable seg_store (nx_registry),
3// canonicalized + content-addressed (nx_canon_cid). The legal-SOTA feature = CONFLICTS
4// CHECK (RPC 1.7/1.9): scan every matter's parties for a name across the whole book.
5// LIB (no main) so the CLI organ AND the independent gate import the SAME shipped code.
6// SCALE-LAW (DECLARED): conflict scan is O(N-parties) linear (fail-closed, exact); a
7// party-name index = the flagged next rung, NOT a hidden cap. license_tier: ORIGINAL
8
9import "nx_canon_cid.nx"
10import "nx_registry.nx"
11const K_MAGIC_2048: i64 = 2048
12const K_MAGIC_1048576: i64 = 1048576
13
14func mt_r32(p: *u8, off: i64) -> i64 {
15 let a: i64 = p[off]
16 let b: i64 = p[off + 1]
17 let c: i64 = p[off + 2]
18 let d: i64 = p[off + 3]
19 return (((((a << 8) | b) << 8) | c) << 8) | d
20}
21
22func mt_catcopy(dst: *u8, off: i64, s: *u8) -> i64 {
23 var i: i64 = 0
24 while s[i] != (0 as u8) { dst[off + i] = s[i]; i = i + 1 }
25 return off + i
26}
27
28func mt_catn(dst: *u8, off: i64, v: i64) -> i64 {
29 var m: i64 = v
30 var o: i64 = off
31 if m == 0 { dst[o] = 48 as u8; return o + 1 }
32 let t: *u8 = sys_mmap(24)
33 var k: i64 = 0
34 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
35 var i: i64 = 0
36 while i < k { dst[o + i] = t[k - 1 - i]; i = i + 1 }
37 return o + k
38}
39
40func mt_streq(a: *u8, b: *u8) -> i64 {
41 var i: i64 = 0
42 while 1 == 1 {
43 if a[i] != b[i] { return 0 }
44 if a[i] == (0 as u8) { return 1 }
45 i = i + 1
46 }
47 return 1
48}
49
50// decode a field value from an NXR1 canonical record ("NXR1"|u32 n|(u32 kl|k|u32 vl|v)*)
51// into out (NUL-terminated); returns vlen or -1 if absent.
52func mt_field(rec: *u8, reclen: i64, key: *u8, keylen: i64, out: *u8) -> i64 {
53 let n: i64 = mt_r32(rec, 4)
54 var o: i64 = 8
55 var i: i64 = 0
56 while i < n {
57 let kl: i64 = mt_r32(rec, o)
58 o = o + 4
59 let kstart: i64 = o
60 o = o + kl
61 let vl: i64 = mt_r32(rec, o)
62 o = o + 4
63 let vstart: i64 = o
64 o = o + vl
65 if kl == keylen {
66 var mm: i64 = 1
67 var c: i64 = 0
68 while c < kl { if rec[kstart + c] != key[c] { mm = 0 } c = c + 1 }
69 if mm == 1 {
70 var d: i64 = 0
71 while d < vl { out[d] = rec[vstart + d]; d = d + 1 }
72 out[vl] = 0 as u8
73 return vl
74 }
75 }
76 i = i + 1
77 }
78 out[0] = 0 as u8
79 return 0 - 1
80}
81
82// build a canonical record from n (key,val) string pairs into out; returns len
83func mt_rec(keys: *i64, vals: *i64, n: i64, out: *u8) -> i64 {
84 return canon_encode(keys, vals, n, out)
85}
86
87func mt_client_put(prefix: *u8, id: *u8, name: *u8, email: *u8) -> i64 {
88 let k: *i64 = sys_mmap(8 * 3) as *i64
89 let v: *i64 = sys_mmap(8 * 3) as *i64
90 k[0] = ("name" as *u8) as i64
91 v[0] = name as i64
92 k[1] = ("email" as *u8) as i64
93 v[1] = email as i64
94 k[2] = ("type" as *u8) as i64
95 v[2] = ("client" as *u8) as i64
96 let rec: *u8 = sys_mmap(K_MAGIC_2048)
97 let rl: i64 = canon_encode(k, v, 3, rec)
98 return reg_put(prefix, "client:" as *u8, "client:__idx__" as *u8, id, rec, rl)
99}
100
101func mt_matter_put(prefix: *u8, mid: *u8, client: *u8, title: *u8, area: *u8) -> i64 {
102 let k: *i64 = sys_mmap(8 * 4) as *i64
103 let v: *i64 = sys_mmap(8 * 4) as *i64
104 k[0] = ("client" as *u8) as i64
105 v[0] = client as i64
106 k[1] = ("title" as *u8) as i64
107 v[1] = title as i64
108 k[2] = ("area" as *u8) as i64
109 v[2] = area as i64
110 k[3] = ("status" as *u8) as i64
111 v[3] = ("open" as *u8) as i64
112 let rec: *u8 = sys_mmap(K_MAGIC_2048)
113 let rl: i64 = canon_encode(k, v, 4, rec)
114 return reg_put(prefix, "matter:" as *u8, "matter:__idx__" as *u8, mid, rec, rl)
115}
116
117// party id = "<mid>:<seq>"
118func mt_party_add(prefix: *u8, mid: *u8, seq: i64, name: *u8, role: *u8) -> i64 {
119 let pid: *u8 = sys_mmap(128)
120 var o: i64 = mt_catcopy(pid, 0, mid)
121 pid[o] = 58 as u8
122 o = o + 1
123 o = mt_catn(pid, o, seq)
124 pid[o] = 0 as u8
125 let k: *i64 = sys_mmap(8 * 3) as *i64
126 let v: *i64 = sys_mmap(8 * 3) as *i64
127 k[0] = ("matter" as *u8) as i64
128 v[0] = mid as i64
129 k[1] = ("name" as *u8) as i64
130 v[1] = name as i64
131 k[2] = ("role" as *u8) as i64
132 v[2] = role as i64
133 let rec: *u8 = sys_mmap(K_MAGIC_2048)
134 let rl: i64 = canon_encode(k, v, 3, rec)
135 return reg_put(prefix, "party:" as *u8, "party:__idx__" as *u8, pid, rec, rl)
136}
137
138// CONFLICTS CHECK: count parties named `name` across ALL matters; append matching
139// matter ids (newline-sep) into matters. Returns the match count.
140func mt_conflict(prefix: *u8, name: *u8, matters: *u8) -> i64 {
141 let idx: *u8 = sys_mmap(K_MAGIC_1048576)
142 let ilen: i64 = reg_index(prefix, "party:__idx__" as *u8, idx, K_MAGIC_1048576)
143 let idb: *u8 = sys_mmap(256)
144 let po: *i64 = sys_mmap(16) as *i64
145 let lo: *i64 = sys_mmap(16) as *i64
146 let nmb: *u8 = sys_mmap(256)
147 let mtb: *u8 = sys_mmap(256)
148 var count: i64 = 0
149 var mo: i64 = 0
150 var ls: i64 = 0
151 var i: i64 = 0
152 while i <= ilen {
153 var eol: i64 = 0
154 if i == ilen { eol = 1 }
155 if i < ilen { if idx[i] == 10 as u8 { eol = 1 } }
156 if eol == 1 {
157 if i > ls {
158 var c: i64 = 0
159 while ls + c < i { idb[c] = idx[ls + c]; c = c + 1 }
160 idb[c] = 0 as u8
161 if reg_get(prefix, "party:" as *u8, idb, po, lo) == 1 {
162 let rec: *u8 = po[0] as *u8
163 mt_field(rec, lo[0], "name" as *u8, 4, nmb)
164 if mt_streq(nmb, name) == 1 {
165 mt_field(rec, lo[0], "matter" as *u8, 6, mtb)
166 mo = mt_catcopy(matters, mo, mtb)
167 matters[mo] = 10 as u8
168 mo = mo + 1
169 count = count + 1
170 }
171 }
172 }
173 ls = i + 1
174 }
175 i = i + 1
176 }
177 matters[mo] = 0 as u8
178 return count
179}
180
181// fetch matter field into out; returns vlen or -1
182func mt_matter_field(prefix: *u8, mid: *u8, field: *u8, flen: i64, out: *u8) -> i64 {
183 let po: *i64 = sys_mmap(16) as *i64
184 let lo: *i64 = sys_mmap(16) as *i64
185 if reg_get(prefix, "matter:" as *u8, mid, po, lo) != 1 { out[0] = 0 as u8; return 0 - 1 }
186 return mt_field(po[0] as *u8, lo[0], field, flen, out)
187}