nx_field_seedgen_gate.nx source
↩ module page · 166 lines · 11036 B
1// nx_field_seedgen_gate.nx -- THE GATE FOR THE SEED GENERATOR'S DECISIONS (nx_field_seedgen_lib, fieldwatch fleet campaign).
2//
3// Drives the lib IN-PROCESS on fixtures assembled at RUNTIME under /tmp/nx_field_seedgen_gate/ (no board file touched).
4// What it must catch: a @cols reader that misses the line or keeps a trailing space; a tokenizer that lets a kind-word
5// (platform, stack, lab) name a member; a matcher that accepts one prose hit as a member or reads a comment row as a ref;
6// an emitter that invents a url for an unsourced column, forgets the marker, or writes a seed row without kind named;
7// a derived-file test that would let the generator rewrite a hand-curated file.
8// license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0
9import "nx_syscalls.nx"
10import "nx_gate_verdict.nx"
11import "nx_field_seedgen_lib.nx"
12
13const G_DIR: *u8 = "/tmp/nx_field_seedgen_gate"
14const G_OUT: *u8 = "/tmp/nx_field_seedgen_gate/fx.seeds"
15const G_MODEDIR: i64 = 493
16const G_TS: i64 = 1788650000
17// '@' at line start stands for '#' (the lexer keeps '#' out of literals); g_fix() rewrites it at runtime. '@cols' itself is real.
18const G_MATRIX: *u8 = "@ fx.matrix header comment\n@title fixture\n@cols DanceXR | Blender 4.5 plus addons|Extension lab|Google Maps Platform \nrow|x|y|0|1|1|1|1|note\n"
19const G_REFS: *u8 = "@ fx.refs header\nref|dancexr-img|DanceXR banner image|https://cdn.dancexr.com/banner.PNG|knowledge/fetched/i.png|h00|2026-09-05|vendor-doc|g\nref|dancexr-cms|DanceXR hero still from the CMS asset pipeline|https://cms.dancexr.com/asset/abc123/auto_image/xyz|knowledge/fetched/dxr_hero.img|h00|2026-09-05|vendor-doc|g\nref|dancexr|DanceXR documentation home|https://dancexr.com/docs/|knowledge/fetched/x.html|h00|2026-09-05|vendor-doc|g\nref|blender-manual|Blender 4.5 reference manual addons chapter|https://docs.blender.org/manual/en/4.5/|knowledge/fetched/y.html|h00|2026-09-05|vendor-doc|g\nref|soil|A paper about the platform of soil science|https://example.org/soil|knowledge/fetched/z.html|h00|2026-09-05|published-paper|g\nnotaref|dancexr-trap|DanceXR again|https://trap.example/dancexr|m|h|d|c|g\n"
20const G_HAND: *u8 = "@ modding.seeds -- hand curated\nseed|nexus|https://www.nexusmods.com/|named|declared|Nexus Mods\n"
21const G_CH_AT: i64 = 64
22const G_CH_HASH: i64 = 35
23const G_CH_NL: i64 = 10
24
25func g_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n }
26// rewrite '@' to '#' only at LINE START, so the real @cols and @title directives survive
27func g_fix(src: *u8) -> *u8 {
28 let n: i64 = g_slen(src)
29 let b: *u8 = sys_mmap(n + 1)
30 var i: i64 = 0
31 var linestart: i64 = 1
32 while i < n {
33 var c: i64 = src[i] as i64
34 if linestart == 1 { if c == G_CH_AT { if i + 1 < n { if (src[i + 1] as i64) == 32 { c = G_CH_HASH } } } }
35 b[i] = c as u8
36 if c == G_CH_NL { linestart = 1 } else { linestart = 0 }
37 i = i + 1
38 }
39 b[n] = 0 as u8
40 return b
41}
42func g_read(path: *u8, lenout: *i64) -> *u8 {
43 let lp: *i64 = sys_mmap(16) as *i64
44 let b: *u8 = sys_read_file(path, lp)
45 if (b as i64) == 0 { lenout[0] = 0; return 0 as *u8 }
46 lenout[0] = lp[0]
47 return b
48}
49func g_count_prefix(b: *u8, n: i64, pfx: *u8) -> i64 {
50 var cnt: i64 = 0
51 var i: i64 = 0
52 while i < n {
53 var e: i64 = i
54 while e < n { if (b[e] as i64) == G_CH_NL { break } e = e + 1 }
55 if fb_prefix_at(b, i, e, pfx) == 1 { cnt = cnt + 1 }
56 i = e + 1
57 }
58 return cnt
59}
60func g_span_eq(b: *u8, s: i64, e: i64, lit: *u8) -> i64 {
61 var i: i64 = 0
62 while s + i < e { if lit[i] == (0 as u8) { return 0 } if b[s + i] != lit[i] { return 0 } i = i + 1 }
63 if lit[i] != (0 as u8) { return 0 }
64 return 1
65}
66
67func main(argc: i64, argv: *i64) -> i64 {
68 let ctr: *i64 = gv_ctr()
69 gv_head("nx_field_seedgen gate -- a domain's seeds are derived from its own board, never guessed" as *u8)
70 sys_mkdir(G_DIR, G_MODEDIR)
71 let mx: *u8 = g_fix(G_MATRIX)
72 let mn: i64 = g_slen(mx)
73 let rf: *u8 = g_fix(G_REFS)
74 let rn: i64 = g_slen(rf)
75
76 // ---- @cols ----
77 let spans: *i64 = sys_mmap(8 * 2 * SG_MAX_COLS) as *i64
78 let ncols: i64 = sg_cols(mx, mn, spans)
79 gv_check_eq("cols-line-yields-four-columns" as *u8, ncols, 4, ctr)
80 var t2: i64 = 0
81 if ncols == 4 { if g_span_eq(mx, spans[0], spans[1], "DanceXR" as *u8) == 1 { if g_span_eq(mx, spans[6], spans[7], "Google Maps Platform" as *u8) == 1 { t2 = 1 } } }
82 gv_check("column-names-are-trimmed-of-surrounding-spaces (DanceXR, Google Maps Platform)" as *u8, t2, ctr)
83 gv_check_eq("neg-control-a-buffer-without-a-cols-line-reads-minus-one" as *u8, sg_cols(rf, rn, spans), 0 - 1, ctr)
84
85 // ---- tokens ----
86 let toks: *u8 = sys_mmap(SG_TOK_CAP * SG_MAX_TOKS)
87 let nt1: i64 = sg_tokens(mx, spans[2], spans[3], toks)
88 var t4: i64 = 0
89 if nt1 == 2 { if fb_streq(sg_tok_at(toks, 0), "blender" as *u8) == 1 { if fb_streq(sg_tok_at(toks, 1), "addons" as *u8) == 1 { t4 = 1 } } }
90 gv_check("blender-4.5-plus-addons-tokenizes-to-blender-and-addons (digits under three chars and the kind-word plus dropped, lowercased)" as *u8, t4, ctr)
91 let nt2: i64 = sg_tokens(mx, spans[4], spans[5], toks)
92 var t5: i64 = 0
93 if nt2 == 1 { if fb_streq(sg_tok_at(toks, 0), "extension" as *u8) == 1 { t5 = 1 } }
94 gv_check("neg-control-a-kind-word-never-becomes-a-token (Extension lab -> extension only)" as *u8, t5, ctr)
95
96 // ---- pick ----
97 let out: *i64 = sys_mmap(8 * 4) as *i64
98 let ntd: i64 = sg_tokens(mx, spans[0], spans[1], toks)
99 let scd: i64 = sg_pick(rf, rn, toks, ntd, out)
100 var t6: i64 = 0
101 if scd >= SG_SCORE_MIN { if g_span_eq(rf, out[0], out[1], "https://dancexr.com/docs/" as *u8) == 1 { if g_span_eq(rf, out[2], out[3], "dancexr" as *u8) == 1 { t6 = 1 } } }
102 gv_check("dancexr-picks-the-ref-row-whose-url-names-it-and-carries-its-key" as *u8, t6, ctr)
103 gv_check_eq("dancexr-scores-its-url-hit-once-and-never-double-counts-the-same-token-in-the-cite (2)" as *u8, scd, SG_SCORE_URL, ctr)
104 let ntb: i64 = sg_tokens(mx, spans[2], spans[3], toks)
105 let scb: i64 = sg_pick(rf, rn, toks, ntb, out)
106 var t8: i64 = 0
107 if g_span_eq(rf, out[0], out[1], "https://docs.blender.org/manual/en/4.5/" as *u8) == 1 { t8 = 1 }
108 gv_check("blender-picks-the-manual-row-by-url-host" as *u8, t8, ctr)
109 gv_check_eq("blender-scores-a-url-hit-for-blender-plus-a-cite-hit-for-addons (2 plus 1)" as *u8, scb, SG_SCORE_URL + SG_SCORE_CITE, ctr)
110 let nte: i64 = sg_tokens(mx, spans[4], spans[5], toks)
111 let sce: i64 = sg_pick(rf, rn, toks, nte, out)
112 gv_check("neg-control-a-column-no-row-names-scores-below-the-member-bar (Extension lab)" as *u8, (sce < SG_SCORE_MIN) as i64, ctr)
113 let ntg: i64 = sg_tokens(mx, spans[6], spans[7], toks)
114 let scg: i64 = sg_pick(rf, rn, toks, ntg, out)
115 gv_check("neg-control-one-prose-hit-is-not-a-member (Google Maps Platform against a soil paper mentioning a platform: platform is a kind-word, maps and google absent)" as *u8, (scg < SG_SCORE_MIN) as i64, ctr)
116 // the trap row: a non-ref row naming dancexr in its url must never be picked over the real ref
117 sg_tokens(mx, spans[0], spans[1], toks)
118 sg_pick(rf, rn, toks, ntd, out)
119 gv_check("neg-control-a-row-not-starting-with-ref-never-competes (trap.example ignored)" as *u8, (g_span_eq(rf, out[0], out[1], "https://dancexr.com/docs/" as *u8) == 1) as i64, ctr)
120 gv_check("neg-control-an-image-url-never-becomes-a-member-page (cdn.dancexr.com/banner.PNG sits FIRST with an equal score and is skipped for the docs page; measured on graphics.refs where Unreal matched a social-share png)" as *u8, (g_span_eq(rf, out[0], out[1], "https://cdn.dancexr.com/banner.PNG" as *u8) == 0) as i64, ctr)
121 gv_check("neg-control-a-mirror-banked-as-an-asset-never-becomes-a-member-page (an extension-less CMS url whose mirror is dxr_hero.img sits before the docs page with an equal score; measured on graphics.refs metahuman-ref1)" as *u8, (g_span_eq(rf, out[0], out[1], "https://cms.dancexr.com/asset/abc123/auto_image/xyz" as *u8) == 0) as i64, ctr)
122
123 // ---- derived-file test ----
124 let hand: *u8 = g_fix(G_HAND)
125 gv_check_eq("neg-control-a-hand-curated-seeds-file-is-not-derived" as *u8, sg_is_derived(hand, g_slen(hand)), 0, ctr)
126
127 // ---- emit ----
128 let fd: i64 = sys_openat_wr(G_OUT, MODE_0644)
129 gv_need("fixture-seeds-opened-for-write" as *u8, (fd >= 0) as i64, ctr)
130 let counts: *i64 = sys_mmap(16) as *i64
131 let srcd: i64 = sg_emit(fd, "fx" as *u8, G_TS, mx, spans, ncols, rf, rn, counts)
132 sys_close(fd)
133 gv_check_eq("emit-returns-two-sourced-columns" as *u8, srcd, 2, ctr)
134 gv_check_eq("emit-counts-two-unsourced-columns" as *u8, counts[1], 2, ctr)
135 gv_check_eq("sourced-plus-unsourced-equals-cols" as *u8, counts[0] + counts[1], ncols, ctr)
136 let sl: *i64 = sys_mmap(16) as *i64
137 let sb: *u8 = g_read(G_OUT, sl)
138 gv_need("fixture-seeds-read-back" as *u8, ((sb as i64) != 0) as i64, ctr)
139 let sn: i64 = sl[0]
140 gv_check_eq("written-file-carries-exactly-two-seed-rows" as *u8, g_count_prefix(sb, sn, "seed|" as *u8), 2, ctr)
141 gv_check_eq("written-file-is-derived (marker line present, so the generator may rewrite it)" as *u8, sg_is_derived(sb, sn), 1, ctr)
142 gv_check_eq("the-first-seed-row-is-col0-dancexr-with-kind-named" as *u8, g_count_prefix(sb, sn, "seed|col0-dancexr|https://dancexr.com/docs/|named|" as *u8), 1, ctr)
143 gv_check_eq("the-second-seed-row-is-col1-blender-with-the-manual-url" as *u8, g_count_prefix(sb, sn, "seed|col1-blender|https://docs.blender.org/manual/en/4.5/|named|" as *u8), 1, ctr)
144 // an unsourced column appears as a comment naming itself and never as a seed row with an invented url
145 let uns: *u8 = g_fix("@ UNSOURCED col2" as *u8)
146 gv_check_eq("an-unsourced-column-is-a-named-comment-never-a-row (Extension lab)" as *u8, g_count_prefix(sb, sn, uns), 1, ctr)
147 gv_check_eq("neg-control-no-seed-row-carries-example-org (the soil url was never a member)" as *u8, g_count_prefix(sb, sn, "seed|col3" as *u8), 0, ctr)
148 // idempotent: a second emit over the derived file yields the same row count
149 let fd2: i64 = sys_openat_wr(G_OUT, MODE_0644)
150 sg_emit(fd2, "fx" as *u8, G_TS, mx, spans, ncols, rf, rn, counts)
151 sys_close(fd2)
152 let sb2: *u8 = g_read(G_OUT, sl)
153 var t_idem: i64 = 0
154 if (sb2 as i64) != 0 { if sl[0] == sn { t_idem = 1 } }
155 gv_check("a-second-emit-over-its-own-output-is-byte-stable" as *u8, t_idem, ctr)
156
157 gv_kv("cols" as *u8, ncols)
158 gv_kv("sourced" as *u8, counts[0])
159 gv_kv("unsourced" as *u8, counts[1])
160 gv_kv("dancexr_score" as *u8, scd)
161 gv_kv("blender_score" as *u8, scb)
162 gv_kv("seeds_bytes" as *u8, sn)
163 let rc: i64 = gv_verdict("NX-FIELDSEEDGEN" as *u8, ctr, "seeds are derived from the board's own columns and pinned refs, a kind-word never names a member, one prose hit is not a member, an unsourced column is a comment and a hand-curated file is never rewritten" as *u8)
164 sys_exit(rc)
165 return rc
166}