code wiki / _hdl_build / nx_anat_consistency_gate.nx
nx_anat_consistency_gate.nx source
↩ module page · 206 lines · 9391 B
1// nx_anat_consistency_gate.nx -- ★CROSS-ARTIFACT ANATOMY CHECK (2026-07-27).
2//
3// Two organs in this codebase independently describe where a human's joints are:
4// nx_skelgen -- generates a rest skeleton from anthropometric rules, emits J rows in millimetres
5// nx_bodyatlas -- a ZygoteBody-style peelable being with its OWN skeleton pivots, authored months
6// earlier for an unrelated purpose
7// ★★NOBODY HAD EVER COMPARED THEM, and on 2026-07-27 that cost was measured: nx_skelgen's acromion sat
8// at 120 per-mille of stature while this atlas's own shoulder pivot sits at 206 -- a disagreement of
9// about 150mm on a 1750mm body, shipped and green in both organs for as long as both existed.
10//
11// ★THE PRINCIPLE THIS ENFORCES is the one nx_skelgen already states about its own internals: two tables
12// cannot disagree when there is only one table -- and where a second table is legitimate (a different
13// representation for a different job), it must be CHECKED rather than trusted. Both sides are converted
14// to PER-MILLE OF THEIR OWN STATURE first, so the comparison is scale-free and neither organ's unit
15// system is privileged.
16//
17// ⚠WHAT THIS DOES **NOT** ASSERT: that the two must be identical. A shoulder JOINT CENTRE is legitimately
18// inboard of an ACROMION, so the girdle check is a BRACKET (joint <= acromion <= bony outer edge), not an
19// equality. Asserting equality there would force one of two correct numbers to become wrong.
20//
21// nx_anat_consistency_gate <skel.dat> (the file nx_skelgen writes)
22// license_tier: ORIGINAL expect_exit: 0 No hw writes (Rule 26).
23import "nx_bodyatlas.nx"
24import "nx_gate_verdict.nx"
25
26const AC_MM: i64 = 1000
27// agreement tolerance in per-mille of stature. 10 permil is ~17mm on a 1750mm body -- looser than a
28// rounding step and far tighter than the 86 permil error this gate exists to have caught.
29const AC_TOL: i64 = 10
30// atlas rig bone ids (from nx_bodyatlas's own rig): 1/3 shoulders, 5/7 hips, 6/8 knees
31const AC_BSHL: i64 = 1
32const AC_BSHR: i64 = 3
33const AC_BHIPL: i64 = 5
34const AC_BHIPR: i64 = 7
35const AC_BKNEEL: i64 = 6
36const AC_BKNEER: i64 = 8
37// nx_skelgen joint ids: 5 acromion, 9 hip, 10 knee (right side); left = +SG mirror, read from the file
38const AC_JACR: i64 = 5
39const AC_JHIP: i64 = 9
40const AC_JKNEE: i64 = 10
41const AC_MAXJ: i64 = 64
42
43func ac_iabs(v: i64) -> i64 { if v < 0 { return 0 - v } return v }
44func ac_isdig(c: i64) -> i64 { if c >= 48 { if c <= 57 { return 1 } } return 0 }
45func ac_tok(b: *u8, n: i64, p: *i64, out: *i64) -> i64 {
46 var i: i64 = p[0]
47 var go: i64 = 1
48 while go == 1 {
49 if i >= n { go = 0 } else {
50 let c: i64 = b[i] as i64
51 var st: i64 = 0
52 if ac_isdig(c) == 1 { st = 1 }
53 if c == 45 { st = 1 }
54 if st == 1 { go = 0 } else { i = i + 1 }
55 }
56 }
57 if i >= n { p[0] = i; return 0 }
58 var sg: i64 = 1
59 if b[i] as i64 == 45 { sg = 0-1; i = i + 1 }
60 var v: i64 = 0
61 var g2: i64 = 1
62 while g2 == 1 {
63 if i >= n { g2 = 0 } else {
64 let c2: i64 = b[i] as i64
65 if ac_isdig(c2) == 1 { v = v*10 + (c2-48); i = i + 1 } else { g2 = 0 }
66 }
67 }
68 p[0] = i
69 out[0] = v*sg
70 return 1
71}
72func ac_nextline(b: *u8, n: i64, p: *i64) -> i64 {
73 var i: i64 = p[0]
74 var go: i64 = 1
75 while go == 1 {
76 if i >= n { go = 0 } else { if b[i] as i64 == 10 { i = i + 1; go = 0 } else { i = i + 1 } }
77 }
78 p[0] = i
79 return 0
80}
81// read nx_skelgen's J rows: J <idx> <parent> <side> <x> <y> <z>. Returns joint count, <0 = refused.
82func ac_load_skel(path: *u8, JX: *i64, JY: *i64, JZ: *i64) -> i64 {
83 let ln: *i64 = sys_mmap(16) as *i64
84 let buf: *u8 = sys_read_file(path, ln)
85 if buf as i64 == 0 { return 0-1 }
86 let n: i64 = ln[0]
87 let p: *i64 = sys_mmap(16) as *i64
88 let v: *i64 = sys_mmap(16) as *i64
89 p[0] = 0
90 var cnt: i64 = 0
91 var go: i64 = 1
92 while go == 1 {
93 if p[0] >= n { go = 0 } else {
94 if buf[p[0]] as i64 == 74 {
95 p[0] = p[0] + 1
96 if ac_tok(buf,n,p,v) == 1 {
97 let j: i64 = v[0]
98 if ac_tok(buf,n,p,v) == 1 {
99 if ac_tok(buf,n,p,v) == 1 {
100 if ac_tok(buf,n,p,v) == 1 {
101 let x: i64 = v[0]
102 if ac_tok(buf,n,p,v) == 1 {
103 let y: i64 = v[0]
104 if ac_tok(buf,n,p,v) == 1 {
105 if j >= 0 { if j < AC_MAXJ {
106 JX[j]=x; JY[j]=y; JZ[j]=v[0]; cnt=cnt+1
107 } }
108 }
109 }
110 }
111 }
112 }
113 }
114 }
115 ac_nextline(buf,n,p)
116 }
117 }
118 return cnt
119}
120// the skeleton's own stature = its highest joint (the vertex), since its chain closes on stature
121func ac_skel_stature(JY: *i64, nj: i64) -> i64 {
122 var top: i64 = 0
123 var j: i64 = 0
124 while j < nj { if JY[j] > top { top = JY[j] } j = j + 1 }
125 return top
126}
127
128func main(argc: i64, argv: *i64) -> i64 {
129 let ctr: *i64 = gv_ctr()
130 gv_head("nx_anat_consistency -- nx_skelgen vs nx_bodyatlas, two independently authored skeletons" as *u8)
131 if argc < 2 {
132 gv_puts("usage: nx_anat_consistency_gate <skel.dat>\n" as *u8)
133 return 2
134 }
135 let JX: *i64 = sys_mmap(AC_MAXJ*8) as *i64
136 let JY: *i64 = sys_mmap(AC_MAXJ*8) as *i64
137 let JZ: *i64 = sys_mmap(AC_MAXJ*8) as *i64
138 let nj: i64 = ac_load_skel(argv[1] as *u8, JX, JY, JZ)
139 // ★REFUSE LOUD on a missing input rather than compare against zeros -- an all-zeros skeleton would
140 // "agree" with nothing and could still be reported as a number.
141 var t0: i64 = 0
142 if nj >= 21 { t0 = 1 }
143 gv_check("T0 the generated skeleton loaded (>=21 joints), else REFUSE not compare-with-zeros" as *u8, t0, ctr)
144 if t0 == 0 { return gv_verdict("ANAT-CONSISTENCY" as *u8, ctr, "no skeleton to compare" as *u8) }
145
146 atlas_build(0)
147 let ah: i64 = atlas_stature()
148 let sh: i64 = ac_skel_stature(JY, AC_MAXJ)
149 gv_puts(" atlas stature=" as *u8); gv_num(ah)
150 gv_puts(" units; skeleton stature=" as *u8); gv_num(sh); gv_puts(" mm\n" as *u8)
151 var t1: i64 = 0
152 if ah > 0 { if sh > 0 { t1 = 1 } }
153 gv_check("T1 both artifacts report a positive stature to normalise by" as *u8, t1, ctr)
154
155 let pl: *i64 = sys_mmap(64) as *i64
156 let pr: *i64 = sys_mmap(64) as *i64
157 // ---- HIP: femoral-head separation. Both organs mean the SAME landmark here, so this is equality.
158 atlas_pivot(AC_BHIPL, pl)
159 atlas_pivot(AC_BHIPR, pr)
160 let a_hip: i64 = (pr[0] - pl[0]) * AC_MM / ah
161 let s_hip: i64 = (JX[AC_JHIP] * 2) * AC_MM / sh
162 gv_puts(" HIP span permil: atlas=" as *u8); gv_num(a_hip)
163 gv_puts(" skelgen=" as *u8); gv_num(s_hip); gv_puts("\n" as *u8)
164 var t2: i64 = 0
165 if ac_iabs(a_hip - s_hip) <= AC_TOL { t2 = 1 }
166 gv_check("T2 HIP joint span agrees across the two artifacts" as *u8, t2, ctr)
167
168 // ---- KNEE
169 atlas_pivot(AC_BKNEEL, pl)
170 atlas_pivot(AC_BKNEER, pr)
171 let a_knee: i64 = (pr[0] - pl[0]) * AC_MM / ah
172 let s_knee: i64 = (JX[AC_JKNEE] * 2) * AC_MM / sh
173 gv_puts(" KNEE span permil: atlas=" as *u8); gv_num(a_knee)
174 gv_puts(" skelgen=" as *u8); gv_num(s_knee); gv_puts("\n" as *u8)
175 var t3: i64 = 0
176 if ac_iabs(a_knee - s_knee) <= AC_TOL { t3 = 1 }
177 gv_check("T3 KNEE span agrees across the two artifacts" as *u8, t3, ctr)
178
179 // ---- GIRDLE: a BRACKET, not an equality. The atlas pivot is a glenohumeral JOINT CENTRE and
180 // skelgen's joint 5 is the ACROMION, which is legitimately lateral to it. Demanding equality would
181 // force one of two correct numbers to become wrong.
182 atlas_pivot(AC_BSHL, pl)
183 atlas_pivot(AC_BSHR, pr)
184 let a_shj: i64 = (pr[0] - pl[0]) * AC_MM / ah
185 let s_acr: i64 = (JX[AC_JACR] * 2) * AC_MM / sh
186 gv_puts(" SHOULDER permil: atlas joint-centre=" as *u8); gv_num(a_shj)
187 gv_puts(" skelgen acromion=" as *u8); gv_num(s_acr); gv_puts("\n" as *u8)
188 var t4: i64 = 0
189 if s_acr >= a_shj { t4 = 1 }
190 gv_check("T4 GIRDLE BRACKET: the acromion is at or lateral to the joint centre, never inboard" as *u8, t4, ctr)
191 // and not absurdly lateral either -- an acromion more than a hand's breadth outside the joint
192 // centre would mean one of them is wrong again
193 var t5: i64 = 0
194 if s_acr - a_shj <= 60 { t5 = 1 }
195 gv_check("T5 GIRDLE BRACKET upper: the offset stays anatomical, not a second 86-permil error" as *u8, t5, ctr)
196 gv_puts(" girdle offset permil (acromion - joint centre)=" as *u8); gv_num(s_acr - a_shj); gv_puts("\n" as *u8)
197
198 // ★T6 ANTI-VACUITY. The comparison must be capable of FAILING -- feed it the value nx_skelgen
199 // actually shipped until today (120 per-mille acromion span) and the bracket must reject it.
200 var t6: i64 = 0
201 if 120 < a_shj { t6 = 1 }
202 gv_check("T6 ANTI-VACUITY: the OLD shipped acromion span (120) IS rejected by this bracket" as *u8, t6, ctr)
203
204 return gv_verdict("ANAT-CONSISTENCY" as *u8, ctr,
205 "two independently authored skeletons agree on the legs and bracket correctly at the girdle" as *u8)
206}