nx_verdictlog_lib.nx
buildroot/runtime/nx_verdictlog_lib.nx
about
nx_verdictlog_lib.nx -- THE VERDICT-LOG RULER: read a detector's own recorded verdicts and say
what its output is worth.
FM3 and FM4 of /compare/failmodes, and ONE ruler for both because both ask the same primitive
question of the same artifacts: WHAT VERDICT DID THIS DETECTOR EMIT, AND WHEN. FM3 reads one
stream through time (is this detector's output informative). FM4 reads two streams of the same
subject side by side (do two vantages agree). Splitting the parser between them would be the
duplicate-ruler defect, and the census and its gate would then be free to disagree about what a
verdict IS.
---------------------------------------------------------------------------------------------
FM3 -- THE ACCEPT RULE, QUOTED VERBATIM FROM failmodes.plan BEFORE THE WORK BEGAN:
"run it over the EXISTING detector fleet and publish the four numbers per detector; the rung is
accepted only if at least one currently-shipping detector is shown to score badly enough to
justify changing or retiring it. A scorer that flatters every incumbent has measured nothing."
THE FOUR NUMBERS ARE SRE'S -- precision, recall, detection time, reset time -- and EACH IS
THREE-STATE. That is not a softening of the rule, it is the only honest way to publish it, and
the reason is measured rather than assumed: A VERDICT LOG RECORDS WHAT THE DETECTOR SAID AND
NEVER WHETHER IT WAS RIGHT. Nothing in this estate joins a detector's firing to an adjudication,
so a precision figure computed from these files would be a CONSTANT WEARING THE SHAPE OF A
MEASUREMENT. Each axis therefore carries either a value or a NAMED abstention:
precision UNINFORMATIVE-CONSTANT the output never varies, so it carries no
information and its precision equals the base rate.
This is an EXACT statement, not an estimate.
UNOBSERVABLE-NO-ADJUDICATION otherwise: nothing joins a firing to a truth.
recall UNVERIFIED-NEVER-FIRED the detector has produced no positive in its whole
recorded history, so nothing has demonstrated it
CAN fire. A green that never had a corresponding
red is unverified.
UNOBSERVABLE-NO-GROUND-TRUTH otherwise: a missed event leaves no trace here.
detect_bound_s <n> the largest observed interval between consecutive
runs. A BOUND, and labelled one: a condition that
becomes visible just after a run waits at most this
long to be seen.
UNOBSERVABLE-NO-TIMESTAMP the stream carries no declared timestamp key.
reset <n> the largest observed number of runs from a
non-green to the next green.
LATCHED the trailing non-green episode never returns to
dependencies 2 imports · 2 importers
imports: nx_syscalls.nxnx_gatekit_lib.nx
imported by: nx_failclass.nxnx_verdictlog_gate.nx
structs
| none |
consts
| 87 | const VL_TAB: i64 = 9 |
| 88 | const VL_NL: i64 = 10 |
| 89 | const VL_QUOTE: i64 = 34 |
| 90 | const VL_HASH: i64 = 35 |
| 91 | const VL_MINUS: i64 = 45 |
| 92 | const VL_DOT: i64 = 46 |
| 93 | const VL_ZERO: i64 = 48 |
| 94 | const VL_NINE: i64 = 57 |
| 95 | const VL_SEMI: i64 = 59 |
| 96 | const VL_UC_A: i64 = 65 |
| 97 | const VL_UC_Z: i64 = 90 |
| 98 | const VL_USCORE: i64 = 95 |
| 99 | const VL_LC_A: i64 = 97 |
| 100 | const VL_LC_Z: i64 = 122 |
| 101 | const VL_BAR: i64 = 124 |
| 102 | const VL_CASEGAP: i64 = 32 |
| 103 | const VL_B10: i64 = 10 |
| 104 | const VL_MODE_0644: i64 = 420 |
| 105 | const VL_NUMBUF: i64 = 32 |
| 106 | const VL_SMALL: i64 = 16 |
| 107 | const VL_PATHBUF: i64 = 4096 |
| 108 | const VL_DENTBUF: i64 = 65536 |
| 109 | const VL_DT_DIR: i64 = 4 |
| 110 | const VL_DENT_RECLEN_OFF: i64 = 16 |
| 111 | const VL_DENT_TYPE_OFF: i64 = 18 |
| 112 | const VL_DENT_NAME_OFF: i64 = 19 |
| 113 | const VL_BYTE_SHIFT: i64 = 8 |
| 117 | const VL_SYS_GETDENTS64: i64 = 217 |
| 122 | const VL_VAN_SUBJ_OFF: i64 = 0 |
| 123 | const VL_VAN_SUBJ_LEN: i64 = 1 |
| 124 | const VL_VAN_A_OFF: i64 = 2 |
| 125 | const VL_VAN_A_LEN: i64 = 3 |
| 126 | const VL_VAN_B_OFF: i64 = 4 |
| 127 | const VL_VAN_B_LEN: i64 = 5 |
| 128 | const VL_VAN_WIN: i64 = 6 |
| 131 | const VL_GREEN: i64 = 0 |
| 132 | const VL_RED: i64 = 1 |
| 133 | const VL_ABSTAIN: i64 = 2 |
| 134 | const VL_UNKWORD: i64 = 3 // a verdict key was present and its word is not declared vocabulary |
| 135 | const VL_NOVERDICT: i64 = 4 // the line carries no verdict key at all |
| 138 | const VL_MAXVOC: i64 = 256 |
| 139 | const VL_MAXVAN: i64 = 64 |
| 140 | const VL_VANSLOTS: i64 = 7 |
| 142 | const VL_C_NVKEY: i64 = 0 |
| 143 | const VL_C_NTSKEY: i64 = 1 |
| 144 | const VL_C_NGREEN: i64 = 2 |
| 145 | const VL_C_NRED: i64 = 3 |
| 146 | const VL_C_NABST: i64 = 4 |
| 147 | const VL_C_NEXT: i64 = 5 |
| 148 | const VL_C_NVAN: i64 = 6 |
| 149 | const VL_C_REJECT: i64 = 7 |
| 150 | const VL_C_OVER: i64 = 8 |
| 151 | const VL_C_MINRUNS: i64 = 9 |
| 152 | const VL_C_MAXFILES: i64 = 10 |
| 153 | const VL_C_STRIDE: i64 = 11 |
| 155 | const VL_C_VKBASE: i64 = 32 |
| 156 | const VL_C_TSBASE: i64 = 544 |
| 157 | const VL_C_GRBASE: i64 = 1056 |
| 158 | const VL_C_RDBASE: i64 = 1568 |
| 159 | const VL_C_ABBASE: i64 = 2080 |
| 160 | const VL_C_EXBASE: i64 = 2592 |
| 161 | const VL_C_VANBASE: i64 = 3104 |
| 162 | const VL_C_LEN: i64 = 3584 |
| 165 | const VL_R_RUNS: i64 = 0 |
| 166 | const VL_R_GREEN: i64 = 1 |
| 167 | const VL_R_RED: i64 = 2 |
| 168 | const VL_R_ABST: i64 = 3 |
| 169 | const VL_R_UNK: i64 = 4 |
| 170 | const VL_R_TSRUNS: i64 = 5 |
| 171 | const VL_R_TSFIRST: i64 = 6 |
| 172 | const VL_R_TSLAST: i64 = 7 |
| 173 | const VL_R_MAXGAP: i64 = 8 |
| 174 | const VL_R_EPISODES: i64 = 9 |
| 175 | const VL_R_MAXRESET: i64 = 10 |
| 176 | const VL_R_LATCHED: i64 = 11 |
| 177 | const VL_R_LASTSTATE: i64 = 12 |
| 178 | const VL_R_LASTTS: i64 = 13 |
| 179 | const VL_R_BYTES: i64 = 14 |
| 180 | const VL_R_NONMONO: i64 = 15 |
| 181 | const VL_R_UNKOFF: i64 = 16 // offset of the first undeclared verdict word, into the file buffer |
| 182 | const VL_R_UNKLEN: i64 = 17 |
| 183 | const VL_R_LEN: i64 = 20 |
| 186 | const VL_B_SCORED: i64 = 0 // has both green and non-green runs: the output varies |
| 187 | const VL_B_CONSTNG: i64 = 1 // every run non-green: never once green -- OFFENDER |
| 188 | const VL_B_CONSTGR: i64 = 2 // every run green: never fired, so its recall is unverified |
| 189 | const VL_B_UNKVOCAB: i64 = 3 // speaks a verdict dialect this ruler cannot read |
| 190 | const VL_B_SNAPSHOT: i64 = 4 // one run: a level cannot express a trajectory |
| 191 | const VL_B_NOVERDICT: i64 = 5 // carries no verdict vocabulary at all |
| 192 | const VL_B_UNREADABLE: i64 = 6 |
| 193 | const VL_NBUCKET: i64 = 7 |
| 196 | const VL_T_FILES: i64 = 0 |
| 197 | const VL_T_SKIPPED: i64 = 1 |
| 198 | const VL_T_BYTES: i64 = 2 |
| 199 | const VL_T_BUCKET0: i64 = 3 // .. VL_T_BUCKET0 + VL_NBUCKET - 1 |
| 200 | const VL_T_LATCHED: i64 = 10 // a SEPARATE AXIS, deliberately not a partition member |
| 201 | const VL_T_OFFEND: i64 = 11 |
| 202 | const VL_T_HIST0: i64 = 12 // .. VL_T_HIST0 + VL_NHIST - 1 |
| 203 | const VL_NHIST: i64 = 11 |
| 204 | const VL_T_LEN: i64 = 32 |
| 207 | const VL_V_AGREE: i64 = 0 |
| 208 | const VL_V_DISAGREE: i64 = 1 |
| 209 | const VL_V_U_AMISS: i64 = 2 |
| 210 | const VL_V_U_BMISS: i64 = 3 |
| 211 | const VL_V_U_ANOOBS: i64 = 4 |
| 212 | const VL_V_U_BNOOBS: i64 = 5 |
| 213 | const VL_V_U_WINDOW: i64 = 6 |
| 214 | const VL_V_U_ABSTAIN: i64 = 7 |
| 215 | const VL_NVOUT: i64 = 8 |
| 217 | const VL_RATCHET_ALLOW: i64 = 0 |
| 218 | const VL_RATCHET_REFUSE: i64 = 1 |
| 219 | const VL_RATCHET_UNMEAS: i64 = 3 |
| 221 | const VL_FNV_OFFSET: i64 = 2166136261 |
| 222 | const VL_FNV_PRIME: i64 = 16777619 |
| 223 | const VL_FNV_MASK32: i64 = 4294967295 |
| 224 | const VL_HASH_LOAD: i64 = 4 |
functions
| 229 | func vl_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } |
| 230 | func vl_err(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(2, s, n); return 0 } |
| 232 | func vl_putn(v: i64) -> i64 called by 4: vl_alert_reportvl_alert_scanvl_alert_ratchetvl_vantage_scan calls 3: sys_mmapsys_writesys_munmap |
| 250 | func vl_nl() -> i64 |
| 258 | func vl_lower(c: i64) -> i64 |
| 265 | func vl_is_alpha(c: i64) -> i64 called by 1: vl_wordch |
| 271 | func vl_wordch(c: i64) -> i64 |
| 278 | func vl_find_byte(buf: *u8, s: i64, e: i64, b: i64) -> i64 |
| 288 | func vl_range_eq(buf: *u8, s: i64, e: i64, lit: *u8) -> i64 |
| 300 | func vl_ci_eq(buf: *u8, s: i64, e: i64, conf: *u8, off: i64, len: i64) -> i64 |
| 311 | func vl_ci_find(buf: *u8, s: i64, e: i64, conf: *u8, off: i64, len: i64) -> i64 |
| 328 | func vl_atoi(buf: *u8, s: i64, e: i64) -> i64 |
| 343 | func vl_fnv_buf(buf: *u8, n: i64) -> i64 called by 1: vl_fnv_file |
| 357 | func vl_fnv_file(path: *u8) -> i64 |
| 368 | func vl_take(conf: *u8, voc: *i64, cnt_slot: i64, base: i64, s: i64, e: i64) -> i64 called by 1: vl_conf_load |
| 377 | func vl_conf_load(confp: *u8, clen: *i64, voc: *i64) -> *u8 called by 3: mainvl_alert_scanvl_vantage_scan calls 7: sys_read_filevl_errgk_eolvl_find_bytevl_range_eqvl_take+1 |
| 499 | func vl_key_at(conf: *u8, voc: *i64, base: i64, n: i64, buf: *u8, s: i64, e: i64, klen: *i64) -> i64 |
| 519 | func vl_tok_in(conf: *u8, voc: *i64, base: i64, n: i64, buf: *u8, s: i64, e: i64) -> i64 |
| 530 | func vl_line_state(conf: *u8, voc: *i64, buf: *u8, s: i64, e: i64, span: *i64) -> i64 |
| 555 | func vl_line_ts(conf: *u8, voc: *i64, buf: *u8, s: i64, e: i64) -> i64 |
| 580 | func vl_series_reset(sr: *i64) -> i64 called by 1: vl_series |
| 594 | func vl_series(path: *u8, conf: *u8, voc: *i64, sr: *i64) -> *u8 |
| 666 | func vl_bucket(sr: *i64, minruns: i64) -> i64 |
| 675 | func vl_bucket_name(b: i64) -> *u8 |
| 685 | func vl_bucket_id(buf: *u8, s: i64, e: i64) -> i64 |
| 705 | func vl_is_offender(bucket: i64, latched: i64) -> i64 |
| 716 | func vl_latched(sr: *i64, minruns: i64) -> i64 |
| 739 | func vl_unscored(bucket: i64) -> *u8 |
| 747 | func vl_precision(bucket: i64) -> *u8 |
| 755 | func vl_recall(bucket: i64, sr: *i64) -> *u8 |
| 765 | func vl_hasext(name: *u8, conf: *u8, voc: *i64) -> i64 |
| 792 | func vl_dirscan(dir: *u8, conf: *u8, voc: *i64, names: *u8, stride: i64, cap: i64) -> i64 |
| 841 | func vl_dircount(dir: *u8) -> i64 |
| 867 | func vl_row(out: *u8, oo: *i64, cap: i64, s: *u8) -> i64 |
| 878 | func vl_rown(out: *u8, oo: *i64, cap: i64, v: i64) -> i64 |
| 897 | func vl_rowb(out: *u8, oo: *i64, cap: i64, src: *u8, s: i64, e: i64) -> i64 |
| 908 | func vl_rowtab(out: *u8, oo: *i64, cap: i64) -> i64 |
| 913 | func vl_rownl(out: *u8, oo: *i64, cap: i64) -> i64 |
| 922 | func vl_emit_row(out: *u8, oo: *i64, cap: i64, path: *u8, sr: *i64, bucket: i64, fbuf: *u8, latched: i64) -> i64 |
| 961 | func vl_bucket_sum(tot: *i64) -> i64 called by 1: main |
| 968 | func vl_bucket_distinct(tot: *i64) -> i64 called by 1: main |
| 981 | func vl_hist_distinct(tot: *i64) -> i64 called by 1: main |
| 991 | func vl_hist_bin(sr: *i64) -> i64 called by 1: vl_alert_scan |
| 1000 | func vl_alert_report(tot: *i64, voc: *i64, dirp: *u8, outp: *u8, wrote: i64) -> i64 |
| 1047 | func vl_alert_scan(confp: *u8, dirp: *u8, outp: *u8, tot: *i64) -> i64 called by 3: fc_alert_scorefc_alert_beatmain calls 16: sys_mmapvl_conf_loadvl_dirscanvl_putsvl_putnvl_dircount+10 |
| 1118 | func vl_row_name(buf: *u8, s: i64, e: i64, span: *i64) -> i64 |
| 1133 | func vl_name_hash(buf: *u8, s: i64, e: i64) -> i64 |
| 1144 | func vl_name_eq(a: *u8, as0: i64, ae: i64, b: *u8, bs: i64, be: i64) -> i64 |
| 1154 | func vl_name_index(bl: *u8, blen: i64, hs: *i64, he: *i64, hcap: i64) -> i64 |
| 1178 | func vl_name_in(bl: *u8, hs: *i64, he: *i64, hcap: i64, needle: *u8, ns: i64, ne: i64) -> i64 |
| 1191 | func vl_write_set(path: *u8, wl: *u8, cs: *i64, ce: *i64, n: i64) -> i64 |
| 1207 | func vl_alert_ratchet(worklistp: *u8, baselinep: *u8) -> i64 |
| 1303 | func vl_last_obs(path: *u8, conf: *u8, voc: *i64, obs: *i64) -> i64 |
| 1331 | func vl_vout_name(v: i64) -> *u8 called by 1: vl_vantage_scan |
| 1342 | func vl_state_name(s: i64) -> *u8 called by 1: vl_vantage_scan |
| 1353 | func vl_vantage_cmp(ra: i64, rb: i64, oa: *i64, ob: *i64, window: i64) -> i64 called by 1: vl_vantage_scan |
| 1369 | func vl_vantage_scan(confp: *u8, outp: *u8, res: *i64) -> i64 |