code wiki / (root) / nx_writehub_score.nx

nx_writehub_score.nx source

↩ module page · 67 lines · 4001 B

1// nx_writehub_score.nx -- WRITING HUB shared LIB: the immune-scoring core, extracted from nx_writehub_loop so the 2// loop AND the self-improvement conductor share ONE scorer (consolidation -- no duplicated scoring logic, per the 3// operator's no-dup doctrine). Pure composition of nx_writecraft (readability) + nx_writestyle (adverb/passive/ 4// weak/hard-sentence) -> a composite quality permil + the worst-dimension directive. No main, no I/O beyond scratch 5// mmap, so any organ can import it. Thresholds are heuristic consts here (move to a writehub_rubric data store 6// next, per nx_writestyle's own "consts -> DATA" note). license_tier: ORIGINAL module: nishi-core.writehub.score 7import "nx_writestyle.nx" 8import "nx_syscalls.nx" 9 10const WHL_ADVERB_TGT: i64 = 15 // adverbs per 1000 words tolerated before penalty 11const WHL_PASSIVE_TGT: i64 = 10 // passive constructions per 1000 words tolerated 12const WHL_WEAK_TGT: i64 = 8 // weak qualifiers per 1000 words tolerated 13const WHL_ADVERB_W: i64 = 6 // penalty permil per (rate-over-target)/10 14const WHL_PASSIVE_W: i64 = 10 15const WHL_WEAK_W: i64 = 8 16const WHL_HARD_W: i64 = 300 // penalty permil at 100% hard sentences 17const WHL_READ_W: i64 = 80 // flat penalty when grade exceeds the band 18const WHL_FK_MAX: i64 = 12000 // FK grade x1000 ceiling (grade ~12); above = too dense 19const WHL_KEEP: i64 = 700 // composite permil at/above which a draft is KEPT 20 21// score t[0..n); fill rep[0..15]; return composite quality permil. 22// rep: 0 words 1 sents 2 fk_milli 3 adv 4 pass 5 weak 6 dia_milli 7 longest 8 hard 23// 9 pen_adv 10 pen_pass 11 pen_weak 12 pen_hard 13 pen_read 14 permil 15 worst-dim 24func whl_eval(t: *u8, n: i64, rep: *i64) -> i64 { 25 let wc: *i64 = sys_mmap(64) as *i64 26 wc_counts(t, n, wc) 27 let words: i64 = wc[1]; let sents: i64 = wc[2] 28 var w: i64 = words; if w < 1 { w = 1 } 29 var s: i64 = sents; if s < 1 { s = 1 } 30 let fk: i64 = wc_fk_grade(wc) 31 let ss: *i64 = sys_mmap(64) as *i64 32 ws_signals(t, n, ss) 33 let adv: i64 = ss[0]; let pas: i64 = ss[1]; let wk: i64 = ss[2]; let dia: i64 = ss[3]; let lng: i64 = ss[4]; let hard: i64 = ss[5] 34 let adv_rate: i64 = adv * 1000 / w 35 let pas_rate: i64 = pas * 1000 / w 36 let wk_rate: i64 = wk * 1000 / w 37 let hard_frac: i64 = hard * 1000 / s 38 var pen_adv: i64 = 0 39 if adv_rate > WHL_ADVERB_TGT { pen_adv = (adv_rate - WHL_ADVERB_TGT) * WHL_ADVERB_W / 10 } 40 var pen_pass: i64 = 0 41 if pas_rate > WHL_PASSIVE_TGT { pen_pass = (pas_rate - WHL_PASSIVE_TGT) * WHL_PASSIVE_W / 10 } 42 var pen_weak: i64 = 0 43 if wk_rate > WHL_WEAK_TGT { pen_weak = (wk_rate - WHL_WEAK_TGT) * WHL_WEAK_W / 10 } 44 let pen_hard: i64 = hard_frac * WHL_HARD_W / 1000 45 var pen_read: i64 = 0 46 if fk > WHL_FK_MAX { pen_read = WHL_READ_W } 47 var permil: i64 = 1000 - pen_adv - pen_pass - pen_weak - pen_hard - pen_read 48 if permil < 0 { permil = 0 } 49 var worst: i64 = 0; var wv: i64 = pen_adv 50 if pen_pass > wv { wv = pen_pass; worst = 1 } 51 if pen_weak > wv { wv = pen_weak; worst = 2 } 52 if pen_hard > wv { wv = pen_hard; worst = 3 } 53 if pen_read > wv { wv = pen_read; worst = 4 } 54 if wv == 0 { worst = 5 } 55 rep[0]=words; rep[1]=sents; rep[2]=fk; rep[3]=adv; rep[4]=pas; rep[5]=wk; rep[6]=dia; rep[7]=lng; rep[8]=hard 56 rep[9]=pen_adv; rep[10]=pen_pass; rep[11]=pen_weak; rep[12]=pen_hard; rep[13]=pen_read; rep[14]=permil; rep[15]=worst 57 return permil 58} 59 60func whl_directive(worst: i64) -> *u8 { 61 if worst==0 { return "cut adverbs -- replace -ly words with stronger verbs" as *u8 } 62 if worst==1 { return "convert passive constructions to active voice" as *u8 } 63 if worst==2 { return "remove weak qualifiers (very/really/just/quite...)" as *u8 } 64 if worst==3 { return "break up the long sentences (split the longest into 2-3)" as *u8 } 65 if worst==4 { return "simplify -- shorter sentences, plainer words" as *u8 } 66 return "none -- keep" as *u8 67}