nx_xport_gate.nx source
↩ module page · 503 lines · 24216 B
1// nx_xport_gate.nx -- GATE for DC12: one authored asset into four consumers, measured by one ruler.
2//
3// The claim under test is not "the exporters run". It is that the geometry a consumer RECEIVES is the
4// geometry that was authored, within a bound that was derived rather than chosen. So every number below
5// comes back OUT OF AN ARTIFACT ON DISK, and the ruler is nx_mmdev's md_measure -- the estate's one
6// millimetre deviation ruler, already proven to read a known 5.0 mm lift as 5.0 mm.
7//
8// Three things make this more than a green light:
9// - a POSITIVE CONTROL: the source measured against ITSELF must read exactly zero on every axis, so the
10// ruler is known to be wired and oriented before any consumer claim rests on it;
11// - an ANTI-VACUITY tooth: one vertex is moved a known 3.0 mm and must be DETECTED at 3.0 mm, so a
12// comparator that always answered zero could not pass;
13// - a MIRROR that has ZERO deviation and is still wrong. It is here because it proves the deviation
14// ruler alone is insufficient, which is the entire reason orientation and scale are separate axes.
15//
16// The fixture is assembled at RUNTIME under /tmp/nx_xport_gate so this gate never shares scratch with a
17// production beat, and it is idempotent: re-running overwrites its own artifacts and asserts nothing
18// about what was there before.
19//
20// license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0
21
22import "nx_syscalls.nx"
23import "nx_gate_verdict.nx"
24import "nx_vecmath.nx"
25import "nx_nxmesh_lib.nx"
26import "nx_mmdev_lib.nx"
27import "nx_xport_lib.nx"
28
29const XG_DIR: *u8 = "/tmp/nx_xport_gate"
30const XG_EMPTY: *u8 = "/tmp/nx_xport_gate/empty"
31const XG_MODE_0755: i64 = 493
32
33// A human-scale subject in tenths of a millimetre: 400 mm x 1700 mm x 250 mm. Every side is an exact
34// multiple of the subdivision, which a tooth asserts -- an inexact division would bow each face out of
35// plane and quietly change what "the same geometry" means.
36const XG_SUB: i64 = 4
37const XG_BX: i64 = 4000
38const XG_BY: i64 = 17000
39const XG_BZ: i64 = 2500
40const XG_FACES: i64 = 6
41
42// 3.0 mm: an order of magnitude above every bound this gate derives, so the anti-vacuity tooth cannot be
43// passed by a comparator that is merely noisy.
44const XG_PERT: i64 = 30
45// The interior grid node of the +X face that gets moved. Strictly inside the face for XG_SUB = 4, which a
46// tooth asserts rather than assumes.
47const XG_PI: i64 = 1
48const XG_PJ: i64 = 1
49const XG_FACE_PX: i64 = 3
50// Two tenths of a millimetre. The perturbation crosses the NXMSH2 float32 codec twice at 0.1 mm
51// resolution (half a unit each way, the figure nx_mmdev_gate uses) and md_measure's isqrt floors, so a
52// measured 3.0 mm can legitimately land one or two units either side of 30.
53const XG_SLACK: i64 = 2
54// The rescale used as the scale neg-control: 5/4 keeps the subject inside the ruler's 2.5 m extent bound
55// while moving the tallest axis by 4250 units, far past any quantisation.
56const XG_SCALE_NUM: i64 = 5
57const XG_SCALE_DEN: i64 = 4
58
59func xg_tpf() -> i64 { return 2 * XG_SUB * XG_SUB }
60func xg_ntris() -> i64 { return XG_FACES * xg_tpf() }
61func xg_pert_tri() -> i64 { return XG_FACE_PX * xg_tpf() + 2 * (XG_PJ * XG_SUB + XG_PI) }
62
63// Six faces as DATA: origin, then two edge vectors u and v whose cross product points OUT of the box.
64// A quad wound P(i,j) -> P(i+1,j) -> P(i+1,j+1) therefore has an outward normal on every face, which is
65// what makes the signed volume positive and the mirror neg-control meaningful.
66func xg_facetab(t: *i64) -> i64 {
67 t[0]=0; t[1]=0; t[2]=0; t[3]=0; t[4]=XG_BY; t[5]=0; t[6]=XG_BX; t[7]=0; t[8]=0
68 t[9]=0; t[10]=0; t[11]=XG_BZ; t[12]=XG_BX; t[13]=0; t[14]=0; t[15]=0; t[16]=XG_BY; t[17]=0
69 t[18]=0; t[19]=0; t[20]=0; t[21]=0; t[22]=0; t[23]=XG_BZ; t[24]=0; t[25]=XG_BY; t[26]=0
70 t[27]=XG_BX; t[28]=0; t[29]=0; t[30]=0; t[31]=XG_BY; t[32]=0; t[33]=0; t[34]=0; t[35]=XG_BZ
71 t[36]=0; t[37]=0; t[38]=0; t[39]=XG_BX; t[40]=0; t[41]=0; t[42]=0; t[43]=0; t[44]=XG_BZ
72 t[45]=0; t[46]=XG_BY; t[47]=0; t[48]=0; t[49]=0; t[50]=XG_BZ; t[51]=XG_BX; t[52]=0; t[53]=0
73 return 0
74}
75func xg_pt(t: *i64, f: i64, a: i64, b: i64, axis: i64) -> i64 {
76 return t[f*9+axis] + t[f*9+3+axis]*a/XG_SUB + t[f*9+6+axis]*b/XG_SUB
77}
78
79func xg_box(buf: *u8) -> i64 {
80 let nt: i64 = xg_ntris()
81 nm_put_u32(buf, NM_OFF_NLAYERS, 0)
82 nm_put_u32(buf, NM_OFF_NTRIS, nt)
83 let tb: i64 = nm_tri_base(buf)
84 let ft: *i64 = sys_mmap(XG_FACES*9*8) as *i64
85 xg_facetab(ft)
86 let p: *i64 = sys_mmap(9*8) as *i64
87 var t: i64 = 0
88 var f: i64 = 0
89 while f < XG_FACES {
90 var j: i64 = 0
91 while j < XG_SUB {
92 var i: i64 = 0
93 while i < XG_SUB {
94 var a: i64 = 0
95 while a < 3 {
96 p[a] = xg_pt(ft, f, i, j, a)
97 p[3+a] = xg_pt(ft, f, i+1, j, a)
98 p[6+a] = xg_pt(ft, f, i+1, j+1, a)
99 a = a + 1
100 }
101 nm_put_tri(buf, tb, t, p)
102 t = t + 1
103 a = 0
104 while a < 3 {
105 p[a] = xg_pt(ft, f, i, j, a)
106 p[3+a] = xg_pt(ft, f, i+1, j+1, a)
107 p[6+a] = xg_pt(ft, f, i, j+1, a)
108 a = a + 1
109 }
110 nm_put_tri(buf, tb, t, p)
111 t = t + 1
112 i = i + 1
113 }
114 j = j + 1
115 }
116 f = f + 1
117 }
118 return t
119}
120
121func xg_copy(src: *u8, dst: *u8) -> i64 {
122 let nt: i64 = nm_ntris(src)
123 let n: i64 = nm_file_bytes(nm_nlayers(src), nt)
124 var i: i64 = 0
125 while i < n { dst[i] = src[i]; i = i + 1 }
126 return n
127}
128
129// Move ONE interior vertex of the +X face outward by a known amount.
130func xg_perturb(buf: *u8) -> i64 {
131 let tb: i64 = nm_tri_base(buf)
132 let t: i64 = xg_pert_tri()
133 let p: *i64 = sys_mmap(9*8) as *i64
134 var v: i64 = 0
135 while v < 3 {
136 var a: i64 = 0
137 while a < 3 { p[v*3+a] = nm_coord(buf, tb, t, v, a); a = a + 1 }
138 v = v + 1
139 }
140 p[0] = p[0] + XG_PERT
141 nm_put_tri(buf, tb, t, p)
142 return 0
143}
144
145// Reflect about the box's own centre plane in x. The SET of points is unchanged, so the deviation ruler
146// reads zero -- and every triangle's winding is reversed, so the enclosed volume changes sign.
147func xg_mirror(src: *u8, dst: *u8) -> i64 {
148 let nt: i64 = nm_ntris(src)
149 nm_put_u32(dst, NM_OFF_NLAYERS, 0)
150 nm_put_u32(dst, NM_OFF_NTRIS, nt)
151 let sb: i64 = nm_tri_base(src)
152 let db: i64 = nm_tri_base(dst)
153 let p: *i64 = sys_mmap(9*8) as *i64
154 var t: i64 = 0
155 while t < nt {
156 var v: i64 = 0
157 while v < 3 {
158 p[v*3] = XG_BX - nm_coord(src, sb, t, v, 0)
159 p[v*3+1] = nm_coord(src, sb, t, v, 1)
160 p[v*3+2] = nm_coord(src, sb, t, v, 2)
161 v = v + 1
162 }
163 nm_put_tri(dst, db, t, p)
164 t = t + 1
165 }
166 return 0
167}
168
169func xg_rescale(src: *u8, dst: *u8) -> i64 {
170 let nt: i64 = nm_ntris(src)
171 nm_put_u32(dst, NM_OFF_NLAYERS, 0)
172 nm_put_u32(dst, NM_OFF_NTRIS, nt)
173 let sb: i64 = nm_tri_base(src)
174 let db: i64 = nm_tri_base(dst)
175 let p: *i64 = sys_mmap(9*8) as *i64
176 var t: i64 = 0
177 while t < nt {
178 var v: i64 = 0
179 while v < 3 {
180 var a: i64 = 0
181 while a < 3 { p[v*3+a] = nm_coord(src, sb, t, v, a) * XG_SCALE_NUM / XG_SCALE_DEN; a = a + 1 }
182 v = v + 1
183 }
184 nm_put_tri(dst, db, t, p)
185 t = t + 1
186 }
187 return 0
188}
189
190func xg_eq(a: i64, b: i64) -> i64 { if a == b { return 1 } return 0 }
191func xg_near(a: i64, b: i64) -> i64 {
192 var d: i64 = a - b
193 if d < 0 { d = 0 - d }
194 if d <= XG_SLACK { return 1 }
195 return 0
196}
197
198// Print everything this consumer measured, then five uniquely-named teeth. The values are printed whether
199// the teeth pass or not, because a verdict vector cannot say WHY.
200func xg_report(res: *i64, c: i64) -> i64 {
201 gv_puts(" " as *u8); gv_puts(xp_name(c))
202 gv_puts(" bytes=" as *u8); gv_num(xp_rg(res, c, XP_R_BYTES))
203 gv_puts(" verts=" as *u8); gv_num(xp_rg(res, c, XP_R_VERTS))
204 gv_puts(" tris " as *u8); gv_num(xp_rg(res, c, XP_R_TRIS_SRC))
205 gv_puts("->" as *u8); gv_num(xp_rg(res, c, XP_R_TRIS_REC))
206 gv_puts(" | dev A->B mean=" as *u8); gv_num(xp_rg(res, c, XP_R_MEAN_AB))
207 gv_puts(" p95=" as *u8); gv_num(xp_rg(res, c, XP_R_P95_AB))
208 gv_puts(" max=" as *u8); gv_num(xp_rg(res, c, XP_R_MAX_AB))
209 gv_puts(" | B->A mean=" as *u8); gv_num(xp_rg(res, c, XP_R_MEAN_BA))
210 gv_puts(" p95=" as *u8); gv_num(xp_rg(res, c, XP_R_P95_BA))
211 gv_puts(" max=" as *u8); gv_num(xp_rg(res, c, XP_R_MAX_BA))
212 gv_puts(" (tenths of a mm)\n bound=" as *u8); gv_num(xp_rg(res, c, XP_R_BOUND))
213 gv_puts(" = ceil(sqrt3 * axis), axis=" as *u8); gv_num(xp_rg(res, c, XP_R_AXIS))
214 gv_puts(" = quant " as *u8); gv_num(xp_rg(res, c, XP_R_AXISQ))
215 gv_puts(" + f32 " as *u8); gv_num(xp_rg(res, c, XP_R_AXISF))
216 gv_puts(" | extent delta=" as *u8); gv_num(xp_rg(res, c, XP_R_EXT_DELTA))
217 gv_puts("/" as *u8); gv_num(xp_rg(res, c, XP_R_EXT_BOUND))
218 gv_puts(" | vol sign_ok=" as *u8); gv_num(xp_rg(res, c, XP_R_VOLSIGN_OK))
219 gv_puts(" permil=" as *u8); gv_num(xp_rg(res, c, XP_R_VOL_PERMIL))
220 gv_puts("/" as *u8); gv_num(xp_rg(res, c, XP_R_VOL_PERMIL_BOUND))
221 gv_puts(" | why=" as *u8); gv_num(xp_rg(res, c, XP_R_WHY))
222 gv_puts(" pass=" as *u8); gv_num(xp_rg(res, c, XP_R_PASS))
223 gv_puts("\n" as *u8)
224 return 0
225}
226
227func xg_teeth(res: *i64, c: i64, n1: *u8, n2: *u8, n3: *u8, n4: *u8, n5: *u8, ctr: *i64) -> i64 {
228 let bnd: i64 = xp_rg(res, c, XP_R_BOUND)
229 var devok: i64 = 0
230 if xp_rg(res, c, XP_R_MAX_AB) <= bnd { if xp_rg(res, c, XP_R_MAX_BA) <= bnd { devok = 1 } }
231 if xp_rg(res, c, XP_R_WHY) != XP_WHY_OK { devok = 0 }
232 gv_check(n1, xg_eq(xp_rg(res, c, XP_R_TRIS_REC), xp_rg(res, c, XP_R_TRIS_SRC)), ctr)
233 gv_check(n2, devok, ctr)
234 gv_check(n3, xg_eq(xp_rg(res, c, XP_R_VOLSIGN_OK), 1), ctr)
235 var extok: i64 = 0
236 let ed: i64 = xp_rg(res, c, XP_R_EXT_DELTA)
237 if ed >= 0 { if ed <= xp_rg(res, c, XP_R_EXT_BOUND) { extok = 1 } }
238 gv_check(n4, extok, ctr)
239 var volok: i64 = 0
240 let vpb: i64 = xp_rg(res, c, XP_R_VOL_PERMIL_BOUND)
241 if vpb >= 0 { if xp_rg(res, c, XP_R_VOL_PERMIL) <= vpb { volok = 1 } }
242 gv_check(n5, volok, ctr)
243 return 0
244}
245
246func main() -> i64 {
247 let c: *i64 = gv_ctr()
248 gv_head("NX-XPORT-GATE -- DC12: one authored asset into four consumers, one ruler" as *u8)
249
250 sys_mkdir(XG_DIR, XG_MODE_0755)
251 sys_mkdir(XG_EMPTY, XG_MODE_0755)
252
253 // ---- fixture -------------------------------------------------------------------------------
254 let nt: i64 = xg_ntris()
255 let mb: i64 = nm_file_bytes(0, nt)
256 let src: *u8 = sys_mmap(mb + 16)
257 let built: i64 = xg_box(src)
258 let bb: *i64 = sys_mmap(6*8) as *i64
259 xp_aabb(src, bb)
260 let ext: i64 = xp_extent(bb)
261 gv_puts(" fixture: subdivided box " as *u8); gv_num(XG_BX); gv_puts("x" as *u8); gv_num(XG_BY)
262 gv_puts("x" as *u8); gv_num(XG_BZ); gv_puts(" tenths-mm, sub=" as *u8); gv_num(XG_SUB)
263 gv_puts(", tris=" as *u8); gv_num(built); gv_puts(", extent=" as *u8); gv_num(ext)
264 gv_puts("/" as *u8); gv_num(MD_EXTENT_MAX); gv_puts("\n" as *u8)
265
266 var emitted: i64 = 0
267 if built == nt { if nm_ntris(src) == nt { emitted = 1 } }
268 gv_check("fixture-box-emits-every-declared-triangle" as *u8, emitted, c)
269
270 var divok: i64 = 0
271 if XG_BX % XG_SUB == 0 { if XG_BY % XG_SUB == 0 { if XG_BZ % XG_SUB == 0 { divok = 1 } } }
272 gv_check("fixture-face-grid-divides-exactly-so-every-face-stays-planar" as *u8, divok, c)
273
274 var extok: i64 = 0
275 if ext > 0 { if ext <= MD_EXTENT_MAX { extok = 1 } }
276 gv_check("fixture-extent-inside-the-rulers-own-declared-bound" as *u8, extok, c)
277
278 // The perturbation target must be an INTERIOR vertex of the +X face, or the anti-vacuity tooth
279 // would be measuring an edge case instead of a face offset.
280 let stb: i64 = nm_tri_base(src)
281 let pvx: i64 = nm_coord(src, stb, xg_pert_tri(), 0, 0)
282 let pvy: i64 = nm_coord(src, stb, xg_pert_tri(), 0, 1)
283 let pvz: i64 = nm_coord(src, stb, xg_pert_tri(), 0, 2)
284 gv_puts(" perturb target tri=" as *u8); gv_num(xg_pert_tri())
285 gv_puts(" v0=(" as *u8); gv_num(pvx); gv_puts("," as *u8); gv_num(pvy)
286 gv_puts("," as *u8); gv_num(pvz); gv_puts(") by +" as *u8); gv_num(XG_PERT); gv_puts(" in x\n" as *u8)
287 var tgtok: i64 = 0
288 if pvx == XG_BX { if pvy > 0 { if pvy < XG_BY { if pvz > 0 { if pvz < XG_BZ { tgtok = 1 } } } } }
289 gv_check("fixture-perturbation-target-is-an-interior-vertex-of-the-plus-x-face" as *u8, tgtok, c)
290
291 // ---- POSITIVE CONTROL: the ruler against itself ----------------------------------------------
292 let rself: *i64 = md_res()
293 let eself: i64 = md_measure(src, src, rself)
294 gv_puts(" pos-control self: rc=" as *u8); gv_num(eself)
295 gv_puts(" verts=" as *u8); gv_num(rself[MD_R_VERTS])
296 gv_puts(" mean=" as *u8); gv_num(md_mean(rself))
297 gv_puts(" p95=" as *u8); gv_num(rself[MD_R_P95])
298 gv_puts(" max=" as *u8); gv_num(rself[MD_R_MAX]); gv_puts("\n" as *u8)
299 var selfok: i64 = 0
300 if eself == 0 { if md_mean(rself) == 0 { if rself[MD_R_P95] == 0 { if rself[MD_R_MAX] == 0 { selfok = 1 } } } }
301 gv_check("pos-control-source-against-itself-reads-exactly-zero-on-every-axis" as *u8, selfok, c)
302 gv_check("pos-control-ruler-visited-every-triangle-vertex-of-the-source" as *u8,
303 xg_eq(rself[MD_R_VERTS], nt*3), c)
304
305 // ---- ANTI-VACUITY: a known 3.0 mm move must be seen as 3.0 mm --------------------------------
306 let pert: *u8 = sys_mmap(mb + 16)
307 xg_copy(src, pert)
308 xg_perturb(pert)
309 let rp: *i64 = md_res()
310 let ep: i64 = md_measure(pert, src, rp)
311 gv_puts(" anti-vacuity: perturbed->source rc=" as *u8); gv_num(ep)
312 gv_puts(" max=" as *u8); gv_num(rp[MD_R_MAX])
313 gv_puts(" expect " as *u8); gv_num(XG_PERT)
314 gv_puts(" +/-" as *u8); gv_num(XG_SLACK); gv_puts("\n" as *u8)
315 var pok: i64 = 0
316 if ep == 0 { if xg_near(rp[MD_R_MAX], XG_PERT) == 1 { pok = 1 } }
317 gv_check("anti-vacuity-a-known-3mm-perturbation-is-detected-at-3mm" as *u8, pok, c)
318 var fires_bad: i64 = 0
319 if rp[MD_R_MAX] > 0 { fires_bad = 1 }
320 var fires_good: i64 = 0
321 if rself[MD_R_MAX] > 0 { fires_good = 1 }
322 gv_bite("neg-control-ruler-fires-on-the-perturbed-copy-and-not-on-the-source" as *u8,
323 fires_bad, fires_good, c)
324
325 // ---- MIRROR: zero deviation and still wrong ---------------------------------------------------
326 let mir: *u8 = sys_mmap(mb + 16)
327 xg_mirror(src, mir)
328 let rm: *i64 = md_res()
329 let em: i64 = md_measure(mir, src, rm)
330 let sdiv: i64 = xp_vol_div(src, bb)
331 let svol: i64 = xp_vol6(src, bb, sdiv)
332 let mvol: i64 = xp_vol6(mir, bb, sdiv)
333 gv_puts(" mirror: dev max=" as *u8); gv_num(rm[MD_R_MAX])
334 gv_puts(" (rc=" as *u8); gv_num(em); gv_puts(") vol6 src=" as *u8); gv_num(svol)
335 gv_puts(" mirrored=" as *u8); gv_num(mvol); gv_puts("\n" as *u8)
336 var mzero: i64 = 0
337 if em == 0 { if rm[MD_R_MAX] == 0 { mzero = 1 } }
338 gv_check("mirror-has-zero-deviation-so-the-ruler-alone-cannot-catch-it" as *u8, mzero, c)
339 var msign_bad: i64 = 0
340 if svol > 0 { if mvol < 0 { msign_bad = 1 } }
341 if svol < 0 { if mvol > 0 { msign_bad = 1 } }
342 gv_bite("neg-control-mirror-is-caught-by-the-orientation-sign" as *u8, msign_bad, 0, c)
343
344 // ---- RESCALE: caught by the extent axis -------------------------------------------------------
345 let sc: *u8 = sys_mmap(mb + 16)
346 xg_rescale(src, sc)
347 let edsc: i64 = xp_ext_delta(src, sc)
348 let edself: i64 = xp_ext_delta(src, src)
349 let glaxis: i64 = xp_axis_bound(XP_GL_UNIT_PER_M)
350 gv_puts(" rescale 5/4: extent delta=" as *u8); gv_num(edsc)
351 gv_puts(" self=" as *u8); gv_num(edself)
352 gv_puts(" bound=" as *u8); gv_num(glaxis*2); gv_puts("\n" as *u8)
353 var sc_bad: i64 = 0
354 if edsc > glaxis*2 { sc_bad = 1 }
355 var sc_good: i64 = 0
356 if edself > glaxis*2 { sc_good = 1 }
357 gv_bite("neg-control-rescaled-mesh-is-caught-by-the-extent-check" as *u8, sc_bad, sc_good, c)
358
359 // ---- the derived bound is arithmetic, not a chosen tolerance ---------------------------------
360 gv_puts(" axis bounds: glb/obj=" as *u8); gv_num(xp_axis_bound(XP_GL_UNIT_PER_M))
361 gv_puts(" nxa=" as *u8); gv_num(xp_axis_bound(XP_NXA_UNIT_PER_M))
362 gv_puts(" nxmsh2=" as *u8); gv_num(xp_axis_bound(NM_UNIT_PER_M)); gv_puts("\n" as *u8)
363 var bderiv: i64 = 0
364 if xp_axis_bound(XP_GL_UNIT_PER_M) > 0 {
365 if xp_axis_bound(XP_NXA_UNIT_PER_M) == 0 {
366 if xp_axis_bound(NM_UNIT_PER_M) == 0 { bderiv = 1 }
367 }
368 }
369 gv_check("derived-bound-is-zero-exactly-when-the-consumer-unit-is-a-multiple-of-the-ruler-unit" as *u8,
370 bderiv, c)
371
372 // ---- EMIT, then MEASURE WHAT EACH CONSUMER RECEIVED -------------------------------------------
373 let res: *i64 = xp_res()
374 let reached: i64 = xp_emit_all(src, XG_DIR, res)
375 let fails: i64 = xp_consumers(src, XG_DIR, res)
376 gv_puts(" emit reached=" as *u8); gv_num(reached)
377 gv_puts(" of " as *u8); gv_num(XP_C_N)
378 gv_puts(" consumers, failing=" as *u8); gv_num(fails); gv_puts("\n" as *u8)
379 gv_check("emit-produced-an-artifact-for-every-reachable-consumer" as *u8, xg_eq(reached, 4), c)
380
381 xg_report(res, XP_C_STORE_GLB)
382 xg_report(res, XP_C_STORE_OBJ)
383 xg_report(res, XP_C_GAME_NXA)
384 xg_report(res, XP_C_CLINICAL)
385
386 gv_need("storefront-glb-artifact-present" as *u8, xp_rg(res, XP_C_STORE_GLB, XP_R_REACHED), c)
387 xg_teeth(res, XP_C_STORE_GLB,
388 "storefront-glb-triangle-count-preserved" as *u8,
389 "storefront-glb-max-deviation-within-derived-bound-both-directions" as *u8,
390 "storefront-glb-orientation-sign-preserved" as *u8,
391 "storefront-glb-aabb-extent-within-twice-the-axis-bound" as *u8,
392 "storefront-glb-volume-magnitude-within-derived-permil" as *u8, c)
393
394 gv_need("storefront-obj-artifact-present" as *u8, xp_rg(res, XP_C_STORE_OBJ, XP_R_REACHED), c)
395 xg_teeth(res, XP_C_STORE_OBJ,
396 "storefront-obj-triangle-count-preserved" as *u8,
397 "storefront-obj-max-deviation-within-derived-bound-both-directions" as *u8,
398 "storefront-obj-orientation-sign-preserved" as *u8,
399 "storefront-obj-aabb-extent-within-twice-the-axis-bound" as *u8,
400 "storefront-obj-volume-magnitude-within-derived-permil" as *u8, c)
401
402 gv_need("game-nxa-artifact-present" as *u8, xp_rg(res, XP_C_GAME_NXA, XP_R_REACHED), c)
403 xg_teeth(res, XP_C_GAME_NXA,
404 "game-nxa-triangle-count-preserved" as *u8,
405 "game-nxa-max-deviation-within-derived-bound-both-directions" as *u8,
406 "game-nxa-orientation-sign-preserved" as *u8,
407 "game-nxa-aabb-extent-within-twice-the-axis-bound" as *u8,
408 "game-nxa-volume-magnitude-within-derived-permil" as *u8, c)
409
410 gv_need("clinical-nxmsh2-artifact-present" as *u8, xp_rg(res, XP_C_CLINICAL, XP_R_REACHED), c)
411 xg_teeth(res, XP_C_CLINICAL,
412 "clinical-nxmsh2-triangle-count-preserved" as *u8,
413 "clinical-nxmsh2-max-deviation-within-derived-bound-both-directions" as *u8,
414 "clinical-nxmsh2-orientation-sign-preserved" as *u8,
415 "clinical-nxmsh2-aabb-extent-within-twice-the-axis-bound" as *u8,
416 "clinical-nxmsh2-volume-magnitude-within-derived-permil" as *u8, c)
417
418 // ---- VR: it ABSTAINS, and the abstention is re-measured, never inherited ----------------------
419 let vr2: *i64 = sys_mmap(4*8) as *i64
420 let vrs: i64 = xp_vr_still_unreached(vr2)
421 gv_puts(" vr-vrframe UNREACHED why=" as *u8); gv_num(xp_rg(res, XP_C_VR_FRAME, XP_R_WHY))
422 gv_puts(" (vf_build takes no mesh; it emits a PNG) source-recheck=" as *u8); gv_num(vrs)
423 gv_puts(" sig@" as *u8); gv_num(vr2[0]); gv_puts(" raster@" as *u8); gv_num(vr2[1])
424 gv_puts("\n" as *u8)
425 // DELIBERATELY NOT gv_need. A gv_need here reads "this gate could not test itself" and turns the
426 // whole run into a SKIP -- measured: it swallowed 38 real checks and reported that NOTHING had been
427 // proved. VR being unable to receive a mesh is not a missing precondition of this gate, it is one of
428 // the results this gate exists to publish, so it is ASSERTED as a fact about the live source instead.
429 gv_check("vr-abstention-is-still-true-of-the-live-vrframe-source" as *u8, xg_eq(vrs, 1), c)
430 gv_check("vr-abstains-with-a-named-reason-rather-than-scoring-zero" as *u8,
431 xg_eq(xp_rg(res, XP_C_VR_FRAME, XP_R_WHY), XP_WHY_NO_MESH_PARAM), c)
432
433 // ---- NEG-CONTROL: a missing artifact must ABSTAIN, not pass -----------------------------------
434 // Same four consumers marked reached, pointed at a directory nothing was ever written into.
435 let res2: *i64 = xp_res()
436 xp_rs(res2, XP_C_STORE_GLB, XP_R_REACHED, 1)
437 xp_rs(res2, XP_C_STORE_OBJ, XP_R_REACHED, 1)
438 xp_rs(res2, XP_C_GAME_NXA, XP_R_REACHED, 1)
439 xp_rs(res2, XP_C_CLINICAL, XP_R_REACHED, 1)
440 xp_consumers(src, XG_EMPTY, res2)
441 var miss_bad: i64 = 1
442 var cc: i64 = 0
443 while cc < XP_C_N {
444 if xp_rg(res2, cc, XP_R_REACHED) == 1 {
445 if xp_rg(res2, cc, XP_R_WHY) != XP_WHY_ARTIFACT_MISSING { miss_bad = 0 }
446 if xp_rg(res2, cc, XP_R_PASS) != 0 { miss_bad = 0 }
447 }
448 cc = cc + 1
449 }
450 var miss_good: i64 = 1
451 cc = 0
452 while cc < XP_C_N {
453 if xp_rg(res, cc, XP_R_REACHED) == 1 {
454 if xp_rg(res, cc, XP_R_WHY) != XP_WHY_ARTIFACT_MISSING { miss_good = 0 }
455 }
456 cc = cc + 1
457 }
458 gv_puts(" missing-artifact probe: empty-dir detector=" as *u8); gv_num(miss_bad)
459 gv_puts(" real-dir detector=" as *u8); gv_num(miss_good); gv_puts("\n" as *u8)
460 gv_bite("neg-control-missing-artifact-abstains-instead-of-passing" as *u8, miss_bad, miss_good, c)
461
462 // ---- NEG-CONTROL: a glb whose node scale is not the declared one must be REFUSED --------------
463 let gp: *u8 = sys_mmap(XP_PATH_CAP)
464 xp_path(XG_DIR, XP_F_GLB, gp)
465 let gl: *i64 = sys_mmap(16) as *i64
466 let graw: *u8 = sys_read_file(gp, gl)
467 var scale_bad: i64 = 0
468 var scale_good: i64 = 0
469 var trunc_bad: i64 = 0
470 var trunc_good: i64 = 0
471 let ro: *i64 = sys_mmap(4*8) as *i64
472 if (graw as i64) != 0 {
473 let gn: i64 = gl[0]
474 let cp: *u8 = sys_mmap(gn + 16)
475 var i: i64 = 0
476 while i < gn { cp[i] = graw[i]; i = i + 1 }
477 // change one digit inside the node scale so it no longer reads as the declared 1/1024
478 let sp: i64 = ge_find(cp, gn, XP_GLB_SCALE_LIT, xp_slen(XP_GLB_SCALE_LIT), 0)
479 if sp >= 0 {
480 cp[sp + xp_slen(XP_GLB_SCALE_LIT) - 2] = 55 as u8
481 let bad: *u8 = xp_recover(XP_C_STORE_GLB, cp, gn, ro)
482 if (bad as i64) == 0 { if ro[0] == XP_WHY_SCALE_UNDECLARED { scale_bad = 1 } }
483 }
484 let good: *u8 = xp_recover(XP_C_STORE_GLB, graw, gn, ro)
485 if (good as i64) == 0 { if ro[0] == XP_WHY_SCALE_UNDECLARED { scale_good = 1 } }
486 // a truncated container must not parse as geometry
487 let half: *u8 = xp_recover(XP_C_STORE_GLB, graw, gn/2, ro)
488 if (half as i64) == 0 { trunc_bad = 1 }
489 let whole: *u8 = xp_recover(XP_C_STORE_GLB, graw, gn, ro)
490 if (whole as i64) == 0 { trunc_good = 1 }
491 gv_puts(" glb probes: scale-lit@" as *u8); gv_num(sp)
492 gv_puts(" corrupt-refused=" as *u8); gv_num(scale_bad)
493 gv_puts(" intact-refused=" as *u8); gv_num(scale_good)
494 gv_puts(" truncated-refused=" as *u8); gv_num(trunc_bad)
495 gv_puts(" whole-refused=" as *u8); gv_num(trunc_good); gv_puts("\n" as *u8)
496 }
497 gv_bite("neg-control-glb-with-an-undeclared-node-scale-is-refused-not-mis-scaled" as *u8,
498 scale_bad, scale_good, c)
499 gv_bite("neg-control-truncated-glb-does-not-parse-as-geometry" as *u8, trunc_bad, trunc_good, c)
500
501 return gv_verdict("nx_xport_gate" as *u8, c,
502 "DC12: every consumer measured out of its own artifact by md_measure; unreachable consumers named, never scored" as *u8)
503}