code wiki / (root) / nx_field_seedgen_lib.nx

nx_field_seedgen_lib.nx source

↩ module page · 281 lines · 15139 B

1// nx_field_seedgen_lib.nx -- THE DECISION CORE OF THE SEED GENERATOR (/compare/fieldwatch fleet campaign, 2026-09-05). 2// A domain's DECLARED population already exists on its board: the @cols rivals of <dom>.matrix, whose pages are already 3// mirrored and pinned as <dom>.refs rows. This lib turns those two data files into <dom>.seeds rows of kind `named`, one 4// per column that a refs row names, so every domain inherits a field on the next fieldbeat without a seat authoring URLs 5// by hand -- and it NEVER invents a URL: a column no refs row names is emitted as an UNSOURCED comment, counted, announced. 6// Discovery seeds (wiki-raw, gh-topic, md-list) stay hand-curated per domain; a derived file carries a marker line so the 7// generator only ever rewrites its own output and refuses a hand-authored file. Pure functions over buffers; the program 8// owns the reads and the write. Byte helpers come from the beat lib (one slen, one puts, one putn in this family). 9// license_tier: ORIGINAL No hw writes (Rule 26). 10import "nx_syscalls.nx" 11import "nx_field_beat_lib.nx" 12 13const SG_MAX_COLS: i64 = 16 // nx_compare_rank parses @cols with maxf=8; 16 is twice that so a wide board is never cut here 14const SG_TOK_CAP: i64 = 48 15const SG_MAX_TOKS: i64 = 12 16const SG_TOK_MIN: i64 = 3 // shorter runs (4, 5, io) match everything and name nothing 17const SG_SCORE_URL: i64 = 2 18const SG_SCORE_CITE: i64 = 1 19const SG_SCORE_MIN: i64 = 2 // one url hit, or two prose hits: a single word in a citation is not a member 20const SG_SLUG_CAP: i64 = 16 21const SG_REF_F: i64 = 9 22const SG_F_KEY: i64 = 1 23const SG_F_CITE: i64 = 2 24const SG_F_URL: i64 = 3 25const SG_F_MIRROR: i64 = 4 // the seat's own declaration of what was fetched: a mirror banked as .img/.png/.pdf is an asset, whatever the url looks like 26const SG_CH_PIPE: i64 = 124 27const SG_CH_A: i64 = 97 28const SG_CH_Z: i64 = 122 29const SG_CH_AU: i64 = 65 30const SG_CH_ZU: i64 = 90 31const SG_CH_0: i64 = 48 32const SG_CH_9: i64 = 57 33const SG_CASE_GAP: i64 = 32 34const SG_COLS_PFX: *u8 = "@cols " 35const SG_MARKER: *u8 = " SEEDGEN-MARKER regenerable: rewritten by nx_field_seedgen while this line stands" 36const SG_CLASS_GENERATED: i64 = 1 37const SG_CLASS_HAND: i64 = 2 // an existing seeds file without the marker: a seat curated it, never touched 38const SG_CLASS_NO_MATRIX: i64 = 3 39const SG_CLASS_NO_COLS: i64 = 4 40const SG_CLASS_NO_SOURCED: i64 = 5 // every column unsourced: nothing written, so the beat keeps skipping the domain cleanly 41const SG_CLASS_UNWRITABLE: i64 = 6 42const SG_CLASS_N: i64 = 7 43 44func sg_lower(c: i64) -> i64 { if c >= SG_CH_AU { if c <= SG_CH_ZU { return c + SG_CASE_GAP } } return c } 45func sg_is_alnum(c: i64) -> i64 { 46 if c >= SG_CH_A { if c <= SG_CH_Z { return 1 } } 47 if c >= SG_CH_AU { if c <= SG_CH_ZU { return 1 } } 48 if c >= SG_CH_0 { if c <= SG_CH_9 { return 1 } } 49 return 0 50} 51func sg_putspan(fd: i64, b: *u8, s: i64, e: i64) -> i64 { if e > s { sys_write(fd, ((b as i64) + s) as *u8, e - s) } return 0 } 52func sg_tok_at(toks: *u8, i: i64) -> *u8 { return ((toks as i64) + i * SG_TOK_CAP) as *u8 } 53// words that name a KIND of rival, never a rival: they would match every citation in the register 54func sg_is_stop(t: *u8) -> i64 { 55 if fb_streq(t, "the" as *u8) == 1 { return 1 } 56 if fb_streq(t, "and" as *u8) == 1 { return 1 } 57 if fb_streq(t, "plus" as *u8) == 1 { return 1 } 58 if fb_streq(t, "class" as *u8) == 1 { return 1 } 59 if fb_streq(t, "stack" as *u8) == 1 { return 1 } 60 if fb_streq(t, "web" as *u8) == 1 { return 1 } 61 if fb_streq(t, "app" as *u8) == 1 { return 1 } 62 if fb_streq(t, "tool" as *u8) == 1 { return 1 } 63 if fb_streq(t, "kit" as *u8) == 1 { return 1 } 64 if fb_streq(t, "lab" as *u8) == 1 { return 1 } 65 if fb_streq(t, "desk" as *u8) == 1 { return 1 } 66 if fb_streq(t, "platform" as *u8) == 1 { return 1 } 67 if fb_streq(t, "brand" as *u8) == 1 { return 1 } 68 if fb_streq(t, "program" as *u8) == 1 { return 1 } 69 if fb_streq(t, "data" as *u8) == 1 { return 1 } 70 if fb_streq(t, "svc" as *u8) == 1 { return 1 } 71 if fb_streq(t, "open" as *u8) == 1 { return 1 } 72 if fb_streq(t, "free" as *u8) == 1 { return 1 } 73 if fb_streq(t, "native" as *u8) == 1 { return 1 } 74 if fb_streq(t, "manual" as *u8) == 1 { return 1 } 75 if fb_streq(t, "service" as *u8) == 1 { return 1 } 76 if fb_streq(t, "engine" as *u8) == 1 { return 1 } 77 if fb_streq(t, "results" as *u8) == 1 { return 1 } 78 if fb_streq(t, "provider" as *u8) == 1 { return 1 } 79 if fb_streq(t, "shop" as *u8) == 1 { return 1 } 80 if fb_streq(t, "print" as *u8) == 1 { return 1 } 81 if fb_streq(t, "transfer" as *u8) == 1 { return 1 } 82 if fb_streq(t, "research" as *u8) == 1 { return 1 } 83 if fb_streq(t, "line" as *u8) == 1 { return 1 } 84 if fb_streq(t, "apis" as *u8) == 1 { return 1 } 85 if fb_streq(t, "standard" as *u8) == 1 { return 1 } 86 if fb_streq(t, "index" as *u8) == 1 { return 1 } 87 if fb_streq(t, "grid" as *u8) == 1 { return 1 } 88 if fb_streq(t, "wave" as *u8) == 1 { return 1 } 89 if fb_streq(t, "search" as *u8) == 1 { return 1 } 90 return 0 91} 92// PURE: the first @cols line of a matrix -> column spans (start,end pairs, spaces trimmed). -1 when the matrix has none. 93func sg_cols(b: *u8, n: i64, spans: *i64) -> i64 { 94 var i: i64 = 0 95 while i < n { 96 var e: i64 = i 97 while e < n { if (b[e] as i64) == FB_CH_NL { break } e = e + 1 } 98 if fb_prefix_at(b, i, e, SG_COLS_PFX) == 1 { 99 var cnt: i64 = 0 100 var f0: i64 = i + fb_slen(SG_COLS_PFX) 101 var q: i64 = f0 102 while q <= e { 103 var atend: i64 = 0 104 if q == e { atend = 1 } else { if (b[q] as i64) == SG_CH_PIPE { atend = 1 } } 105 if atend == 1 { 106 var s: i64 = f0 107 var t: i64 = q 108 while s < t { if (b[s] as i64) == FB_CH_SP { s = s + 1 } else { break } } 109 while t > s { if (b[t - 1] as i64) == FB_CH_SP { t = t - 1 } else { if (b[t - 1] as i64) == FB_CH_CR { t = t - 1 } else { break } } } 110 if t > s { if cnt < SG_MAX_COLS { spans[cnt * 2] = s; spans[cnt * 2 + 1] = t; cnt = cnt + 1 } } 111 f0 = q + 1 112 } 113 q = q + 1 114 } 115 return cnt 116 } 117 i = e + 1 118 } 119 return 0 - 1 120} 121// PURE: a column name -> its lowercase alnum tokens (len >= SG_TOK_MIN, stop words dropped). toks arena = SG_TOK_CAP * SG_MAX_TOKS. 122func sg_tokens(b: *u8, s: i64, e: i64, toks: *u8) -> i64 { 123 var ntok: i64 = 0 124 var i: i64 = s 125 var rs: i64 = 0 - 1 126 while i <= e { 127 var al: i64 = 0 128 if i < e { al = sg_is_alnum(b[i] as i64) } 129 if al == 1 { if rs < 0 { rs = i } } else { 130 if rs >= 0 { 131 let ln: i64 = i - rs 132 if ln >= SG_TOK_MIN { if ntok < SG_MAX_TOKS { 133 let t: *u8 = sg_tok_at(toks, ntok) 134 var k: i64 = 0 135 while k < ln { if k < SG_TOK_CAP - 1 { t[k] = sg_lower(b[rs + k] as i64) as u8 } k = k + 1 } 136 if ln > SG_TOK_CAP - 1 { t[SG_TOK_CAP - 1] = 0 as u8 } else { t[ln] = 0 as u8 } 137 if sg_is_stop(t) == 0 { ntok = ntok + 1 } 138 } } 139 rs = 0 - 1 140 } 141 } 142 i = i + 1 143 } 144 return ntok 145} 146// PURE: case-insensitive substring of a lowercase token inside [hs,he) 147func sg_contains_ci(hay: *u8, hs: i64, he: i64, tok: *u8) -> i64 { 148 let tl: i64 = fb_slen(tok) 149 if tl == 0 { return 0 } 150 var i: i64 = hs 151 while i + tl <= he { 152 var j: i64 = 0 153 var same: i64 = 1 154 while j < tl { if sg_lower(hay[i + j] as i64) != (tok[j] as i64) { same = 0; j = tl } else { j = j + 1 } } 155 if same == 1 { return 1 } 156 i = i + 1 157 } 158 return 0 159} 160// PURE: how strongly one refs row names a column: SG_SCORE_URL per token found in the url, else SG_SCORE_CITE if in the citation 161func sg_score(b: *u8, us: i64, ue: i64, cs: i64, ce: i64, toks: *u8, ntok: i64) -> i64 { 162 var sc: i64 = 0 163 var k: i64 = 0 164 while k < ntok { 165 let t: *u8 = sg_tok_at(toks, k) 166 if sg_contains_ci(b, us, ue, t) == 1 { sc = sc + SG_SCORE_URL } else { if sg_contains_ci(b, cs, ce, t) == 1 { sc = sc + SG_SCORE_CITE } } 167 k = k + 1 168 } 169 return sc 170} 171// PURE: a member's page must be a PAGE. A refs row whose url is an image, a font, an archive or a paper file names a 172// mirrored asset, never a home page (measured on graphics.refs: Unreal Engine 5 matched a social-share png first). 173func sg_url_is_page(b: *u8, s: i64, e: i64) -> i64 { 174 if sg_url_ends(b, s, e, ".png" as *u8) == 1 { return 0 } 175 if sg_url_ends(b, s, e, ".jpg" as *u8) == 1 { return 0 } 176 if sg_url_ends(b, s, e, ".jpeg" as *u8) == 1 { return 0 } 177 if sg_url_ends(b, s, e, ".gif" as *u8) == 1 { return 0 } 178 if sg_url_ends(b, s, e, ".webp" as *u8) == 1 { return 0 } 179 if sg_url_ends(b, s, e, ".svg" as *u8) == 1 { return 0 } 180 if sg_url_ends(b, s, e, ".ico" as *u8) == 1 { return 0 } 181 if sg_url_ends(b, s, e, ".pdf" as *u8) == 1 { return 0 } 182 if sg_url_ends(b, s, e, ".zip" as *u8) == 1 { return 0 } 183 if sg_url_ends(b, s, e, ".mp4" as *u8) == 1 { return 0 } 184 if sg_url_ends(b, s, e, ".woff" as *u8) == 1 { return 0 } 185 if sg_url_ends(b, s, e, ".woff2" as *u8) == 1 { return 0 } 186 if sg_url_ends(b, s, e, ".img" as *u8) == 1 { return 0 } 187 if sg_url_ends(b, s, e, ".bin" as *u8) == 1 { return 0 } 188 if sg_url_ends(b, s, e, ".raw" as *u8) == 1 { return 0 } 189 return 1 190} 191// PURE: the mirror field is the seat's own declaration of what was fetched, so an asset behind an extension-less CDN url 192// (measured: cms-assets.unrealengine.com/.../auto_image/... banked as cmp_graphics_metahuman_ref1.img) is caught here. 193// A row too short to carry a mirror abstains toward the pre-change behaviour (allowed), never toward inventing a verdict. 194func sg_mirror_is_page(refs: *u8, fs: *i64, nf: i64) -> i64 { 195 if nf <= SG_F_MIRROR { return 1 } 196 return sg_url_is_page(refs, fs[SG_F_MIRROR * 2], fs[SG_F_MIRROR * 2 + 1]) 197} 198// PURE: case-insensitive suffix test on a url span (a trailing query string is not stripped: a refs url carries none) 199func sg_url_ends(b: *u8, s: i64, e: i64, ext: *u8) -> i64 { 200 let xl: i64 = fb_slen(ext) 201 if e - s < xl { return 0 } 202 var k: i64 = 0 203 while k < xl { if sg_lower(b[e - xl + k] as i64) != (ext[k] as i64) { return 0 } k = k + 1 } 204 return 1 205} 206// PURE: the best refs row for a column. out[0..1] = url span, out[2..3] = key span. Returns the best score, -1 when no row. 207// Rows are ref|key|cite|url|... ; comment lines and rows without a url field never compete. 208func sg_pick(refs: *u8, n: i64, toks: *u8, ntok: i64, out: *i64) -> i64 { 209 var best: i64 = 0 - 1 210 let fs: *i64 = sys_mmap(8 * 2 * SG_REF_F) as *i64 211 var i: i64 = 0 212 while i < n { 213 var e: i64 = i 214 while e < n { if (refs[e] as i64) == FB_CH_NL { break } e = e + 1 } 215 if e > i { if (refs[i] as i64) != FB_CH_HASH { 216 var nf: i64 = 0 217 var f0: i64 = i 218 var q: i64 = i 219 while q <= e { 220 var atend: i64 = 0 221 if q == e { atend = 1 } else { if (refs[q] as i64) == SG_CH_PIPE { atend = 1 } } 222 if atend == 1 { if nf < SG_REF_F { fs[nf * 2] = f0; fs[nf * 2 + 1] = q; nf = nf + 1 } f0 = q + 1 } 223 q = q + 1 224 } 225 if nf > SG_F_URL { if fb_prefix_at(refs, fs[0], fs[1], "ref" as *u8) == 1 { if fs[1] - fs[0] == 3 { if sg_url_is_page(refs, fs[SG_F_URL * 2], fs[SG_F_URL * 2 + 1]) == 1 { if sg_mirror_is_page(refs, fs, nf) == 1 { 226 let sc: i64 = sg_score(refs, fs[SG_F_URL * 2], fs[SG_F_URL * 2 + 1], fs[SG_F_CITE * 2], fs[SG_F_CITE * 2 + 1], toks, ntok) 227 if sc > best { best = sc; out[0] = fs[SG_F_URL * 2]; out[1] = fs[SG_F_URL * 2 + 1]; out[2] = fs[SG_F_KEY * 2]; out[3] = fs[SG_F_KEY * 2 + 1] } 228 } } } } } 229 } } 230 i = e + 1 231 } 232 return best 233} 234// PURE: does a seeds file carry the generator's marker (so it is ours to rewrite)? 235func sg_is_derived(b: *u8, n: i64) -> i64 { 236 let ml: i64 = fb_slen(SG_MARKER) 237 var i: i64 = 0 238 while i + ml <= n { if fb_prefix_at(b, i, n, SG_MARKER) == 1 { return 1 } i = i + 1 } 239 return 0 240} 241func sg_class_name(c: i64) -> *u8 { 242 if c == SG_CLASS_GENERATED { return "GENERATED" as *u8 } 243 if c == SG_CLASS_HAND { return "HAND-AUTHORED" as *u8 } 244 if c == SG_CLASS_NO_MATRIX { return "NO-MATRIX" as *u8 } 245 if c == SG_CLASS_NO_COLS { return "NO-COLS" as *u8 } 246 if c == SG_CLASS_NO_SOURCED { return "NO-SOURCED" as *u8 } 247 return "UNWRITABLE" as *u8 248} 249func sg_hash(fd: i64) -> i64 { let h: *u8 = sys_mmap(1); h[0] = FB_CH_HASH as u8; sys_write(fd, h, 1); return 0 } 250// PURE over an fd: the derived seeds file. counts[0]=sourced counts[1]=unsourced. Never writes a url it did not read from refs. 251func sg_emit(fd: i64, dom: *u8, ts: i64, mx: *u8, spans: *i64, ncols: i64, refs: *u8, rn: i64, counts: *i64) -> i64 { 252 counts[0] = 0; counts[1] = 0 253 sg_hash(fd); fb_puts(fd, " " as *u8); fb_puts(fd, dom); fb_puts(fd, ".seeds -- DERIVED by nx_field_seedgen at ts=" as *u8); fb_putn(fd, ts) 254 fb_puts(fd, " from " as *u8); fb_puts(fd, dom); fb_puts(fd, ".matrix @cols (the declared population) and " as *u8); fb_puts(fd, dom); fb_puts(fd, ".refs (their pinned pages); kind named only. To hand-curate: delete the marker line below and add rows (seed|key|url|kind|why|Display Name; kinds wiki-raw gh-topic md-list named).\n" as *u8) 255 sg_hash(fd); fb_puts(fd, SG_MARKER); fb_puts(fd, "\n" as *u8) 256 let toks: *u8 = sys_mmap(SG_TOK_CAP * SG_MAX_TOKS) 257 let out: *i64 = sys_mmap(8 * 4) as *i64 258 var c: i64 = 0 259 while c < ncols { 260 let cs: i64 = spans[c * 2] 261 let ce: i64 = spans[c * 2 + 1] 262 let ntok: i64 = sg_tokens(mx, cs, ce, toks) 263 var sc: i64 = 0 - 1 264 if ntok > 0 { sc = sg_pick(refs, rn, toks, ntok, out) } 265 if sc >= SG_SCORE_MIN { 266 fb_puts(fd, "seed|col" as *u8); fb_putn(fd, c); fb_puts(fd, "-" as *u8) 267 let t0: *u8 = sg_tok_at(toks, 0) 268 var k: i64 = 0 269 while t0[k] != (0 as u8) { if k < SG_SLUG_CAP { sys_write(fd, ((t0 as i64) + k) as *u8, 1) } k = k + 1 } 270 fb_puts(fd, "|" as *u8); sg_putspan(fd, refs, out[0], out[1]) 271 fb_puts(fd, "|named|derived from @cols column " as *u8); fb_putn(fd, c); fb_puts(fd, " and refs row " as *u8); sg_putspan(fd, refs, out[2], out[3]); fb_puts(fd, " (score " as *u8); fb_putn(fd, sc); fb_puts(fd, ")|" as *u8) 272 sg_putspan(fd, mx, cs, ce); fb_puts(fd, "\n" as *u8) 273 counts[0] = counts[0] + 1 274 } else { 275 sg_hash(fd); fb_puts(fd, " UNSOURCED col" as *u8); fb_putn(fd, c); fb_puts(fd, " \x22" as *u8); sg_putspan(fd, mx, cs, ce); fb_puts(fd, "\x22: no refs row names it (best score " as *u8); fb_putn(fd, sc); fb_puts(fd, ") -- add a seed row by hand, never a guessed url\n" as *u8) 276 counts[1] = counts[1] + 1 277 } 278 c = c + 1 279 } 280 return counts[0] 281}