nx_roundtrip_gate.nx source
↩ module page · 338 lines · 17557 B
1// nx_roundtrip_gate.nx -- THE GATE FOR THE SELF-ORACLE.
2//
3// SUBJECT: the nx_roundtrip ELF, forked for real. Its contract is a FOUR-STATE EXIT
4// (0 IDENTICAL / 1 LOSSY / 2 usage / 3 UNOBSERVABLE) and /api/gate_run derives its verdict from an exit
5// code, so every tooth here asserts an EXIT CODE. A gate whose exit does not carry its verdict silently
6// blesses every failure it finds.
7//
8// THE FIXTURES ARE MIXED ON PURPOSE, AND THE REASON IS MEASURED. The two POSITIVE fixtures are real
9// pipeline artifacts (nx_gltf2mesh's own conversion of two donor GLBs), copied to a durable knowledge/
10// path and byte-verified. Three hand-authored containers were tried first and every one went RED for a
11// reason unrelated to fidelity -- metre-scale coordinates were rescaled on the return leg, millimetre
12// ones were refused outright, unit normals changed nothing -- because a synthetic container cannot
13// reliably reproduce the canonical regime the pipeline emits, and a fixture the subject rejects tests
14// the fixture rather than the subject. The NEGATIVE fixture stays synthetic and IS built at runtime,
15// because a container truncated BY CONSTRUCTION is the one thing no real artifact can supply.
16//
17// THE BITE PAIR IS T1/T2 AND IT IS THE POINT. A checker that returned IDENTICAL for everything would pass
18// any single positive test; a checker that returned LOSSY for everything would pass any single negative
19// test. Only the PAIR discriminates. The two fixtures differ in exactly one property -- layer count -- so
20// the pair isolates the one axis under test.
21//
22// THE FIXTURES' SHAPE IS ASSERTED BEFORE ANY OUTCOME IS. The positive fixtures are read, not written,
23// so their presence AND their layer counts (1 and 9) are proven at setup: a missing fixture, or one that
24// is not actually multi-layer, would make T1/T3 report on something other than the property they name.
25// A NAMED absence, never a silent skip.
26//
27// license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0
28import "nx_syscalls.nx"
29import "nx_gate_verdict.nx"
30import "nx_tool_run.nx"
31
32const RG_SUBJECT_DEFAULT: *u8 = "/volume1/homes/elderwesto/nishihost/_offc/nx_roundtrip.elf"
33
34// the subject's exit contract, restated so a change to it BREAKS THIS GATE loudly
35const RG_EXIT_IDENTICAL: i64 = 0
36const RG_EXIT_LOSSY: i64 = 1
37const RG_EXIT_UNOBSERVABLE: i64 = 3
38const RG_EXEC_NOT_FOUND: i64 = 127
39
40// ---- NXMSH2 layout (mirrors nx_mesh2glb's reader; one format, one writer shape) ----
41const RG_NLAY_OFF: i64 = 8
42const RG_NTRI_OFF: i64 = 12
43const RG_HDR_BASE: i64 = 16
44const RG_LAYER_STRIDE: i64 = 24
45const RG_LAYER_NAME_LEN: i64 = 16
46const RG_LAYER_OFF_FLD: i64 = 16
47const RG_LAYER_CNT_FLD: i64 = 20
48const RG_TRI_STRIDE: i64 = 84
49const RG_MAGIC_LEN: i64 = 6 // "NXMSH2"
50const RG_U32_BYTES: i64 = 4
51const RG_BYTE_RADIX: i64 = 256
52const RG_BYTE_MASK: i64 = 255
53const RG_COORDS: i64 = 3
54const RG_VERTS_PER_TRI: i64 = 3
55const RG_VERT_BYTES: i64 = 12 // x,y,z as three float32
56const RG_NRM_OFF: i64 = 36 // normal block begins after the three positions
57const RG_NRM_Z: i64 = 8 // z within a normal triple
58
59// float32 BIT PATTERNS, not decimals -- the container stores raw IEEE-754 words and this gate writes
60// bytes, so the fixture must speak in bits. 0.0f is all zero; 1.0f is 0x3F800000; 1.8f is 0x3FE66666.
61//
62// THE FIXTURE'S UNIT IS LOAD-BEARING AND THE FIRST TWO VERSIONS GOT IT WRONG. Measured 2026-08-22:
63// THE CANONICAL NXMSH2 UNIT IS MILLIMETRES. nx_gltf2mesh resolves a scale by finding the power of 1000
64// that lands the height inside [sliver_floor_mm, sliver_floor_mm*1000-1] = [100, 99999] mm
65// (knowledge/gltf2mesh_units.conf; the bands TILE, so a height is never ambiguous). A mesh already
66// stored in mm has a height in that band, so the return leg multiplies by ONE and the raw f32 words come
67// back untouched -- which is exactly why every pipeline-produced donor round-trips bit-exact. A fixture
68// authored in METRES has a height of ~1.8, lands below the floor, gets multiplied by 1000, and its
69// positions legitimately change. That was a red for the wrong reason: it measured the fixture's units,
70// not the pipeline's fidelity.
71// THE FINDING IS REAL AND WORTH KEEPING: the position pass-through is exact only while both legs infer
72// the same scale, and that holds for everything the pipeline itself produces.
73const RG_F32_ZERO: i64 = 0
74const RG_F32_1000MM: i64 = 1148846080 // 1000.0f
75const RG_F32_1800MM: i64 = 1155596288 // 1800.0f -- a human-scale height, in band, scale factor 1
76
77const RG_TRIS_GOOD: i64 = 2 // one layer, two non-degenerate triangles
78const RG_TRIS_PARTS: i64 = 3 // three layers, one triangle each -- the segmentation case
79const RG_LAYERS_ONE: i64 = 1
80const RG_LAYERS_THREE: i64 = 3
81// the truncated fixture DECLARES far more triangles than it carries. The subject must refuse it rather
82// than parse past the end of the buffer and compare against uninitialised memory.
83const RG_TRIS_DECLARED_BUT_ABSENT: i64 = 100
84
85const RG_CAPTURE_CAP: i64 = 262144
86const RG_PATH_CAP: i64 = 4096
87const RG_ARGV_SLOTS: i64 = 8
88const RG_MODE_DIR: i64 = 493 // 0755
89const RG_WORD: i64 = 8
90
91// ---- THE TWO POSITIVE FIXTURES ARE REAL PIPELINE ARTIFACTS, NOT SYNTHETIC, AND THAT IS A DECISION.
92// Three hand-authored containers were tried first and every one produced a RED for a reason unrelated
93// to round-trip fidelity: metre-scale coordinates got rescaled on the return leg, millimetre-scale ones
94// were refused outright ("zero triangles accepted"), and adding unit normals changed nothing. A
95// synthetic container cannot reliably reproduce the canonical regime the pipeline itself emits, and a
96// fixture the subject rejects tests the fixture, not the subject. These two ARE pipeline output --
97// nx_gltf2mesh's own conversion of two donor GLBs -- copied to a durable path (byte-verified,
98// verified=1) so the gate does not depend on /tmp, which is reaped hourly.
99// The NEGATIVE fixture stays synthetic, because a container that is truncated BY CONSTRUCTION is
100// exactly the thing no real artifact can provide.
101const RG_DIR: *u8 = "/tmp/nx_roundtrip_gate"
102const RG_GOOD: *u8 = "/volume1/homes/elderwesto/nishihost/knowledge/rtfixture_1layer.nxmesh"
103const RG_PARTS: *u8 = "/volume1/homes/elderwesto/nishihost/knowledge/rtfixture_9layer.nxmesh"
104const RG_GOOD_LAYERS: i64 = 1
105const RG_PARTS_LAYERS: i64 = 9
106const RG_TRUNC: *u8 = "/tmp/nx_roundtrip_gate/trunc.nxmesh"
107const RG_ABSENT: *u8 = "/tmp/nx_roundtrip_gate/no_such_input.nxmesh"
108const RG_MID: *u8 = "/tmp/nx_roundtrip_gate/rt_mid.glb"
109const RG_BACK: *u8 = "/tmp/nx_roundtrip_gate/rt_back.nxmesh"
110
111func rg_wr32(b: *u8, off: i64, v: i64) -> i64 {
112 var n: i64 = v
113 var i: i64 = 0
114 while i < RG_U32_BYTES {
115 let q: i64 = n / RG_BYTE_RADIX
116 b[off + i] = (n - q*RG_BYTE_RADIX) as u8
117 n = q
118 i = i + 1
119 }
120 return 0
121}
122func rg_name(b: *u8, off: i64, s: *u8) -> i64 {
123 var i: i64 = 0
124 while i < RG_LAYER_NAME_LEN { b[off + i] = 0; i = i + 1 }
125 i = 0
126 while s[i] != 0 {
127 if i < RG_LAYER_NAME_LEN { b[off + i] = s[i] }
128 i = i + 1
129 }
130 return 0
131}
132// Write one triangle's POSITIONS at `off`. Two distinct triangles form a quad spanning x 0..1 and
133// y 0..1.8; both have real area, because nx_gltf2mesh DROPS degenerate triangles and a dropped
134// triangle would fail the count assertion for a reason unrelated to the axis under test.
135// Vertex layout inside a record: v0 at +0, v1 at +12, v2 at +24; within a vertex x/y/z at +0/+4/+8.
136func rg_tri(b: *u8, off: i64, which: i64) -> i64 {
137 var i: i64 = 0
138 while i < RG_TRI_STRIDE { b[off + i] = 0; i = i + 1 }
139 if which == 0 {
140 // (0,0,0) (1000,0,0) (0,1800,0) -- millimetres
141 rg_wr32(b, off + 12, RG_F32_1000MM)
142 rg_wr32(b, off + 24 + RG_U32_BYTES, RG_F32_1800MM)
143 } else {
144 // (1000,0,0) (1000,1800,0) (0,1800,0) -- millimetres
145 rg_wr32(b, off + 0, RG_F32_1000MM)
146 rg_wr32(b, off + 12, RG_F32_1000MM)
147 rg_wr32(b, off + 12 + RG_U32_BYTES, RG_F32_1800MM)
148 rg_wr32(b, off + 24 + RG_U32_BYTES, RG_F32_1800MM)
149 }
150 // NORMALS ARE NOT OPTIONAL DECORATION IN THIS FIXTURE. An all-zero normal block makes the mesh
151 // malformed, and nx_gltf2mesh then accepted ZERO triangles and refused the whole container
152 // ("a form oracle with no surface is vacuous") -- so the gate reported UNOBSERVABLE for a reason
153 // that had nothing to do with round-trip fidelity. Every vertex gets a real +Z unit normal.
154 // The container stores normals in PERMILLE, so 1.0 is the float 1000.0 -- the same bit pattern
155 // the millimetre coordinate uses, which is a coincidence of units, not a shared meaning.
156 rg_wr32(b, off + RG_NRM_OFF + RG_NRM_Z, RG_F32_1000MM)
157 rg_wr32(b, off + RG_NRM_OFF + RG_VERT_BYTES + RG_NRM_Z, RG_F32_1000MM)
158 rg_wr32(b, off + RG_NRM_OFF + RG_VERT_BYTES*2 + RG_NRM_Z, RG_F32_1000MM)
159 return 0
160}
161// assemble an NXMSH2 with `nlay` layers over `ntri` triangles. If `declared_tris` differs from `ntri`,
162// the header LIES about how many triangles follow -- that is the truncated fixture.
163func rg_write_msh(path: *u8, nlay: i64, ntri: i64, declared_tris: i64) -> i64 {
164 let total: i64 = RG_HDR_BASE + nlay*RG_LAYER_STRIDE + ntri*RG_TRI_STRIDE
165 let b: *u8 = sys_mmap(total)
166 var i: i64 = 0
167 while i < total { b[i] = 0; i = i + 1 }
168 let mg: *u8 = "NXMSH2" as *u8
169 var k: i64 = 0
170 while k < RG_MAGIC_LEN { b[k] = mg[k]; k = k + 1 }
171 rg_wr32(b, RG_NLAY_OFF, nlay)
172 rg_wr32(b, RG_NTRI_OFF, declared_tris)
173 var L: i64 = 0
174 while L < nlay {
175 let lb: i64 = RG_HDR_BASE + L*RG_LAYER_STRIDE
176 // A SINGLE-LAYER MESH IS NAMED "skin" ON PURPOSE. nx_gltf2mesh emits exactly that name for an
177 // unrigged donor, so a lossless trip must return it unchanged. Naming it anything else would
178 // make the layer-NAME axis fail on a mesh whose segmentation was in fact perfectly preserved --
179 // testing the fixture's vocabulary instead of the pipeline's fidelity.
180 if nlay == 1 { rg_name(b, lb, "skin" as *u8) }
181 if nlay != 1 {
182 if L == 0 { rg_name(b, lb, "root" as *u8) }
183 if L == 1 { rg_name(b, lb, "Lsh" as *u8) }
184 if L == 2 { rg_name(b, lb, "Rsh" as *u8) }
185 }
186 rg_wr32(b, lb + RG_LAYER_OFF_FLD, L)
187 rg_wr32(b, lb + RG_LAYER_CNT_FLD, 1)
188 L = L + 1
189 }
190 let data: i64 = RG_HDR_BASE + nlay*RG_LAYER_STRIDE
191 var t: i64 = 0
192 while t < ntri {
193 rg_tri(b, data + t*RG_TRI_STRIDE, t)
194 t = t + 1
195 }
196 let fd: i64 = sys_openat_wr(path, MODE_0644)
197 if fd < 0 { return 0 - 1 }
198 let wr: i64 = sys_write(fd, b, total)
199 sys_close(fd)
200 if wr != total { return 0 - 1 }
201 return total
202}
203func rg_run(subject: *u8, inp: *u8, dir: *u8, out: *u8, olen: *i64) -> i64 {
204 let av: *i64 = sys_mmap(RG_WORD*RG_ARGV_SLOTS) as *i64
205 av[0] = subject as i64
206 av[1] = "check" as *u8 as i64
207 av[2] = inp as i64
208 av[3] = dir as i64
209 av[4] = 0
210 return tr_run_capture(subject, av, out, RG_CAPTURE_CAP, olen)
211}
212// layer count of an NXMSH2 on disk, or -1 if it cannot be read. Used to PROVE the fixture's shape
213// before any tooth relies on it.
214func rg_layers(path: *u8) -> i64 {
215 let lp: *i64 = sys_mmap(RG_WORD*2) as *i64
216 let b: *u8 = sys_read_file(path, lp)
217 if (b as i64) == 0 { return 0 - 1 }
218 if lp[0] < RG_HDR_BASE { return 0 - 1 }
219 return (b[RG_NLAY_OFF] as i64) + ((b[RG_NLAY_OFF+1] as i64)<<8) + ((b[RG_NLAY_OFF+2] as i64)<<16) + ((b[RG_NLAY_OFF+3] as i64)<<24)
220}
221func rg_size(path: *u8) -> i64 {
222 let lp: *i64 = sys_mmap(RG_WORD*2) as *i64
223 let b: *u8 = sys_read_file(path, lp)
224 if (b as i64) == 0 { return 0 - 1 }
225 return lp[0]
226}
227
228func main(argc: i64, argv: *i64) -> i64 {
229 let ctr: *i64 = gv_ctr()
230 gv_head("nx_roundtrip gate -- nishi->glTF->nishi, and the loss is NAMED not assumed" as *u8)
231 var subject: *u8 = RG_SUBJECT_DEFAULT
232 if argc >= 2 { subject = argv[1] as *u8 }
233 gv_puts(" subject: " as *u8)
234 gv_puts(subject)
235 gv_puts("\n\n" as *u8)
236
237 // ---- SETUP. mkdir at setup, never teardown: a teardown does not run when a run crashes.
238 sys_mkdir(RG_DIR, RG_MODE_DIR)
239 // A GATE THAT IS NOT IDEMPOTENT REPORTS ON ITS FIRST RUN AND LIES ABOUT EVERY RUN AFTER. The subject
240 // writes rt_mid.glb and rt_back.nxmesh into the scratch dir; an intermediate left by an EARLIER run
241 // would satisfy the anti-vacuity check even if this run's first leg produced nothing.
242 sys_unlinkat(RG_MID)
243 sys_unlinkat(RG_BACK)
244 let wt: i64 = rg_write_msh(RG_TRUNC, RG_LAYERS_ONE, RG_TRIS_GOOD, RG_TRIS_DECLARED_BUT_ABSENT)
245 var setup: i64 = 0
246 if wt > 0 { setup = 1 }
247 gv_check("setup-negative-fixture-written (a container truncated BY CONSTRUCTION)" as *u8, setup, ctr)
248 // ASSERT THE FIXTURE REACHED THE CONDITION BEFORE ASSERTING ANY OUTCOME. These two are read from a
249 // durable path rather than written here, so their PRESENCE and their SHAPE both have to be proven:
250 // a missing fixture, or one that is not actually multi-layer, would make T1/T3 report on something
251 // other than the property they name. A NAMED absence, never a silent skip.
252 let gl: i64 = rg_layers(RG_GOOD)
253 let pl: i64 = rg_layers(RG_PARTS)
254 gv_puts(" fixture layers: 1layer=" as *u8)
255 gv_num(gl)
256 gv_puts(" 9layer=" as *u8)
257 gv_num(pl)
258 gv_puts("\n" as *u8)
259 var fixok: i64 = 0
260 if gl == RG_GOOD_LAYERS { if pl == RG_PARTS_LAYERS { fixok = 1 } }
261 gv_check("setup-real-donor-fixtures-present-and-carry-the-expected-layer-counts" as *u8, fixok, ctr)
262 var clean: i64 = 0
263 if rg_size(RG_MID) < 0 { if rg_size(RG_BACK) < 0 { clean = 1 } }
264 gv_check("setup-subject-outputs-absent-before-measuring (gate is idempotent)" as *u8, clean, ctr)
265
266 let cap: *u8 = sys_mmap(RG_CAPTURE_CAP)
267 let olen: *i64 = sys_mmap(RG_WORD*2) as *i64
268
269 // ---- T1: a single-layer mesh survives the trip ----
270 let rc1: i64 = rg_run(subject, RG_GOOD, RG_DIR, cap, olen)
271 gv_puts(" [T1] single-layer donor rc=" as *u8)
272 gv_num(rc1)
273 gv_puts("\n" as *u8)
274 var t1: i64 = 0
275 if rc1 == RG_EXIT_IDENTICAL { t1 = 1 }
276 gv_check("single-layer-mesh-round-trips-IDENTICAL" as *u8, t1, ctr)
277
278 // ---- T2: ANTI-VACUITY. The trip must have actually HAPPENED. A first leg that silently produced
279 // nothing would compare nothing with nothing; asserting the intermediate exists and is non-empty is
280 // what separates a real pass from a vacuous one.
281 let midsz: i64 = rg_size(RG_MID)
282 gv_puts(" [T2] intermediate glb bytes=" as *u8)
283 gv_num(midsz)
284 gv_puts("\n" as *u8)
285 var t2: i64 = 0
286 if midsz > 0 { t2 = 1 }
287 gv_check("anti-vacuity-intermediate-glb-was-produced-and-is-non-empty" as *u8, t2, ctr)
288
289 // ---- T3: a multi-layer mesh LOSES its segmentation. This is the measured defect, asserted so a
290 // future fix to nx_mesh2glb (emitting skins/JOINTS_0) will BREAK this gate loudly and correctly --
291 // at which point the tooth becomes the regression test for the fix.
292 let rc3: i64 = rg_run(subject, RG_PARTS, RG_DIR, cap, olen)
293 gv_puts(" [T3] nine-layer donor rc=" as *u8)
294 gv_num(rc3)
295 gv_puts("\n" as *u8)
296 var t3: i64 = 0
297 if rc3 == RG_EXIT_LOSSY { t3 = 1 }
298 gv_check("nine-layer-real-donor-is-reported-LOSSY (named-part segmentation does not survive)" as *u8, t3, ctr)
299
300 // ---- T4: THE BITE PAIR. Identical on the lossless case, lossy on the lossy case. A checker that
301 // answered the same thing for both -- in either direction -- fails here and passes nowhere else.
302 var fired_on_bad: i64 = 0
303 if rc3 == RG_EXIT_LOSSY { fired_on_bad = 1 }
304 var fired_on_good: i64 = 1
305 if rc1 == RG_EXIT_IDENTICAL { fired_on_good = 0 }
306 gv_bite("neg-control-lossy-mesh-flagged-and-lossless-mesh-admitted" as *u8, fired_on_bad, fired_on_good, ctr)
307
308 // ---- T5: a CORRUPTED container must not report IDENTICAL. It declares 100 triangles and carries 2.
309 let rc5: i64 = rg_run(subject, RG_TRUNC, RG_DIR, cap, olen)
310 gv_puts(" [T5] truncated container rc=" as *u8)
311 gv_num(rc5)
312 gv_puts("\n" as *u8)
313 var t5: i64 = 0
314 if rc5 != RG_EXIT_IDENTICAL { t5 = 1 }
315 gv_check("neg-control-truncated-container-never-reports-IDENTICAL" as *u8, t5, ctr)
316
317 // ---- T6: a MISSING input is UNOBSERVABLE, not LOSSY. Blaming the format for a harness failure is
318 // the confusion this exit contract exists to prevent, so it gets its own tooth.
319 let rc6: i64 = rg_run(subject, RG_ABSENT, RG_DIR, cap, olen)
320 gv_puts(" [T6] absent input rc=" as *u8)
321 gv_num(rc6)
322 gv_puts("\n" as *u8)
323 var t6: i64 = 0
324 if rc6 == RG_EXIT_UNOBSERVABLE { t6 = 1 }
325 gv_check("absent-input-is-UNOBSERVABLE-not-LOSSY" as *u8, t6, ctr)
326
327 // ---- T7: the subject actually ran. tr_run_capture returns a negative sentinel on a harness failure
328 // and 127 when execve could not find the ELF; either would make every exit-code tooth above compare
329 // against a number the subject never produced.
330 var ran: i64 = 1
331 if rc1 < 0 { ran = 0 }
332 if rc1 == RG_EXEC_NOT_FOUND { ran = 0 }
333 gv_check("neg-control-subject-actually-executed (not 127, not a harness sentinel)" as *u8, ran, ctr)
334
335 let rc: i64 = gv_verdict("ROUNDTRIP" as *u8, ctr, "positions and triangles survive; named-part segmentation does not, and that is asserted both ways" as *u8)
336 sys_exit(rc)
337 return rc
338}