code wiki / (root) / nx_symdecl_lib.nx

nx_symdecl_lib.nx source

↩ module page · 483 lines · 26351 B

1// nx_symdecl_lib.nx -- THE ONE SYMBOL RULER for the compare surface (2026-08-23, lane L). 2// 3// "Does organ O carry symbol S?" was answered by THREE different rulers in three organs, and two of 4// them disagreed with the third in public: 5// nx_swcompare_matrix c_file_has -- bare SUBSTRING over the organ source (a comment, a call site, 6// a gate name or a string literal containing S flips the cell) 7// nx_compare_regen tr_contains -- the same substring rule, feeding the comparewatch- plane that 8// every seat reads to pick up work 9// nx_compare_rank rk_measure -- a TOP-LEVEL `func S(` declaration at line start, whose own 10// comment claimed "presence measured EXACTLY as the emitter 11// measures it" -- MEASURED FALSE 2026-08-23 12// Live consequence: lang LN8 (_ABSENT_:opt_eqsat_pass on runtime/nx_opt.nx, which only CALLS the pass) 13// read LANDED on the page and in the plane while the ranker priced it OPEN. A completion signal that 14// keys on a name rewards writing the name; the substring rule rewards a comment. 15// 16// THE RULE (one definition, four importers: nx_swcompare_lib -> both generators, nx_compare_rank, 17// nx_compare_regen): S is DECLARED in O iff O's source carries, at the START of a line, one of the 18// declaration keywords `func ` `const ` `struct ` `static ` followed by S followed by a character that 19// cannot continue an identifier. Column 0 only -- NishiLang has no nested declarations, so an indented 20// `func` is prose inside a comment block or a string, never a definition. Comments, call sites, gate 21// names, and longer identifiers sharing the prefix (`sym` vs `symx`) do not count. 22// 23// The organ is read WHOLE (sys_read_file sizes its buffer from the file): the matrix generator's old 24// 256 KiB read cap made every symbol past that offset invisible -- nx_parse.nx is 366 KB today. 25// sd_declared returns -1 when the organ cannot be read at all, so a caller can say "organ unreadable" 26// instead of the indistinguishable "symbol absent". 27import "nx_syscalls.nx" 28 29// ---- THE KEYWORD TABLE IS THE DIALECT'S TOP-LEVEL FORMS, ENUMERATED FROM THE PARSER (2026-09-01) ---- 30// It carried 4 of the 6 forms nx_cc actually accepts at module level. The reported miss was ONE keyword, 31// but a ruler that knows 5 of 7 forms is the same defect one keyword later, so this table was DERIVED 32// from the compiler's own top-level dispatch instead of from the case that was reported: nx_parse.nx's 33// parse loop branches on TK_FUNC / TK_CONST / TK_STRUCT / TK_STATIC / TK_ENUM, and prepass_register_aliases 34// registers the sixth form, `type NAME = BASE`. Those six BIND A NAME; nothing else at module level does. 35// MEASURED over the whole runtime tree, column 0: enum in 11 files, type in 3 -- both live, not theoretical. 36// THE MISS WAS A FALSE RED, NOT A NEAR-MISS. doctor's `Opt` axis is a real column-0 declaration at 37// nx_probe_ctor.nx:3 (`enum Opt { None, Some(i64) }`) and the 4-keyword table convicted it of being a 38// comment. Adding a form can only ADD grounding, so this direction cannot manufacture a new RED -- which 39// is why the whole list was completed here rather than only the one keyword a census happened to surface. 40// DELIBERATELY ABSENT: `import` binds no name (it includes a module), and `@priv` needs no entry -- it is 41// an attribute on its OWN line, measured 0 occurrences of `@priv func` on one line estate-wide, and the 42// declaration it decorates still starts at column 0 where the existing rule already finds it. 43// DOCUMENTED IMPRECISION: an enum VARIANT (`None`, `Some`) is registered by the compiler as a QUALIFIED 44// module const, not as a column-0 declaration, so a row naming a variant instead of the enum still reads 45// absent. No board row does today; if one appears it is a variant gap, NOT this keyword gap. 46const SD_KW_COUNT: i64 = 6 47 48func sd_ident_char(c: i64) -> i64 { 49 if c >= 97 { if c <= 122 { return 1 } } 50 if c >= 65 { if c <= 90 { return 1 } } 51 if c >= 48 { if c <= 57 { return 1 } } 52 if c == 95 { return 1 } 53 return 0 54} 55func sd_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } 56// the keyword table: index -> keyword text (with its trailing space) 57func sd_kw(i: i64) -> *u8 { 58 if i == 0 { return "func " as *u8 } 59 if i == 1 { return "const " as *u8 } 60 if i == 2 { return "struct " as *u8 } 61 if i == 3 { return "static " as *u8 } 62 if i == 4 { return "enum " as *u8 } 63 return "type " as *u8 64} 65// does buffer b (n bytes) declare sym at offset i (which must be a line start)? returns 1/0 66func sd_decl_at(b: *u8, n: i64, i: i64, sym: *u8, sl: i64) -> i64 { 67 var k: i64 = 0 68 while k < SD_KW_COUNT { 69 let kw: *u8 = sd_kw(k) 70 let kl: i64 = sd_slen(kw) 71 if i + kl + sl < n { 72 var same: i64 = 1 73 var j: i64 = 0 74 while j < kl { if b[i + j] != kw[j] { same = 0; j = kl } j = j + 1 } 75 if same == 1 { 76 j = 0 77 while j < sl { if b[i + kl + j] != sym[j] { same = 0; j = sl } j = j + 1 } 78 if same == 1 { 79 let nx: i64 = b[i + kl + sl] as i64 80 if sd_ident_char(nx) == 0 { return 1 } 81 } 82 } 83 } 84 k = k + 1 85 } 86 return 0 87} 88// THE RULER over an in-memory source: 1 declared, 0 not declared. An empty symbol is never declared. 89func sd_declared_buf(b: *u8, n: i64, sym: *u8) -> i64 { 90 let sl: i64 = sd_slen(sym) 91 if sl == 0 { return 0 } 92 if n <= 0 { return 0 } 93 var i: i64 = 0 94 while i < n { 95 var bol: i64 = 0 96 if i == 0 { bol = 1 } else { if b[i - 1] == (10 as u8) { bol = 1 } } 97 if bol == 1 { if sd_decl_at(b, n, i, sym, sl) == 1 { return 1 } } 98 i = i + 1 99 } 100 return 0 101} 102// THE RULER over a file: reads the organ WHOLE. -1 unreadable, 0 not declared, 1 declared. 103func sd_declared(path: *u8, sym: *u8) -> i64 { 104 let ln: *i64 = sys_mmap(16) as *i64 105 let b: *u8 = sys_read_file(path, ln) 106 if (b as i64) == 0 { return 0 - 1 } 107 let n: i64 = ln[0] 108 let r: i64 = sd_declared_buf(b, n, sym) 109 sys_free_file(b, n) 110 return r 111} 112// the OLD rule, kept ONLY as a named control so gates can prove a fixture discriminates the two 113// rulers (a fixture on which substring and declaration agree proves nothing about either). 114func sd_substring_control(b: *u8, n: i64, sym: *u8) -> i64 { 115 let sl: i64 = sd_slen(sym) 116 if sl == 0 { return 0 } 117 var i: i64 = 0 118 while i + sl <= n { 119 var same: i64 = 1 120 var j: i64 = 0 121 while j < sl { if b[i + j] != sym[j] { same = 0; j = sl } j = j + 1 } 122 if same == 1 { return 1 } 123 i = i + 1 124 } 125 return 0 126} 127 128// ---- THE RULE IS DERIVED FROM THE CLAIM'S SHAPE, AND NAMED (2026-08-23, lane L, after the census) ---- 129// The first cut applied the NishiLang declaration rule to EVERY row and the real-population census 130// (70 matrices, 1,617 symbol rows) showed why that is the wrong-direction error: only a minority of the 131// 246 flips were the LN8 class (an identifier on a .nx organ that is merely called or commented). The 132// rest were rows whose symbol field never claimed a declaration -- the organ's OWN NAME on its own file 133// (an existence claim), a marker literal the organ emits or parses ("PROJECT-TIME", "w:rPr", 134// "/api/services"), an author-spelled "func main(argc", a JS identifier in app.v2.js, a data token in a 135// .refs register. Measuring those with a NishiLang declaration rule turns ~200 true cells into MISSING, 136// which is a second lie wearing the first one's fix. So: ONE function, the rule chosen from the shape of 137// (organ, symbol), the rule NAMED in every output so a reader sees what was measured. 138// SD_RULE_DECL identifier on a .nx organ -> top-level NishiLang declaration (strict) 139// SD_RULE_JSDECL identifier on a .js/.mjs organ -> JS declaration forms (function/const/let/var/ 140// class, or a method/property definition 141// `name(` `name:` `name =` at line start after 142// whitespace -- JS nests its definitions) 143// SD_RULE_EXISTS symbol == the organ's own basename -> the organ exists (readable) 144// SD_RULE_MARKER non-identifier text on a code organ -> the literal is carried in the source 145// SD_RULE_DATA any symbol on a non-code organ -> the token is present in the data file 146// "func name(" / "func name" as the symbol spells the declaration: the prefix is stripped and DECL applies. 147const SD_RULE_DECL: i64 = 1 148const SD_RULE_JSDECL: i64 = 2 149const SD_RULE_EXISTS: i64 = 3 150const SD_RULE_MARKER: i64 = 4 151const SD_RULE_DATA: i64 = 5 152func sd_rule_name(r: i64) -> *u8 { 153 if r == SD_RULE_DECL { return "decl" as *u8 } 154 if r == SD_RULE_JSDECL { return "jsdecl" as *u8 } 155 if r == SD_RULE_EXISTS { return "exists" as *u8 } 156 if r == SD_RULE_MARKER { return "marker" as *u8 } 157 return "data" as *u8 158} 159func sd_ends(s: *u8, sfx: *u8) -> i64 { 160 let n: i64 = sd_slen(s) 161 let m: i64 = sd_slen(sfx) 162 if n < m { return 0 } 163 var k: i64 = 0 164 while k < m { if s[n - m + k] != sfx[k] { return 0 } k = k + 1 } 165 return 1 166} 167func sd_is_ident(s: *u8) -> i64 { 168 if s[0] == (0 as u8) { return 0 } 169 if s[0] >= (48 as u8) { if s[0] <= (57 as u8) { return 0 } } 170 var i: i64 = 0 171 while s[i] != (0 as u8) { if sd_ident_char(s[i] as i64) == 0 { return 0 } i = i + 1 } 172 return 1 173} 174// the organ's basename without its extension, compared to sym 175func sd_is_organ_name(organ: *u8, sym: *u8) -> i64 { 176 var i: i64 = 0 177 var start: i64 = 0 178 while organ[i] != (0 as u8) { if organ[i] == (47 as u8) { start = i + 1 } i = i + 1 } 179 var end: i64 = i 180 var j: i64 = i - 1 181 while j > start { if organ[j] == (46 as u8) { end = j; j = start } j = j - 1 } 182 let sl: i64 = sd_slen(sym) 183 if end - start != sl { return 0 } 184 var k: i64 = 0 185 while k < sl { if organ[start + k] != sym[k] { return 0 } k = k + 1 } 186 return 1 187} 188// an identifier with no lowercase letter at all (digits and underscores allowed) 189func sd_is_all_caps(s: *u8) -> i64 { 190 if s[0] == (0 as u8) { return 0 } 191 var i: i64 = 0 192 while s[i] != (0 as u8) { let c: i64 = s[i] as i64; if c >= 97 { if c <= 122 { return 0 } } i = i + 1 } 193 return 1 194} 195func sd_is_code_organ(organ: *u8) -> i64 { 196 if sd_ends(organ, ".nx" as *u8) == 1 { return 1 } 197 if sd_ends(organ, ".js" as *u8) == 1 { return 2 } 198 if sd_ends(organ, ".mjs" as *u8) == 1 { return 2 } 199 return 0 200} 201// the symbol after an optional author-spelled "func " prefix 202func sd_after_func(sym: *u8) -> *u8 { 203 if sd_slen(sym) > 5 { if sym[0] == (102 as u8) { if sym[1] == (117 as u8) { if sym[2] == (110 as u8) { if sym[3] == (99 as u8) { if sym[4] == (32 as u8) { return (sym as i64 + 5) as *u8 } } } } } } 204 return sym 205} 206// strip an author-spelled "func " prefix and anything from '(' on; writes the identifier into out 207func sd_strip_func(sym: *u8, out: *u8) -> i64 { 208 let s: *u8 = sd_after_func(sym) 209 var i: i64 = 0 210 while s[i] != (0 as u8) { if sd_ident_char(s[i] as i64) == 0 { break } out[i] = s[i]; i = i + 1 } 211 out[i] = 0 as u8 212 return i 213} 214func sd_rule_for(organ: *u8, sym: *u8, ident_out: *u8) -> i64 { 215 let kind: i64 = sd_is_code_organ(organ) 216 if kind == 0 { sd_strip_func(sym, ident_out); return SD_RULE_DATA } 217 if sd_is_organ_name(organ, sym) == 1 { sd_strip_func(sym, ident_out); return SD_RULE_EXISTS } 218 let n: i64 = sd_strip_func(sym, ident_out) 219 // the whole symbol (after an optional "func " prefix) must be one identifier, else it is a marker 220 let rest: *u8 = sd_after_func(sym) 221 var ident_only: i64 = 1 222 if n == 0 { ident_only = 0 } 223 if rest[n] != (0 as u8) { if rest[n] != (40 as u8) { ident_only = 0 } } // "name" or "name(..." only 224 if rest[0] >= (48 as u8) { if rest[0] <= (57 as u8) { ident_only = 0 } } 225 if ident_only == 0 { return SD_RULE_MARKER } 226 if kind == 2 { return SD_RULE_JSDECL } 227 return SD_RULE_DECL 228} 229// JS declaration forms at line start after whitespace 230func sd_js_decl_at(b: *u8, n: i64, i0: i64, sym: *u8, sl: i64) -> i64 { 231 var i: i64 = i0 232 while i < n { if b[i] == (32 as u8) { i = i + 1 } else { if b[i] == (9 as u8) { i = i + 1 } else { break } } } 233 // keyword forms 234 var k: i64 = 0 235 while k < 6 { 236 var kw: *u8 = "function " as *u8 237 if k == 1 { kw = "async function " as *u8 } 238 if k == 2 { kw = "const " as *u8 } 239 if k == 3 { kw = "let " as *u8 } 240 if k == 4 { kw = "var " as *u8 } 241 if k == 5 { kw = "class " as *u8 } 242 let kl: i64 = sd_slen(kw) 243 if i + kl + sl < n { 244 var same: i64 = 1 245 var j: i64 = 0 246 while j < kl { if b[i + j] != kw[j] { same = 0; j = kl } j = j + 1 } 247 if same == 1 { 248 j = 0 249 while j < sl { if b[i + kl + j] != sym[j] { same = 0; j = sl } j = j + 1 } 250 if same == 1 { if sd_ident_char(b[i + kl + sl] as i64) == 0 { return 1 } } 251 } 252 } 253 k = k + 1 254 } 255 // method / property definition: name( name: name = (not ==) 256 if i + sl < n { 257 var same2: i64 = 1 258 var j2: i64 = 0 259 while j2 < sl { if b[i + j2] != sym[j2] { same2 = 0; j2 = sl } j2 = j2 + 1 } 260 if same2 == 1 { 261 var p: i64 = i + sl 262 while p < n { if b[p] == (32 as u8) { p = p + 1 } else { break } } 263 if p < n { 264 let c: i64 = b[p] as i64 265 if c == 40 { return 1 } 266 if c == 58 { return 1 } 267 if c == 61 { if p + 1 < n { if b[p + 1] != (61 as u8) { return 1 } } } 268 } 269 } 270 } 271 return 0 272} 273func sd_js_declared_buf(b: *u8, n: i64, sym: *u8) -> i64 { 274 let sl: i64 = sd_slen(sym) 275 if sl == 0 { return 0 } 276 var i: i64 = 0 277 while i < n { 278 var bol: i64 = 0 279 if i == 0 { bol = 1 } else { if b[i - 1] == (10 as u8) { bol = 1 } } 280 if bol == 1 { if sd_js_decl_at(b, n, i, sym, sl) == 1 { return 1 } } 281 i = i + 1 282 } 283 return 0 284} 285// THE RULER, over an in-memory source: applies the rule derived from (organ, sym). rule_out receives 286// the rule. 1 present, 0 absent. (Existence cannot be judged from a buffer alone: the caller that has 287// a buffer has a readable organ, so EXISTS is 1 here.) 288// ---- THE THIRD STATE: THE RULER ABSTAINS WHERE IT HAS NO COMPETENCE (2026-09-01) ---- 289// SD_ABSTAIN is "I COULD NOT LOOK", which is not "IT IS ABSENT", and it is returned for exactly one 290// condition today: a JS-dialect row whose symbol is not a JS DECLARATION. 291// 292// WHY, MEASURED. Over the full population (96 boards, 2,185 rows, coverage_complete=1) the strict ruler 293// strips grounding from 83 rows, and 9 of those are rule=jsdecl. All 9 were adjudicated BY HAND and NOT 294// ONE is a comment. They are live call sites, constraint keys and object properties in shipped client 295// code: navigator.mediaDevices.getDisplayMedia(...), audio with echoCancellation set true, 296// window.localStorage.getItem(K), fpsTx assigned from Math.round(...). Screen share, echo cancellation 297// and QoE telemetry demonstrably ship, so convicting those rows would MANUFACTURE 9 FALSE REDs. 298// 299// AND THE CAUSE IS A SUBJECT MISMATCH, NOT A MISSING JS FORM. A board row for a browser capability names 300// THE PLATFORM API THE CLIENT CALLS -- getDisplayMedia is declared by the browser, never by us -- so a 301// DECLARATION rule can never ground it, and no amount of widening the JS forms would change that. 302// Widening is also the precise substring looseness this ruler exists to remove. The honest answer from a 303// declaration ruler asked whether a browser capability SHIPS is that IT IS THE WRONG INSTRUMENT. 304// "I COULD NOT LOOK" IS NOT "IT IS BROKEN" -- AND AN ABSTENTION MUST BE NAMED, OR IT IS A SILENT PASS. 305// 306// IT IS ONE-DIRECTIONAL BY CONSTRUCTION. A JS row that DOES satisfy the JS declaration rule still returns 307// 1, so no cell that reads present today can move. Abstention can only convert a would-be RED into a 308// declared "not judged"; it can never bless a claim, and it cannot reach the .nx dialect at all. 309const SD_ABSTAIN: i64 = 2 310// The abstention's REASON as a token rather than a bare flag -- the same discipline the referee's 311// unproven_reason already follows, so a reader learns WHICH competence was missing, not merely that one was. 312func sd_abstain_name() -> *u8 { return "no-competence-js-dialect" as *u8 } 313 314// THE THREE-STATE RULER over an in-memory source: 1 present, 0 absent, SD_ABSTAIN cannot-judge. THIS IS 315// THE IMPLEMENTATION -- sd_present_buf below is a FOLD of this one, so there is still exactly ONE rule 316// and no second copy to drift. rule_out receives the rule the lib CHOSE on every path, abstain included. 317func sd_present_or_abstain_buf(b: *u8, n: i64, organ: *u8, sym: *u8, rule_out: *i64) -> i64 { 318 let ident: *u8 = sys_mmap(sd_slen(sym) + 8) 319 let r: i64 = sd_rule_for(organ, sym, ident) 320 rule_out[0] = r 321 if r == SD_RULE_EXISTS { return 1 } 322 if r == SD_RULE_DECL { 323 if sd_declared_buf(b, n, ident) == 1 { return 1 } 324 // AN ALL-CAPS IDENTIFIER IS AMBIGUOUS IN THIS DIALECT: a const (a declaration) or an emitted 325 // token (a gate name, a log tag -- SWARMBEATGATE, PROJECT-TIME's cousins). Measured 2026-08-23 326 // on the first regen under the strict rule: nine matrix domains whose cells were carried by such 327 // tokens fell under the generator's present>=5 liar-kill floor and refused to publish. So: the 328 // declaration is tried FIRST (a real const wins as decl); an undeclared all-caps token falls back 329 // to the MARKER rule and the page prints `marker` beside it -- a visibly weaker claim, not a hidden 330 // one. Lowercase identifiers never fall back: a called-or-commented function is the LN8 class. 331 if sd_is_all_caps(ident) == 1 { rule_out[0] = SD_RULE_MARKER; return sd_substring_control(b, n, ident) } 332 return 0 333 } 334 if r == SD_RULE_JSDECL { 335 // THE ONE ABSTAINING BRANCH. A real JS declaration still grounds the row; anything else on a JS 336 // organ is NOT JUDGED HERE, because a declaration rule cannot decide whether a CALLED platform 337 // API ships. rule_out still reports jsdecl, so a reader sees which rule was attempted and why it 338 // could not decide, rather than a bare refusal with no subject. 339 if sd_js_declared_buf(b, n, ident) == 1 { return 1 } 340 return SD_ABSTAIN 341 } 342 return sd_substring_control(b, n, sym) 343} 344 345// THE TWO-STATE RULER, UNCHANGED IN MEANING FOR EVERY EXISTING CALLER (rule 19: adding a function is 346// safe, changing a contract is not). Six live call sites read this answer as a boolean, and 347// nx_compare_regen.nx:263 assigns it STRAIGHT into `landed` -- so a third return value reaching them 348// would be written into the comparewatch- plane as a state code and would flip published cells across the 349// fleet. They keep the question they already ask, "is this symbol DECLARED", for which a call-site-only 350// JS symbol is correctly 0 (nx_swcompare_watch_gate's T13j neg-control pins exactly that, and stays 351// green under this change). The referee asks a DIFFERENT question -- "can this claim be judged at all" -- 352// and is the one caller that takes the third state. 353// TWO QUESTIONS, TWO ENTRY POINTS, ONE RULE UNDERNEATH -- never two rulers. 354func sd_present_buf(b: *u8, n: i64, organ: *u8, sym: *u8, rule_out: *i64) -> i64 { 355 let r: i64 = sd_present_or_abstain_buf(b, n, organ, sym, rule_out) 356 if r == SD_ABSTAIN { return 0 } 357 return r 358} 359// ---- CE4: THE CLAIM-BINDING RULER -- re-read a board claim against the LIVE SERVED ARTIFACT (2026-09-05) ---- 360// sd_present below answers "is symbol S declared in organ O's SOURCE". CE5 named its own limit in one 361// line: SYMBOL PRESENCE CANNOT SEE A PROMOTE. The motivating defect: /compare/codequality asserted the 362// McCabe keystone SHIPPED with its gate GREEN while nx_catalog read the served binary SOURCE-ONLY -- built 363// nowhere -- and sd_present passes that claim because mc_scan_file was in the source the whole time. So this 364// is a SECOND, COMPLEMENTARY ruler on the SAME claim: not "is the symbol in source" but "is the organ's 365// binary on the serving surface". It re-implements no part of nx_catalog's resolution; it stats the two 366// artifacts that decide the one distinction CE4 turns on -- served, source-only, or absent. 367// THE ROOTS ARE ARGUMENTS, NOT A CWD (the nx_comparetree_lib lesson: a bare path is right in one CWD and a 368// latent defect in its neighbour). cb_serve_state_at takes both roots so a gate points them at a /tmp 369// fixture tree; cb_serve_state supplies the estate's absolute roots so a caller needs no CWD. 370const CB_HOST: *u8 = "/volume1/homes/elderwesto/nishihost" 371const CB_BUILDROOT: *u8 = "/volume1/homes/elderwesto/nishihost/buildroot" 372const CB_ABSENT: i64 = 0 373const CB_SOURCE_ONLY: i64 = 1 374const CB_SERVED: i64 = 2 375const CB_CLASS_CONSISTENT: i64 = 0 376const CB_CLASS_STALE_UNDER: i64 = 1 377const CB_CLASS_REFUSE: i64 = 2 378func cb_class_name(c: i64) -> *u8 { 379 if c == CB_CLASS_CONSISTENT { return "CONSISTENT" as *u8 } 380 if c == CB_CLASS_STALE_UNDER { return "STALE-UNDER" as *u8 } 381 return "REFUSE" as *u8 382} 383func cb_state_name(s: i64) -> *u8 { 384 if s == CB_SERVED { return "SERVED" as *u8 } 385 if s == CB_SOURCE_ONLY { return "SOURCE-ONLY" as *u8 } 386 return "ABSENT" as *u8 387} 388func cb_exists(path: *u8) -> i64 { 389 let fd: i64 = sys_openat_rd(path) 390 if fd < 0 { return 0 } 391 sys_close(fd) 392 return 1 393} 394func cb_app(dst: *u8, off: i64, s: *u8) -> i64 { 395 var x: i64 = off 396 var i: i64 = 0 397 while s[i] != (0 as u8) { dst[x] = s[i]; x = x + 1; i = i + 1 } 398 return x 399} 400// basename of an organ path, extension stripped, into out; returns length. "runtime/nx_mccabe.nx" -> "nx_mccabe" 401func cb_base(organ: *u8, out: *u8) -> i64 { 402 var i: i64 = 0 403 var start: i64 = 0 404 while organ[i] != (0 as u8) { if organ[i] == (47 as u8) { start = i + 1 } i = i + 1 } 405 var end: i64 = i 406 var j: i64 = i - 1 407 while j > start { if organ[j] == (46 as u8) { end = j; j = start } j = j - 1 } 408 var k: i64 = 0 409 while start + k < end { out[k] = organ[start + k]; k = k + 1 } 410 out[k] = 0 as u8 411 return k 412} 413// SERVED state given both roots. serving_root holds <base>.elf; build_root holds <organ> (the source path). 414func cb_serve_state_at(serving_root: *u8, build_root: *u8, organ: *u8) -> i64 { 415 let base: *u8 = sys_mmap(512) 416 cb_base(organ, base) 417 let elfp: *u8 = sys_mmap(1024) 418 var x: i64 = cb_app(elfp, 0, serving_root) 419 x = cb_app(elfp, x, "/" as *u8) 420 x = cb_app(elfp, x, base) 421 x = cb_app(elfp, x, ".elf" as *u8) 422 elfp[x] = 0 as u8 423 if cb_exists(elfp) == 1 { return CB_SERVED } 424 let srcp: *u8 = sys_mmap(1024) 425 var y: i64 = cb_app(srcp, 0, build_root) 426 y = cb_app(srcp, y, "/" as *u8) 427 y = cb_app(srcp, y, organ) 428 srcp[y] = 0 as u8 429 if cb_exists(srcp) == 1 { return CB_SOURCE_ONLY } 430 return CB_ABSENT 431} 432func cb_serve_state(organ: *u8) -> i64 { 433 return cb_serve_state_at(CB_HOST, CB_BUILDROOT, organ) 434} 435// THE CLASSIFIER: claim_present (the board asserts the capability present: 1) vs the served state. 436// A "No" claim needs no backing and is CONSISTENT. A "yes" over a source-only organ is the verdict 437// CONTRADICTING the claim (STALE-UNDER, publish WITH the badge); over an absent organ it is the verdict 438// DENYING it (REFUSE, do not publish) -- the exact ACCEPT wording of rung CE4. 439func cb_classify(claim_present: i64, serve_state: i64) -> i64 { 440 if claim_present == 0 { return CB_CLASS_CONSISTENT } 441 if serve_state == CB_SERVED { return CB_CLASS_CONSISTENT } 442 if serve_state == CB_SOURCE_ONLY { return CB_CLASS_STALE_UNDER } 443 return CB_CLASS_REFUSE 444} 445 446// THE CWD-RELATIVE TWIN, for the generators (CE4, 2026-09-05). sd_present resolves the organ path CWD-relative, so 447// the served twin must resolve the SAME way or the two rulers judge DIFFERENT SUBJECTS for one path -- the exact 448// two-rulers defect, and it would also convict every /tmp fixture organ a gate plants. The generators run from 449// exactly two CWDs: nx_compare_regen chdirs to buildroot (the serving root is its parent, ..) and the mgmt daemon 450// runs the same elf from the serving root itself (.), so both are probed, parent first. 451// FAIL DIRECTION, declared: a twin not found from an unexpected CWD reads SOURCE-ONLY, which the consumer ANNOUNCES 452// with a badge and never refuses on; a stray twin can only hold a row at today's CONSISTENT. Neither direction lies loud. 453const CB_CWD_SERVING_UP: *u8 = ".." 454const CB_CWD_SERVING_HERE: *u8 = "." 455const CB_CWD_BUILD: *u8 = "." 456func cb_serve_state_cwd(organ: *u8) -> i64 { 457 if cb_serve_state_at(CB_CWD_SERVING_UP, CB_CWD_BUILD, organ) == CB_SERVED { return CB_SERVED } 458 return cb_serve_state_at(CB_CWD_SERVING_HERE, CB_CWD_BUILD, organ) 459} 460 461// THE CE4 CONTRACT VERB, NAMED EXACTLY AS THE BOARD DECLARED IT (2026-09-05). The codeeffectiveness matrix row, its 462// plan rung, the PM intake and the comparewatch plane all key on the symbol `ce_claim_binding`; renaming the contract 463// to the ruler's internal names broke that join (the ranker read CE4 UNMAPPED, priority 0, the moment the matrix said 464// cb_classify while the plan said ce_claim_binding). The fix for a classifier keyed on a name is a DECLARATION, never a 465// rename: this is the ONE-CALL form of the ruler -- re-read a bound claim against the live served artifact and classify. 466func ce_claim_binding(organ: *u8, claim_present: i64) -> i64 { 467 return cb_classify(claim_present, cb_serve_state_cwd(organ)) 468} 469 470// THE RULER, over a file: -1 unreadable (rule still reported), 0 absent, 1 present. 471func sd_present(organ: *u8, sym: *u8, rule_out: *i64) -> i64 { 472 let ln: *i64 = sys_mmap(16) as *i64 473 let b: *u8 = sys_read_file(organ, ln) 474 if (b as i64) == 0 { 475 let ident: *u8 = sys_mmap(sd_slen(sym) + 8) 476 rule_out[0] = sd_rule_for(organ, sym, ident) 477 return 0 - 1 478 } 479 let n: i64 = ln[0] 480 let r: i64 = sd_present_buf(b, n, organ, sym, rule_out) 481 sys_free_file(b, n) 482 return r 483}