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}