code wiki / (root) / nx_slopmeter_lib.nx

nx_slopmeter_lib.nx source

↩ module page · 150 lines · 7235 B

1// nx_slopmeter_lib.nx -- MEASURE THE OUTPUT, NOT THE REGISTRY. 2// 3// u2605u2605u2605u2605u2605u2605A BOARD THAT SCORES YOUR TAXONOMY MEASURES YOUR INTENTIONS. nx_writebench reads 625 permil, 4// and every one of its 28 axes asks whether we HAVE a registry, a gate or a lexicon for something. 5// Not one of them looks at a single byte the generator actually produced. The board could reach 1000 6// while the product emits garbage, and nothing in the estate would notice -- because nothing in the 7// estate reads the output. 8// 9// So this organ measures the artifact. It starts with the ONE axis that decides whether small-model 10// prose is usable at all: DEGENERATE SELF-REPETITION. A 4B model asked for 1200 tokens loops -- it 11// re-emits the same phrase with the same rhythm until the budget runs out. Humans call it slop; it 12// is mechanically detectable and needs no judge, no model and no network to see. 13// 14// WHAT THIS IS NOT: a quality score. It cannot tell good prose from bad. It detects a specific, 15// well-defined failure -- the text repeating itself -- and reports how much. Naming it honestly is 16// the difference between an instrument and an advertisement. 17// u2605A METRIC THAT CLAIMS MORE THAN IT MEASURES CORRUPTS EVERY DECISION MADE FROM IT. 18// 19// NO THRESHOLD LIVES HERE, DELIBERATELY. A verdict needs a cutoff, and a cutoff invented at the 20// keyboard is exactly the magic number this estate keeps paying for. The organ REPORTS permil; the 21// cutoff is a policy that belongs to a caller with measurements behind it. What the gate proves 22// instead is MONOTONICITY -- degenerate text must score strictly above varied text -- which is 23// threshold-free and cannot be satisfied by a broken meter. 24// 25// PURE: no syscalls, no allocation of its own, caller owns every buffer. 26// license_tier: ORIGINAL 27// module: nishi-core.write.slopmeter 28// capability: WRITE_OUTPUT_REPETITION_MEASURE 29import "nx_txtscan_lib.nx" 30 31const SM_PERMIL: i64 = 1000 32 33// N-gram width. 3 is not a taste call: a repeated 1-gram is ordinary English ("the", "and"), a 34// repeated 2-gram is common and often correct ("she said"), and a repeated 3-gram is where 35// deliberate phrasing ends and looping begins. Reported width is part of the measurement, so a 36// caller can never mistake one width's number for another's. 37const SM_NGRAM: i64 = 3 38 39func sm_is_wordch(c: i64) -> i64 { 40 if c >= 97 { if c <= 122 { return 1 } } 41 if c >= 65 { if c <= 90 { return 1 } } 42 if c >= 48 { if c <= 57 { return 1 } } 43 if c == 39 { return 1 } // apostrophe: "don't" is one token 44 return 0 45} 46 47// Split buf[0..n) into word tokens, writing start offsets and lengths into caller arrays. 48// Returns the token count, never exceeding cap. Tokens are the unit because BYTE repetition would 49// fire on ordinary whitespace and punctuation and measure nothing. 50func sm_tokenize(buf: *u8, n: i64, starts: *i64, lens: *i64, cap: i64) -> i64 { 51 var cnt: i64 = 0 52 var i: i64 = 0 53 while i < n { 54 if sm_is_wordch(buf[i] as i64) == 1 { 55 let s: i64 = i 56 // u26a0u26a0THIS LOOP TERMINATES WITH A FLAG, AND THE FIRST VERSION DID NOT -- IT SET `i = n + 1` 57 // TO BREAK, WHICH IS THE END-OF-TOKEN POSITION BEING OVERWRITTEN BY THE STOP SIGNAL. 58 // Every token then ran from its first character to the end of the buffer, so the whole 59 // text collapsed into ONE token: the gate read 2/10 with the tokenizer test failing and, 60 // worse, the all-unique-vocabulary test PASSING at a perfect 1000 permil because one 61 // token is trivially distinct from itself. u2605u2605u2605u2605u2605u2605A LOOP THAT SIGNALS TERMINATION BY 62 // OVERWRITING ITS CURSOR DESTROYS THE POSITION IT EXISTS TO REPORT -- and this estate has 63 // now written that bug three times (nx_cwdguard's `q = rn + 1`, rp_name_shaped, here). 64 // u2605A VACUOUS GREEN APPEARS EXACTLY WHERE THE DEFECT MAKES THE QUESTION TRIVIAL. 65 var e: i64 = i 66 var go: i64 = 1 67 while go == 1 { 68 if e >= n { go = 0 } else { 69 if sm_is_wordch(buf[e] as i64) == 0 { go = 0 } else { e = e + 1 } 70 } 71 } 72 if cnt < cap { starts[cnt] = s; lens[cnt] = e - s; cnt = cnt + 1 } 73 i = e 74 } else { i = i + 1 } 75 } 76 return cnt 77} 78 79// case-insensitive equality of two tokens 80func sm_tok_eq(buf: *u8, sa: i64, la: i64, sb: i64, lb: i64) -> i64 { 81 if la != lb { return 0 } 82 var k: i64 = 0 83 while k < la { 84 if tx_lower(buf[sa + k] as i64) != tx_lower(buf[sb + k] as i64) { return 0 } 85 k = k + 1 86 } 87 return 1 88} 89 90// do the SM_NGRAM-token windows at token indices a and b match? 91func sm_gram_eq(buf: *u8, starts: *i64, lens: *i64, a: i64, b: i64) -> i64 { 92 var k: i64 = 0 93 while k < SM_NGRAM { 94 if sm_tok_eq(buf, starts[a + k], lens[a + k], starts[b + k], lens[b + k]) == 0 { return 0 } 95 k = k + 1 96 } 97 return 1 98} 99 100// How many n-gram windows are a REPEAT of an earlier window. Counting "has an earlier twin" rather 101// than "appears more than once" makes the first occurrence innocent and every echo guilty, so a 102// phrase used twice costs 1 and a phrase looped ten times costs 9 -- which is the shape of the 103// failure being measured. 104func sm_repeat_count(buf: *u8, starts: *i64, lens: *i64, ntok: i64) -> i64 { 105 let w: i64 = ntok - SM_NGRAM + 1 106 if w <= 0 { return 0 } 107 var reps: i64 = 0 108 var i: i64 = 1 109 while i < w { 110 var j: i64 = 0 111 var dup: i64 = 0 112 while j < i { 113 if sm_gram_eq(buf, starts, lens, i, j) == 1 { dup = 1; j = i } else { j = j + 1 } 114 } 115 if dup == 1 { reps = reps + 1 } 116 i = i + 1 117 } 118 return reps 119} 120 121// Repetition in exact integer permil of the n-gram windows present. 122// u26a0SHORT TEXT CANNOT BE MEASURED, AND SAYING 0 WOULD BE A LIE. Fewer than SM_NGRAM tokens yields no 123// windows at all; returning 0 would read as "clean" when the truth is "no measurement was possible". 124// SM_UNMEASURABLE is a distinct value so a caller can never average it in as if it were a score. 125const SM_UNMEASURABLE: i64 = 0 - 1 126func sm_repeat_permil(buf: *u8, starts: *i64, lens: *i64, ntok: i64) -> i64 { 127 let w: i64 = ntok - SM_NGRAM + 1 128 if w <= 1 { return SM_UNMEASURABLE } 129 let reps: i64 = sm_repeat_count(buf, starts, lens, ntok) 130 return (reps * SM_PERMIL) / (w - 1) 131} 132 133// Vocabulary breadth: distinct tokens per 1000 tokens. A looping generator collapses this even when 134// it varies word ORDER enough to dodge the n-gram check, so the two axes fail independently -- 135// which is the whole reason to carry both rather than trusting one number. 136func sm_distinct_permil(buf: *u8, starts: *i64, lens: *i64, ntok: i64) -> i64 { 137 if ntok <= 0 { return SM_UNMEASURABLE } 138 var distinct: i64 = 0 139 var i: i64 = 0 140 while i < ntok { 141 var j: i64 = 0 142 var seen: i64 = 0 143 while j < i { 144 if sm_tok_eq(buf, starts[i], lens[i], starts[j], lens[j]) == 1 { seen = 1; j = i } else { j = j + 1 } 145 } 146 if seen == 0 { distinct = distinct + 1 } 147 i = i + 1 148 } 149 return (distinct * SM_PERMIL) / ntok 150}