nx_failclass.nx
buildroot/runtime/nx_failclass.nx
about
nx_failclass.nx -- CLASSIFY THE ESTATE'S OWN FAILURE RECORD AGAINST A PUBLISHED TAXONOMY.
The estate banks ~70,100 distilled law rows and every one of them is failure-shaped, but they
were never CLASSIFIED and never COUNTED -- so nobody could say which failure class bites most,
which is chronic, or whether any class is extinct. Anecdotes without a taxonomy.
This organ answers that question over the WHOLE population, never a sample:
nx_failclass scan <signatures.conf> <learnings.jsonl> <worklist.out>
nx_failclass selftest
AND, since 2026-08-20, THE FM11 RUNG OF /compare/failmodes -- a second census over a DIFFERENT
population, the refusals this estate actually EMITS:
nx_failclass refusal <refusal_shape.conf> <worklist.out>
nx_failclass refusal_ratchet <worklist> <baseline>
The ruler lives in nx_refusal_shape_lib so this verb and nx_refusal_shape_gate cannot disagree,
and it scores the EMITTER only: whether the message names its subject and its remedy. Whether a
caller HEEDED it is a second, independent axis, census-only over the call record, and no counter
in this organ may be read as evidence about it.
THREE PROPERTIES IT REFUSES TO GIVE UP:
1. u2605 IT IS A CENSUS, NOT A GATE. An uncalibrated classifier must report NUMBERS, never
verdicts. There is deliberately no verdict= line and no RED. Exit is 0 for a completed
scan, 3 for an unreadable input, 2 for usage. A reader who wants a bar must set it
themselves against numbers they can see.
2. u2605 THE REASON TRAVELS WITH THE COUNT. Every counted row is also WRITTEN to the worklist
with the exact signature that classified it. A count without a worklist is not actionable,
and a worklist without the reason is still one step short -- the reason is already in hand
at measure time and is normally thrown away.
3. u2605 UNCLASSIFIED IS ITS OWN BUCKET AND MULTI IS ITS OWN AXIS. A row matching no signature
is never folded into a known class; a row matching two classes genuinely names two, so it is
counted once in the MULTI partition member AND once per class on the overlapping per-class
axis, which is labelled as an axis and never summed into the partition.
The partition PRINTS ITS OWN SUM: single + multi + unclassified must equal rows.
WORD BOUNDARIES ARE LOAD-BEARING, NOT COSMETIC. Measured 2026-08-20 over 70,100 rows, the bare
substring "cap" hits 7,802 rows and the WORD cap/caps/capped hits 2,992 -- the residue is
"capability", "capture", "capsearch", "capacity". A substring matcher would have published a
dependencies 4 imports · 0 importers
imports: nx_estate_path.nxnx_itoa_lib.nxnx_refusal_shape_lib.nxnx_verdictlog_lib.nx
imported by: nobody (leaf or entry point)
call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown
structs
| none |
consts
| 51 | const FC_MODE_0644: i64 = 420 |
| 55 | const FC_MAX_CLASS: i64 = 32 |
| 56 | const FC_MAX_MONTH: i64 = 64 |
| 57 | const FC_MONTH_LEN: i64 = 7 |
| 58 | const FC_TEXT_PREVIEW: i64 = 160 |
functions
| 60 | func fw(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } |
| 61 | func fe(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(2, s, n); return 0 } |
| 63 | func fc_strlen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } |
| 65 | func fc_streq(a: *u8, b: *u8) -> i64 called by 1: main |
| 80 | func fc_find_word(hay: *u8, hs: i64, he: i64, nee: *u8, nlen: i64) -> i64 |
| 86 | func fc_find_raw(hay: *u8, hs: i64, he: i64, nee: *u8, nlen: i64) -> i64 called by 1: fc_scan |
| 108 | func fc_class_id(names: *u8, nlens: *i64, ncls: *i64, s: *u8, slen: i64) -> i64 called by 1: fc_scan |
| 133 | func fc_put_class(names: *u8, nlens: *i64, id: i64) -> i64 called by 1: fc_scan |
| 138 | func fc_buf_class(dst: *u8, off: i64, names: *u8, nlens: *i64, id: i64) -> i64 called by 1: fc_scan |
| 144 | func fc_buf_bytes(dst: *u8, off: i64, src: *u8, s: i64, e: i64) -> i64 called by 1: fc_scan |
| 157 | func fc_buf_lit(dst: *u8, off: i64, s: *u8) -> i64 called by 1: fc_scan |
| 169 | func fc_month_id(mons: *u8, nmon: *i64, src: *u8, s: i64, e: i64) -> i64 called by 1: fc_scan |
| 223 | func fc_expect(name: *u8, got: i64, want_hit: i64, passed: *i64, total: *i64) -> i64 |
| 238 | func fc_eq(name: *u8, got: i64, want: i64, passed: *i64, total: *i64) -> i64 |
| 251 | func fc_writef(path: *u8, s: *u8) -> i64 |
| 265 | func fc_e2e(passed: *i64, total: *i64) -> i64 |
| 295 | func fc_selftest() -> i64 |
| 360 | func fc_scan(confp: *u8, corpp: *u8, outp: *u8, res: *i64) -> i64 |
| 630 | func fc_refusal_shape(confp: *u8, outp: *u8) -> i64 |
| 640 | func fc_refusal_beat(confp: *u8, outp: *u8, basep: *u8) -> i64 |
| 651 | func fc_alert_score(confp: *u8, dirp: *u8, outp: *u8) -> i64 |
| 660 | func fc_alert_beat(confp: *u8, dirp: *u8, outp: *u8, basep: *u8) -> i64 |
| 672 | func fc_two_vantage(confp: *u8, outp: *u8) -> i64 |
| 677 | func main(argc: i64, argv: *i64) -> i64 |