nx_kkslider_stats.nx source
↩ module page · 246 lines · 11820 B
1// nx_kkslider_stats.nx -- SLIDER-SEMANTICS MEASUREMENT for the card lane (2026-08-19, the
2// re_card_to_being middle: which shapeValueBody index MEANS what). The bones cheatsheet in the KK
3// pack grounds the SKELETON side; the slider INDEX order is not documented in any artifact we bank,
4// so it is MEASURED instead of recalled: decode shapeValueBody from every banked card whose BepisDB
5// metadata carries community tags (tall, petite, busty, slim...), and report the per-index value
6// distribution of tagged vs untagged cards. An index whose tagged-mean separates from its rest-mean
7// across a growing corpus is that tag's slider, with the evidence count printed beside it.
8// NUMBERS, NEVER VERDICTS (an uncalibrated classifier must report numbers): this organ prints
9// n/mean/delta per (tag, index) and the caller judges with the counts in view.
10// Corpus shape = the bepis mirror lane: <dir>/<name>.png + <dir>/<name>.meta.json pairs.
11// HONESTY COUNTERS: pairs_seen / kk_decoded / skipped_dialect (AIS and friends decode with other
12// keys -- skipped, never silently zero) / decode_partial (parsed<declared stops the card's row).
13// license_tier: ORIGINAL No hw writes (Rule 26).
14import "nx_syscalls.nx"
15import "nx_kkfacts_lib.nx"
16
17const KS_MAXCARDS: i64 = 512 // corpus ceiling per run; reaching it REFUSES loudly, never truncates
18const KS_MAXTAGS: i64 = 64 // distinct tags tracked; overflow is counted and announced
19const KS_TAGLEN: i64 = 32 // one tag name slot
20const KS_NBODY: i64 = 44 // shapeValueBody carries 44 floats (measured on the benchmark card)
21const KS_MAXVALS: i64 = 256 // decode reserve, same bound the kkfacts CLI uses
22const KS_DIRBUF: i64 = 65536
23const KS_PATH: i64 = 1024
24const KS_METAEXT: *u8 = ".meta.json"
25const KS_METAEXT_LEN: i64 = 10
26const KS_NL: i64 = 10
27
28func ks_len(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n }
29func ks_w(s: *u8) -> i64 { sys_write(1, s, ks_len(s)); return 0 }
30func ks_n(v: i64) -> i64 {
31 var m: i64 = v
32 if m < 0 { sys_write(1, "-" as *u8, 1); m = 0 - m }
33 let t: *u8 = sys_mmap(32)
34 var k: i64 = 0
35 if m == 0 { t[0] = 48 as u8; k = 1 }
36 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
37 let o: *u8 = sys_mmap(32)
38 var i: i64 = 0
39 while i < k { o[i] = t[k - 1 - i]; i = i + 1 }
40 sys_write(1, o, k)
41 return 0
42}
43func ks_cat(d: *u8, o: i64, s: *u8) -> i64 { var i: i64 = 0; while s[i] != (0 as u8) { d[o+i] = s[i]; i = i + 1 } d[o+i] = 0 as u8; return o + i }
44func ks_find(b: *u8, start: i64, end: i64, needle: *u8) -> i64 {
45 var m: i64 = ks_len(needle)
46 var i: i64 = start
47 while i + m <= end {
48 var k: i64 = 0
49 while k < m { if (b[i+k] as i64) != (needle[k] as i64) { k = m + 9 } else { k = k + 1 } }
50 if k == m { return i }
51 i = i + 1
52 }
53 return 0 - 1
54}
55// does the meta buffer carry tag <name>? tags ride as "name":"<tag>" inside the tags array; the
56// uploader object has "username" not "name", so the "name":" needle is tag-specific in this schema.
57func ks_has_tag(mb: *u8, mn: i64, tag: *u8) -> i64 {
58 let needle: *u8 = sys_mmap(KS_TAGLEN + 16)
59 var o: i64 = ks_cat(needle, 0, "\"name\":\"" as *u8)
60 o = ks_cat(needle, o, tag)
61 o = ks_cat(needle, o, "\"" as *u8)
62 if ks_find(mb, 0, mn, needle) >= 0 { return 1 }
63 return 0
64}
65// collect every distinct tag name in a meta buffer into the tag table; returns overflowed count
66func ks_collect_tags(mb: *u8, mn: i64, tags: *u8, ntags: *i64) -> i64 {
67 var over: i64 = 0
68 var at: i64 = ks_find(mb, 0, mn, "\"name\":\"" as *u8)
69 while at >= 0 {
70 let vs: i64 = at + 8
71 var ve: i64 = vs
72 while ve < mn { if mb[ve] == (34 as u8) { break } ve = ve + 1 }
73 if ve > vs { if ve - vs < KS_TAGLEN - 1 {
74 // dedupe against the table
75 var found: i64 = 0
76 var t: i64 = 0
77 while t < ntags[0] {
78 let slot: *u8 = ((tags as i64) + t * KS_TAGLEN) as *u8
79 var eq: i64 = 1
80 var z: i64 = 0
81 while z < ve - vs { if slot[z] != mb[vs + z] { eq = 0; z = ve - vs } else { z = z + 1 } }
82 if eq == 1 { if slot[ve - vs] == (0 as u8) { found = 1; t = ntags[0] } }
83 if found == 0 { t = t + 1 }
84 }
85 if found == 0 {
86 if ntags[0] >= KS_MAXTAGS { over = over + 1 } else {
87 let slot: *u8 = ((tags as i64) + ntags[0] * KS_TAGLEN) as *u8
88 var z: i64 = 0
89 while z < ve - vs { slot[z] = mb[vs + z]; z = z + 1 }
90 slot[ve - vs] = 0 as u8
91 ntags[0] = ntags[0] + 1
92 }
93 }
94 } }
95 at = ks_find(mb, at + 1, mn, "\"name\":\"" as *u8)
96 }
97 return over
98}
99
100func main(argc: i64, argv: *i64) -> i64 {
101 if argc < 2 {
102 ks_w("usage: nx_kkslider_stats <pairs-dir> (pairs = <name>.png + <name>.meta.json, the bepis mirror shape)\n" as *u8)
103 sys_exit(2)
104 return 2
105 }
106 let dir: *u8 = argv[1] as *u8
107 // per-card storage: values[card][idx], tagged flags resolved later per tag
108 let vals: *i64 = sys_mmap(8 * KS_MAXCARDS * KS_NBODY) as *i64
109 let metas: *i64 = sys_mmap(8 * KS_MAXCARDS) as *i64 // meta buffer ptr per card
110 let metan: *i64 = sys_mmap(8 * KS_MAXCARDS) as *i64 // meta buffer len per card
111 let tags: *u8 = sys_mmap(KS_MAXTAGS * KS_TAGLEN)
112 let ntags: *i64 = sys_mmap(8) as *i64
113 ntags[0] = 0
114 var pairs_seen: i64 = 0
115 var kk_decoded: i64 = 0
116 var skipped_dialect: i64 = 0
117 var decode_partial: i64 = 0
118 var tag_overflow: i64 = 0
119 // walk the dir for *.meta.json (loop getdents64 until 0 -- one call is not a listing)
120 let fd: i64 = sys_openat_rd(dir)
121 if fd < 0 { ks_w("ERROR: cannot open pairs-dir\n" as *u8); sys_exit(1); return 1 }
122 let dbuf: *u8 = sys_mmap(KS_DIRBUF)
123 let mpath: *u8 = sys_mmap(KS_PATH)
124 let cpath: *u8 = sys_mmap(KS_PATH)
125 let facts: *i64 = sys_mmap(KK_N_SLOTS * 8) as *i64
126 let dvals: *i64 = sys_mmap(8 * KS_MAXVALS) as *i64
127 let dmeta: *i64 = sys_mmap(16) as *i64
128 let flen: *i64 = sys_mmap(16) as *i64
129 var go: i64 = 1
130 while go == 1 {
131 let nb: i64 = sys_getdents64(fd, dbuf, KS_DIRBUF)
132 if nb <= 0 { go = 0 } else {
133 var off: i64 = 0
134 while off < nb {
135 let rec: *u8 = (dbuf as i64 + off) as *u8
136 let rl: i64 = dirent_reclen(rec)
137 if rl <= 0 { off = nb } else {
138 let nm: *u8 = dirent_name(rec)
139 let nl: i64 = ks_len(nm)
140 var ismeta: i64 = 0
141 if nl > KS_METAEXT_LEN {
142 var k: i64 = 0
143 ismeta = 1
144 while k < KS_METAEXT_LEN {
145 if nm[nl - KS_METAEXT_LEN + k] != KS_METAEXT[k] { ismeta = 0; k = KS_METAEXT_LEN } else { k = k + 1 }
146 }
147 }
148 if ismeta == 1 {
149 if pairs_seen >= KS_MAXCARDS {
150 ks_w("REFUSED: more than KS_MAXCARDS pairs -- shard the corpus or raise the const deliberately (a silent cap is a partial read wearing a total)\n" as *u8)
151 sys_exit(1)
152 return 1
153 }
154 var po: i64 = ks_cat(mpath, 0, dir)
155 po = ks_cat(mpath, po, "/" as *u8)
156 po = ks_cat(mpath, po, nm)
157 var co: i64 = ks_cat(cpath, 0, dir)
158 co = ks_cat(cpath, co, "/" as *u8)
159 var z: i64 = 0
160 while z < nl - KS_METAEXT_LEN { cpath[co] = nm[z]; co = co + 1; z = z + 1 }
161 co = ks_cat(cpath, co, ".png" as *u8)
162 let mb: *u8 = sys_read_file(mpath, flen)
163 let mn: i64 = flen[0]
164 let cb: *u8 = sys_read_file(cpath, flen)
165 let cn: i64 = flen[0]
166 if (mb as i64) != 0 { if mn > 0 { if (cb as i64) != 0 { if cn > 0 {
167 pairs_seen = pairs_seen + 1
168 kk_probe(cb, cn, cn, facts)
169 if facts[0] == 0 {
170 // not a KK-dialect card (AIS and friends decode with other keys)
171 skipped_dialect = skipped_dialect + 1
172 sys_free_file(cb, cn)
173 } else {
174 let parsed: i64 = kk_decode_sliders(cb, facts[1], cn, "shapeValueBody" as *u8, dvals, KS_MAXVALS, dmeta)
175 if dmeta[0] == KS_NBODY { if parsed == KS_NBODY {
176 var i2: i64 = 0
177 while i2 < KS_NBODY { vals[kk_decoded * KS_NBODY + i2] = dvals[i2]; i2 = i2 + 1 }
178 metas[kk_decoded] = mb as i64
179 metan[kk_decoded] = mn
180 tag_overflow = tag_overflow + ks_collect_tags(mb, mn, tags, ntags)
181 kk_decoded = kk_decoded + 1
182 } else { decode_partial = decode_partial + 1 } } else { decode_partial = decode_partial + 1 }
183 sys_free_file(cb, cn)
184 }
185 } } } }
186 }
187 off = off + rl
188 }
189 }
190 }
191 }
192 sys_close(fd)
193 ks_w("KKSLIDER-STATS pairs_seen=" as *u8); ks_n(pairs_seen)
194 ks_w(" kk_decoded=" as *u8); ks_n(kk_decoded)
195 ks_w(" skipped_dialect=" as *u8); ks_n(skipped_dialect)
196 ks_w(" decode_partial=" as *u8); ks_n(decode_partial)
197 ks_w(" tags_distinct=" as *u8); ks_n(ntags[0])
198 ks_w(" tag_overflow=" as *u8); ks_n(tag_overflow)
199 ks_w("\n" as *u8)
200 if kk_decoded == 0 {
201 ks_w("NO-EVIDENCE: zero KK cards decoded in full -- nothing to correlate (this is not a distribution of zero)\n" as *u8)
202 sys_exit(3)
203 return 3
204 }
205 // per (tag, index): mean permil among tagged vs rest. delta printed only WITH its denominators.
206 var t: i64 = 0
207 while t < ntags[0] {
208 let tag: *u8 = ((tags as i64) + t * KS_TAGLEN) as *u8
209 // resolve membership once per tag
210 let memb: *i64 = sys_mmap(8 * KS_MAXCARDS) as *i64
211 var n_tag: i64 = 0
212 var c: i64 = 0
213 while c < kk_decoded {
214 memb[c] = ks_has_tag(metas[c] as *u8, metan[c], tag)
215 if memb[c] == 1 { n_tag = n_tag + 1 }
216 c = c + 1
217 }
218 let n_rest: i64 = kk_decoded - n_tag
219 var i3: i64 = 0
220 while i3 < KS_NBODY {
221 var sum_t: i64 = 0
222 var sum_r: i64 = 0
223 c = 0
224 while c < kk_decoded {
225 if memb[c] == 1 { sum_t = sum_t + vals[c * KS_NBODY + i3] } else { sum_r = sum_r + vals[c * KS_NBODY + i3] }
226 c = c + 1
227 }
228 var mean_t: i64 = 0
229 if n_tag > 0 { mean_t = sum_t / n_tag }
230 var mean_r: i64 = 0
231 if n_rest > 0 { mean_r = sum_r / n_rest }
232 ks_w("tag=" as *u8); ks_w(tag)
233 ks_w(" idx=" as *u8); ks_n(i3)
234 ks_w(" n_tag=" as *u8); ks_n(n_tag)
235 ks_w(" mean_tag=" as *u8); ks_n(mean_t)
236 ks_w(" n_rest=" as *u8); ks_n(n_rest)
237 ks_w(" mean_rest=" as *u8); ks_n(mean_r)
238 ks_w(" delta=" as *u8); ks_n(mean_t - mean_r)
239 ks_w("\n" as *u8)
240 i3 = i3 + 1
241 }
242 t = t + 1
243 }
244 sys_exit(0)
245 return 0
246}