nx_domain_profile.nx source
↩ module page · 409 lines · 16668 B
1// nx_domain_profile.nx -- generative-domain dispatcher registry.
2//
3// Per NISHI_CLOSED_LOOP_GENERATIVE_ROADMAP.md: each generative
4// domain (real human / orc / clothing / weapon / etc.) has its
5// own profile that names which tier bricks to invoke + what
6// range to expect on each + reward-shaping coefficient per axis.
7//
8// This primitive is the SEALED-ENUM REGISTRY of currently-known
9// domains + the per-domain bitmask of which tier axes apply.
10// Catalog-driven extension via JSONL (per cardinal `feedback-
11// catalog-driven-not-per-instance-hardcoded`) is queued; the
12// initial 11 domains are hardcoded as sealed-enum starter set.
13//
14// genealogy_id: substrate_closed_loop_generative_2026_05_16
15// lineage_id: nishi_domain_profile_v1
16
17// nx_safety_envelope:
18// intended_use: AUTO_APPLIED -- primitive-specific tuning queued
19// sil_target: SIL1
20// evidence: [bulk_applied_2026-05-16, see-file-comment-for-detail]
21// verdict: NOT_YET_EVALUATED
22
23import "nx_syscalls.nx"
24import "nx_runtime.nx"
25import "nx_tier.nx"
26
27// ===== sealed-enum: domain IDs ====================================
28
29const NX_DOMAIN_UNKNOWN: nx_int = 0
30const NX_DOMAIN_HUMAN_ADULT: nx_int = 1
31const NX_DOMAIN_HUMAN_CHILD: nx_int = 2 // tier-profile only; subject-matter gating is Elder AI's job
32const NX_DOMAIN_FANTASY_ORC: nx_int = 3
33const NX_DOMAIN_FANTASY_ELF: nx_int = 4
34const NX_DOMAIN_FANTASY_DWARF: nx_int = 5
35const NX_DOMAIN_CREATURE_WOLF: nx_int = 6
36const NX_DOMAIN_CLOTHING_GARMENT: nx_int = 7
37const NX_DOMAIN_WEAPON_STEEL: nx_int = 8
38const NX_DOMAIN_WEAPON_WOOD: nx_int = 9
39const NX_DOMAIN_ARCHITECTURE: nx_int = 10
40const NX_DOMAIN_ENVIRONMENT: nx_int = 11
41const NX_DOMAIN_FOOD: nx_int = 12
42const NX_DOMAIN_N_KINDS: nx_int = 13
43
44func nx_domain_is_valid(d: nx_int) -> nx_int {
45 if d < 0 { return 0 }
46 if d >= NX_DOMAIN_N_KINDS { return 0 }
47 return 1
48}
49
50// ===== sealed-enum: tier-axis IDs (bit positions in mask) =========
51//
52// One bit per shipped tier brick. Up to 64 bits; substrate has
53// 30+ axes today plus room to grow.
54
55const NX_AXIS_T0_DIMENSIONS: nx_int = 0
56const NX_AXIS_T1_LUMINANCE: nx_int = 1
57const NX_AXIS_T1_HISTOGRAM: nx_int = 2
58const NX_AXIS_T1_SSIM: nx_int = 3
59const NX_AXIS_T1_SKIN_TONE_ITA: nx_int = 4
60const NX_AXIS_T2_GLCM_TEXTURE: nx_int = 5
61const NX_AXIS_T2_EDGE_DENSITY: nx_int = 6
62const NX_AXIS_T2_PORE_DETAIL: nx_int = 7
63const NX_AXIS_T2_KMEANS_CLUSTERS: nx_int = 8
64const NX_AXIS_T3_FACE_PRESENT: nx_int = 9
65const NX_AXIS_T3_HAND_PRESENT: nx_int = 10
66const NX_AXIS_T3_BODY_PRESENT: nx_int = 11
67const NX_AXIS_T4_UNDERTONE: nx_int = 12
68const NX_AXIS_T4_AGE_CLASS: nx_int = 13
69const NX_AXIS_T4_EXPRESSION_CLASS: nx_int = 14
70const NX_AXIS_T4_MATERIAL_CLASS: nx_int = 15
71const NX_AXIS_T5_VEIN_SIGNAL: nx_int = 16
72const NX_AXIS_T5_SUBSURFACE_SIGNAL: nx_int = 17
73const NX_AXIS_T5_IRIS_DETAIL: nx_int = 18
74const NX_AXIS_T5_LIP_TEXTURE: nx_int = 19
75const NX_AXIS_T5_HAIR_FOLLICLE: nx_int = 20
76const NX_AXIS_T5_MICRO_WRINKLE: nx_int = 21
77const NX_AXIS_T5B_MICRO_EXPRESSION: nx_int = 22
78const NX_AXIS_T6_SHADOW_DIRECTION: nx_int = 23
79const NX_AXIS_T6_FINGER_COUNT: nx_int = 24
80const NX_AXIS_T6_LIMB_COUNT: nx_int = 25
81const NX_AXIS_T6_POSE_NATURALNESS: nx_int = 26
82const NX_AXIS_T6_SURFACE_PLANE: nx_int = 27
83const NX_AXIS_T6_SILHOUETTE_INTEG: nx_int = 28
84const NX_AXIS_T6_JOINT_CONTINUITY: nx_int = 29
85const NX_AXIS_T6_VANISHING_POINT: nx_int = 30
86
87// Domain-specific extras occupy bits 32-63.
88const NX_AXIS_DX_FABRIC_DRAPE: nx_int = 32
89const NX_AXIS_DX_SEAM_CONTINUITY: nx_int = 33
90const NX_AXIS_DX_WEAVE_PATTERN: nx_int = 34
91const NX_AXIS_DX_BUTTONS_ALIGN: nx_int = 35
92const NX_AXIS_DX_EDGE_GEOMETRY: nx_int = 36
93const NX_AXIS_DX_HAMMERED_PATTERN: nx_int = 37
94const NX_AXIS_DX_BLADE_TAPER: nx_int = 38
95const NX_AXIS_DX_GRAIN_DIRECTION: nx_int = 39
96const NX_AXIS_DX_CARVING_DEPTH: nx_int = 40
97const NX_AXIS_DX_TUSK_COUNT: nx_int = 41
98const NX_AXIS_DX_SCARRING_DENSITY: nx_int = 42
99const NX_AXIS_DX_SKIN_PEBBLE: nx_int = 43
100const NX_AXIS_DX_EAR_POINT: nx_int = 44
101const NX_AXIS_DX_FUR_DIRECTION: nx_int = 45
102const NX_AXIS_DX_CANINE_DENTITION: nx_int = 46
103const NX_AXIS_DX_BRICK_ALIGNMENT: nx_int = 47
104const NX_AXIS_DX_WINDOW_UNIFORM: nx_int = 48
105const NX_AXIS_DX_ROOF_PITCH: nx_int = 49
106const NX_AXIS_DX_HORIZON_LINE: nx_int = 50
107const NX_AXIS_DX_AERIAL_PERSP: nx_int = 51
108const NX_AXIS_DX_ATMOSPHERIC_HAZE: nx_int = 52
109
110// ===== profile struct ============================================
111//
112// per-domain settings: which axes apply + reward-shaping
113// coefficients (Q10) per axis + a 64-bit applicable_mask for
114// fast filtering.
115
116struct NxDomainProfile {
117 domain_id: nx_int,
118 applicable_mask: nx_int, // bit-per-axis
119 n_applicable: nx_int,
120 weight_default: nx_int, // Q10 default weight when not overridden
121}
122
123const NX_DOMAIN_PROFILE_BYTES: nx_size = 32
124
125// Default Q10 weight when an axis applies.
126const NX_DOMAIN_WEIGHT_DEFAULT_Q10: nx_int = 1024
127
128// ===== helpers ====================================================
129
130func _domain_bitor(mask: nx_int, bit: nx_int) -> nx_int {
131 if bit < 0 { return mask }
132 if bit >= 64 { return mask }
133 let one_shifted: nx_int = 1 << bit
134 return mask | one_shifted
135}
136
137func _domain_popcount(mask: nx_int) -> nx_int {
138 var count: nx_int = 0
139 var x: nx_int = mask
140 var safety: nx_int = 0
141 while safety < 64 {
142 if x == 0 { return count }
143 let lsb: nx_int = x & 1
144 if lsb == 1 { count = count + 1 }
145 x = x >> 1
146 safety = safety + 1
147 }
148 return count
149}
150
151func nx_domain_axis_applies(profile: *NxDomainProfile, axis: nx_int) -> nx_int {
152 if axis < 0 { return 0 }
153 if axis >= 64 { return 0 }
154 let shifted: nx_int = profile.applicable_mask >> axis
155 let lsb: nx_int = shifted & 1
156 return lsb
157}
158
159// ===== profile builders ==========================================
160//
161// Per-domain applicable-axis masks. Hardcoded for the 11 starter
162// domains; future catalog-driven extension reads JSONL.
163
164func _domain_human_adult_mask() -> nx_int {
165 var m: nx_int = 0
166 m = _domain_bitor(m, NX_AXIS_T0_DIMENSIONS)
167 m = _domain_bitor(m, NX_AXIS_T1_LUMINANCE)
168 m = _domain_bitor(m, NX_AXIS_T1_HISTOGRAM)
169 m = _domain_bitor(m, NX_AXIS_T1_SKIN_TONE_ITA)
170 m = _domain_bitor(m, NX_AXIS_T2_GLCM_TEXTURE)
171 m = _domain_bitor(m, NX_AXIS_T2_PORE_DETAIL)
172 m = _domain_bitor(m, NX_AXIS_T3_FACE_PRESENT)
173 m = _domain_bitor(m, NX_AXIS_T3_HAND_PRESENT)
174 m = _domain_bitor(m, NX_AXIS_T3_BODY_PRESENT)
175 m = _domain_bitor(m, NX_AXIS_T4_UNDERTONE)
176 m = _domain_bitor(m, NX_AXIS_T4_EXPRESSION_CLASS)
177 m = _domain_bitor(m, NX_AXIS_T5_VEIN_SIGNAL)
178 m = _domain_bitor(m, NX_AXIS_T5_SUBSURFACE_SIGNAL)
179 m = _domain_bitor(m, NX_AXIS_T5_IRIS_DETAIL)
180 m = _domain_bitor(m, NX_AXIS_T5_LIP_TEXTURE)
181 m = _domain_bitor(m, NX_AXIS_T5_HAIR_FOLLICLE)
182 m = _domain_bitor(m, NX_AXIS_T5_MICRO_WRINKLE)
183 m = _domain_bitor(m, NX_AXIS_T5B_MICRO_EXPRESSION)
184 m = _domain_bitor(m, NX_AXIS_T6_SHADOW_DIRECTION)
185 m = _domain_bitor(m, NX_AXIS_T6_FINGER_COUNT)
186 m = _domain_bitor(m, NX_AXIS_T6_LIMB_COUNT)
187 m = _domain_bitor(m, NX_AXIS_T6_POSE_NATURALNESS)
188 m = _domain_bitor(m, NX_AXIS_T6_SILHOUETTE_INTEG)
189 m = _domain_bitor(m, NX_AXIS_T6_JOINT_CONTINUITY)
190 return m
191}
192
193func _domain_fantasy_orc_mask() -> nx_int {
194 var m: nx_int = 0
195 m = _domain_bitor(m, NX_AXIS_T0_DIMENSIONS)
196 m = _domain_bitor(m, NX_AXIS_T1_LUMINANCE)
197 m = _domain_bitor(m, NX_AXIS_T1_HISTOGRAM)
198 m = _domain_bitor(m, NX_AXIS_T2_GLCM_TEXTURE)
199 m = _domain_bitor(m, NX_AXIS_T2_PORE_DETAIL)
200 m = _domain_bitor(m, NX_AXIS_T3_FACE_PRESENT)
201 m = _domain_bitor(m, NX_AXIS_T3_BODY_PRESENT)
202 m = _domain_bitor(m, NX_AXIS_T6_SHADOW_DIRECTION)
203 m = _domain_bitor(m, NX_AXIS_T6_LIMB_COUNT)
204 m = _domain_bitor(m, NX_AXIS_T6_POSE_NATURALNESS)
205 m = _domain_bitor(m, NX_AXIS_T6_SILHOUETTE_INTEG)
206 m = _domain_bitor(m, NX_AXIS_T6_JOINT_CONTINUITY)
207 // Domain-specific:
208 m = _domain_bitor(m, NX_AXIS_DX_TUSK_COUNT)
209 m = _domain_bitor(m, NX_AXIS_DX_SCARRING_DENSITY)
210 m = _domain_bitor(m, NX_AXIS_DX_SKIN_PEBBLE)
211 return m
212}
213
214func _domain_fantasy_elf_mask() -> nx_int {
215 var m: nx_int = _domain_human_adult_mask()
216 m = _domain_bitor(m, NX_AXIS_DX_EAR_POINT)
217 return m
218}
219
220func _domain_creature_wolf_mask() -> nx_int {
221 var m: nx_int = 0
222 m = _domain_bitor(m, NX_AXIS_T0_DIMENSIONS)
223 m = _domain_bitor(m, NX_AXIS_T1_LUMINANCE)
224 m = _domain_bitor(m, NX_AXIS_T2_GLCM_TEXTURE)
225 m = _domain_bitor(m, NX_AXIS_T3_BODY_PRESENT)
226 m = _domain_bitor(m, NX_AXIS_T6_SHADOW_DIRECTION)
227 m = _domain_bitor(m, NX_AXIS_T6_LIMB_COUNT)
228 m = _domain_bitor(m, NX_AXIS_T6_POSE_NATURALNESS)
229 m = _domain_bitor(m, NX_AXIS_T6_SILHOUETTE_INTEG)
230 m = _domain_bitor(m, NX_AXIS_DX_FUR_DIRECTION)
231 m = _domain_bitor(m, NX_AXIS_DX_CANINE_DENTITION)
232 return m
233}
234
235func _domain_clothing_garment_mask() -> nx_int {
236 var m: nx_int = 0
237 m = _domain_bitor(m, NX_AXIS_T0_DIMENSIONS)
238 m = _domain_bitor(m, NX_AXIS_T1_LUMINANCE)
239 m = _domain_bitor(m, NX_AXIS_T1_HISTOGRAM)
240 m = _domain_bitor(m, NX_AXIS_T2_GLCM_TEXTURE)
241 m = _domain_bitor(m, NX_AXIS_T2_EDGE_DENSITY)
242 m = _domain_bitor(m, NX_AXIS_T6_SHADOW_DIRECTION)
243 m = _domain_bitor(m, NX_AXIS_T6_SILHOUETTE_INTEG)
244 m = _domain_bitor(m, NX_AXIS_DX_FABRIC_DRAPE)
245 m = _domain_bitor(m, NX_AXIS_DX_SEAM_CONTINUITY)
246 m = _domain_bitor(m, NX_AXIS_DX_WEAVE_PATTERN)
247 m = _domain_bitor(m, NX_AXIS_DX_BUTTONS_ALIGN)
248 return m
249}
250
251func _domain_weapon_steel_mask() -> nx_int {
252 var m: nx_int = 0
253 m = _domain_bitor(m, NX_AXIS_T0_DIMENSIONS)
254 m = _domain_bitor(m, NX_AXIS_T1_LUMINANCE)
255 m = _domain_bitor(m, NX_AXIS_T2_GLCM_TEXTURE)
256 m = _domain_bitor(m, NX_AXIS_T2_EDGE_DENSITY)
257 m = _domain_bitor(m, NX_AXIS_T6_SHADOW_DIRECTION)
258 m = _domain_bitor(m, NX_AXIS_T6_SILHOUETTE_INTEG)
259 m = _domain_bitor(m, NX_AXIS_DX_EDGE_GEOMETRY)
260 m = _domain_bitor(m, NX_AXIS_DX_HAMMERED_PATTERN)
261 m = _domain_bitor(m, NX_AXIS_DX_BLADE_TAPER)
262 return m
263}
264
265func _domain_weapon_wood_mask() -> nx_int {
266 var m: nx_int = 0
267 m = _domain_bitor(m, NX_AXIS_T0_DIMENSIONS)
268 m = _domain_bitor(m, NX_AXIS_T1_LUMINANCE)
269 m = _domain_bitor(m, NX_AXIS_T2_GLCM_TEXTURE)
270 m = _domain_bitor(m, NX_AXIS_T2_EDGE_DENSITY)
271 m = _domain_bitor(m, NX_AXIS_T6_SHADOW_DIRECTION)
272 m = _domain_bitor(m, NX_AXIS_T6_SILHOUETTE_INTEG)
273 m = _domain_bitor(m, NX_AXIS_DX_GRAIN_DIRECTION)
274 m = _domain_bitor(m, NX_AXIS_DX_CARVING_DEPTH)
275 return m
276}
277
278func _domain_architecture_mask() -> nx_int {
279 var m: nx_int = 0
280 m = _domain_bitor(m, NX_AXIS_T0_DIMENSIONS)
281 m = _domain_bitor(m, NX_AXIS_T1_LUMINANCE)
282 m = _domain_bitor(m, NX_AXIS_T2_EDGE_DENSITY)
283 m = _domain_bitor(m, NX_AXIS_T6_SHADOW_DIRECTION)
284 m = _domain_bitor(m, NX_AXIS_T6_VANISHING_POINT)
285 m = _domain_bitor(m, NX_AXIS_T6_SURFACE_PLANE)
286 m = _domain_bitor(m, NX_AXIS_DX_BRICK_ALIGNMENT)
287 m = _domain_bitor(m, NX_AXIS_DX_WINDOW_UNIFORM)
288 m = _domain_bitor(m, NX_AXIS_DX_ROOF_PITCH)
289 return m
290}
291
292func _domain_environment_mask() -> nx_int {
293 var m: nx_int = 0
294 m = _domain_bitor(m, NX_AXIS_T0_DIMENSIONS)
295 m = _domain_bitor(m, NX_AXIS_T1_LUMINANCE)
296 m = _domain_bitor(m, NX_AXIS_T1_HISTOGRAM)
297 m = _domain_bitor(m, NX_AXIS_T2_EDGE_DENSITY)
298 m = _domain_bitor(m, NX_AXIS_T6_SHADOW_DIRECTION)
299 m = _domain_bitor(m, NX_AXIS_T6_VANISHING_POINT)
300 m = _domain_bitor(m, NX_AXIS_DX_HORIZON_LINE)
301 m = _domain_bitor(m, NX_AXIS_DX_AERIAL_PERSP)
302 m = _domain_bitor(m, NX_AXIS_DX_ATMOSPHERIC_HAZE)
303 return m
304}
305
306// ===== profile factory ============================================
307
308func nx_domain_profile_get(domain_id: nx_int) -> *NxDomainProfile {
309 if nx_domain_is_valid(domain_id) == 0 { return 0 as *NxDomainProfile }
310 let p_ptr: *u8 = sys_mmap(NX_DOMAIN_PROFILE_BYTES)
311 let p: *NxDomainProfile = p_ptr as *NxDomainProfile
312 p.domain_id = domain_id
313 p.weight_default = NX_DOMAIN_WEIGHT_DEFAULT_Q10
314
315 var mask: nx_int = 0
316 if domain_id == NX_DOMAIN_HUMAN_ADULT {
317 mask = _domain_human_adult_mask()
318 }
319 if domain_id == NX_DOMAIN_HUMAN_CHILD {
320 mask = _domain_human_adult_mask()
321 }
322 if domain_id == NX_DOMAIN_FANTASY_ORC {
323 mask = _domain_fantasy_orc_mask()
324 }
325 if domain_id == NX_DOMAIN_FANTASY_ELF {
326 mask = _domain_fantasy_elf_mask()
327 }
328 if domain_id == NX_DOMAIN_FANTASY_DWARF {
329 mask = _domain_human_adult_mask()
330 }
331 if domain_id == NX_DOMAIN_CREATURE_WOLF {
332 mask = _domain_creature_wolf_mask()
333 }
334 if domain_id == NX_DOMAIN_CLOTHING_GARMENT {
335 mask = _domain_clothing_garment_mask()
336 }
337 if domain_id == NX_DOMAIN_WEAPON_STEEL {
338 mask = _domain_weapon_steel_mask()
339 }
340 if domain_id == NX_DOMAIN_WEAPON_WOOD {
341 mask = _domain_weapon_wood_mask()
342 }
343 if domain_id == NX_DOMAIN_ARCHITECTURE {
344 mask = _domain_architecture_mask()
345 }
346 if domain_id == NX_DOMAIN_ENVIRONMENT {
347 mask = _domain_environment_mask()
348 }
349 p.applicable_mask = mask
350 p.n_applicable = _domain_popcount(mask)
351 return p
352}
353
354// ===== self-test ==================================================
355
356func main() -> nx_int {
357 // HUMAN_ADULT applies many axes including ITA + vein.
358 let p_human: *NxDomainProfile = nx_domain_profile_get(NX_DOMAIN_HUMAN_ADULT)
359 if p_human == (0 as *NxDomainProfile) { return 1 }
360 if p_human.domain_id != NX_DOMAIN_HUMAN_ADULT { return 2 }
361 if nx_domain_axis_applies(p_human, NX_AXIS_T1_SKIN_TONE_ITA) != 1 { return 3 }
362 if nx_domain_axis_applies(p_human, NX_AXIS_T5_VEIN_SIGNAL) != 1 { return 4 }
363 if nx_domain_axis_applies(p_human, NX_AXIS_T5B_MICRO_EXPRESSION) != 1 { return 5 }
364 if nx_domain_axis_applies(p_human, NX_AXIS_DX_FABRIC_DRAPE) != 0 { return 6 }
365 if nx_domain_axis_applies(p_human, NX_AXIS_DX_TUSK_COUNT) != 0 { return 7 }
366
367 // ORC: pebble + tusk apply; ITA does NOT (orcs aren't on
368 // Fitzpatrick), micro-expression does NOT (orcs aren't graded
369 // on the human-aliveness ladder).
370 let p_orc: *NxDomainProfile = nx_domain_profile_get(NX_DOMAIN_FANTASY_ORC)
371 if nx_domain_axis_applies(p_orc, NX_AXIS_DX_TUSK_COUNT) != 1 { return 10 }
372 if nx_domain_axis_applies(p_orc, NX_AXIS_DX_SKIN_PEBBLE) != 1 { return 11 }
373 if nx_domain_axis_applies(p_orc, NX_AXIS_T1_SKIN_TONE_ITA) != 0 { return 12 }
374 if nx_domain_axis_applies(p_orc, NX_AXIS_T5B_MICRO_EXPRESSION) != 0 { return 13 }
375
376 // CLOTHING: fabric / seam / weave / buttons apply; ITA + vein
377 // + tusk all DO NOT apply.
378 let p_cloth: *NxDomainProfile = nx_domain_profile_get(NX_DOMAIN_CLOTHING_GARMENT)
379 if nx_domain_axis_applies(p_cloth, NX_AXIS_DX_FABRIC_DRAPE) != 1 { return 20 }
380 if nx_domain_axis_applies(p_cloth, NX_AXIS_DX_SEAM_CONTINUITY) != 1 { return 21 }
381 if nx_domain_axis_applies(p_cloth, NX_AXIS_T1_SKIN_TONE_ITA) != 0 { return 22 }
382 if nx_domain_axis_applies(p_cloth, NX_AXIS_DX_TUSK_COUNT) != 0 { return 23 }
383
384 // WEAPON_STEEL: hammered + blade-taper apply; fabric does not.
385 let p_swrd: *NxDomainProfile = nx_domain_profile_get(NX_DOMAIN_WEAPON_STEEL)
386 if nx_domain_axis_applies(p_swrd, NX_AXIS_DX_HAMMERED_PATTERN) != 1 { return 30 }
387 if nx_domain_axis_applies(p_swrd, NX_AXIS_DX_BLADE_TAPER) != 1 { return 31 }
388 if nx_domain_axis_applies(p_swrd, NX_AXIS_DX_FABRIC_DRAPE) != 0 { return 32 }
389
390 // ARCHITECTURE: vanishing-point + brick-alignment apply; vein
391 // does not.
392 let p_arch: *NxDomainProfile = nx_domain_profile_get(NX_DOMAIN_ARCHITECTURE)
393 if nx_domain_axis_applies(p_arch, NX_AXIS_T6_VANISHING_POINT) != 1 { return 40 }
394 if nx_domain_axis_applies(p_arch, NX_AXIS_DX_BRICK_ALIGNMENT) != 1 { return 41 }
395 if nx_domain_axis_applies(p_arch, NX_AXIS_T5_VEIN_SIGNAL) != 0 { return 42 }
396
397 // Per-axis applicability count consistency.
398 if p_human.n_applicable < 20 { return 50 }
399 if p_orc.n_applicable < 10 { return 51 }
400 if p_cloth.n_applicable < 8 { return 52 }
401
402 // Out-of-range domain refused.
403 let p_bad: *NxDomainProfile = nx_domain_profile_get(NX_DOMAIN_N_KINDS)
404 if p_bad != (0 as *NxDomainProfile) { return 60 }
405 let p_neg: *NxDomainProfile = nx_domain_profile_get(-1)
406 if p_neg != (0 as *NxDomainProfile) { return 61 }
407
408 return 0
409}