code wiki / _hdl_build / nx_vizsla_profile.nx

nx_vizsla_profile.nx source

↩ module page · 455 lines · 15859 B

1// nx_vizsla_profile.nx -- NISHI VIZSLA V0: the archetype gap profiler. 2// The operator's three-archetype theory (architect/author/editor; a household 3// usually covers two; the missing one is THE structural gap) as a measured, 4// re-runnable instrument. The MODEL IS DATA: archetypes, trait weights, 5// domains and fill capabilities all come from knowledge/vizsla/archetype_matrix.txt 6// (the engine reads N archetypes from the file -- "three" is matrix content, 7// never a constant here). Household answers come from knowledge/vizsla/household.txt. 8// Output rows (stdout deterministic; epoch header -> log only): 9// VIZSLA-MEMBER name=<m> primary=<arch> <arch>=<permil>... 10// VIZSLA-COVERAGE archetypes=<n> covered=<k> gaps=<g> threshold=<thr> 11// VIZSLA-GAP archetype=<a> nearest=<member> nearest_permil=<p> 12// VIZSLA-FILL domain=<d> gap=<a> capability=<cap> partner=<member> 13// VIZSLA-VERDICT coverage=FULL | coverage=GAPPED gaps=<g> 14// argv overrides (gate fixture isolation, site-gate pattern): 15// argv[1]=matrix path argv[2]=household path argv[3]=log path 16// Loud-fail law: missing/empty inputs, unknown archetype/member references = exit 1. 17// spec: knowledge/specs/2026-06-10-nishi-vizsla-ladder.md license_tier: ORIGINAL 18import "nx_syscalls.nx" 19const K_MAGIC_65536: i64 = 65536 20 21func vz_slen(s: *u8) -> i64 { 22 var n: i64 = 0 23 while s[n] != (0 as u8) { n = n + 1 } 24 return n 25} 26 27func vz_p(s: *u8) -> i64 { 28 sys_write(1, s, vz_slen(s)) 29 return 0 30} 31 32func vz_eq(a: *u8, b: *u8) -> i64 { 33 var i: i64 = 0 34 var go: i64 = 1 35 while go == 1 { 36 if a[i] != b[i] { return 0 } 37 if a[i] == (0 as u8) { return 1 } 38 i = i + 1 39 } 40 return 0 41} 42 43func vz_dup(s: *u8) -> *u8 { 44 let n: i64 = vz_slen(s) 45 let d: *u8 = sys_mmap(n + 2) 46 var i: i64 = 0 47 while i <= n { d[i] = s[i]; i = i + 1 } 48 return d 49} 50 51func vz_atoi(s: *u8) -> i64 { 52 var v: i64 = 0 53 var i: i64 = 0 54 while s[i] != (0 as u8) { 55 let d: i64 = (s[i] as i64) - 48 56 if d >= 0 { if d <= 9 { v = v * 10 + d } } 57 i = i + 1 58 } 59 return v 60} 61 62func vz_isws(c: i64) -> i64 { 63 if c == 32 { return 1 } 64 if c == 13 { return 1 } 65 if c == 9 { return 1 } 66 return 0 67} 68 69// next whitespace-delimited token from b[off..lend) -> dst (NUL-terminated); 70// returns offset after the token; dst[0]=0 means no token left on the line 71func vz_tok(b: *u8, off: i64, lend: i64, dst: *u8, cap: i64) -> i64 { 72 var p: i64 = off 73 var go: i64 = 1 74 while go == 1 { 75 if p >= lend { go = 0 } else { 76 if vz_isws(b[p] as i64) == 1 { p = p + 1 } else { go = 0 } 77 } 78 } 79 var t: i64 = 0 80 go = 1 81 while go == 1 { 82 if p >= lend { go = 0 } else { 83 if vz_isws(b[p] as i64) == 1 { go = 0 } else { 84 if t < cap - 1 { dst[t] = b[p]; t = t + 1 } 85 p = p + 1 86 } 87 } 88 } 89 dst[t] = 0 as u8 90 return p 91} 92 93func vz_readall(path: *u8, szout: *i64) -> *u8 { 94 let fd: i64 = sys_openat_rd(path) 95 if fd < 0 { szout[0] = 0 - 1; return 0 as *u8 } 96 let sz: i64 = sys_lseek(fd, 0, 2) 97 sys_lseek(fd, 0, 0) 98 let buf: *u8 = sys_mmap(sz + 64) 99 var got: i64 = 0 100 var n: i64 = 1 101 while n > 0 { 102 n = sys_read(fd, (buf as i64 + got) as *u8, K_MAGIC_65536) 103 if n > 0 { got = got + n } 104 } 105 sys_close(fd) 106 szout[0] = got 107 return buf 108} 109 110func vz_find(list: *i64, n: i64, s: *u8) -> i64 { 111 var i: i64 = 0 112 while i < n { 113 if vz_eq(list[i] as *u8, s) == 1 { return i } 114 i = i + 1 115 } 116 return 0 - 1 117} 118 119func vz_cat(dst: *u8, off: i64, s: *u8) -> i64 { 120 var i: i64 = 0 121 while s[i] != (0 as u8) { dst[off + i] = s[i]; i = i + 1 } 122 return off + i 123} 124 125func vz_catn(dst: *u8, off: i64, v: i64) -> i64 { 126 var o: i64 = off 127 var m: i64 = v 128 if m < 0 { dst[o] = 45 as u8; o = o + 1; m = 0 - m } 129 let t: *u8 = sys_mmap(28) 130 var k: i64 = 0 131 if m == 0 { t[0] = 48 as u8; k = 1 } 132 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 133 var i: i64 = 0 134 while i < k { dst[o + i] = t[k - 1 - i]; i = i + 1 } 135 return o + k 136} 137 138// answered value (0/1) for member mi on trait key (last write wins, scan) 139func vz_ans(a_mem: *i64, a_key: *i64, a_val: *i64, nans: i64, mi: i64, key: *u8) -> i64 { 140 var v: i64 = 0 141 var qi: i64 = 0 142 while qi < nans { 143 if a_mem[qi] == mi { 144 if vz_eq(a_key[qi] as *u8, key) == 1 { v = a_val[qi] } 145 } 146 qi = qi + 1 147 } 148 return v 149} 150 151func main(argc: i64, argv: *i64) -> i64 { 152 var mpath: *u8 = "knowledge/vizsla/archetype_matrix.txt" as *u8 153 var hpath: *u8 = "knowledge/vizsla/household.txt" as *u8 154 var lpath: *u8 = "knowledge/status/vizsla_profile.log" as *u8 155 if argc > 1 { mpath = argv[1] as *u8 } 156 if argc > 2 { hpath = argv[2] as *u8 } 157 if argc > 3 { lpath = argv[3] as *u8 } 158 159 let szp: *i64 = sys_mmap(16) as *i64 160 let mb: *u8 = vz_readall(mpath, szp) 161 let msz: i64 = szp[0] 162 if msz <= 0 { vz_p("VIZSLA-PROFILE matrix MISSING/EMPTY -- fail loud\n" as *u8); return 1 } 163 let hb: *u8 = vz_readall(hpath, szp) 164 let hsz: i64 = szp[0] 165 if hsz <= 0 { vz_p("VIZSLA-PROFILE household MISSING/EMPTY -- fail loud\n" as *u8); return 1 } 166 167 // model tables (all FROM DATA; capacities are buffer sizes, not model shape) 168 let archs: *i64 = sys_mmap(8 * 8) as *i64 169 let totw: *i64 = sys_mmap(8 * 8) as *i64 170 var narch: i64 = 0 171 let t_arch: *i64 = sys_mmap(8 * 64) as *i64 172 let t_w: *i64 = sys_mmap(8 * 64) as *i64 173 let t_key: *i64 = sys_mmap(8 * 64) as *i64 174 var ntrait: i64 = 0 175 let doms: *i64 = sys_mmap(8 * 16) as *i64 176 var ndom: i64 = 0 177 let n_dom: *i64 = sys_mmap(8 * 96) as *i64 178 let n_arch: *i64 = sys_mmap(8 * 96) as *i64 179 let n_cap: *i64 = sys_mmap(8 * 96) as *i64 180 var nneed: i64 = 0 181 var thr: i64 = 500 182 183 let t0: *u8 = sys_mmap(128) 184 let t1: *u8 = sys_mmap(128) 185 let t2: *u8 = sys_mmap(128) 186 let t3: *u8 = sys_mmap(128) 187 188 // ---- parse matrix ---- 189 var i: i64 = 0 190 while i < msz { 191 var e: i64 = i 192 var go: i64 = 1 193 while go == 1 { 194 if e >= msz { go = 0 } else { 195 if mb[e] == (10 as u8) { go = 0 } else { e = e + 1 } 196 } 197 } 198 var p: i64 = vz_tok(mb, i, e, t0, 128) 199 if t0[0] == (35 as u8) { t0[0] = 0 as u8 } 200 if t0[0] != (0 as u8) { 201 if vz_eq(t0, "CONF" as *u8) == 1 { 202 p = vz_tok(mb, p, e, t1, 128) 203 p = vz_tok(mb, p, e, t2, 128) 204 if vz_eq(t1, "threshold_permil" as *u8) == 1 { thr = vz_atoi(t2) } 205 } 206 if vz_eq(t0, "ARCH" as *u8) == 1 { 207 p = vz_tok(mb, p, e, t1, 128) 208 if narch < 8 { archs[narch] = vz_dup(t1) as i64; totw[narch] = 0; narch = narch + 1 } 209 } 210 if vz_eq(t0, "TRAIT" as *u8) == 1 { 211 p = vz_tok(mb, p, e, t1, 128) 212 p = vz_tok(mb, p, e, t2, 128) 213 p = vz_tok(mb, p, e, t3, 128) 214 let ai: i64 = vz_find(archs, narch, t1) 215 if ai < 0 { vz_p("VIZSLA-PROFILE TRAIT references unknown archetype -- fail loud\n" as *u8); return 1 } 216 if ntrait < 64 { 217 t_arch[ntrait] = ai 218 t_w[ntrait] = vz_atoi(t2) 219 t_key[ntrait] = vz_dup(t3) as i64 220 totw[ai] = totw[ai] + t_w[ntrait] 221 ntrait = ntrait + 1 222 } 223 } 224 if vz_eq(t0, "DOMAIN" as *u8) == 1 { 225 p = vz_tok(mb, p, e, t1, 128) 226 if ndom < 16 { doms[ndom] = vz_dup(t1) as i64; ndom = ndom + 1 } 227 } 228 if vz_eq(t0, "NEED" as *u8) == 1 { 229 p = vz_tok(mb, p, e, t1, 128) 230 p = vz_tok(mb, p, e, t2, 128) 231 p = vz_tok(mb, p, e, t3, 128) 232 let di: i64 = vz_find(doms, ndom, t1) 233 if di < 0 { vz_p("VIZSLA-PROFILE NEED references unknown domain -- fail loud\n" as *u8); return 1 } 234 let na: i64 = vz_find(archs, narch, t2) 235 if na < 0 { vz_p("VIZSLA-PROFILE NEED references unknown archetype -- fail loud\n" as *u8); return 1 } 236 if nneed < 96 { 237 n_dom[nneed] = di 238 n_arch[nneed] = na 239 n_cap[nneed] = vz_dup(t3) as i64 240 nneed = nneed + 1 241 } 242 } 243 } 244 i = e + 1 245 } 246 247 // ---- parse household ---- 248 let mems: *i64 = sys_mmap(8 * 16) as *i64 249 var nmem: i64 = 0 250 let a_mem: *i64 = sys_mmap(8 * 512) as *i64 251 let a_key: *i64 = sys_mmap(8 * 512) as *i64 252 let a_val: *i64 = sys_mmap(8 * 512) as *i64 253 var nans: i64 = 0 254 255 i = 0 256 while i < hsz { 257 var e2: i64 = i 258 var go2: i64 = 1 259 while go2 == 1 { 260 if e2 >= hsz { go2 = 0 } else { 261 if hb[e2] == (10 as u8) { go2 = 0 } else { e2 = e2 + 1 } 262 } 263 } 264 var p2: i64 = vz_tok(hb, i, e2, t0, 128) 265 if t0[0] == (35 as u8) { t0[0] = 0 as u8 } 266 if t0[0] != (0 as u8) { 267 if vz_eq(t0, "MEMBER" as *u8) == 1 { 268 p2 = vz_tok(hb, p2, e2, t1, 128) 269 if nmem < 16 { mems[nmem] = vz_dup(t1) as i64; nmem = nmem + 1 } 270 } 271 if vz_eq(t0, "ANS" as *u8) == 1 { 272 p2 = vz_tok(hb, p2, e2, t1, 128) 273 p2 = vz_tok(hb, p2, e2, t2, 128) 274 p2 = vz_tok(hb, p2, e2, t3, 128) 275 let mi0: i64 = vz_find(mems, nmem, t1) 276 if mi0 < 0 { vz_p("VIZSLA-PROFILE ANS references unknown member -- fail loud\n" as *u8); return 1 } 277 if nans < 512 { 278 a_mem[nans] = mi0 279 a_key[nans] = vz_dup(t2) as i64 280 a_val[nans] = vz_atoi(t3) 281 nans = nans + 1 282 } 283 } 284 } 285 i = e2 + 1 286 } 287 288 if narch < 1 { vz_p("VIZSLA-PROFILE no archetypes in matrix -- fail loud\n" as *u8); return 1 } 289 if ntrait < 1 { vz_p("VIZSLA-PROFILE no traits in matrix -- fail loud\n" as *u8); return 1 } 290 if nmem < 1 { vz_p("VIZSLA-PROFILE no members in household -- fail loud\n" as *u8); return 1 } 291 292 // ---- score: member x archetype permil ---- 293 let permil: *i64 = sys_mmap(8 * 16 * 8) as *i64 294 var mi: i64 = 0 295 while mi < nmem { 296 var ai2: i64 = 0 297 while ai2 < narch { 298 var sum: i64 = 0 299 var ti: i64 = 0 300 while ti < ntrait { 301 if t_arch[ti] == ai2 { 302 if vz_ans(a_mem, a_key, a_val, nans, mi, t_key[ti] as *u8) == 1 { sum = sum + t_w[ti] } 303 } 304 ti = ti + 1 305 } 306 var pm: i64 = 0 307 if totw[ai2] > 0 { pm = (sum * 1000) / totw[ai2] } 308 permil[mi * 8 + ai2] = pm 309 ai2 = ai2 + 1 310 } 311 mi = mi + 1 312 } 313 314 // ---- primary per member (argmax, file order breaks ties; none if all 0) ---- 315 let prim: *i64 = sys_mmap(8 * 16) as *i64 316 mi = 0 317 while mi < nmem { 318 var best: i64 = 0 319 var bi: i64 = 0 - 1 320 var ai3: i64 = 0 321 while ai3 < narch { 322 if permil[mi * 8 + ai3] > best { best = permil[mi * 8 + ai3]; bi = ai3 } 323 ai3 = ai3 + 1 324 } 325 prim[mi] = bi 326 mi = mi + 1 327 } 328 329 // ---- coverage: someone's primary OR anyone >= threshold ---- 330 let cov: *i64 = sys_mmap(8 * 8) as *i64 331 var ai4: i64 = 0 332 while ai4 < narch { cov[ai4] = 0; ai4 = ai4 + 1 } 333 mi = 0 334 while mi < nmem { 335 if prim[mi] >= 0 { cov[prim[mi]] = 1 } 336 var ai5: i64 = 0 337 while ai5 < narch { 338 if permil[mi * 8 + ai5] >= thr { cov[ai5] = 1 } 339 ai5 = ai5 + 1 340 } 341 mi = mi + 1 342 } 343 var covered: i64 = 0 344 var ai6: i64 = 0 345 while ai6 < narch { 346 if cov[ai6] == 1 { covered = covered + 1 } 347 ai6 = ai6 + 1 348 } 349 let gaps: i64 = narch - covered 350 351 // ---- compose the report (stdout-deterministic; epoch goes to log only) ---- 352 let rep: *u8 = sys_mmap(K_MAGIC_65536) 353 var o: i64 = 0 354 mi = 0 355 while mi < nmem { 356 o = vz_cat(rep, o, "VIZSLA-MEMBER name=" as *u8) 357 o = vz_cat(rep, o, mems[mi] as *u8) 358 o = vz_cat(rep, o, " primary=" as *u8) 359 if prim[mi] >= 0 { o = vz_cat(rep, o, archs[prim[mi]] as *u8) } else { o = vz_cat(rep, o, "none" as *u8) } 360 var ai7: i64 = 0 361 while ai7 < narch { 362 o = vz_cat(rep, o, " " as *u8) 363 o = vz_cat(rep, o, archs[ai7] as *u8) 364 o = vz_cat(rep, o, "=" as *u8) 365 o = vz_catn(rep, o, permil[mi * 8 + ai7]) 366 ai7 = ai7 + 1 367 } 368 o = vz_cat(rep, o, "\n" as *u8) 369 mi = mi + 1 370 } 371 o = vz_cat(rep, o, "VIZSLA-COVERAGE archetypes=" as *u8) 372 o = vz_catn(rep, o, narch) 373 o = vz_cat(rep, o, " covered=" as *u8) 374 o = vz_catn(rep, o, covered) 375 o = vz_cat(rep, o, " gaps=" as *u8) 376 o = vz_catn(rep, o, gaps) 377 o = vz_cat(rep, o, " threshold=" as *u8) 378 o = vz_catn(rep, o, thr) 379 o = vz_cat(rep, o, "\n" as *u8) 380 381 // gap rows: nearest member = highest permil in the gap archetype (partnership) 382 var ag: i64 = 0 383 while ag < narch { 384 if cov[ag] == 0 { 385 var nbest: i64 = 0 - 1 386 var nbp: i64 = 0 - 1 387 var mj: i64 = 0 388 while mj < nmem { 389 if permil[mj * 8 + ag] > nbp { nbp = permil[mj * 8 + ag]; nbest = mj } 390 mj = mj + 1 391 } 392 if nbest < 0 { nbest = 0; nbp = 0 } 393 o = vz_cat(rep, o, "VIZSLA-GAP archetype=" as *u8) 394 o = vz_cat(rep, o, archs[ag] as *u8) 395 o = vz_cat(rep, o, " nearest=" as *u8) 396 o = vz_cat(rep, o, mems[nbest] as *u8) 397 o = vz_cat(rep, o, " nearest_permil=" as *u8) 398 o = vz_catn(rep, o, nbp) 399 o = vz_cat(rep, o, "\n" as *u8) 400 } 401 ag = ag + 1 402 } 403 404 // fill plan: every NEED row whose archetype is a gap (needs-file order) 405 var ni: i64 = 0 406 while ni < nneed { 407 if cov[n_arch[ni]] == 0 { 408 var pbest: i64 = 0 409 var pbp: i64 = 0 - 1 410 var mk: i64 = 0 411 while mk < nmem { 412 if permil[mk * 8 + n_arch[ni]] > pbp { pbp = permil[mk * 8 + n_arch[ni]]; pbest = mk } 413 mk = mk + 1 414 } 415 o = vz_cat(rep, o, "VIZSLA-FILL domain=" as *u8) 416 o = vz_cat(rep, o, doms[n_dom[ni]] as *u8) 417 o = vz_cat(rep, o, " gap=" as *u8) 418 o = vz_cat(rep, o, archs[n_arch[ni]] as *u8) 419 o = vz_cat(rep, o, " capability=" as *u8) 420 o = vz_cat(rep, o, n_cap[ni] as *u8) 421 o = vz_cat(rep, o, " partner=" as *u8) 422 o = vz_cat(rep, o, mems[pbest] as *u8) 423 o = vz_cat(rep, o, "\n" as *u8) 424 } 425 ni = ni + 1 426 } 427 428 if gaps == 0 { 429 o = vz_cat(rep, o, "VIZSLA-VERDICT coverage=FULL\n" as *u8) 430 } else { 431 o = vz_cat(rep, o, "VIZSLA-VERDICT coverage=GAPPED gaps=" as *u8) 432 o = vz_catn(rep, o, gaps) 433 o = vz_cat(rep, o, "\n" as *u8) 434 } 435 436 sys_write(1, rep, o) 437 438 // log: epoch header + the same report (append-only, additive law) 439 let logfd: i64 = sys_openat_append(lpath, 0x1a4) 440 if logfd > 0 { 441 let hdr: *u8 = sys_mmap(512) 442 var ho: i64 = 0 443 ho = vz_cat(hdr, ho, "VIZSLA-PROFILE epoch=" as *u8) 444 ho = vz_catn(hdr, ho, sys_now_realtime_sec()) 445 ho = vz_cat(hdr, ho, " matrix=" as *u8) 446 ho = vz_cat(hdr, ho, mpath) 447 ho = vz_cat(hdr, ho, " household=" as *u8) 448 ho = vz_cat(hdr, ho, hpath) 449 ho = vz_cat(hdr, ho, "\n" as *u8) 450 sys_write(logfd, hdr, ho) 451 sys_write(logfd, rep, o) 452 sys_close(logfd) 453 } 454 return 0 455}