nx_nxa_play_gate.nx source
↩ module page · 147 lines · 8408 B
1// nx_nxa_play_gate.nx -- THE POSE PLAYER GATE: skinning is JOINT-DRIVEN, deterministic, bounded at
2// identity, and refuses an unrigged asset by name -- each proven on REAL corpus artifacts.
3//
4// Subject: ./nx_nxa_play.elf (the serving-root binary; e2e fork via nx_gatekit_lib's proven capture,
5// never a hand-rolled pipe -- a v1 of a sibling gate deadlocked in pipe_wait for 50+ minutes on
6// exactly that mistake, and the banked law is that fixtures and subprocess come from nx_gatekit_lib).
7//
8// THE ANTI-VACUITY TOOTH IS SPREAD, NOT MOTION. "The mesh moved" is passed by a global translate and
9// by uniform jitter -- neither is skinning. A joint-driven deformation moves different vertices by
10// DIFFERENT amounts (a shoulder swings the hand far, the hip barely at all), so max-min displacement
11// is strictly positive; a whole-mesh shove makes every vertex travel the same distance and collapses
12// that spread to ZERO. This gate therefore asserts SPREAD, which the trivial wrong implementation
13// cannot produce.
14//
15// IDENTITY IS BOUNDED, NOT EXACT, AND THE BOUND IS DERIVED. Applying the identity pose does NOT
16// reproduce bind pose bit-for-bit: nx_skeleton blends in fx256 and truncates once per influence in
17// `w * (...) / 256`, plus once in the matvec, so the worst-case residual is INFLUENCES + 1 = 5 model
18// units. Measured across all 16 corpus rigs (14,164 to 423,919 verts) the actual floor is a stable 3.
19// The tooth asserts the DERIVED bound of 5 and PRINTS the observed value, so a regression that pushes
20// residue past truncation noise fails while honest rounding passes. This floor is also the CONTROL
21// for any future twist/volume claim: a real LBS artifact must exceed it to be real at all.
22import "nx_syscalls.nx"
23import "nx_gate_verdict.nx"
24import "nx_gatekit_lib.nx"
25
26const NG_ELF: *u8 = "./nx_nxa_play.elf"
27const NG_RIG: *u8 = "sites/nishifamily/world/ref9d.nxa"
28// ref.nxa is the estate's OWN documented unrigged asset -- knowledge/rigfloor.roster names it as
29// "DELIBERATELY ABSENT ... it carries NO SKEL SECTION". A real artifact, not a synthesised stub.
30const NG_NORIG: *u8 = "sites/nishifamily/world/ref.nxa"
31const NG_POSE: *u8 = "0"
32const NG_CAP: i64 = 65536
33const NG_INFLUENCES: i64 = 4
34// DERIVED, not picked: one fx256 truncation per influence in the blend, plus one in the matvec.
35const NG_IDENT_BOUND: i64 = NG_INFLUENCES + 1
36const NG_EXIT_NOSEC: i64 = 5
37
38func ng_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n }
39
40func ng_run(asset: *u8, pose: *u8, buf: *u8, blen: *i64) -> i64 {
41 return gk_run_capture(NG_ELF, asset, pose, 0 as *u8, 0 as *u8, buf, NG_CAP, blen)
42}
43
44// first integer following <key> in the captured output; -1 when the key is absent.
45func ng_num_after(buf: *u8, n: i64, key: *u8) -> i64 {
46 let m: i64 = ng_slen(key)
47 var i: i64 = 0
48 while i + m <= n {
49 var k: i64 = 0
50 while k < m { if buf[i+k] != key[k] { k = m + 9 } else { k = k + 1 } }
51 if k == m {
52 var j: i64 = i + m
53 var v: i64 = 0
54 var got: i64 = 0
55 var neg: i64 = 0
56 if buf[j] == (45 as u8) { neg = 1; j = j + 1 }
57 while j < n {
58 let c: i64 = buf[j] as i64
59 if c < 48 { j = n + 9 } else { if c > 57 { j = n + 9 } else {
60 v = v * 10 + (c - 48); got = 1; j = j + 1
61 } }
62 }
63 if got == 1 { if neg == 1 { return 0 - v } return v }
64 return 0 - 1
65 }
66 i = i + 1
67 }
68 return 0 - 1
69}
70
71func ng_has(buf: *u8, n: i64, ned: *u8) -> i64 {
72 let m: i64 = ng_slen(ned)
73 var i: i64 = 0
74 while i + m <= n {
75 var k: i64 = 0
76 while k < m { if buf[i+k] != ned[k] { k = m + 9 } else { k = k + 1 } }
77 if k == m { return 1 }
78 i = i + 1
79 }
80 return 0
81}
82
83func main() -> i64 {
84 let ctr: *i64 = gv_ctr()
85 gv_puts("nx_nxa_play_gate -- skinning is joint-driven, deterministic, identity-bounded, and refuses the unrigged\n\n" as *u8)
86
87 let buf: *u8 = sys_mmap(NG_CAP)
88 let bl: *i64 = sys_mmap(64)
89 let buf2: *u8 = sys_mmap(NG_CAP)
90 let bl2: *i64 = sys_mmap(64)
91
92 // ---- T1 identity: the asset parses and the evaluator reaches every vertex -----------------
93 let rc_i: i64 = ng_run(NG_RIG, 0 as *u8, buf, bl)
94 let nj: i64 = ng_num_after(buf, bl[0], "joints=" as *u8)
95 let nv: i64 = ng_num_after(buf, bl[0], "verts=" as *u8)
96 let inf: i64 = ng_num_after(buf, bl[0], "influences=" as *u8)
97 let zw: i64 = ng_num_after(buf, bl[0], "zero_weight_verts=" as *u8)
98 let id_max: i64 = ng_num_after(buf, bl[0], "max_disp_umm=" as *u8)
99 gv_puts(" [T1] identity rc=" as *u8); gv_num(rc_i)
100 gv_puts(" joints=" as *u8); gv_num(nj); gv_puts(" verts=" as *u8); gv_num(nv)
101 gv_puts(" influences=" as *u8); gv_num(inf); gv_puts(" zero_weight=" as *u8); gv_num(zw)
102 gv_puts(" max_disp=" as *u8); gv_num(id_max); gv_puts("\n" as *u8)
103 gv_check("identity-run-exits-zero" as *u8, rc_i == 0, ctr)
104 // the counts are bound IN the condition: a run over an empty or unparsed asset cannot pass.
105 gv_check("fixture-reached-the-condition-real-rig-parsed" as *u8, nj > 0 && nv > 0 && inf == NG_INFLUENCES, ctr)
106 gv_check("every-vertex-carries-weight-no-zero-weight-verts" as *u8, zw == 0, ctr)
107 gv_check("identity-pose-within-DERIVED-truncation-floor-not-asserted-exact" as *u8, id_max >= 0 && id_max <= NG_IDENT_BOUND, ctr)
108
109 // ---- T2 pose: real deformation, and it is JOINT-DRIVEN ------------------------------------
110 let rc_p: i64 = ng_run(NG_RIG, NG_POSE, buf, bl)
111 let posed: i64 = ng_num_after(buf, bl[0], "joints_posed=" as *u8)
112 let moved: i64 = ng_num_after(buf, bl[0], "verts_moved=" as *u8)
113 let pmax: i64 = ng_num_after(buf, bl[0], "max_disp_umm=" as *u8)
114 let pmin: i64 = ng_num_after(buf, bl[0], "min_disp_umm=" as *u8)
115 let spread: i64 = ng_num_after(buf, bl[0], "disp_spread_umm=" as *u8)
116 gv_puts(" [T2] pose rc=" as *u8); gv_num(rc_p)
117 gv_puts(" joints_posed=" as *u8); gv_num(posed); gv_puts(" verts_moved=" as *u8); gv_num(moved)
118 gv_puts(" max=" as *u8); gv_num(pmax); gv_puts(" min=" as *u8); gv_num(pmin)
119 gv_puts(" spread=" as *u8); gv_num(spread); gv_puts("\n" as *u8)
120 gv_check("pose-run-exits-zero" as *u8, rc_p == 0, ctr)
121 gv_check("pose-actually-applied-joints-posed-positive" as *u8, posed > 0, ctr)
122 gv_check("pose-displacement-exceeds-the-identity-floor" as *u8, pmax > NG_IDENT_BOUND, ctr)
123 // ANTI-VACUITY: a global translate or uniform jitter moves every vertex equally -> spread 0.
124 gv_check("ANTI-VACUITY-deformation-is-joint-driven-spread-nonzero" as *u8, spread > 0, ctr)
125 // and the spread must be a real signal, not truncation noise: it must clear the floor too.
126 gv_check("ANTI-VACUITY-spread-exceeds-truncation-floor" as *u8, spread > NG_IDENT_BOUND, ctr)
127
128 // ---- T3 determinism: identical inputs, byte-identical measured outcome --------------------
129 let rc_d: i64 = ng_run(NG_RIG, NG_POSE, buf2, bl2)
130 let dmax: i64 = ng_num_after(buf2, bl2[0], "max_disp_umm=" as *u8)
131 let dspread: i64 = ng_num_after(buf2, bl2[0], "disp_spread_umm=" as *u8)
132 let dmoved: i64 = ng_num_after(buf2, bl2[0], "verts_moved=" as *u8)
133 gv_puts(" [T3] rerun rc=" as *u8); gv_num(rc_d)
134 gv_puts(" max=" as *u8); gv_num(dmax); gv_puts(" spread=" as *u8); gv_num(dspread); gv_puts("\n" as *u8)
135 gv_check("determinism-same-pose-same-measured-result" as *u8, rc_d == 0 && dmax == pmax && dspread == spread && dmoved == moved, ctr)
136
137 // ---- T4 neg-control: an UNRIGGED asset must be refused BY NAME ----------------------------
138 let rc_n: i64 = ng_run(NG_NORIG, 0 as *u8, buf2, bl2)
139 var fired: i64 = 0
140 if rc_n == NG_EXIT_NOSEC { fired = ng_has(buf2, bl2[0], "asset is not rigged" as *u8) }
141 gv_puts(" [T4] unrigged rc=" as *u8); gv_num(rc_n); gv_puts(" named_refusal=" as *u8); gv_num(fired); gv_puts("\n" as *u8)
142 // gv_bite(fired-on-bad, fired-on-good): the good leg asks whether the refusal ALSO fired on the
143 // real rig -- it must not. rc_i is that run, and rc_i == NG_EXIT_NOSEC is false for a good asset.
144 gv_bite("neg-control-unrigged-asset-refused-by-name" as *u8, fired, rc_i == NG_EXIT_NOSEC, ctr)
145
146 return gv_verdict("NX-NXA-PLAY" as *u8, ctr, "the corpus is posable: joint-driven, deterministic, identity-bounded, unrigged refused" as *u8)
147}