code wiki / _hdl_build / nx_vizsla_log.nx
nx_vizsla_log.nx source
↩ module page · 347 lines · 14003 B
1// nx_vizsla_log.nx -- NISHI VIZSLA: TYPED INTERACTIONS + TIMELINE (PRM/CRM depth b,c). Operator 2026-06-23:
2// real-system depth. A real interaction is not one generic "touch" -- it has a TYPE (call/meeting/email/note/
3// text/coffee/intro/gift...) and CONTENT. This stores typed interactions as ADDITIVE CID records on the
4// sovereign seg_store plane and renders a full chronological per-contact TIMELINE (newest-first). Type is data
5// (any label). Foundation for typed-weighted health + reporting. Computed locally; tamper-evident; idempotent.
6// load <logfile> <prefix> [segid] INT <date> <contact> <type> <note...> -> "int:" records
7// timeline <prefix> <contact> that contact's interactions newest-first + first/last/count verdict
8// The note is the REST OF THE LINE (multi-word content preserved). Determinism: no clocks in stdout.
9// license_tier: ORIGINAL
10import "nx_syscalls.nx"
11import "nx_canon_cid.nx"
12import "nx_seg_store.nx"
13const K_MAGIC_1970: i64 = 1970
14const K_MAGIC_146097: i64 = 146097
15const K_MAGIC_719468: i64 = 719468
16const K_MAGIC_4096: i64 = 4096
17const K_MAGIC_1024: i64 = 1024
18const K_MAGIC_2048: i64 = 2048
19const K_MAGIC_131072: i64 = 131072
20
21func vl_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n }
22func vl_p(s: *u8) -> i64 { sys_write(1, s, vl_slen(s)); return 0 }
23
24func vl_eq(a: *u8, b: *u8) -> i64 {
25 var i: i64 = 0
26 var go: i64 = 1
27 while go == 1 { if a[i] != b[i] { return 0 } if a[i] == (0 as u8) { return 1 } i = i + 1 }
28 return 0
29}
30
31func vl_dup(s: *u8) -> *u8 {
32 let n: i64 = vl_slen(s)
33 let d: *u8 = sys_mmap(n + 2)
34 var i: i64 = 0
35 while i <= n { d[i] = s[i]; i = i + 1 }
36 return d
37}
38
39func vl_atoi(s: *u8) -> i64 {
40 var v: i64 = 0
41 var i: i64 = 0
42 while s[i] != (0 as u8) { let d: i64 = (s[i] as i64) - 48; if d >= 0 { if d <= 9 { v = v * 10 + d } } i = i + 1 }
43 return v
44}
45
46func vl_isws(c: i64) -> i64 { if c == 32 { return 1 } if c == 13 { return 1 } if c == 9 { return 1 } return 0 }
47
48func vl_tok(b: *u8, off: i64, lend: i64, dst: *u8, cap: i64) -> i64 {
49 var p: i64 = off
50 var go: i64 = 1
51 while go == 1 { if p >= lend { go = 0 } else { if vl_isws(b[p] as i64) == 1 { p = p + 1 } else { go = 0 } } }
52 var t: i64 = 0
53 go = 1
54 while go == 1 {
55 if p >= lend { go = 0 } else {
56 if vl_isws(b[p] as i64) == 1 { go = 0 } else { if t < cap - 1 { dst[t] = b[p]; t = t + 1 } p = p + 1 }
57 }
58 }
59 dst[t] = 0 as u8
60 return p
61}
62
63// rest of line [p,e) trimmed of leading whitespace -> dst (multi-word content)
64func vl_restline(b: *u8, p: i64, e: i64, dst: *u8, cap: i64) -> i64 {
65 var q: i64 = p
66 var go: i64 = 1
67 while go == 1 { if q >= e { go = 0 } else { if vl_isws(b[q] as i64) == 1 { q = q + 1 } else { go = 0 } } }
68 var t: i64 = 0
69 while q < e { if t < cap - 1 { dst[t] = b[q]; t = t + 1 } q = q + 1 }
70 dst[t] = 0 as u8
71 return t
72}
73
74func vl_cat(dst: *u8, off: i64, s: *u8) -> i64 {
75 var i: i64 = 0
76 while s[i] != (0 as u8) { dst[off + i] = s[i]; i = i + 1 }
77 return off + i
78}
79
80func vl_catn(dst: *u8, off: i64, v: i64) -> i64 {
81 var o: i64 = off
82 var m: i64 = v
83 if m < 0 { dst[o] = 45 as u8; o = o + 1; m = 0 - m }
84 let t: *u8 = sys_mmap(28)
85 var k: i64 = 0
86 if m == 0 { t[0] = 48 as u8; k = 1 }
87 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
88 var i: i64 = 0
89 while i < k { dst[o + i] = t[k - 1 - i]; i = i + 1 }
90 return o + k
91}
92
93func vl_kmemeq(b: *u8, off: i64, n: i64, s: *u8) -> i64 {
94 if vl_slen(s) != n { return 0 }
95 var i: i64 = 0
96 while i < n { if b[off + i] != s[i] { return 0 } i = i + 1 }
97 return 1
98}
99
100func vl_iskind(b: *u8, koff: i64, kl: i64, pfx: *u8) -> i64 {
101 let pl: i64 = vl_slen(pfx)
102 if kl <= pl { return 0 }
103 return vl_kmemeq(b, koff, pl, pfx)
104}
105
106func vl_field(rec: *u8, rl: i64, want: *u8, out: *u8, cap: i64) -> i64 {
107 if rl < 8 { return 0 }
108 let nf: i64 = ss_r32(rec, 4)
109 var off: i64 = 8
110 var fi: i64 = 0
111 while fi < nf {
112 if off + 8 > rl { return 0 }
113 let kl: i64 = ss_r32(rec, off)
114 let koff: i64 = off + 4
115 let vl: i64 = ss_r32(rec, koff + kl)
116 let voff: i64 = koff + kl + 4
117 if vl_kmemeq(rec, koff, kl, want) == 1 {
118 var t: i64 = 0
119 while t < vl { if t < cap - 1 { out[t] = rec[voff + t] } t = t + 1 }
120 if t > cap - 1 { t = cap - 1 }
121 out[t] = 0 as u8
122 return 1
123 }
124 off = voff + vl
125 fi = fi + 1
126 }
127 return 0
128}
129
130func vl_datedays(s: *u8) -> i64 {
131 let nums: *i64 = sys_mmap(8 * 4) as *i64
132 var nn: i64 = 0
133 var cur: i64 = 0
134 var indig: i64 = 0
135 var i: i64 = 0
136 var go: i64 = 1
137 while go == 1 {
138 let c: i64 = s[i] as i64
139 var isd: i64 = 0
140 if c >= 48 { if c <= 57 { isd = 1 } }
141 if isd == 1 { cur = cur * 10 + (c - 48); indig = 1 }
142 if isd == 0 { if indig == 1 { if nn < 4 { nums[nn] = cur; nn = nn + 1 } cur = 0; indig = 0 } }
143 if c == 0 { go = 0 }
144 i = i + 1
145 }
146 if nn != 3 { return 0 - 1 }
147 var y: i64 = nums[0]
148 let m: i64 = nums[1]
149 let d: i64 = nums[2]
150 if y < K_MAGIC_1970 { return 0 - 1 }
151 if m < 1 { return 0 - 1 }
152 if m > 12 { return 0 - 1 }
153 if d < 1 { return 0 - 1 }
154 if d > 31 { return 0 - 1 }
155 if m <= 2 { y = y - 1 }
156 let era: i64 = y / 400
157 let yoe: i64 = y - era * 400
158 var mp: i64 = m - 3
159 if m <= 2 { mp = m + 9 }
160 let doy: i64 = (153 * mp + 2) / 5 + d - 1
161 let doe: i64 = yoe * 365 + yoe / 4 - yoe / 100 + doy
162 return era * K_MAGIC_146097 + doe - K_MAGIC_719468
163}
164
165func vl_put(keys: *i64, vals: *i64, nf: i64, kp: *u8, st: *i64) -> i64 {
166 let enc: *u8 = sys_mmap(K_MAGIC_4096)
167 let el: i64 = canon_encode(keys, vals, nf, enc)
168 let cid: *u8 = sys_mmap(96)
169 cid_of(enc, el, cid)
170 let kbuf: *u8 = sys_mmap(128)
171 var ko: i64 = 0
172 ko = vl_cat(kbuf, ko, kp); ko = vl_cat(kbuf, ko, cid); kbuf[ko] = 0 as u8
173 let seen: *i64 = st[1] as *i64
174 var fresh: i64 = 1
175 var si: i64 = 0
176 while si < st[2] { if vl_eq(seen[si] as *u8, kbuf) == 1 { fresh = 0; st[4] = st[4] + 1; si = st[2] } si = si + 1 }
177 if fresh == 1 { if st[2] < K_MAGIC_4096 { seen[st[2]] = vl_dup(kbuf) as i64; st[2] = st[2] + 1 } }
178 if fresh == 1 {
179 let pp: *i64 = sys_mmap(16) as *i64
180 let ll: *i64 = sys_mmap(16) as *i64
181 if ss_get_idx(st[6] as *u8, kbuf, pp, ll) == 1 { fresh = 0; st[5] = st[5] + 1 }
182 }
183 if fresh == 1 { if ss_add(st[0] as *i64, 1, kbuf, enc, el) != 0 { return 0 - 1 } st[3] = st[3] + 1 }
184 return 0
185}
186
187// ---------------- LOAD ----------------
188func vl_cmd_load(argc: i64, argv: *i64) -> i64 {
189 if argc < 4 { vl_p("VIZSLA-LOG load needs <logfile> <prefix> -- fail loud\n" as *u8); return 1 }
190 let lfile: *u8 = argv[2] as *u8
191 let prefix: *u8 = argv[3] as *u8
192 var segid: i64 = 0
193 if argc > 4 { segid = vl_atoi(argv[4] as *u8) }
194 if segid == 0 { segid = sys_now_us() }
195 let szp: *i64 = sys_mmap(16) as *i64
196 let b: *u8 = ss_readall(lfile, szp)
197 let sz: i64 = szp[0]
198 if sz <= 0 { vl_p("VIZSLA-LOG logfile MISSING/EMPTY -- fail loud\n" as *u8); return 1 }
199
200 let keys: *i64 = sys_mmap(8 * 8) as *i64
201 let vals: *i64 = sys_mmap(8 * 8) as *i64
202 keys[0] = "kind" as *u8 as i64; keys[1] = "date" as *u8 as i64; keys[2] = "contact" as *u8 as i64
203 keys[3] = "type" as *u8 as i64; keys[4] = "note" as *u8 as i64
204 vals[0] = "int" as *u8 as i64
205
206 let st: *i64 = sys_mmap(8 * 8) as *i64
207 st[0] = ss_begin() as i64; st[1] = sys_mmap(8 * K_MAGIC_4096); st[2] = 0; st[3] = 0; st[4] = 0; st[5] = 0; st[6] = prefix as i64
208
209 let t0: *u8 = sys_mmap(128)
210 let f1: *u8 = sys_mmap(128)
211 let f2: *u8 = sys_mmap(128)
212 let f3: *u8 = sys_mmap(128)
213 let f4: *u8 = sys_mmap(K_MAGIC_1024)
214 var scanned: i64 = 0
215 var i: i64 = 0
216 while i < sz {
217 var e: i64 = i
218 var go: i64 = 1
219 while go == 1 { if e >= sz { go = 0 } else { if b[e] == (10 as u8) { go = 0 } else { e = e + 1 } } }
220 var p: i64 = vl_tok(b, i, e, t0, 128)
221 if t0[0] == (35 as u8) { t0[0] = 0 as u8 }
222 if vl_eq(t0, "INT" as *u8) == 1 {
223 p = vl_tok(b, p, e, f1, 128); p = vl_tok(b, p, e, f2, 128); p = vl_tok(b, p, e, f3, 128)
224 vl_restline(b, p, e, f4, K_MAGIC_1024)
225 if vl_datedays(f1) < 0 { vl_p("VIZSLA-LOG INT bad date -- fail loud\n" as *u8); return 1 }
226 if f2[0] == (0 as u8) { vl_p("VIZSLA-LOG INT missing contact -- fail loud\n" as *u8); return 1 }
227 if f3[0] == (0 as u8) { vl_p("VIZSLA-LOG INT missing type -- fail loud\n" as *u8); return 1 }
228 if f4[0] == (0 as u8) { vl_p("VIZSLA-LOG INT missing note -- fail loud\n" as *u8); return 1 }
229 vals[1] = f1 as i64; vals[2] = f2 as i64; vals[3] = f3 as i64; vals[4] = f4 as i64
230 scanned = scanned + 1
231 if vl_put(keys, vals, 5, "int:" as *u8, st) != 0 { vl_p("VIZSLA-LOG writer full -- fail loud\n" as *u8); return 1 }
232 }
233 i = e + 1
234 }
235 var committed: i64 = 0
236 if st[3] > 0 { if ss_commit(prefix, st[0] as *i64, segid) != 0 { vl_p("VIZSLA-LOG commit FAILED -- fail loud\n" as *u8); return 1 } committed = 1 }
237
238 let rep: *u8 = sys_mmap(K_MAGIC_4096)
239 var o: i64 = 0
240 o = vl_cat(rep, o, "VIZSLA-LOG-LOAD scanned=" as *u8); o = vl_catn(rep, o, scanned)
241 o = vl_cat(rep, o, " new=" as *u8); o = vl_catn(rep, o, st[3])
242 o = vl_cat(rep, o, " dup_infile=" as *u8); o = vl_catn(rep, o, st[4])
243 o = vl_cat(rep, o, " dup_instore=" as *u8); o = vl_catn(rep, o, st[5])
244 o = vl_cat(rep, o, " segment=" as *u8)
245 if committed == 1 { o = vl_cat(rep, o, "seg-" as *u8); o = vl_catn(rep, o, segid) } else { o = vl_cat(rep, o, "none" as *u8) }
246 o = vl_cat(rep, o, "\n" as *u8)
247 sys_write(1, rep, o)
248 return 0
249}
250
251// ---------------- TIMELINE ----------------
252func vl_cmd_timeline(argc: i64, argv: *i64) -> i64 {
253 if argc < 4 { vl_p("VIZSLA-LOG timeline needs <prefix> <contact> -- fail loud\n" as *u8); return 1 }
254 let prefix: *u8 = argv[2] as *u8
255 let contact: *u8 = argv[3] as *u8
256
257 let i_dstr: *i64 = sys_mmap(8 * K_MAGIC_2048) as *i64
258 let i_dnum: *i64 = sys_mmap(8 * K_MAGIC_2048) as *i64
259 let i_type: *i64 = sys_mmap(8 * K_MAGIC_2048) as *i64
260 let i_note: *i64 = sys_mmap(8 * K_MAGIC_2048) as *i64
261 var n: i64 = 0
262
263 let segs: *i64 = sys_mmap(8 * 260) as *i64
264 let nseg: i64 = ss_manifest(prefix, segs)
265 let fct: *u8 = sys_mmap(128)
266 let fdt: *u8 = sys_mmap(128)
267 let fty: *u8 = sys_mmap(128)
268 let fnt: *u8 = sys_mmap(K_MAGIC_1024)
269 var s: i64 = 0
270 while s < nseg {
271 let path: *u8 = sys_mmap(512)
272 var po: i64 = 0
273 po = vl_cat(path, po, prefix); po = vl_cat(path, po, segs[s] as *u8); po = vl_cat(path, po, ".docs" as *u8)
274 path[po] = 0 as u8
275 let szp: *i64 = sys_mmap(16) as *i64
276 let b: *u8 = ss_readall(path, szp)
277 let sz: i64 = szp[0]
278 var j: i64 = 0
279 while j + 9 <= sz {
280 let kind: i64 = b[j]
281 let kl: i64 = ss_r32(b, j + 1)
282 let koff: i64 = j + 5
283 let vl: i64 = ss_r32(b, koff + kl)
284 let voff: i64 = koff + kl + 4
285 var take: i64 = 0
286 if kind == 1 { take = vl_iskind(b, koff, kl, "int:" as *u8) }
287 if take == 1 {
288 let rec: *u8 = (b as i64 + voff) as *u8
289 if vl_field(rec, vl, "contact" as *u8, fct, 128) == 1 {
290 if vl_eq(fct, contact) == 1 {
291 vl_field(rec, vl, "date" as *u8, fdt, 128)
292 vl_field(rec, vl, "type" as *u8, fty, 128)
293 vl_field(rec, vl, "note" as *u8, fnt, K_MAGIC_1024)
294 if n < K_MAGIC_2048 { i_dstr[n] = vl_dup(fdt) as i64; i_dnum[n] = vl_datedays(fdt); i_type[n] = vl_dup(fty) as i64; i_note[n] = vl_dup(fnt) as i64; n = n + 1 }
295 }
296 }
297 }
298 j = voff + vl
299 }
300 s = s + 1
301 }
302
303 // selection sort by date descending (newest first)
304 var a: i64 = 0
305 while a < n {
306 var mx: i64 = a
307 var c: i64 = a + 1
308 while c < n { if i_dnum[c] > i_dnum[mx] { mx = c } c = c + 1 }
309 if mx != a {
310 let t1: i64 = i_dstr[a]; i_dstr[a] = i_dstr[mx]; i_dstr[mx] = t1
311 let t2: i64 = i_dnum[a]; i_dnum[a] = i_dnum[mx]; i_dnum[mx] = t2
312 let t3: i64 = i_type[a]; i_type[a] = i_type[mx]; i_type[mx] = t3
313 let t4: i64 = i_note[a]; i_note[a] = i_note[mx]; i_note[mx] = t4
314 }
315 a = a + 1
316 }
317
318 let rep: *u8 = sys_mmap(K_MAGIC_131072)
319 var o: i64 = 0
320 var ii: i64 = 0
321 while ii < n {
322 o = vl_cat(rep, o, "VIZSLA-LOG date=" as *u8); o = vl_cat(rep, o, i_dstr[ii] as *u8)
323 o = vl_cat(rep, o, " contact=" as *u8); o = vl_cat(rep, o, contact)
324 o = vl_cat(rep, o, " type=" as *u8); o = vl_cat(rep, o, i_type[ii] as *u8)
325 o = vl_cat(rep, o, " note=" as *u8); o = vl_cat(rep, o, i_note[ii] as *u8)
326 o = vl_cat(rep, o, "\n" as *u8)
327 ii = ii + 1
328 }
329 o = vl_cat(rep, o, "VIZSLA-LOG-TIMELINE contact=" as *u8); o = vl_cat(rep, o, contact)
330 o = vl_cat(rep, o, " interactions=" as *u8); o = vl_catn(rep, o, n)
331 if n > 0 {
332 o = vl_cat(rep, o, " first=" as *u8); o = vl_cat(rep, o, i_dstr[n - 1] as *u8)
333 o = vl_cat(rep, o, " last=" as *u8); o = vl_cat(rep, o, i_dstr[0] as *u8)
334 }
335 o = vl_cat(rep, o, "\n" as *u8)
336 sys_write(1, rep, o)
337 return 0
338}
339
340func main(argc: i64, argv: *i64) -> i64 {
341 if argc < 2 { vl_p("VIZSLA-LOG usage: load|timeline -- fail loud\n" as *u8); return 1 }
342 let cmd: *u8 = argv[1] as *u8
343 if vl_eq(cmd, "load" as *u8) == 1 { return vl_cmd_load(argc, argv) }
344 if vl_eq(cmd, "timeline" as *u8) == 1 { return vl_cmd_timeline(argc, argv) }
345 vl_p("VIZSLA-LOG unknown command (load|timeline) -- fail loud\n" as *u8)
346 return 1
347}