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}