code wiki / (root) / nx_ladder_lib.nx

nx_ladder_lib.nx source

↩ module page · 388 lines · 19026 B

1// nx_ladder_lib.nx -- THE ONE RULER FOR A BOARD'S LADDER TO SOTA: every rung says what it is FOR, and the board says 2// what best-in-class and the frontier ARE, dated. 3// 4// Operator 2026-09-06, after a day spent climbing toward a 2014 bar: "how you framed it here is how all the /compare 5// domains should be emitting with clarity on what dependencies from the first byte up all grow us each rung up to sota 6// with a clear target on what is best in class and what is frontier." The framing that answered "how much of the 2014 7// work applies to the 2026 stuff" was a role per rung (the ruler and the syntax tools are SUBSTRATE the frontier itself 8// uses; the perceptron is a triangulation ARM, not the contender; the target was SUPERSEDED) against two named, dated 9// targets. This lib makes that framing DATA every board carries and every consumer reads, instead of prose one seat 10// wrote once. 11// 12// THE DATA (rows in <domain>.plan, pipe-separated, NO pipe inside a field): 13// sotatarget|<id>|<class>|<sotabar-id>|<statement>|<ref key> 14// class is best-in-class (the proven, deployed leader today) or frontier (the research edge, current month); 15// <sotabar-id> names the sotabar| row that DATES it (nx_barfresh_lib judges that month), so a target without a 16// bar is UNDATED -- the exact defect that cost the day. 17// rungrole|<rung-id>|<role>|<target-id>|<why> 18// role is substrate (infrastructure the target's own methods consume: data, rulers, syntax tools, arithmetic), 19// arm (a sovereign arm that triangulates or baselines the target without competing for its number), 20// contender (a rung whose done-rule is a number against the target's) or superseded (kept as capability, retired 21// as a claim). Dependencies come from the rung| row's own deps field; this row adds the DIRECTION. 22// THE STATES: per target DATED (its bar row exists), UNDATED, BADCLASS, DUPLICATE (its id an earlier sotatarget row 23// already carries: one target declared twice); per rung PLACED, UNPLACED (no rungrole row), BADROLE, BADTARGET (its 24// rungrole row names a target no sotatarget row declares); rungrole rows naming no rung are ORPHANS, and a rungrole row 25// for a rung an earlier rungrole row already placed is a DUPLICATE ROLE (counted apart from orphans, refused alike). 26// MEASURED 2026-09-14 on search.plan: two sotatarget rows for one bar and one rung id used twice landed across a 27// transport drop, and only the rung id was refused (the plan-graph rule); ld_refusal_rule names WHICH rule refused so a 28// consumer prints it from this lib instead of paraphrasing. 29// THE VERDICT: NO-LADDER (exit 3) when the plan declares no target rows -- a domain opts in by declaring its first target 30// and is LABELED until then, never refused; LADDERED (exit 0) when both classes are declared and dated and every rung is 31// placed; PARTIAL (exit 1) otherwise, with every offender named -- a half-declared ladder is the "12-year-old tech" 32// shape (a target without a month, a rung with no direction), so once a board opts in it is held to the whole contract. 33// COMPOSES nx_barfresh_lib's line and field readers (one parser for plan rows) and its sotabar tag; classifies only. 34// license_tier: ORIGINAL No hw writes (Rule 26). 35import "nx_syscalls.nx" 36import "nx_barfresh_lib.nx" 37 38// sotatarget and rungrole, NOT target and ladder: the plan renderer already owns ladder| (the market-entry ladder, 39// ladder|level|best_in_class|have|grow|verdict), and a bare target| would be the next collision waiting to happen. 40const LD_TARGET_TAG: *u8 = "sotatarget|" 41const LD_LADDER_TAG: *u8 = "rungrole|" 42const LD_RUNG_TAG: *u8 = "rung|" 43const LD_CLASS_BIC: *u8 = "best-in-class" 44const LD_CLASS_FRONTIER: *u8 = "frontier" 45const LD_ROLE_SUBSTRATE: *u8 = "substrate" 46const LD_ROLE_ARM: *u8 = "arm" 47const LD_ROLE_CONTENDER: *u8 = "contender" 48const LD_ROLE_SUPERSEDED: *u8 = "superseded" 49const LD_I64: i64 = 8 50// fields 51const LD_F_T_ID: i64 = 1 52const LD_F_T_CLASS: i64 = 2 53const LD_F_T_BAR: i64 = 3 54const LD_F_T_STATEMENT: i64 = 4 55const LD_F_T_REF: i64 = 5 56const LD_F_L_RUNG: i64 = 1 57const LD_F_L_ROLE: i64 = 2 58const LD_F_L_TARGET: i64 = 3 59const LD_F_L_WHY: i64 = 4 60const LD_F_R_ID: i64 = 1 61const LD_F_R_TITLE: i64 = 2 62const LD_F_R_DEPS: i64 = 7 63// class codes 64const LD_C_BIC: i64 = 0 65const LD_C_FRONTIER: i64 = 1 66const LD_C_BADCLASS: i64 = 2 67// role codes 68const LD_R_SUBSTRATE: i64 = 0 69const LD_R_ARM: i64 = 1 70const LD_R_CONTENDER: i64 = 2 71const LD_R_SUPERSEDED: i64 = 3 72const LD_R_BADROLE: i64 = 4 73// rung placement 74const LD_P_PLACED: i64 = 0 75const LD_P_UNPLACED: i64 = 1 76const LD_P_BADROLE: i64 = 2 77const LD_P_BADTARGET: i64 = 3 78// target state 79const LD_T_DATED: i64 = 0 80const LD_T_UNDATED: i64 = 1 81const LD_T_BADCLASS: i64 = 2 82const LD_T_DUPLICATE: i64 = 3 83// exits 84const LD_EXIT_LADDERED: i64 = 0 85const LD_EXIT_PARTIAL: i64 = 1 86const LD_EXIT_NOLADDER: i64 = 3 87// census slots 88const LD_N_TARGETS: i64 = 0 89const LD_N_BIC: i64 = 1 90const LD_N_FRONTIER: i64 = 2 91const LD_N_UNDATED: i64 = 3 92const LD_N_BADCLASS: i64 = 4 93const LD_N_RUNGS: i64 = 5 94const LD_N_PLACED: i64 = 6 95const LD_N_UNPLACED: i64 = 7 96const LD_N_BADROLE: i64 = 8 97const LD_N_BADTARGET: i64 = 9 98const LD_N_SUBSTRATE: i64 = 10 99const LD_N_ARM: i64 = 11 100const LD_N_CONTENDER: i64 = 12 101const LD_N_SUPERSEDED: i64 = 13 102const LD_N_LADDER_ROWS: i64 = 14 103const LD_N_ORPHANS: i64 = 15 104// LD_N_UNCLIMBED -- declared targets with ZERO placed rungs climbing them. A SEPARATE AXIS: deliberately 105// NOT a partition member and deliberately NOT in ld_verdict. See ld_target_climbers for why each of those 106// would do harm rather than good. 107const LD_N_UNCLIMBED: i64 = 16 108const LD_N_DUPTARGET: i64 = 17 // sotatarget rows whose id an earlier row already carries (state DUPLICATE) 109const LD_N_DUPROLE: i64 = 18 // rungrole rows for a rung an earlier rungrole row already placed 110const LD_N_COUNT: i64 = 19 111const LD_NONE: i64 = 0 - 1 112 113// a span of the buffer equals a NUL-terminated literal 114func ld_span_is(buf: *u8, off: i64, len: i64, lit: *u8) -> i64 { 115 if len != bf_slen(lit) { return 0 } 116 var i: i64 = 0 117 while i < len { if buf[off + i] != lit[i] { return 0 } i = i + 1 } 118 return 1 119} 120 121func ld_class_code(buf: *u8, off: i64, len: i64) -> i64 { 122 if ld_span_is(buf, off, len, LD_CLASS_BIC) == 1 { return LD_C_BIC } 123 if ld_span_is(buf, off, len, LD_CLASS_FRONTIER) == 1 { return LD_C_FRONTIER } 124 return LD_C_BADCLASS 125} 126 127func ld_role_code(buf: *u8, off: i64, len: i64) -> i64 { 128 if ld_span_is(buf, off, len, LD_ROLE_SUBSTRATE) == 1 { return LD_R_SUBSTRATE } 129 if ld_span_is(buf, off, len, LD_ROLE_ARM) == 1 { return LD_R_ARM } 130 if ld_span_is(buf, off, len, LD_ROLE_CONTENDER) == 1 { return LD_R_CONTENDER } 131 if ld_span_is(buf, off, len, LD_ROLE_SUPERSEDED) == 1 { return LD_R_SUPERSEDED } 132 return LD_R_BADROLE 133} 134 135func ld_role_name(r: i64) -> *u8 { 136 if r == LD_R_SUBSTRATE { return LD_ROLE_SUBSTRATE } 137 if r == LD_R_ARM { return LD_ROLE_ARM } 138 if r == LD_R_CONTENDER { return LD_ROLE_CONTENDER } 139 if r == LD_R_SUPERSEDED { return LD_ROLE_SUPERSEDED } 140 return "BADROLE" as *u8 141} 142 143func ld_class_name(k: i64) -> *u8 { 144 if k == LD_C_BIC { return LD_CLASS_BIC } 145 if k == LD_C_FRONTIER { return LD_CLASS_FRONTIER } 146 return "BADCLASS" as *u8 147} 148 149func ld_place_name(p: i64) -> *u8 { 150 if p == LD_P_PLACED { return "PLACED" as *u8 } 151 if p == LD_P_UNPLACED { return "UNPLACED" as *u8 } 152 if p == LD_P_BADROLE { return "BADROLE" as *u8 } 153 return "BADTARGET" as *u8 154} 155 156func ld_tstate_name(t: i64) -> *u8 { 157 if t == LD_T_DATED { return "DATED" as *u8 } 158 if t == LD_T_UNDATED { return "UNDATED" as *u8 } 159 if t == LD_T_DUPLICATE { return "DUPLICATE" as *u8 } 160 return "BADCLASS" as *u8 161} 162 163func ld_verdict_name(v: i64) -> *u8 { 164 if v == LD_EXIT_LADDERED { return "LADDERED" as *u8 } 165 if v == LD_EXIT_PARTIAL { return "PARTIAL" as *u8 } 166 return "NO-LADDER" as *u8 167} 168 169// does any sotabar| row carry this id in its id field 170func ld_bar_exists(buf: *u8, n: i64, idoff: i64, idlen: i64) -> i64 { 171 let fo: *i64 = sys_mmap(LD_I64) as *i64 172 var p: i64 = 0 173 while p < n { 174 let e: i64 = bf_line_end(buf, n, p) 175 if bf_line_starts(buf, p, e, BF_BAR_TAG) == 1 { 176 let l: i64 = bf_field(buf, p, e, BF_F_BAR_ID, fo) 177 if l > 0 { if bf_span_eq(buf, fo[0], l, idoff, idlen) == 1 { return 1 } } 178 } 179 p = e + 1 180 } 181 return 0 182} 183 184// THE CLASSIFIER. Targets: toff[i] = line start, tcls[i] = class code, tst[i] = state. Rungs: roff[i] = line start, 185// rrole[i] = role code (LD_NONE when unplaced), rtgt[i] = index of its target (LD_NONE), rst[i] = placement. 186// c[] = the census. Returns the number of rung rows. Arrays are sized by the caller from bf_count_rows over the tags. 187func ld_classify(buf: *u8, n: i64, toff: *i64, tcls: *i64, tst: *i64, roff: *i64, rrole: *i64, rtgt: *i64, rst: *i64, c: *i64) -> i64 { 188 var k: i64 = 0 189 while k < LD_N_COUNT { c[k] = 0; k = k + 1 } 190 let fo: *i64 = sys_mmap(LD_I64) as *i64 191 // pass 1: targets 192 var nt: i64 = 0 193 let t_idoff: *i64 = sys_mmap((bf_count_rows(buf, n, LD_TARGET_TAG) + 1) * LD_I64) as *i64 194 let t_idlen: *i64 = sys_mmap((bf_count_rows(buf, n, LD_TARGET_TAG) + 1) * LD_I64) as *i64 195 var p: i64 = 0 196 while p < n { 197 let e: i64 = bf_line_end(buf, n, p) 198 if bf_line_starts(buf, p, e, LD_TARGET_TAG) == 1 { 199 toff[nt] = p 200 var il: i64 = bf_field(buf, p, e, LD_F_T_ID, fo) 201 if il < 0 { il = 0 } 202 t_idoff[nt] = fo[0]; t_idlen[nt] = il 203 var cl: i64 = bf_field(buf, p, e, LD_F_T_CLASS, fo) 204 var code: i64 = LD_C_BADCLASS 205 if cl > 0 { code = ld_class_code(buf, fo[0], cl) } 206 tcls[nt] = code 207 var bl: i64 = bf_field(buf, p, e, LD_F_T_BAR, fo) 208 var state: i64 = LD_T_UNDATED 209 if code == LD_C_BADCLASS { state = LD_T_BADCLASS } 210 else { if bl > 0 { if ld_bar_exists(buf, n, fo[0], bl) == 1 { state = LD_T_DATED } } } 211 // a repeated declaration: the same id as an earlier sotatarget row 212 var tq: i64 = 0 213 while tq < nt { if bf_span_eq(buf, t_idoff[tq], t_idlen[tq], t_idoff[nt], t_idlen[nt]) == 1 { state = LD_T_DUPLICATE; tq = nt } tq = tq + 1 } 214 tst[nt] = state 215 c[LD_N_TARGETS] = c[LD_N_TARGETS] + 1 216 if code == LD_C_BIC { c[LD_N_BIC] = c[LD_N_BIC] + 1 } 217 if code == LD_C_FRONTIER { c[LD_N_FRONTIER] = c[LD_N_FRONTIER] + 1 } 218 if state == LD_T_UNDATED { c[LD_N_UNDATED] = c[LD_N_UNDATED] + 1 } 219 if state == LD_T_BADCLASS { c[LD_N_BADCLASS] = c[LD_N_BADCLASS] + 1 } 220 if state == LD_T_DUPLICATE { c[LD_N_DUPTARGET] = c[LD_N_DUPTARGET] + 1 } 221 nt = nt + 1 222 } 223 p = e + 1 224 } 225 // pass 2: rungrole rows 226 let nl_cap: i64 = bf_count_rows(buf, n, LD_LADDER_TAG) + 1 227 let l_rungoff: *i64 = sys_mmap(nl_cap * LD_I64) as *i64 228 let l_runglen: *i64 = sys_mmap(nl_cap * LD_I64) as *i64 229 let l_role: *i64 = sys_mmap(nl_cap * LD_I64) as *i64 230 let l_tgt: *i64 = sys_mmap(nl_cap * LD_I64) as *i64 231 let l_used: *i64 = sys_mmap(nl_cap * LD_I64) as *i64 232 let l_dup: *i64 = sys_mmap(nl_cap * LD_I64) as *i64 233 var nl: i64 = 0 234 p = 0 235 while p < n { 236 let e2: i64 = bf_line_end(buf, n, p) 237 if bf_line_starts(buf, p, e2, LD_LADDER_TAG) == 1 { 238 var rl: i64 = bf_field(buf, p, e2, LD_F_L_RUNG, fo) 239 if rl < 0 { rl = 0 } 240 l_rungoff[nl] = fo[0]; l_runglen[nl] = rl 241 // a rung placed twice: the same rung id as an earlier rungrole row (a duplicate role, not an orphan) 242 var ldup: i64 = 0 243 var lq: i64 = 0 244 while lq < nl { if bf_span_eq(buf, l_rungoff[lq], l_runglen[lq], l_rungoff[nl], l_runglen[nl]) == 1 { ldup = 1; lq = nl } lq = lq + 1 } 245 l_dup[nl] = ldup 246 if ldup == 1 { c[LD_N_DUPROLE] = c[LD_N_DUPROLE] + 1 } 247 var ol: i64 = bf_field(buf, p, e2, LD_F_L_ROLE, fo) 248 var role: i64 = LD_R_BADROLE 249 if ol > 0 { role = ld_role_code(buf, fo[0], ol) } 250 l_role[nl] = role 251 var tl: i64 = bf_field(buf, p, e2, LD_F_L_TARGET, fo) 252 var ti: i64 = LD_NONE 253 if tl > 0 { 254 var q: i64 = 0 255 while q < nt { if bf_span_eq(buf, t_idoff[q], t_idlen[q], fo[0], tl) == 1 { ti = q; q = nt } q = q + 1 } 256 } 257 l_tgt[nl] = ti 258 l_used[nl] = 0 259 c[LD_N_LADDER_ROWS] = c[LD_N_LADDER_ROWS] + 1 260 nl = nl + 1 261 } 262 p = e2 + 1 263 } 264 // pass 3: rungs 265 var nr: i64 = 0 266 p = 0 267 while p < n { 268 let e3: i64 = bf_line_end(buf, n, p) 269 if bf_line_starts(buf, p, e3, LD_RUNG_TAG) == 1 { 270 roff[nr] = p 271 var il2: i64 = bf_field(buf, p, e3, LD_F_R_ID, fo) 272 if il2 < 0 { il2 = 0 } 273 let ido: i64 = fo[0] 274 var hit: i64 = LD_NONE 275 var li: i64 = 0 276 while li < nl { if bf_span_eq(buf, l_rungoff[li], l_runglen[li], ido, il2) == 1 { hit = li; li = nl } li = li + 1 } 277 var state: i64 = LD_P_UNPLACED 278 var role: i64 = LD_NONE 279 var tgt: i64 = LD_NONE 280 if hit != LD_NONE { 281 l_used[hit] = 1 282 role = l_role[hit] 283 tgt = l_tgt[hit] 284 if role == LD_R_BADROLE { state = LD_P_BADROLE } 285 else { if tgt == LD_NONE { state = LD_P_BADTARGET } else { state = LD_P_PLACED } } 286 } 287 rrole[nr] = role 288 rtgt[nr] = tgt 289 rst[nr] = state 290 c[LD_N_RUNGS] = c[LD_N_RUNGS] + 1 291 if state == LD_P_PLACED { 292 c[LD_N_PLACED] = c[LD_N_PLACED] + 1 293 if role == LD_R_SUBSTRATE { c[LD_N_SUBSTRATE] = c[LD_N_SUBSTRATE] + 1 } 294 if role == LD_R_ARM { c[LD_N_ARM] = c[LD_N_ARM] + 1 } 295 if role == LD_R_CONTENDER { c[LD_N_CONTENDER] = c[LD_N_CONTENDER] + 1 } 296 if role == LD_R_SUPERSEDED { c[LD_N_SUPERSEDED] = c[LD_N_SUPERSEDED] + 1 } 297 } 298 if state == LD_P_UNPLACED { c[LD_N_UNPLACED] = c[LD_N_UNPLACED] + 1 } 299 if state == LD_P_BADROLE { c[LD_N_BADROLE] = c[LD_N_BADROLE] + 1 } 300 if state == LD_P_BADTARGET { c[LD_N_BADTARGET] = c[LD_N_BADTARGET] + 1 } 301 nr = nr + 1 302 } 303 p = e3 + 1 304 } 305 // orphans: rungrole rows no rung claimed 306 var oi: i64 = 0 307 while oi < nl { if l_used[oi] == 0 { if l_dup[oi] == 0 { c[LD_N_ORPHANS] = c[LD_N_ORPHANS] + 1 } } oi = oi + 1 } 308 return nr 309} 310 311func ld_partition_sum(c: *i64) -> i64 { 312 return c[LD_N_PLACED] + c[LD_N_UNPLACED] + c[LD_N_BADROLE] + c[LD_N_BADTARGET] 313} 314 315func ld_role_sum(c: *i64) -> i64 { 316 return c[LD_N_SUBSTRATE] + c[LD_N_ARM] + c[LD_N_CONTENDER] + c[LD_N_SUPERSEDED] 317} 318 319// TARGET COVERAGE -- the direction the placement census structurally cannot ask. ld_classify validates 320// RUNG-to-TARGET (does this rung's rungrole name a declared target?), so it reports a board LADDERED while 321// a DECLARED TARGET HAS NOBODY CLIMBING IT: every rung is placed, just not there. 322// MEASURED 2026-09-06 on gameengine: 6 targets declared, 4 climbed, and the two with zero rungs were 323// T-FR-COMPOSE and T-BIC-ENGINE -- the first of which carries the operator's own stated end state and the 324// priority one of that day's goal. The board read LADDERED 58 of 58 with orphans=0 throughout, and 325// nx_absent proved T-BIC-ENGINE occurs exactly once across the whole compare tree (corpus_complete=1), so 326// nothing anywhere in the estate climbed it. A target with no climber is a goal the board STATES and no 327// work ADVANCES -- the darkness class (operator 2026-09-06: we dont want to build and lose capabilities to 328// darkness) -- and it was invisible to every existing instrument. 329// Fills tclimb[i] with the number of PLACED rungs whose rungrole names target i; returns the count of 330// targets with zero, and records it in c. 331// A SEPARATE AXIS, NOT A PARTITION MEMBER: each rung is already counted exactly once across 332// placed/unplaced/badrole/badtarget, and a TARGET is not a rung, so folding this in would break 333// ld_partition_sum and silently redefine a figure other lanes act on. 334// AND DELIBERATELY NOT IN ld_verdict: nx_compare_rank REFUSES a board at exit 6 on LADDER-PARTIAL, so 335// moving the verdict would drop every board carrying an unclimbed target out of the ranking on the next 336// beat -- the permanently-red detector everyone learns to ignore, installed on the estate's headline 337// surface. This axis ANNOUNCES and COUNTS; a ratchet consumes it. The fail direction was chosen before 338// shipping, not conceded after. 339func ld_target_climbers(nt: i64, nr: i64, rtgt: *i64, rst: *i64, tclimb: *i64, c: *i64) -> i64 { 340 var i: i64 = 0 341 while i < nt { tclimb[i] = 0; i = i + 1 } 342 var k: i64 = 0 343 while k < nr { 344 if rst[k] == LD_P_PLACED { 345 let t: i64 = rtgt[k] 346 if t >= 0 { if t < nt { tclimb[t] = tclimb[t] + 1 } } 347 } 348 k = k + 1 349 } 350 var u: i64 = 0 351 var j: i64 = 0 352 while j < nt { if tclimb[j] == 0 { u = u + 1 } j = j + 1 } 353 c[LD_N_UNCLIMBED] = u 354 return u 355} 356 357// the verdict every consumer branches on 358func ld_verdict(c: *i64) -> i64 { 359 if c[LD_N_TARGETS] == 0 { return LD_EXIT_NOLADDER } 360 if c[LD_N_BIC] == 0 { return LD_EXIT_PARTIAL } 361 if c[LD_N_FRONTIER] == 0 { return LD_EXIT_PARTIAL } 362 if c[LD_N_UNDATED] > 0 { return LD_EXIT_PARTIAL } 363 if c[LD_N_BADCLASS] > 0 { return LD_EXIT_PARTIAL } 364 if c[LD_N_UNPLACED] > 0 { return LD_EXIT_PARTIAL } 365 if c[LD_N_BADROLE] > 0 { return LD_EXIT_PARTIAL } 366 if c[LD_N_BADTARGET] > 0 { return LD_EXIT_PARTIAL } 367 if c[LD_N_ORPHANS] > 0 { return LD_EXIT_PARTIAL } 368 if c[LD_N_DUPTARGET] > 0 { return LD_EXIT_PARTIAL } 369 if c[LD_N_DUPROLE] > 0 { return LD_EXIT_PARTIAL } 370 return LD_EXIT_LADDERED 371} 372 373// WHICH rule refused, in the order a seat should fix them: a declaration made twice first, then a target without a 374// month or in no class, then a missing class, then the rungs. The one name every consumer prints (a hand-copied 375// paraphrase of a verdict is a duplicate ruler made of prose). NONE when nothing refuses. 376func ld_refusal_rule(c: *i64) -> *u8 { 377 if c[LD_N_DUPTARGET] > 0 { return "TARGET-DUPLICATE" as *u8 } 378 if c[LD_N_DUPROLE] > 0 { return "ROLE-DUPLICATE" as *u8 } 379 if c[LD_N_UNDATED] > 0 { return "TARGET-UNDATED" as *u8 } 380 if c[LD_N_BADCLASS] > 0 { return "TARGET-BADCLASS" as *u8 } 381 if c[LD_N_TARGETS] > 0 { if c[LD_N_BIC] == 0 { return "NO-BEST-IN-CLASS" as *u8 } } 382 if c[LD_N_TARGETS] > 0 { if c[LD_N_FRONTIER] == 0 { return "NO-FRONTIER" as *u8 } } 383 if c[LD_N_UNPLACED] > 0 { return "RUNG-UNPLACED" as *u8 } 384 if c[LD_N_BADROLE] > 0 { return "RUNG-BADROLE" as *u8 } 385 if c[LD_N_BADTARGET] > 0 { return "RUNG-BADTARGET" as *u8 } 386 if c[LD_N_ORPHANS] > 0 { return "ROLE-ORPHAN" as *u8 } 387 return "NONE" as *u8 388}