code wiki / (root) / nx_layer_verdict.nx

nx_layer_verdict.nx source

↩ module page · 349 lines · 15222 B

1// nx_layer_verdict.nx -- polymorphic per-layer grader verdict. 2// 3// Per user 2026-05-16: "i also again want our proc gen to always 4// layer by layer and overall meta have a god is this good and it 5// should do that based on the math like we were building in the 6// elder ai for images and video and sound" 7// 8// This primitive is the SHARED DATA STRUCTURE that every per-layer 9// grader emits. Composes with nx_meta_verdict.nx (the META 10// aggregator that produces the "God saw it was good" overall grade). 11// 12// Mathematical posture (matches Elder AI's image/video/sound grader 13// design): 14// - Every layer has 1-12 axes, each scored Q14 [0, Q]. 15// - Axis verdicts: WIN (>= 0.6Q), MARGINAL (>= 0.4Q), LOSS (else). 16// - Layer grade is computed from axis verdict counts (4-axis-wins, 17// etc.); same rubric as nx_quality_grade.nx for inter-grader 18// consistency. 19// - REFINE_HINT names the weakest axis to direct iterative 20// improvement. 21// 22// LAYER_VERDICT layout (16 i64, all Q14 except sealed-enums): 23// v[0] layer_kind sealed enum NX_LAYER_KIND_* 24// v[1] grade F=0..S=5 25// v[2] n_axes_used 1..12 (number of axes actually scored) 26// v[3] refine_hint sealed enum NX_LAYER_REFINE_* 27// v[4..15] axis_scores[12] Q14 [0, Q] per axis; unused axes = 0 28// 29// The 12-axis ceiling is a hard cap; if a grader needs more axes, 30// either split into multiple LAYER_VERDICT records or pre-aggregate. 31// 32// genealogy_id: elder_ai_image_grader + elder_ai_sound_grader_canon + 33// nx_quality_grade_sclass_canon 34// lineage_id: nx_layer_verdict_polymorphic_v1 35 36// nx_safety_envelope: 37// intended_use: AUTO_APPLIED -- primitive-specific tuning queued 38// sil_target: SIL1 39// evidence: [bulk_applied_2026-05-16, see-file-comment-for-detail] 40// verdict: NOT_YET_EVALUATED 41 42import "nx_syscalls.nx" 43import "nx_tier.nx" 44 45// ===== Q14 ========================================================== 46const NX_LV_Q: nx_int = 16384 47 48// ===== LAYER_VERDICT layout ========================================= 49const NX_LV_STRIDE: nx_int = 16 50 51const NX_LV_OFF_KIND: nx_int = 0 52const NX_LV_OFF_GRADE: nx_int = 1 53const NX_LV_OFF_N_AXES: nx_int = 2 54const NX_LV_OFF_REFINE_HINT: nx_int = 3 55const NX_LV_OFF_AXIS_0: nx_int = 4 56const NX_LV_OFF_AXIS_LAST: nx_int = 15 57 58const NX_LV_MAX_AXES: nx_int = 12 59 60// ===== Layer-kind sealed enum ======================================= 61// Each procgen layer in the substrate gets a unique kind ID. Add new 62// kinds at the END additively per cardinal rule 13. 63const NX_LAYER_KIND_HEIGHTMAP: nx_int = 0 // nx_terrestrial_surface / nx_world_quality_grader 64const NX_LAYER_KIND_BIOME: nx_int = 1 // nx_biome_classifier output 65const NX_LAYER_KIND_FOREST: nx_int = 2 // nx_forest_layout placement 66const NX_LAYER_KIND_RIVER: nx_int = 3 // nx_river_carve path quality 67const NX_LAYER_KIND_TOWN: nx_int = 4 // nx_town_layout coherence 68const NX_LAYER_KIND_CRATER: nx_int = 5 // nx_crater_field density 69const NX_LAYER_KIND_WEATHER: nx_int = 6 // nx_weather_pattern coherence 70const NX_LAYER_KIND_ATMOSPHERE: nx_int = 7 // sky/fog/scattering quality 71const NX_LAYER_KIND_AUDIO: nx_int = 8 // sound design grader (Elder AI parallel) 72const NX_LAYER_KIND_COLOR: nx_int = 9 // color palette / contrast / vibrancy 73const NX_LAYER_KIND_READABILITY: nx_int = 10 // overall visual readability 74const NX_LAYER_KIND_HAMMERED: nx_int = 11 // nx_hammered_zone variety 75const NX_LAYER_KIND_CASTLE: nx_int = 12 // nx_castle_layout / architectural 76const NX_LAYER_KIND_WATER_EROSION: nx_int = 13 // nx_water_erosion convergence 77const NX_LAYER_KIND_ORE_DEPOSIT: nx_int = 14 // nx_ore_deposit distribution 78 79const NX_LAYER_KIND_COUNT: nx_int = 15 80 81func nx_layer_kind_is_valid(k: nx_int) -> nx_int { 82 if k >= 0 { if k < NX_LAYER_KIND_COUNT { return 1 } } 83 return 0 84} 85 86// ===== Grade sealed enum (matches nx_quality_grade.nx) ============= 87const NX_LV_GRADE_F: nx_int = 0 88const NX_LV_GRADE_D: nx_int = 1 89const NX_LV_GRADE_C: nx_int = 2 90const NX_LV_GRADE_B: nx_int = 3 91const NX_LV_GRADE_A: nx_int = 4 92const NX_LV_GRADE_S: nx_int = 5 93 94const NX_LV_GRADE_COUNT: nx_int = 6 95 96func nx_lv_grade_is_valid(g: nx_int) -> nx_int { 97 if g >= NX_LV_GRADE_F { if g <= NX_LV_GRADE_S { return 1 } } 98 return 0 99} 100 101// ===== Refine-hint sealed enum ===================================== 102// Generic refinement directions; per-layer graders can use these or 103// add layer-specific extensions via the meta field (queued). 104const NX_LAYER_REFINE_NONE: nx_int = 0 105const NX_LAYER_REFINE_MORE_RELIEF: nx_int = 1 106const NX_LAYER_REFINE_MORE_FEATURES: nx_int = 2 107const NX_LAYER_REFINE_LESS_FLATNESS: nx_int = 3 108const NX_LAYER_REFINE_ADD_DETAIL: nx_int = 4 109const NX_LAYER_REFINE_SMOOTH_NOISE: nx_int = 5 110const NX_LAYER_REFINE_FIX_FRACTAL: nx_int = 6 111const NX_LAYER_REFINE_FIX_BIOMES: nx_int = 7 112const NX_LAYER_REFINE_MORE_VARIETY: nx_int = 8 113const NX_LAYER_REFINE_IMPROVE_READ: nx_int = 9 114const NX_LAYER_REFINE_FIX_COHERENCE: nx_int = 10 115const NX_LAYER_REFINE_REPLACE_LAYER: nx_int = 11 // layer is hopeless; regenerate 116 117const NX_LAYER_REFINE_COUNT: nx_int = 12 118 119func nx_layer_refine_is_valid(r: nx_int) -> nx_int { 120 if r >= 0 { if r < NX_LAYER_REFINE_COUNT { return 1 } } 121 return 0 122} 123 124// ===== Axis verdict thresholds ====================================== 125const NX_LV_AXIS_WIN_FLOOR: nx_int = 9830 // 0.6Q 126const NX_LV_AXIS_MARGINAL_FLOOR: nx_int = 6553 // 0.4Q 127 128// Axis verdict: 1 = WIN, 0 = MARGINAL, -1 = LOSS. 129func nx_lv_axis_verdict(score: nx_int) -> nx_int { 130 if score >= NX_LV_AXIS_WIN_FLOOR { return 1 } 131 if score >= NX_LV_AXIS_MARGINAL_FLOOR { return 0 } 132 return 0 - 1 133} 134 135// ===== Grade calculator from axis verdicts ========================= 136// Sums axis verdicts (WIN=1, MARG=0, LOSS=-1) and applies a consistent 137// rubric (matches nx_world_quality_grader's _wqg_grade_from_8 for 138// 8 axes, and degrades smoothly for other axis counts). 139// 140// Rule (n axes used, w wins, l losses): 141// w == n -> S 142// w == n - 1 -> A 143// w >= n * 3 / 4 -> B if losses <= 1 else C 144// w >= n / 2 -> C if losses <= 1 else D 145// losses >= n / 2 -> F 146// otherwise -> D 147func nx_layer_grade_from_axes( 148 axis_scores: *i64, n_axes: nx_int 149) -> nx_int { 150 if n_axes <= 0 { return NX_LV_GRADE_F } 151 if n_axes > NX_LV_MAX_AXES { return NX_LV_GRADE_F } 152 var wins: nx_int = 0 153 var losses: nx_int = 0 154 var i: nx_int = 0 155 while i < n_axes { 156 let v: nx_int = nx_lv_axis_verdict(axis_scores[i]) 157 if v == 1 { wins = wins + 1 } 158 if v == 0 - 1 { losses = losses + 1 } 159 i = i + 1 160 } 161 if losses * 2 >= n_axes { return NX_LV_GRADE_F } 162 if wins == n_axes { return NX_LV_GRADE_S } 163 if wins == n_axes - 1 { return NX_LV_GRADE_A } 164 let three_quarter_n: nx_int = (n_axes * 3) / 4 165 let half_n: nx_int = n_axes / 2 166 if wins >= three_quarter_n { 167 if losses <= 1 { return NX_LV_GRADE_B } 168 return NX_LV_GRADE_C 169 } 170 if wins >= half_n { 171 if losses <= 1 { return NX_LV_GRADE_C } 172 return NX_LV_GRADE_D 173 } 174 return NX_LV_GRADE_D 175} 176 177// ===== Writer (convenience) ========================================= 178// Initialises a LAYER_VERDICT record: zero-fills axes 0..12, sets the 179// supplied kind / n_axes / refine_hint, leaves grade as F. Caller 180// fills axis_scores via direct writes, then calls nx_layer_verdict_finalize. 181func nx_layer_verdict_init( 182 v: *i64, 183 layer_kind: nx_int, 184 n_axes: nx_int, 185 refine_hint: nx_int 186) { 187 var i: nx_int = 0 188 while i < NX_LV_STRIDE { v[i] = 0; i = i + 1 } 189 v[NX_LV_OFF_KIND] = layer_kind 190 v[NX_LV_OFF_GRADE] = NX_LV_GRADE_F 191 v[NX_LV_OFF_N_AXES] = n_axes 192 v[NX_LV_OFF_REFINE_HINT] = refine_hint 193} 194 195// ===== Finalizer ==================================================== 196// Computes the grade from axis scores and writes it into v[GRADE]. 197// Caller should write all axis scores before calling this. 198func nx_layer_verdict_finalize(v: *i64) { 199 let n: nx_int = v[NX_LV_OFF_N_AXES] 200 let axes: *i64 = (v as i64 + NX_LV_OFF_AXIS_0 * NX_SIZEOF_NX_INT) as *i64 201 let grade: nx_int = nx_layer_grade_from_axes(axes, n) 202 v[NX_LV_OFF_GRADE] = grade 203} 204 205// ===== Accessor: axis_score_q14 ==================================== 206func nx_layer_verdict_axis(v: *i64, axis_idx: nx_int) -> nx_int { 207 if axis_idx < 0 { return 0 } 208 if axis_idx >= NX_LV_MAX_AXES { return 0 } 209 return v[NX_LV_OFF_AXIS_0 + axis_idx] 210} 211 212// ===== Bulk writer (caller pre-fills 12 axes) ====================== 213func nx_layer_verdict_write( 214 v: *i64, 215 layer_kind: nx_int, 216 n_axes: nx_int, 217 refine_hint: nx_int, 218 axis_scores: *i64 219) { 220 nx_layer_verdict_init(v, layer_kind, n_axes, refine_hint) 221 var i: nx_int = 0 222 while i < n_axes { 223 if i < NX_LV_MAX_AXES { 224 v[NX_LV_OFF_AXIS_0 + i] = axis_scores[i] 225 } 226 i = i + 1 227 } 228 nx_layer_verdict_finalize(v) 229} 230 231// ===== Adapter: nx_world_quality_grader output -> LAYER_VERDICT ==== 232// nx_world_quality_grader writes 12 i64s with grade + 8 axis scores + 233// refine_axis + min/max heights. We copy the 8 axes into LAYER_VERDICT 234// axis slots 0..7, set kind=HEIGHTMAP, set refine_hint from refine_axis. 235// 236// wqg layout (per nx_world_quality_grader.nx NX_WQG_OFF_*): 237// 0=grade, 1=diversity, 2=local_var, 3=extremes, 4=flatness, 238// 5=fractal, 6=biome, 7=variety, 8=readability, 9=refine_axis, 239// 10=min, 11=max 240func nx_layer_verdict_from_wqg( 241 wqg_output: *i64, out: *i64 242) { 243 let refine: nx_int = wqg_output[9] 244 nx_layer_verdict_init(out, NX_LAYER_KIND_HEIGHTMAP, 8, refine) 245 out[NX_LV_OFF_AXIS_0 ] = wqg_output[1] // diversity 246 out[NX_LV_OFF_AXIS_0 + 1] = wqg_output[2] // local_variation 247 out[NX_LV_OFF_AXIS_0 + 2] = wqg_output[3] // extremes 248 // FLATNESS is inverted (lower = better); convert to a score where 249 // higher = better. 250 let q: nx_int = NX_LV_Q 251 let flat_inv: nx_int = q - wqg_output[4] 252 var clamped_flat: nx_int = flat_inv 253 if clamped_flat < 0 { clamped_flat = 0 } 254 if clamped_flat > q { clamped_flat = q } 255 out[NX_LV_OFF_AXIS_0 + 3] = clamped_flat 256 out[NX_LV_OFF_AXIS_0 + 4] = wqg_output[5] // fractal_dim 257 out[NX_LV_OFF_AXIS_0 + 5] = wqg_output[6] // biome_coherence 258 out[NX_LV_OFF_AXIS_0 + 6] = wqg_output[7] // feature_variety 259 out[NX_LV_OFF_AXIS_0 + 7] = wqg_output[8] // readability 260 nx_layer_verdict_finalize(out) 261} 262 263// ===== Self-test ==================================================== 264func main() -> i64 { 265 let q: nx_int = NX_LV_Q 266 267 // T1: Validity predicates. 268 if nx_layer_kind_is_valid(NX_LAYER_KIND_HEIGHTMAP) != 1 { return __syscall(93, 1, 0, 0, 0, 0, 0) } 269 if nx_layer_kind_is_valid(NX_LAYER_KIND_AUDIO) != 1 { return __syscall(93, 2, 0, 0, 0, 0, 0) } 270 if nx_layer_kind_is_valid(99) != 0 { return __syscall(93, 3, 0, 0, 0, 0, 0) } 271 if nx_lv_grade_is_valid(NX_LV_GRADE_S) != 1 { return __syscall(93, 4, 0, 0, 0, 0, 0) } 272 if nx_lv_grade_is_valid(99) != 0 { return __syscall(93, 5, 0, 0, 0, 0, 0) } 273 if nx_layer_refine_is_valid(NX_LAYER_REFINE_NONE) != 1 { return __syscall(93, 6, 0, 0, 0, 0, 0) } 274 if nx_layer_refine_is_valid(99) != 0 { return __syscall(93, 7, 0, 0, 0, 0, 0) } 275 276 // T2: Axis verdict bands. 277 if nx_lv_axis_verdict(q) != 1 { return __syscall(93, 10, 0, 0, 0, 0, 0) } // full-WIN 278 if nx_lv_axis_verdict(q * 7 / 10) != 1 { return __syscall(93, 11, 0, 0, 0, 0, 0) } // WIN 279 if nx_lv_axis_verdict(q / 2) != 0 { return __syscall(93, 12, 0, 0, 0, 0, 0) } // MARGINAL 280 if nx_lv_axis_verdict(q / 5) != 0 - 1 { return __syscall(93, 13, 0, 0, 0, 0, 0) } // LOSS 281 282 // T3: Grade from axes. 283 let axes: *i64 = (sys_mmap(NX_LV_MAX_AXES * NX_SIZEOF_NX_INT)) as *i64 284 var i: nx_int = 0 285 while i < NX_LV_MAX_AXES { axes[i] = 0; i = i + 1 } 286 287 // All 8 axes at full WIN -> S. 288 var j: nx_int = 0 289 while j < 8 { axes[j] = q; j = j + 1 } 290 if nx_layer_grade_from_axes(axes, 8) != NX_LV_GRADE_S { return __syscall(93, 20, 0, 0, 0, 0, 0) } 291 292 // 7 WIN + 1 MARGINAL -> A. 293 axes[7] = q / 2 294 if nx_layer_grade_from_axes(axes, 8) != NX_LV_GRADE_A { return __syscall(93, 21, 0, 0, 0, 0, 0) } 295 296 // 6 WIN + 2 MARGINAL (no losses) -> B. 297 axes[6] = q / 2 298 if nx_layer_grade_from_axes(axes, 8) != NX_LV_GRADE_B { return __syscall(93, 22, 0, 0, 0, 0, 0) } 299 300 // All 8 at LOSS -> F. 301 var k: nx_int = 0 302 while k < 8 { axes[k] = q / 10; k = k + 1 } 303 if nx_layer_grade_from_axes(axes, 8) != NX_LV_GRADE_F { return __syscall(93, 23, 0, 0, 0, 0, 0) } 304 305 // T4: Writer + finalizer pipeline. 306 let v: *i64 = (sys_mmap(NX_LV_STRIDE * NX_SIZEOF_NX_INT)) as *i64 307 var w: nx_int = 0 308 while w < 5 { axes[w] = q; w = w + 1 } 309 while w < 8 { axes[w] = q / 2; w = w + 1 } 310 nx_layer_verdict_write(v, NX_LAYER_KIND_FOREST, 8, NX_LAYER_REFINE_NONE, axes) 311 if v[NX_LV_OFF_KIND] != NX_LAYER_KIND_FOREST { return __syscall(93, 30, 0, 0, 0, 0, 0) } 312 if v[NX_LV_OFF_N_AXES] != 8 { return __syscall(93, 31, 0, 0, 0, 0, 0) } 313 // 5 WIN + 3 MARGINAL = wins=5, losses=0. half_n=4, three_quarter=6. 314 // wins >= half_n=4, losses<=1 -> C. 315 if v[NX_LV_OFF_GRADE] != NX_LV_GRADE_C { return __syscall(93, 32, 0, 0, 0, 0, 0) } 316 317 // T5: Accessor reads back axis scores. 318 if nx_layer_verdict_axis(v, 0) != q { return __syscall(93, 40, 0, 0, 0, 0, 0) } 319 if nx_layer_verdict_axis(v, 5) != q / 2 { return __syscall(93, 41, 0, 0, 0, 0, 0) } 320 if nx_layer_verdict_axis(v, 99) != 0 { return __syscall(93, 42, 0, 0, 0, 0, 0) } 321 322 // T6: WQG-to-LayerVerdict adapter. 323 // Build a fake wqg output: grade=A, 8 axes all 0.7Q, refine=0. 324 let wqg: *i64 = (sys_mmap(12 * NX_SIZEOF_NX_INT)) as *i64 325 wqg[0] = NX_LV_GRADE_A 326 wqg[1] = q * 7 / 10 // diversity 327 wqg[2] = q * 7 / 10 // local_var 328 wqg[3] = q * 7 / 10 // extremes 329 wqg[4] = q * 3 / 10 // flatness (lower = better; inverted to 0.7Q in axis) 330 wqg[5] = q * 7 / 10 // fractal 331 wqg[6] = q * 7 / 10 // biome 332 wqg[7] = q * 7 / 10 // variety 333 wqg[8] = q * 7 / 10 // readability 334 wqg[9] = NX_LAYER_REFINE_NONE 335 wqg[10] = 0 336 wqg[11] = 1000 337 let v2: *i64 = (sys_mmap(NX_LV_STRIDE * NX_SIZEOF_NX_INT)) as *i64 338 nx_layer_verdict_from_wqg(wqg, v2) 339 if v2[NX_LV_OFF_KIND] != NX_LAYER_KIND_HEIGHTMAP { return __syscall(93, 50, 0, 0, 0, 0, 0) } 340 if v2[NX_LV_OFF_N_AXES] != 8 { return __syscall(93, 51, 0, 0, 0, 0, 0) } 341 // axis[3] = q - 0.3Q = 0.7Q. 342 let inv_flat: nx_int = nx_layer_verdict_axis(v2, 3) 343 if inv_flat < q * 6 / 10 { return __syscall(93, 52, 0, 0, 0, 0, 0) } 344 if inv_flat > q * 8 / 10 { return __syscall(93, 53, 0, 0, 0, 0, 0) } 345 // 8 axes all at 0.7Q -> 8 wins -> S. 346 if v2[NX_LV_OFF_GRADE] != NX_LV_GRADE_S { return __syscall(93, 54, 0, 0, 0, 0, 0) } 347 348 return 0 349}