code wiki / (root) / nx_corolla.nx

nx_corolla.nx source

↩ module page · 244 lines · 9047 B

1// nx_corolla.nx -- joy + beauty as primary first-class metric. 2// 3// Biology: the corolla is the colored petal whorl that signals reproductive 4// vitality to pollinators -- beauty as HONEST signal of fitness. In Nishi, 5// it is the substrate's commitment that aesthetic outcomes (joy, beauty, 6// playability, awe) are FIRST-CLASS observables, not afterthoughts measured 7// only at end of integration. 8// 9// Per CARDINAL feedback-real-playtest-loop-not-just-logs: quantitative 10// telemetry (FPS, frame correctness) is NECESSARY but NEVER SUFFICIENT. 11// nx_corolla holds the qualitative axes alongside the quantitative. 12// 13// Resolves the earlier nx_bloom name collision per [[feedback-naming- 14// discipline-no-industry-competitor-overlap]] -- corolla is unowned in 15// software-infra trademark space. 16 17import "nx_syscalls.nx" 18import "nx_tier.nx" 19const NX_MAGIC_1024: i64 = 1024 20 21// ===== Sealed enum: NxAestheticAxis =============================== 22 23const NX_CO_AXIS_JOY: nx_int = 0 // user-reported delight 24const NX_CO_AXIS_BEAUTY: nx_int = 1 // visual / acoustic harmony 25const NX_CO_AXIS_AWE: nx_int = 2 // scale / unexpectedness 26const NX_CO_AXIS_PLAYABILITY: nx_int = 3 // game-feel correctness 27const NX_CO_AXIS_LIVENESS: nx_int = 4 // organic / alive feel 28const NX_CO_AXIS_COHERENCE: nx_int = 5 // parts feel-of-a-piece 29const NX_CO_AXIS_SURPRISE: nx_int = 6 // novelty within coherence 30const NX_CO_AXIS_PEACE: nx_int = 7 // calm / restorative 31const NX_CO_AXIS_N: nx_int = 8 32 33// ===== Sealed enum: NxCorollaSource =============================== 34// 35// Per CARDINAL feedback-real-playtest-loop-not-just-logs: never claim 36// substrate produces joy without HUMAN observation. Source enum makes 37// provenance of every score auditable. 38 39const NX_CO_SRC_AUTOMATED_PROXY: nx_int = 0 // smoke / heuristic (LOW WEIGHT) 40const NX_CO_SRC_OPERATOR: nx_int = 1 // operator playtest 41const NX_CO_SRC_FAMILY: nx_int = 2 // family member playtest 42const NX_CO_SRC_TRUSTED_REVIEWER: nx_int = 3 // formal review 43const NX_CO_SRC_COMMUNITY: nx_int = 4 // aggregated community 44const NX_CO_SRC_N: nx_int = 5 45 46// ===== Sealed verdict ============================================= 47 48const NX_CO_V_OK: nx_int = 0 49const NX_CO_V_THIN_EVIDENCE: nx_int = 1 // only automated proxies 50const NX_CO_V_BELOW_THRESHOLD: nx_int = 2 51const NX_CO_V_DIVERGENT: nx_int = 3 // quant green, qual low 52const NX_CO_V_NULL: nx_int = 4 53const NX_CO_V_INVALID: nx_int = 5 54const NX_CO_V_N: nx_int = 6 55 56// ===== Struct: NxCorollaReading ================================== 57 58struct NxCorollaReading { 59 axis: nx_int, 60 score_q10: nx_int, // 0..NX_MAGIC_1024 61 source: nx_int, 62 observer_id: nx_int, 63 observed_at_us: nx_size, 64 duration_us: nx_size, // observation window 65} 66 67const NX_CO_R_BYTES: nx_int = 40 68 69struct NxCorolla { 70 target_id: nx_int, 71 readings: *u8, 72 n_readings: nx_int, 73 capacity: nx_int, 74 threshold_q10: nx_int, // minimum acceptable mean score 75 minimum_human_readings: nx_int, 76 created_at_us: nx_size, 77} 78 79const NX_CO_BYTES: nx_int = 48 80 81// ===== Validators ================================================= 82 83func nx_co_axis_is_valid(a: nx_int) -> nx_int { 84 if a < 0 { return 0 } 85 if a >= NX_CO_AXIS_N { return 0 } 86 return 1 87} 88 89func nx_co_src_is_valid(s: nx_int) -> nx_int { 90 if s < 0 { return 0 } 91 if s >= NX_CO_SRC_N { return 0 } 92 return 1 93} 94 95func nx_co_v_is_valid(v: nx_int) -> nx_int { 96 if v < 0 { return 0 } 97 if v >= NX_CO_V_N { return 0 } 98 return 1 99} 100 101func nx_co_src_is_human(s: nx_int) -> nx_int { 102 if s == NX_CO_SRC_OPERATOR { return 1 } 103 if s == NX_CO_SRC_FAMILY { return 1 } 104 if s == NX_CO_SRC_TRUSTED_REVIEWER { return 1 } 105 if s == NX_CO_SRC_COMMUNITY { return 1 } 106 return 0 107} 108 109// ===== Constructor ================================================ 110 111func nx_co_new(target_id: nx_int, 112 capacity: nx_int, 113 threshold_q10: nx_int, 114 minimum_human_readings: nx_int, 115 now_us: nx_size) -> *NxCorolla { 116 if capacity <= 0 { return 0 as *NxCorolla } 117 if threshold_q10 < 0 { return 0 as *NxCorolla } 118 if threshold_q10 > NX_MAGIC_1024 { return 0 as *NxCorolla } 119 if minimum_human_readings < 0 { return 0 as *NxCorolla } 120 let raw: *u8 = sys_mmap(NX_CO_BYTES) 121 let c: *NxCorolla = raw as *NxCorolla 122 c.target_id = target_id 123 c.readings = sys_mmap(capacity * NX_CO_R_BYTES) 124 c.n_readings = 0 125 c.capacity = capacity 126 c.threshold_q10 = threshold_q10 127 c.minimum_human_readings = minimum_human_readings 128 c.created_at_us = now_us 129 return c 130} 131 132func _co_reading_at(c: *NxCorolla, idx: nx_int) -> *NxCorollaReading { 133 if idx < 0 { return 0 as *NxCorollaReading } 134 if idx >= c.n_readings { return 0 as *NxCorollaReading } 135 let off: nx_int = idx * NX_CO_R_BYTES 136 return (c.readings + off) as *NxCorollaReading 137} 138 139// ===== Record reading ============================================= 140 141func nx_co_record(c: *NxCorolla, 142 axis: nx_int, 143 score_q10: nx_int, 144 source: nx_int, 145 observer_id: nx_int, 146 duration_us: nx_size, 147 now_us: nx_size) -> nx_int { 148 if (c as i64) == 0 { return NX_CO_V_NULL } 149 if nx_co_axis_is_valid(axis) == 0 { return NX_CO_V_INVALID } 150 if nx_co_src_is_valid(source) == 0 { return NX_CO_V_INVALID } 151 if score_q10 < 0 { return NX_CO_V_INVALID } 152 if score_q10 > NX_MAGIC_1024 { return NX_CO_V_INVALID } 153 if c.n_readings >= c.capacity { return NX_CO_V_INVALID } 154 let off: nx_int = c.n_readings * NX_CO_R_BYTES 155 let r: *NxCorollaReading = (c.readings + off) as *NxCorollaReading 156 r.axis = axis 157 r.score_q10 = score_q10 158 r.source = source 159 r.observer_id = observer_id 160 r.observed_at_us = now_us 161 r.duration_us = duration_us 162 c.n_readings = c.n_readings + 1 163 return NX_CO_V_OK 164} 165 166// ===== Aggregations =============================================== 167 168func nx_co_mean_q10_by_axis(c: *NxCorolla, axis: nx_int) -> nx_int { 169 if (c as i64) == 0 { return 0 } 170 var sum: nx_int = 0 171 var count: nx_int = 0 172 var i: nx_int = 0 173 while i < c.n_readings { 174 let r: *NxCorollaReading = _co_reading_at(c, i) 175 if r.axis == axis { 176 sum = sum + r.score_q10 177 count = count + 1 178 } 179 i = i + 1 180 } 181 if count == 0 { return 0 } 182 return sum / count 183} 184 185func nx_co_human_reading_count(c: *NxCorolla) -> nx_int { 186 if (c as i64) == 0 { return 0 } 187 var count: nx_int = 0 188 var i: nx_int = 0 189 while i < c.n_readings { 190 let r: *NxCorollaReading = _co_reading_at(c, i) 191 if nx_co_src_is_human(r.source) == 1 { count = count + 1 } 192 i = i + 1 193 } 194 return count 195} 196 197func nx_co_mean_q10_human_only(c: *NxCorolla, axis: nx_int) -> nx_int { 198 if (c as i64) == 0 { return 0 } 199 var sum: nx_int = 0 200 var count: nx_int = 0 201 var i: nx_int = 0 202 while i < c.n_readings { 203 let r: *NxCorollaReading = _co_reading_at(c, i) 204 if r.axis == axis { 205 if nx_co_src_is_human(r.source) == 1 { 206 sum = sum + r.score_q10 207 count = count + 1 208 } 209 } 210 i = i + 1 211 } 212 if count == 0 { return 0 } 213 return sum / count 214} 215 216// ===== Classify =================================================== 217// 218// Verdict logic per CARDINAL feedback-real-playtest-loop-not-just-logs: 219// - Insufficient human readings -> THIN_EVIDENCE (refuse to claim joy 220// from automated proxies alone) 221// - Human mean below threshold -> BELOW_THRESHOLD 222// - Automated mean OK but human mean low -> DIVERGENT (the dangerous 223// passing-smokes-while-broken-UX case) 224// - Otherwise OK 225 226func nx_co_classify(c: *NxCorolla, axis: nx_int) -> nx_int { 227 if (c as i64) == 0 { return NX_CO_V_NULL } 228 if nx_co_axis_is_valid(axis) == 0 { return NX_CO_V_INVALID } 229 let human_count: nx_int = nx_co_human_reading_count(c) 230 if human_count < c.minimum_human_readings { return NX_CO_V_THIN_EVIDENCE } 231 let human_mean: nx_int = nx_co_mean_q10_human_only(c, axis) 232 if human_mean < c.threshold_q10 { return NX_CO_V_BELOW_THRESHOLD } 233 let overall_mean: nx_int = nx_co_mean_q10_by_axis(c, axis) 234 // DIVERGENT: automated alone would have passed but human is significantly 235 // lower (delta >= 200/1024 ~ 20%). This is the "smokes green, UX broken" 236 // class CARDINAL feedback-real-playtest-loop-not-just-logs catches. 237 var delta: nx_int = 0 238 delta = overall_mean - human_mean 239 if delta < 0 { delta = 0 - delta } 240 if delta >= 200 { 241 if human_mean < (c.threshold_q10 + 100) { return NX_CO_V_DIVERGENT } 242 } 243 return NX_CO_V_OK 244}