code wiki / _hdl_build / nx_asset_floor_gate.nx
nx_asset_floor_gate.nx source
↩ module page · 580 lines · 30775 B
1// nx_asset_floor_gate.nx -- THE ASSET FLOOR: measure our shipped character against a declared
2// game-ready floor, and NAME WHAT IS MISSING. Operator 2026-08-02 pointed at a commercial
3// game-ready character listing as "the floor we need to reach". That listing is behind a bot
4// challenge and could not be read, so this gate does the honest version instead: it parses OUR
5// OWN asset and reports the capability gaps a commercial game-ready character would carry.
6//
7// THE POINT IS THE GAP LIST, NOT A GREEN LIGHT. A gate that only says PASS/FAIL on triangle
8// count would call our figure "game ready" while she ships with no face geometry, no breast
9// bones and no blend shapes -- the exact defects the operator saw on screen. So every capability
10// is REPORTED, present or absent, and the absent ones are the roadmap.
11//
12// Reads the NXA container directly (the format the browser loads): magic NXANIM01, u64 version,
13// u64 section count, then 32-byte section headers {tag[4], _, off, wordlen, ck_lo, ck_hi}.
14// Sections: VERT TRIS SKEL SKIN ANIM (required) + GVRT GTRI (garment) HSTR (hair) POSE (idle).
15// license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0
16import "nx_syscalls.nx"
17import "nx_gate_verdict.nx"
18
19// the SHIPPED asset: the page fetches ref9d.nxa (DYNA-bearing) first and falls back to ref9.
20// This gate once pointed at the fallback and its DYNA tooth failed against an artifact nothing
21// serves preferentially -- measure what ships, not what shipped before it.
22const AF_PATH: *u8 = "sites/nishifamily/world/ref9d.nxa"
23// midline threshold in bind-x units -- THE SAME 3000 the page's chj classifier uses (one meaning,
24// one number). The previous span/12 (~14294 here) swallowed the REAL pectoral chain (|x|~8800,
25// joints 76-79, skinned 230-428 verts each, tracked) into the "midline spine" count and reported
26// LATERAL PAIR = 0 against a rig that has carried a wired 2-bone-per-side pair all along. Months
27// of vertex-band workaround rode that false RED.
28// AF_MIDLINE is NOT a floor threshold and is NOT derivable from a corpus: it is a geometric
29// classifier boundary in bind-x units, shared "one meaning, one number" with the page-side chj
30// classifier (nx_charjudge). It stays a named const. TRUE single-homing needs the page side to
31// read the same key; moving it here alone would create a THIRD copy, not remove the second, so
32// the co-owner is NAMED rather than the number relocated. Out of this gate's scope to touch both.
33const AF_MIDLINE: i64 = 3000
34const AF_HDR: i64 = 32
35const AF_SECHDR: i64 = 32
36// THE FOUR PICKED FLOOR BOUNDS ARE GONE (AF_VERT_MIN/AF_TRI_MIN/AF_TRI_MAX/AF_JOINT_MIN were
37// DECLARED numbers -- the magic-number defect itself). Every floor band is now MEASURED by
38// nx_rigfloor from a reference corpus. TWO confs exist and they are NOT interchangeable:
39// AF_RIG_CONF knowledge/rigfloor_nxa.conf container=1 (NXANIM01): the RIG floor, derived from
40// the three distinct rigged assets the estate holds (ref9d + two glTF donors carried
41// to NXA by R22). verts/tris/joints and the two scale-free ratios all have width here.
42// AF_DONOR_CONF knowledge/rigfloor_msh.conf container=2 (NXMSH2): the FORM floor from the glTF
43// donors. NXMSH2 carries no vertex table and no joint section, so it can never grade
44// a rig. nx_rigfloor itself REFUSES to score across containers (its gate bite-proves
45// it), and this gate obeys the same law: for an NXANIM01 subject the donor conf is
46// printed as a reference line ONLY and contributes to NO verdict.
47// An axis whose conf is absent, incomplete, or of the wrong container ABSTAINS (UNOBSERVABLE) with
48// the reason named -- never a picked default, never a pass. An axis that cannot see must not acquit.
49// AF_RIGFLOOR_CONF retired: AF_RIG_CONF is the ruler, AF_DONOR_CONF the reference line
50const AF_RIG_CONF: *u8 = "knowledge/rigfloor_nxa.conf"
51const AF_DONOR_CONF: *u8 = "knowledge/rigfloor_msh.conf"
52const AF_CONTAINER_NXA: i64 = 1
53const AF_PERMIL: i64 = 1000
54// af_rig_band outcomes -- the reason travels with the refusal
55const AF_BAND_UNOBS: i64 = 0
56const AF_BAND_OK: i64 = 1
57const AF_BAND_XCONT: i64 = 2
58// runtime fixture for the out-of-band bite: COUNTS ONLY, the only fields the band axes read. Its
59// joints count is far outside any rigged population the estate holds, so the tooth proves the joints
60// axis DISCRIMINATES rather than that the fixture is broken.
61const AF_FIX_VERTS: i64 = 7000
62const AF_FIX_TRIS: i64 = 14000
63const AF_FIX_JOINTS: i64 = 2
64const AF_FIX_NSEC: i64 = 3
65const AF_FIX_VERSION: i64 = 1
66const AF_WORD: i64 = 8
67const AF_ASCII_NL: i64 = 10
68const AF_ASCII_EQ: i64 = 61
69const AF_ASCII_ZERO: i64 = 48
70const AF_ASCII_NINE: i64 = 57
71const AF_DECIMAL: i64 = 10
72const AF_MISS: i64 = 0 - 1
73const AF_CORPUS_COMPLETE: i64 = 1
74const AF_TMPDIR_MODE: i64 = 493
75// the anthropometric bust-height BAND, in per-mille of the mesh's own vertical span. A LANDMARK,
76// not a picked floor: a bust bone sits near 744 permil of stature (front hemisphere) and the band
77// is +/- ~44 permil around it. Named so the two literals read as the anatomy they are.
78const AF_BUST_PERMIL_LO: i64 = 700
79const AF_BUST_PERMIL_HI: i64 = 790
80
81func af_rd64(b: *u8, off: i64) -> i64 {
82 var v: i64 = 0
83 var i: i64 = 7
84 while i >= 0 { v = v*256 + ((b[off + i] & 0xff) as i64); i = i - 1 }
85 return v
86}
87func af_tag(b: *u8, off: i64, t: *u8) -> i64 {
88 var i: i64 = 0
89 while i < 4 { if b[off + i] != t[i] { return 0 } i = i + 1 }
90 return 1
91}
92// section offset by tag, or -1
93func af_find(b: *u8, nsec: i64, t: *u8) -> i64 {
94 var s: i64 = 0
95 while s < nsec {
96 let e: i64 = AF_HDR + s*AF_SECHDR
97 if af_tag(b, e, t) == 1 { return af_rd64(b, e + 8) }
98 s = s + 1
99 }
100 return 0 - 1
101}
102// LINE-ANCHORED equals-separated conf read (key=value). Anchoring matters: an unanchored match
103// would read a number out of the conf's prose header and answer with the wrong bound. Returns
104// AF_MISS when the key is absent, so "not in the conf" and "legitimately zero" never collapse.
105func af_conf_int(path: *u8, key: *u8, miss: i64) -> i64 {
106 let lp: *i64 = sys_mmap(16) as *i64
107 let b: *u8 = sys_read_file(path, lp)
108 if (b as i64) == 0 { return miss }
109 let n: i64 = lp[0]
110 var klen: i64 = 0
111 while key[klen] != (0 as u8) { klen = klen + 1 }
112 var i: i64 = 0
113 var at_line_start: i64 = 1
114 var found: i64 = 0
115 var result: i64 = miss
116 while i < n {
117 if found == 0 { if at_line_start == 1 {
118 var matched: i64 = 1
119 var k: i64 = 0
120 while k < klen {
121 if i + k >= n { matched = 0 }
122 if matched == 1 { if b[i + k] != key[k] { matched = 0 } }
123 k = k + 1
124 }
125 if matched == 1 { if i + klen < n { if b[i + klen] == AF_ASCII_EQ {
126 var o: i64 = i + klen + 1
127 var v: i64 = 0
128 var digits: i64 = 0
129 var scanning: i64 = 1
130 while scanning == 1 {
131 if o >= n { scanning = 0 }
132 if scanning == 1 {
133 let c: i64 = (b[o] & 0xff) as i64
134 if c < AF_ASCII_ZERO { scanning = 0 }
135 if c > AF_ASCII_NINE { scanning = 0 }
136 if scanning == 1 { v = v*AF_DECIMAL + (c - AF_ASCII_ZERO); digits = digits + 1; o = o + 1 }
137 }
138 }
139 if digits > 0 { result = v; found = 1 }
140 } } }
141 } }
142 if b[i] == AF_ASCII_NL { at_line_start = 1 } else { at_line_start = 0 }
143 i = i + 1
144 }
145 return result
146}
147// af_tris_band retired with the container-matched rewire: bands come from af_rig_band, and the
148// donor (form) conf is a reference line only.
149// Read one floor BAND [kmin..kmax] from a rigfloor conf for an NXANIM01 subject. Three outcomes,
150// and the reason travels with each: AF_BAND_OK (container==1, corpus_complete==1, both keys
151// present, lo/hi filled) . AF_BAND_XCONT (conf complete but container!=1 -- a FORM floor cannot
152// grade a RIG; nx_rigfloor refuses this too) . AF_BAND_UNOBS (absent, incomplete, or a key missing).
153// Only OK may feed a verdict; the other two make the axis ABSTAIN by name.
154func af_rig_band(path: *u8, kmin: *u8, kmax: *u8, lo: *i64, hi: *i64) -> i64 {
155 let cc: i64 = af_conf_int(path, "corpus_complete" as *u8, AF_MISS)
156 if cc != AF_CORPUS_COMPLETE { return AF_BAND_UNOBS }
157 let cont: i64 = af_conf_int(path, "container" as *u8, AF_MISS)
158 if cont != AF_CONTAINER_NXA { return AF_BAND_XCONT }
159 let vlo: i64 = af_conf_int(path, kmin, AF_MISS)
160 let vhi: i64 = af_conf_int(path, kmax, AF_MISS)
161 if vlo == AF_MISS { return AF_BAND_UNOBS }
162 if vhi == AF_MISS { return AF_BAND_UNOBS }
163 lo[0] = vlo
164 hi[0] = vhi
165 return AF_BAND_OK
166}
167func af_in_band(v: i64, lo: i64, hi: i64) -> i64 {
168 if v < lo { return 0 }
169 if v > hi { return 0 }
170 return 1
171}
172// one axis: print the band with its source+container and CHECK it, or print the named abstention.
173// Returns the band code so the caller can state coverage.
174func af_axis(name: *u8, tooth: *u8, v: i64, kmin: *u8, kmax: *u8, ctr: *i64) -> i64 {
175 let band: *i64 = sys_mmap(16) as *i64
176 let code: i64 = af_rig_band(AF_RIG_CONF, kmin, kmax, band, ((band as i64) + 8) as *i64)
177 gv_puts(" " as *u8); gv_puts(name)
178 if code == AF_BAND_OK {
179 gv_puts(" floor [" as *u8); gv_num(band[0]); gv_puts(".." as *u8); gv_num(band[1])
180 gv_puts("] source=" as *u8); gv_puts(AF_RIG_CONF)
181 gv_puts(" (rig corpus, container=" as *u8); gv_num(AF_CONTAINER_NXA)
182 gv_puts(") measured=" as *u8); gv_num(v); gv_puts("\n" as *u8)
183 gv_check(tooth, af_in_band(v, band[0], band[1]), ctr)
184 }
185 if code == AF_BAND_XCONT {
186 gv_puts(" axis: UNOBSERVABLE-container-mismatch (" as *u8); gv_puts(AF_RIG_CONF)
187 gv_puts(" is not container=1; a form floor cannot grade a rig) -- measured " as *u8); gv_num(v); gv_puts("\n" as *u8)
188 }
189 if code == AF_BAND_UNOBS {
190 gv_puts(" axis: UNOBSERVABLE-no-rig-floor (" as *u8); gv_puts(AF_RIG_CONF)
191 gv_puts(" absent, corpus_complete!=1, or band missing) -- abstaining, NOT passing on a picked default; measured " as *u8); gv_num(v); gv_puts("\n" as *u8)
192 }
193 return code
194}
195func af_wr64(b: *u8, off: i64, v: i64) -> i64 {
196 var n: i64 = v
197 var i: i64 = 0
198 while i < AF_WORD { b[off + i] = (n & 0xff) as u8; n = n >> 8; i = i + 1 }
199 return 0
200}
201// a structurally minimal NXANIM01 at RUNTIME: magic, version, section count, three section headers
202// (VERT/TRIS/SKEL) and the COUNT word of each -- the only fields the band axes read. Under /tmp so no
203// detector finds the pattern in source and no production beat shares the fixture.
204func af_write_fixture(path: *u8, nv: i64, nt: i64, nj: i64) -> i64 {
205 let total: i64 = AF_HDR + AF_FIX_NSEC*AF_SECHDR + AF_FIX_NSEC*AF_WORD
206 let b: *u8 = sys_mmap(total)
207 var i: i64 = 0
208 while i < total { b[i] = 0 as u8; i = i + 1 }
209 let mg: *u8 = "NXANIM01" as *u8
210 var k: i64 = 0
211 while k < 8 { b[k] = mg[k]; k = k + 1 }
212 af_wr64(b, 8, AF_FIX_VERSION)
213 af_wr64(b, 16, AF_FIX_NSEC)
214 let data: i64 = AF_HDR + AF_FIX_NSEC*AF_SECHDR
215 let h0: i64 = AF_HDR
216 let h1: i64 = AF_HDR + AF_SECHDR
217 let h2: i64 = AF_HDR + AF_SECHDR*2
218 let tv: *u8 = "VERT" as *u8
219 let tt: *u8 = "TRIS" as *u8
220 let tk: *u8 = "SKEL" as *u8
221 var c: i64 = 0
222 while c < 4 { b[h0 + c] = tv[c]; b[h1 + c] = tt[c]; b[h2 + c] = tk[c]; c = c + 1 }
223 af_wr64(b, h0 + 8, data)
224 af_wr64(b, h0 + 16, 1)
225 af_wr64(b, h1 + 8, data + AF_WORD)
226 af_wr64(b, h1 + 16, 1)
227 af_wr64(b, h2 + 8, data + AF_WORD*2)
228 af_wr64(b, h2 + 16, 1)
229 af_wr64(b, data, nv)
230 af_wr64(b, data + AF_WORD, nt)
231 af_wr64(b, data + AF_WORD*2, nj)
232 let fd: i64 = sys_openat_wr(path, MODE_0644)
233 if fd < 0 { return 0 - 1 }
234 let wr: i64 = sys_write(fd, b, total)
235 sys_close(fd)
236 if wr != total { return 0 - 1 }
237 return total
238}
239// read the three counts of an NXANIM01 file the same way main does (af_find + af_rd64)
240func af_counts(path: *u8, out: *i64) -> i64 {
241 let lp: *i64 = sys_mmap(16) as *i64
242 let b: *u8 = sys_read_file(path, lp)
243 if (b as i64) == 0 { return 0 }
244 let nsec: i64 = af_rd64(b, 16)
245 let ov: i64 = af_find(b, nsec, "VERT" as *u8)
246 let ot: i64 = af_find(b, nsec, "TRIS" as *u8)
247 let ok: i64 = af_find(b, nsec, "SKEL" as *u8)
248 if ov < 0 { return 0 }
249 if ot < 0 { return 0 }
250 if ok < 0 { return 0 }
251 out[0] = af_rd64(b, ov)
252 out[1] = af_rd64(b, ot)
253 out[2] = af_rd64(b, ok)
254 return 1
255}
256func af_report(name: *u8, present: i64) -> i64 {
257 gv_puts(" " as *u8)
258 gv_puts(name)
259 if present == 1 { gv_puts(": PRESENT\n" as *u8) } else { gv_puts(": ABSENT -- gap to the floor\n" as *u8) }
260 return present
261}
262
263func main(argc: i64, argv: *i64) -> i64 {
264 let ctr: *i64 = gv_ctr()
265 gv_head("nx_asset_floor gate -- our shipped character measured against a game-ready floor" as *u8)
266 // ★ THE ASSET UNDER TEST IS AN ARGUMENT. A gate that can only ever read ONE hardcoded path
267 // cannot measure a candidate against the shipped one, so it can never PROVE an improvement --
268 // it can only ever describe the status quo. Defaults to the shipped asset when given nothing.
269 var apath: *u8 = AF_PATH
270 if argc >= 2 { apath = argv[1] as *u8 }
271 gv_puts(" asset: " as *u8); gv_puts(apath); gv_puts("\n" as *u8)
272 let lp: *i64 = sys_mmap(16) as *i64
273 let b: *u8 = sys_read_file(apath, lp)
274 if (b as i64) == 0 {
275 gv_puts(" cannot read the character asset\n" as *u8)
276 gv_check("asset present" as *u8, 0, ctr)
277 let rcx: i64 = gv_verdict("ASSET-FLOOR" as *u8, ctr, "no asset" as *u8)
278 sys_exit(rcx)
279 return rcx
280 }
281 let n: i64 = lp[0]
282 gv_puts(" container bytes=" as *u8); gv_num(n); gv_puts("\n" as *u8)
283 var magic: i64 = 1
284 let mg: *u8 = "NXANIM01" as *u8
285 var i: i64 = 0
286 while i < 8 { if b[i] != mg[i] { magic = 0 } i = i + 1 }
287 gv_check("container magic is NXANIM01" as *u8, magic, ctr)
288 if magic == 0 {
289 let rcm: i64 = gv_verdict("ASSET-FLOOR" as *u8, ctr, "bad container" as *u8)
290 sys_exit(rcm)
291 return rcm
292 }
293 let nsec: i64 = af_rd64(b, 16)
294 gv_puts(" sections=" as *u8); gv_num(nsec); gv_puts("\n" as *u8)
295 // ★A CAPABILITY REPORT THAT ONLY NAMES WHAT IT LOOKED FOR CANNOT TELL YOU WHAT YOU HAVE.
296 // This gate checked 7 tags against an asset carrying 11 sections, so four were invisible to
297 // its own inventory -- and the texture-capability question ("does this mesh carry UVs at all?")
298 // lives in exactly that blind spot. Enumerate every tag the file declares, then answer.
299 gv_puts(" declared tags:" as *u8)
300 let tagbuf: *u8 = sys_mmap(8)
301 var si: i64 = 0
302 while si < nsec {
303 let se: i64 = AF_HDR + si*AF_SECHDR
304 gv_puts(" " as *u8)
305 var ci: i64 = 0
306 while ci < 4 { tagbuf[ci] = b[se + ci]; ci = ci + 1 }
307 tagbuf[4] = 0
308 gv_puts(tagbuf)
309 gv_puts(":" as *u8); gv_num(af_rd64(b, se + 16))
310 si = si + 1
311 }
312 gv_puts("\n" as *u8)
313
314 // ---- geometry the floor requires ----
315 let ov: i64 = af_find(b, nsec, "VERT" as *u8)
316 let ot: i64 = af_find(b, nsec, "TRIS" as *u8)
317 let ok9: i64 = af_find(b, nsec, "SKEL" as *u8)
318 var nv: i64 = 0
319 var nt: i64 = 0
320 var nj: i64 = 0
321 if ov >= 0 { nv = af_rd64(b, ov) }
322 if ot >= 0 { nt = af_rd64(b, ot) }
323 if ok9 >= 0 { nj = af_rd64(b, ok9) }
324 gv_puts(" verts=" as *u8); gv_num(nv)
325 gv_puts(" tris=" as *u8); gv_num(nt)
326 gv_puts(" joints=" as *u8); gv_num(nj); gv_puts("\n" as *u8)
327 // ---- THE FLOOR: every band MEASURED from the container-matched RIG corpus, never declared ----
328 let c_v: i64 = af_axis("verts" as *u8, "vertex count inside the measured rig-corpus band" as *u8, nv, "verts_min" as *u8, "verts_max" as *u8, ctr)
329 let c_t: i64 = af_axis("tris" as *u8, "triangle count inside the measured rig-corpus band" as *u8, nt, "tris_min" as *u8, "tris_max" as *u8, ctr)
330 let c_j: i64 = af_axis("joints" as *u8, "joint count inside the measured rig-corpus band" as *u8, nj, "joints_min" as *u8, "joints_max" as *u8, ctr)
331 // SCALE-FREE axes: a larger or smaller character is still the same KIND of character
332 var tpv: i64 = 0
333 if nv > 0 { tpv = nt*AF_PERMIL/nv }
334 var vpj: i64 = 0
335 if nj > 0 { vpj = nv/nj }
336 let c_p: i64 = af_axis("tris_per_vert_permil" as *u8, "tris-per-vertex ratio inside the measured rig-corpus band" as *u8, tpv, "tris_per_vert_permil_min" as *u8, "tris_per_vert_permil_max" as *u8, ctr)
337 let c_r: i64 = af_axis("verts_per_joint" as *u8, "verts-per-joint ratio inside the measured rig-corpus band" as *u8, vpj, "verts_per_joint_min" as *u8, "verts_per_joint_max" as *u8, ctr)
338 var axes_measured: i64 = 0
339 if c_v == AF_BAND_OK { axes_measured = axes_measured + 1 }
340 if c_t == AF_BAND_OK { axes_measured = axes_measured + 1 }
341 if c_j == AF_BAND_OK { axes_measured = axes_measured + 1 }
342 if c_p == AF_BAND_OK { axes_measured = axes_measured + 1 }
343 if c_r == AF_BAND_OK { axes_measured = axes_measured + 1 }
344 gv_puts(" floor axes measured=" as *u8); gv_num(axes_measured); gv_puts(" of 5 (any others ABSTAIN by name above)\n" as *u8)
345 // the DONOR (form) floor is a REFERENCE line only: container=2 cannot grade an NXANIM01 subject
346 let dlo: i64 = af_conf_int(AF_DONOR_CONF, "tris_min" as *u8, AF_MISS)
347 let dhi: i64 = af_conf_int(AF_DONOR_CONF, "tris_max" as *u8, AF_MISS)
348 let dcont: i64 = af_conf_int(AF_DONOR_CONF, "container" as *u8, AF_MISS)
349 if dlo != AF_MISS { if dhi != AF_MISS {
350 gv_puts(" donor-form reference (container=" as *u8); gv_num(dcont)
351 gv_puts(", NOT the ruler for an NXA subject, contributes to NO verdict): tris [" as *u8); gv_num(dlo); gv_puts(".." as *u8); gv_num(dhi)
352 gv_puts("] source=" as *u8); gv_puts(AF_DONOR_CONF); gv_puts("\n" as *u8)
353 } }
354 // The VR-budget CEILING the old AF_TRI_MAX encoded was a HARDWARE constraint (tris/frame / cast
355 // size), NOT a corpus observation -- merging it with the donor-corpus max would conflate two
356 // different quantities that happen to be numerically close. DEMOTED to informational; it
357 // re-arms only when a SOURCED tris/frame budget and cast size are declared (same precedent as
358 // charjudge.conf's demoted face axis: never re-arm on an unsourced number).
359 gv_puts(" vr-budget ceiling: UNOBSERVABLE-no-sourced-budget (needs a cited tris/frame + cast size to re-arm)\n" as *u8)
360
361 // ---- the capability gaps: reported whether present or not ----
362 gv_puts("\n -- capability inventory (absent rows ARE the roadmap) --\n" as *u8)
363 var have: i64 = 0
364 var want: i64 = 0
365 let gv1: i64 = af_find(b, nsec, "GVRT" as *u8)
366 var p1: i64 = 0
367 if gv1 >= 0 { p1 = 1 }
368 af_report("garment geometry (GVRT)" as *u8, p1)
369 have = have + p1
370 want = want + 1
371 let hs1: i64 = af_find(b, nsec, "HSTR" as *u8)
372 var p2: i64 = 0
373 if hs1 >= 0 { p2 = 1 }
374 af_report("hair strands (HSTR)" as *u8, p2)
375 have = have + p2
376 want = want + 1
377 let po1: i64 = af_find(b, nsec, "POSE" as *u8)
378 var p3: i64 = 0
379 if po1 >= 0 { p3 = 1 }
380 af_report("idle pose (POSE)" as *u8, p3)
381 have = have + p3
382 want = want + 1
383 // a commercial game-ready character ships these; ours does not yet. Named, not hidden.
384 let fa1: i64 = af_find(b, nsec, "FACE" as *u8)
385 var p4: i64 = 0
386 if fa1 >= 0 { p4 = 1 }
387 af_report("face geometry (FACE) -- we PAINT the face from ratios instead" as *u8, p4)
388 have = have + p4
389 want = want + 1
390 let mo1: i64 = af_find(b, nsec, "MORF" as *u8)
391 var p5: i64 = 0
392 if mo1 >= 0 { p5 = 1 }
393 af_report("blend shapes / morph targets (MORF) -- no expressions without these" as *u8, p5)
394 have = have + p5
395 want = want + 1
396 let tx1: i64 = af_find(b, nsec, "TEXM" as *u8)
397 var p6: i64 = 0
398 if tx1 >= 0 { p6 = 1 }
399 af_report("PBR texture maps (TEXM) -- we shade procedurally from genome" as *u8, p6)
400 have = have + p6
401 want = want + 1
402 let dy1: i64 = af_find(b, nsec, "DYNA" as *u8)
403 var p7: i64 = 0
404 if dy1 >= 0 { p7 = 1 }
405 af_report("per-bone physics declarations (DYNA)" as *u8, p7)
406 have = have + p7
407 want = want + 1
408 // ★ PRESENCE OF A SECTION IS NOT PRESENCE OF THE CAPABILITY. A DYNA section carrying two
409 // midline bones would satisfy "DYNA: PRESENT" while leaving soft tissue exactly as unriggable
410 // as before -- so the tooth is the LATERAL PAIR itself: one bone declared left of the midline
411 // and one right of it, each with a real anchor. That is what a spine chain cannot fake.
412 var latpair: i64 = 0
413 if dy1 >= 0 {
414 let ndb: i64 = af_rd64(b, dy1)
415 let dstr: i64 = af_rd64(b, dy1 + 8)
416 gv_puts(" DYNA bones=" as *u8); gv_num(ndb)
417 gv_puts(" stride=" as *u8); gv_num(dstr); gv_puts("\n" as *u8)
418 var sawL: i64 = 0
419 var sawR: i64 = 0
420 var d: i64 = 0
421 while d < ndb {
422 let db: i64 = dy1 + 16 + d*dstr*8
423 let dside: i64 = af_rd64(b, db)
424 let dx: i64 = af_rd64(b, db + 8)
425 let dz: i64 = af_rd64(b, db + 24)
426 let dk: i64 = af_rd64(b, db + 32)
427 let dmax: i64 = af_rd64(b, db + 48)
428 gv_puts(" bone side=" as *u8); gv_num(dside)
429 gv_puts(" x=" as *u8); gv_num(dx)
430 gv_puts(" z=" as *u8); gv_num(dz)
431 gv_puts(" k=" as *u8); gv_num(dk)
432 gv_puts(" travel=" as *u8); gv_num(dmax); gv_puts("\n" as *u8)
433 if dside < 0 { if dx < 0 { sawL = 1 } }
434 if dside > 0 { if dx > 0 { sawR = 1 } }
435 d = d + 1
436 }
437 if sawL == 1 { if sawR == 1 { latpair = 1 } }
438 }
439 gv_check("DYNA declares a LATERAL soft-tissue pair (not the spine)" as *u8, latpair, ctr)
440
441 // ---- SOFT-TISSUE BONES: the defect the anatomy probe already proved ----
442 // a bust bone would sit near 744 permil of stature, front hemisphere. Its ABSENCE is why
443 // the chest had to be driven at the vertex band instead of a joint.
444 // ★NORMALIZE ON THE VERTEX SPAN, exactly as the browser-side anatomy probe does. A first
445 // version normalized on the JOINT span and reported 5 bust-band joints where the browser
446 // reported none -- two instruments measuring the SAME asset and CONTRADICTING each other,
447 // purely because the joint ladder is shorter than the mesh (feet and crown carry no bones).
448 // A shared basis is what makes two probes corroborate instead of argue.
449 var bust: i64 = 0
450 var central: i64 = 0
451 var latL: i64 = 0
452 var latR: i64 = 0
453 if ok9 >= 0 { if ov >= 0 {
454 var zmin: i64 = 0
455 var zmax: i64 = 0
456 var first: i64 = 1
457 var vi: i64 = 0
458 while vi < nv {
459 let vz: i64 = af_rd64(b, ov + 8 + (vi*3 + 2)*8)
460 if first == 1 { zmin = vz; zmax = vz; first = 0 }
461 if vz < zmin { zmin = vz }
462 if vz > zmax { zmax = vz }
463 vi = vi + 1
464 }
465 let span: i64 = zmax - zmin
466 if span > 0 {
467 var j: i64 = 0
468 while j < nj {
469 let jb2: i64 = ok9 + 8 + j*64
470 let bz2: i64 = af_rd64(b, jb2 + 24)
471 let by2: i64 = af_rd64(b, jb2 + 16)
472 let permil: i64 = (bz2 - zmin)*1000/span
473 let bx2: i64 = af_rd64(b, jb2 + 8)
474 var ax2: i64 = bx2
475 if ax2 < 0 { ax2 = 0 - ax2 }
476 // CENTRAL vs LATERAL decides usability: a sternum/chest joint sits near the
477 // midline; a clavicle or shoulder sits far off it and would swing the ARM.
478 // Counting them together is how "the rig has bust joints" and "the rig has
479 // none" can both look true.
480 if permil >= AF_BUST_PERMIL_LO { if permil <= AF_BUST_PERMIL_HI { if by2 < 0 {
481 bust = bust + 1
482 if ax2 < AF_MIDLINE { central = central + 1 }
483 if ax2 >= AF_MIDLINE { if bx2 < 0 { latL = latL + 1 } }
484 if ax2 >= AF_MIDLINE { if bx2 > 0 { latR = latR + 1 } }
485 } } }
486 j = j + 1
487 }
488 }
489 } }
490 gv_puts(" bust-band joints (700..790 permil, front): " as *u8); gv_num(bust)
491 gv_puts(" | midline (spine/sternum chain): " as *u8); gv_num(central)
492 gv_puts(" | lateral L=" as *u8); gv_num(latL)
493 gv_puts(" R=" as *u8); gv_num(latR); gv_puts("\n" as *u8)
494 // a PAIR means one per side -- four same-side helpers must not pass as a pair
495 var skelpair: i64 = 0
496 if latL >= 1 { if latR >= 1 { skelpair = 1 } }
497 if skelpair == 1 {
498 gv_puts(" <- THE SKELETON CARRIES THE LATERAL PAIR (wired: skinned + tracked). The vertex-band\n" as *u8)
499 gv_puts(" chest workaround is now driving AROUND real bones -- route the spring onto them.\n" as *u8)
500 }
501 if skelpair == 0 {
502 gv_puts(" <- NO LATERAL PAIR IN THE SKELETON: real breast bones come in L/R pairs OFF the\n" as *u8)
503 gv_puts(" midline; midline joints at chest height are the SPINE chain. Soft tissue must\n" as *u8)
504 gv_puts(" then be driven at the vertex band (and nx_nxa_dyna can declare the pair).\n" as *u8)
505 }
506 gv_check("SKEL carries a lateral bust pair (one bone per side, off-midline, front)" as *u8, skelpair, ctr)
507
508 gv_puts("\n capability score: " as *u8); gv_num(have); gv_puts("/" as *u8); gv_num(want)
509 gv_puts(" -- every ABSENT row above is a named rung, not a hidden failure\n" as *u8)
510 // the floor gate PASSES on geometry and REPORTS capability: a red here would say the asset
511 // is broken, which it is not. What it lacks is coverage, and coverage is tracked as debt.
512 // ---- TEETH FOR THE CONF-DRIVEN FLOOR ITSELF ----
513 // These prove every axis ABSTAINS when it cannot see, rather than acquitting on a picked default,
514 // and that the bands DISCRIMINATE (an out-of-band asset fires, the shipped asset does not).
515 let afl: *i64 = sys_mmap(16) as *i64
516 sys_mkdir("/tmp/nx_asset_floor_gate" as *u8, AF_TMPDIR_MODE)
517 // outputs this block creates are removed FIRST -- a gate that is not idempotent reports on its
518 // first run and lies about every run after
519 sys_unlinkat("/tmp/nx_asset_floor_gate/incomplete.conf" as *u8)
520 sys_unlinkat("/tmp/nx_asset_floor_gate/xcont.conf" as *u8)
521 sys_unlinkat("/tmp/nx_asset_floor_gate/oob.nxa" as *u8)
522 // (a) the REAL rig conf must be observable on the joints band -- the whole change depends on it
523 let real_code: i64 = af_rig_band(AF_RIG_CONF, "joints_min" as *u8, "joints_max" as *u8, afl, ((afl as i64) + 8) as *i64)
524 var real_ok: i64 = 0
525 if real_code == AF_BAND_OK { real_ok = 1 }
526 gv_check("real-rig-conf-is-observable (container=1, corpus_complete, joints band present)" as *u8, real_ok, ctr)
527 // (b) ANTI-VACUITY: an ABSENT conf must make the axis abstain, never pass
528 let absent_code: i64 = af_rig_band("/tmp/nx_asset_floor_gate/definitely_absent.conf" as *u8, "joints_min" as *u8, "joints_max" as *u8, afl, ((afl as i64) + 8) as *i64)
529 var t_absent: i64 = 0
530 if absent_code == AF_BAND_UNOBS { t_absent = 1 }
531 gv_check("absent-conf-abstains-not-passes (UNOBSERVABLE, never a picked default)" as *u8, t_absent, ctr)
532 // (c) NEGATIVE CONTROL, paired via gv_bite: a conf that IS present, RIGHT container, but
533 // corpus_complete=0 is refused, while the real conf is accepted. Fixture at RUNTIME.
534 let incp: *u8 = "/tmp/nx_asset_floor_gate/incomplete.conf" as *u8
535 let icontent: *u8 = "corpus_complete=0\ncontainer=1\njoints_min=9\njoints_max=104\n" as *u8
536 var iclen: i64 = 0
537 while icontent[iclen] != (0 as u8) { iclen = iclen + 1 }
538 let ifd: i64 = sys_openat_wr(incp, MODE_0644)
539 if ifd >= 0 { sys_write(ifd, icontent, iclen); sys_close(ifd) }
540 let inc_code: i64 = af_rig_band(incp, "joints_min" as *u8, "joints_max" as *u8, afl, ((afl as i64) + 8) as *i64)
541 var fired_bad: i64 = 0
542 if inc_code == AF_BAND_UNOBS { fired_bad = 1 }
543 var fired_good: i64 = 1
544 if real_ok == 1 { fired_good = 0 }
545 gv_bite("neg-control-incomplete-corpus-refused-and-complete-corpus-accepted" as *u8, fired_bad, fired_good, ctr)
546 // (d) CONTAINER MISMATCH is its OWN abstention, distinct from absent/incomplete: a complete
547 // container=2 conf carrying every key must still refuse to grade an NXANIM01 subject.
548 let xcp: *u8 = "/tmp/nx_asset_floor_gate/xcont.conf" as *u8
549 let xcontent: *u8 = "corpus_complete=1\ncontainer=2\nverts_min=1\nverts_max=999999\ntris_min=1\ntris_max=9999999\njoints_min=1\njoints_max=9999\n" as *u8
550 var xclen: i64 = 0
551 while xcontent[xclen] != (0 as u8) { xclen = xclen + 1 }
552 let xfd: i64 = sys_openat_wr(xcp, MODE_0644)
553 if xfd >= 0 { sys_write(xfd, xcontent, xclen); sys_close(xfd) }
554 let xc_code: i64 = af_rig_band(xcp, "joints_min" as *u8, "joints_max" as *u8, afl, ((afl as i64) + 8) as *i64)
555 var t_xc: i64 = 0
556 if xc_code == AF_BAND_XCONT { t_xc = 1 }
557 gv_check("container-mismatch-conf-abstains-not-passes (a form floor cannot grade a rig)" as *u8, t_xc, ctr)
558 // (e) THE BANDS DISCRIMINATE: an NXANIM01 fixture with joints=2 lands OUT of the rig band while
559 // the shipped asset lands IN it. Paired via gv_bite so a band that admitted everything cannot score.
560 let oobp: *u8 = "/tmp/nx_asset_floor_gate/oob.nxa" as *u8
561 let wrote: i64 = af_write_fixture(oobp, AF_FIX_VERTS, AF_FIX_TRIS, AF_FIX_JOINTS)
562 let oobc: *i64 = sys_mmap(24) as *i64
563 let oob_read: i64 = af_counts(oobp, oobc)
564 var fix_ok: i64 = 0
565 if wrote > 0 { if oob_read == 1 { if oobc[2] == AF_FIX_JOINTS { fix_ok = 1 } } }
566 gv_check("setup-oob-fixture-written-and-reads-back-joints-as-declared (fixture reached the condition)" as *u8, fix_ok, ctr)
567 // re-read the REAL joints band right before using it -- never lean on a slot a sibling call may have touched
568 let jb_code: i64 = af_rig_band(AF_RIG_CONF, "joints_min" as *u8, "joints_max" as *u8, afl, ((afl as i64) + 8) as *i64)
569 var oob_fires: i64 = 0
570 var real_in: i64 = 0
571 if jb_code == AF_BAND_OK { if fix_ok == 1 {
572 if af_in_band(oobc[2], afl[0], afl[1]) == 0 { oob_fires = 1 }
573 if af_in_band(nj, afl[0], afl[1]) == 1 { real_in = 1 }
574 } }
575 gv_bite("neg-control-out-of-band-joints-fires-and-shipped-joints-admitted" as *u8, oob_fires, 1 - real_in, ctr)
576
577 let rc: i64 = gv_verdict("ASSET-FLOOR" as *u8, ctr, "geometry clears the floor; capability gaps enumerated" as *u8)
578 sys_exit(rc)
579 return rc
580}