code wiki / _hdl_build / nx_procchurn_gate.nx

nx_procchurn_gate.nx source

↩ module page · 353 lines · 20683 B

1// nx_procchurn_gate.nx -- proves the four pure predicates of nx_procchurn_lib, BOTH POLARITIES. 2// 3// Non-vacuity discipline (seq395 / the quality ruler): every policy cell is a gv_bite -- it must FIRE on 4// the crafted-bad input AND stay SILENT on the crafted-good one. A cell that is green before the defect 5// exists proves nothing. The value cells are pinned to the ACTUAL 2026-07-30 field measurement so the 6// gate would have caught the live fork-storm, not merely compiled. 7// license_tier: ORIGINAL expect_exit: 0 No hw writes (Rule 26). 8import "nx_procchurn_lib.nx" 9import "nx_gate_verdict.nx" 10 11const PG_BUF: i64 = 2048 12const PG_OUT_BYTES: i64 = 256 13// the real numbers measured on the NAS 2026-07-30 (two /proc/stat samples 117s apart) 14const PG_FIELD_FORKS: i64 = 9164 15const PG_FIELD_MS: i64 = 117000 16const PG_FIELD_FORKS_PS: i64 = 78 17const PG_FIELD_SYS_J: i64 = 21639 18const PG_FIELD_USR_J: i64 = 9163 19const PG_FIELD_RATIO: i64 = 2361 20const PG_FIELD_CTXSW_PS: i64 = 91718 21// thresholds under test (the shipped defaults) 22const PG_F_AMBER: i64 = 20 23const PG_F_RED: i64 = 50 24const PG_R_AMBER: i64 = 1000 25const PG_R_RED: i64 = 1500 26const PG_C_AMBER: i64 = 20000 27const PG_C_RED: i64 = 50000 28// OB5 consumer bars. 6s = two 3000ms measurement windows, i.e. the SHIPPED derivation, so the gate 29// tests the same arithmetic the organ runs rather than a number chosen to make the teeth pass. 30const PG_ACT_MAXAGE: i64 = 6 31const PG_ACT_STALE_AGE: i64 = 999 32// OB4 fixture bounds. PG_PIDCAP is generously above this host process count (measured ~800) so T39 can 33// distinguish a real enumeration from a capped one; PG_TALLY_MAX is small on purpose so the full-table 34// refusal is reachable in a test rather than only in production. 35const PG_PIDCAP: i64 = 4096 36const PG_PIDS_BYTES: i64 = 32768 37const PG_TALLY_MAX: i64 = 8 38const PG_TALLY_BYTES: i64 = 256 39const PG_PATHBUF: i64 = 64 40 41func pg_cpy(d: *u8, s: *u8) -> i64 { 42 var i: i64 = 0 43 while s[i] != (0 as u8) { d[i] = s[i]; i = i + 1 } 44 d[i] = 0 as u8 45 return i 46} 47func pg_eq(a: i64, b: i64) -> i64 { if a == b { return 1 } return 0 } 48 49func main() -> i64 { 50 let ctr: *i64 = gv_ctr() 51 gv_head("nx_procchurn_gate -- process-churn predicates, pinned to the 2026-07-30 field data" as *u8) 52 53 gv_check("T1 pc_rate reproduces the field measurement 9164 forks / 117000ms = 78/s" as *u8, 54 pg_eq(pc_rate(PG_FIELD_FORKS, PG_FIELD_MS), PG_FIELD_FORKS_PS), ctr) 55 gv_bite("T2 pc_rate refuses a zero-length window" as *u8, 56 pg_eq(pc_rate(PG_FIELD_FORKS, 0), 0 - 1), 57 pg_eq(pc_rate(PG_FIELD_FORKS, PG_FIELD_MS), 0 - 1), ctr) 58 gv_bite("T3 pc_rate refuses a BACKWARD counter (wrap/reboot between samples)" as *u8, 59 pg_eq(pc_rate(0 - 5, PG_FIELD_MS), 0 - 1), 60 pg_eq(pc_rate(5, PG_FIELD_MS), 0 - 1), ctr) 61 62 gv_check("T4 pc_ratio_permil reproduces the field kernel:user 21639:9163 = 2361 permil" as *u8, 63 pg_eq(pc_ratio_permil(PG_FIELD_SYS_J, PG_FIELD_USR_J), PG_FIELD_RATIO), ctr) 64 gv_bite("T5 pc_ratio_permil saturates on zero userspace instead of reading as parity" as *u8, 65 pg_eq(pc_ratio_permil(100, 0), PC_RATIO_SAT), 66 pg_eq(pc_ratio_permil(100, 100), PC_RATIO_SAT), ctr) 67 68 gv_check("T6 pc_verdict is GREEN when every axis is quiet" as *u8, 69 pg_eq(pc_verdict(1, 100, 100, PG_F_AMBER, PG_F_RED, PG_R_AMBER, PG_R_RED, PG_C_AMBER, PG_C_RED), 0), ctr) 70 gv_bite("T7 the FORK axis alone raises RED" as *u8, 71 pg_eq(pc_verdict(60, 100, 100, PG_F_AMBER, PG_F_RED, PG_R_AMBER, PG_R_RED, PG_C_AMBER, PG_C_RED), 2), 72 pg_eq(pc_verdict(10, 100, 100, PG_F_AMBER, PG_F_RED, PG_R_AMBER, PG_R_RED, PG_C_AMBER, PG_C_RED), 2), ctr) 73 gv_bite("T8 the KERNEL:USER axis alone raises RED" as *u8, 74 pg_eq(pc_verdict(1, 1600, 100, PG_F_AMBER, PG_F_RED, PG_R_AMBER, PG_R_RED, PG_C_AMBER, PG_C_RED), 2), 75 pg_eq(pc_verdict(1, 900, 100, PG_F_AMBER, PG_F_RED, PG_R_AMBER, PG_R_RED, PG_C_AMBER, PG_C_RED), 2), ctr) 76 gv_bite("T9 the CONTEXT-SWITCH axis alone raises RED" as *u8, 77 pg_eq(pc_verdict(1, 100, 60000, PG_F_AMBER, PG_F_RED, PG_R_AMBER, PG_R_RED, PG_C_AMBER, PG_C_RED), 2), 78 pg_eq(pc_verdict(1, 100, 100, PG_F_AMBER, PG_F_RED, PG_R_AMBER, PG_R_RED, PG_C_AMBER, PG_C_RED), 2), ctr) 79 gv_check("T10 RED dominates AMBER (amber-only input stays 1)" as *u8, 80 pg_eq(pc_verdict(25, 900, 100, PG_F_AMBER, PG_F_RED, PG_R_AMBER, PG_R_RED, PG_C_AMBER, PG_C_RED), 1), ctr) 81 82 let buf: *u8 = sys_mmap(PG_BUF) 83 let out: *i64 = sys_mmap(PG_OUT_BYTES) as *i64 84 let n: i64 = pg_cpy(buf, "cpu0 999 999 999\ncpu 11 22 33 44 55 66 77 88 99 1010\nprocesses 4153147\nctxt 5007810360\n" as *u8) 85 let cnt: i64 = pc_line_ints(buf, n, "cpu " as *u8, out, 10) 86 gv_check("T11 pc_line_ints reads all 10 jiffy fields off the aggregate cpu line" as *u8, pg_eq(cnt, 10), ctr) 87 var t12: i64 = 0 88 if out[0] == 11 { if out[2] == 33 { if out[9] == 1010 { t12 = 1 } } } 89 gv_check("T12 PREFIX DISCIPLINE: cpu-space takes the aggregate line, NOT cpu0 decoy 999s" as *u8, t12, ctr) 90 let pcnt: i64 = pc_line_ints(buf, n, "processes " as *u8, out, 1) 91 var t13: i64 = 0 92 if pcnt == 1 { if out[0] == 4153147 { t13 = 1 } } 93 gv_check("T13 pc_line_ints reads the scalar processes fork counter" as *u8, t13, ctr) 94 gv_bite("T14 pc_line_ints is FAIL-CLOSED on an absent key (-1, never a silent 0)" as *u8, 95 pg_eq(pc_line_ints(buf, n, "nosuchkey " as *u8, out, 1), 0 - 1), 96 pg_eq(pc_line_ints(buf, n, "ctxt " as *u8, out, 1), 0 - 1), ctr) 97 98 gv_check("T15 the REAL 2026-07-30 numbers (78/s, 2361 permil, 91718 ctxsw/s) verdict RED" as *u8, 99 pg_eq(pc_verdict(PG_FIELD_FORKS_PS, PG_FIELD_RATIO, PG_FIELD_CTXSW_PS, 100 PG_F_AMBER, PG_F_RED, PG_R_AMBER, PG_R_RED, PG_C_AMBER, PG_C_RED), 2), ctr) 101 102 // ---- the append-only journal frame: proven BYTE-FOR-BYTE without touching a filesystem ---- 103 let fb: *u8 = sys_mmap(PG_BUF) 104 let eb: *u8 = sys_mmap(PG_BUF) 105 let frmn: i64 = pc_frame(fb, 1785433000, 3000, 18, 81480, 47557, 2361, 98, 231, 351, 2, 3, 11) 106 let expn: i64 = pg_cpy(eb, "ts=1785433000 window_ms=3000 forks_ps=18 ctxsw_ps=81480 intr_ps=47557 ku_permil=2361 usr_permil=98 sys_permil=231 busy_permil=351 sev=2 running=3 blocked=11\n" as *u8) 107 var t16: i64 = 0 108 if frmn == expn { 109 var q: i64 = 0 110 var same: i64 = 1 111 while q < frmn { if fb[q] != eb[q] { same = 0 } q = q + 1 } 112 t16 = same 113 } 114 gv_check("T16 pc_frame emits the journal frame BYTE-FOR-BYTE (parseable trend line)" as *u8, t16, ctr) 115 116 // An UNMEASURED axis is -1. If pc_catn dropped the sign it would land in the journal as a huge 117 // positive number and read as a catastrophic measurement instead of an absent one. 118 let nb: *u8 = sys_mmap(PG_BUF) 119 let nb2: *u8 = sys_mmap(PG_BUF) 120 let nn1: i64 = pc_catn(nb, 0, 0 - 1) 121 var neg_ok: i64 = 0 122 if nn1 == 2 { if nb[0] == (45 as u8) { if nb[1] == (49 as u8) { neg_ok = 1 } } } 123 pc_catn(nb2, 0, 1) 124 var pos_signed: i64 = 0 125 if nb2[0] == (45 as u8) { pos_signed = 1 } 126 gv_bite("T17 pc_catn keeps the sign on -1 (UNMEASURED stays visible, never wraps huge)" as *u8, 127 neg_ok, pos_signed, ctr) 128 129 // ==== OB5: THE SEVERITY CONSUMER ================================================================= 130 // Every tooth below runs the SHIPPED lib functions in-process on crafted bytes, so the fixture is 131 // assembled at runtime and no filesystem is touched. The gate can therefore never share a fixture 132 // with a production beat, and a RED here tracks the CODE rather than the state of a directory. 133 let jb2: *u8 = sys_mmap(PG_BUF) 134 let so2: *i64 = sys_mmap(PG_OUT_BYTES) as *i64 135 136 // T18 -- the head of an append-only file is its PAST: the oldest and most-tested part, where no 137 // regression has ever lived. A reader that takes the first frame reports history as current. 138 let jn18: i64 = pg_cpy(jb2, "ts=1000 window_ms=3000 forks_ps=1 sev=0 running=1 blocked=0\nts=2000 window_ms=3000 forks_ps=99 sev=2 running=3 blocked=14\n" as *u8) 139 let r18: i64 = pc_sev_last(jb2, jn18, so2) 140 var t18: i64 = 0 141 if r18 == 1 { if so2[0] == 2 { if so2[1] == 2000 { t18 = 1 } } } 142 gv_check("T18 pc_sev_last takes the LAST frame of the journal, never its head" as *u8, t18, ctr) 143 144 // T19 -- the same defect that made WritebackTmp: answer for Writeback: in the I/O ruler. The key 145 // carries its leading space, so a longer key ending in the same letters cannot shadow it. 146 let jn19: i64 = pg_cpy(jb2, "ts=3000 prevsev=9 sev=1 running=1 blocked=0\n" as *u8) 147 let r19: i64 = pc_sev_last(jb2, jn19, so2) 148 var t19bad: i64 = 0 149 if r19 == 1 { if so2[0] == 1 { t19bad = 1 } } 150 let jn19b: i64 = pg_cpy(jb2, "ts=3000 prevsev=9 running=1 blocked=0\n" as *u8) 151 let r19b: i64 = pc_sev_last(jb2, jn19b, so2) 152 var t19good: i64 = 0 153 if r19b == 1 { t19good = 1 } 154 gv_bite("T19 the severity key carries its leading space, so prevsev=9 cannot shadow sev=1" as *u8, 155 t19bad, t19good, ctr) 156 157 // T20 -- ts= is ANCHORED to line start rather than searched. An unanchored key would take the tail 158 // of starts= and return a number from a field that is not the timestamp. 159 let jn20: i64 = pg_cpy(jb2, "starts=999 sev=1 running=1 blocked=0\n" as *u8) 160 var t20bad: i64 = 0 161 if pc_sev_last(jb2, jn20, so2) < 0 { t20bad = 1 } 162 let jn20b: i64 = pg_cpy(jb2, "ts=500 sev=1 running=1 blocked=0\n" as *u8) 163 var t20good: i64 = 1 164 if pc_sev_last(jb2, jn20b, so2) == 1 { if so2[1] == 500 { t20good = 0 } } 165 gv_bite("T20 ts= is anchored to LINE START, so starts=999 is UNPARSEABLE and not a timestamp" as *u8, 166 t20bad, t20good, ctr) 167 168 // T21 -- THREE STATES. An empty journal and a corrupt one demand opposite remedies, and a single 169 // negative word would have the reader guess the alarming one. 170 var t21bad: i64 = 0 171 if pc_sev_last(jb2, 0, so2) == 0 { t21bad = 1 } 172 let jn21: i64 = pg_cpy(jb2, "ts=7 sev=0 running=0 blocked=0\n" as *u8) 173 var t21good: i64 = 0 174 if pc_sev_last(jb2, jn21, so2) == 0 { t21good = 1 } 175 gv_bite("T21 an EMPTY journal reads NO-FRAME(0), distinct from UNPARSEABLE(-1)" as *u8, 176 t21bad, t21good, ctr) 177 178 // T22 -- a journal that ends in blank lines must still yield its last real frame. 179 let jn22: i64 = pg_cpy(jb2, "ts=8000 sev=2 running=1 blocked=9\n\n\n" as *u8) 180 var t22: i64 = 0 181 if pc_sev_last(jb2, jn22, so2) == 1 { if so2[0] == 2 { if so2[1] == 8000 { t22 = 1 } } } 182 gv_check("T22 trailing blank lines do not hide the last real frame" as *u8, t22, ctr) 183 184 // T23 -- the mapping itself, all three severities in one condition so a dropped arm cannot hide. 185 var t23: i64 = 0 186 if pc_sev_consumer(0, 1, PG_ACT_MAXAGE) == PC_ACT_PROCEED { 187 if pc_sev_consumer(1, 1, PG_ACT_MAXAGE) == PC_ACT_SLOW { 188 if pc_sev_consumer(2, 1, PG_ACT_MAXAGE) == PC_ACT_DEFER { t23 = 1 } 189 } 190 } 191 gv_check("T23 severity maps 0->PROCEED 1->SLOW 2->DEFER on a fresh, armed reading" as *u8, t23, ctr) 192 193 // T24 -- THE LOAD-BEARING ONE. A stale GREEN is the flattering direction: it says go ahead at the 194 // exact moment the consumer could not look, and it fails silently because nobody investigates a 195 // permission. Abstention is the only safe answer, and it must beat sev=0. 196 var t24bad: i64 = 0 197 if pc_sev_consumer(0, PG_ACT_STALE_AGE, PG_ACT_MAXAGE) == PC_ACT_UNOBSERVABLE { t24bad = 1 } 198 var t24good: i64 = 1 199 if pc_sev_consumer(0, 1, PG_ACT_MAXAGE) == PC_ACT_PROCEED { t24good = 0 } 200 gv_bite("T24 a STALE sev=0 abstains and does NOT acquit, while a fresh sev=0 proceeds" as *u8, 201 t24bad, t24good, ctr) 202 203 // T25 -- an UNARMED guard that returns PROCEED is byte-for-byte indistinguishable from no guard. 204 var t25bad: i64 = 0 205 if pc_sev_consumer(0, 0, 0) == PC_ACT_UNOBSERVABLE { t25bad = 1 } 206 var t25good: i64 = 1 207 if pc_sev_consumer(0, 0, PG_ACT_MAXAGE) == PC_ACT_PROCEED { t25good = 0 } 208 gv_bite("T25 an UNARMED consumer (no bar declared) abstains rather than waving work through" as *u8, 209 t25bad, t25good, ctr) 210 211 // T26 -- a future timestamp is clock skew, not freshness. Negative age is a third unobservable. 212 var t26bad: i64 = 0 213 if pc_sev_consumer(0, 0 - 1, PG_ACT_MAXAGE) == PC_ACT_UNOBSERVABLE { t26bad = 1 } 214 var t26good: i64 = 1 215 if pc_sev_consumer(2, 1, PG_ACT_MAXAGE) == PC_ACT_DEFER { t26good = 0 } 216 gv_bite("T26 a NEGATIVE age (future stamp / clock skew) abstains, never reads as fresh" as *u8, 217 t26bad, t26good, ctr) 218 219 // T27 -- an unmeasurable severity is -1, and -1 compares below every threshold. Without this screen 220 // it would read as a confident GREEN: the partial-as-complete defect wearing an actuator costume. 221 var t27bad: i64 = 0 222 if pc_sev_consumer(0 - 1, 1, PG_ACT_MAXAGE) == PC_ACT_UNOBSERVABLE { t27bad = 1 } 223 var t27good: i64 = 1 224 if pc_sev_consumer(0, 1, PG_ACT_MAXAGE) == PC_ACT_PROCEED { t27good = 0 } 225 gv_bite("T27 an UNMEASURABLE severity (-1) abstains and never reads as GREEN" as *u8, 226 t27bad, t27good, ctr) 227 228 // T28 -- THE WIRE. The producer and the consumer are each proven correct above IN ISOLATION, which 229 // is exactly the state in which two organs still disagree on the format between them. This is the 230 // only tooth that tests the format itself: pc_frame writes the bytes, pc_sev_last reads them back. 231 let wb: *u8 = sys_mmap(PG_BUF) 232 let wn: i64 = pc_frame(wb, 1788400000, 3000, 37, 151312, 73865, 1200, 147, 177, 330, 2, 3, 14) 233 var t28: i64 = 0 234 if pc_sev_last(wb, wn, so2) == 1 { if so2[0] == 2 { if so2[1] == 1788400000 { t28 = 1 } } } 235 gv_check("T28 WIRE ROUND-TRIP: pc_frame writes a frame that pc_sev_last reads back exactly" as *u8, t28, ctr) 236 237 // T29 -- a control that MUST fail. Without it, a parser that accepted anything would score 100pct. 238 let jn29: i64 = pg_cpy(jb2, "ts=9000 Sev=2 running=1 blocked=0\n" as *u8) 239 var t29: i64 = 0 240 if pc_sev_last(jb2, jn29, so2) < 0 { t29 = 1 } 241 gv_check("neg-control-T29 a mis-cased Sev= is UNPARSEABLE, never silently accepted" as *u8, t29, ctr) 242 243 // ==== OB4: FORK SOURCES BY PARENT =============================================================== 244 let pbA: *u8 = sys_mmap(PG_BUF) 245 let pbB: *u8 = sys_mmap(PG_BUF) 246 let pathb: *u8 = sys_mmap(PG_PATHBUF) 247 let stout: *i64 = sys_mmap(PG_OUT_BYTES) as *i64 248 let o4: *i64 = sys_mmap(PG_OUT_BYTES) as *i64 249 let fullf: *i64 = sys_mmap(PG_OUT_BYTES) as *i64 250 251 // T30/T31 -- /proc holds named entries beside the pids. A walk that does not screen them hands 252 // "self" to a decimal parser, which returns 0, which is a REAL PID -- a fabricated process. 253 pg_cpy(pbA, "31039" as *u8) 254 pg_cpy(pbB, "self" as *u8) 255 gv_check("T30 pc_name_is_pid accepts an all-digit /proc entry" as *u8, pg_eq(pc_name_is_pid(pbA), 1), ctr) 256 var t31bad: i64 = 0 257 if pc_name_is_pid(pbB) == 0 { pg_cpy(pbB, "" as *u8); if pc_name_is_pid(pbB) == 0 { t31bad = 1 } } 258 var t31good: i64 = 1 259 if pc_name_is_pid(pbA) == 1 { t31good = 0 } 260 gv_bite("neg-control-T31 named /proc entries and the empty name are REJECTED, digits are not" as *u8, 261 t31bad, t31good, ctr) 262 gv_check("T32 pc_name_to_i64 reads the enumerated name back as its number" as *u8, 263 pg_eq(pc_name_to_i64(pbA), 31039), ctr) 264 265 // T33/T34 -- the tally is the only pure part of the attribution, so it is the only part that can be 266 // proven without a /proc. A table that grows past its cap would corrupt the arrays beside it. 267 let tp: *i64 = sys_mmap(PG_TALLY_BYTES) as *i64 268 let tc: *i64 = sys_mmap(PG_TALLY_BYTES) as *i64 269 var np: i64 = 0 270 np = pc_tally_parent(tp, tc, np, PG_TALLY_MAX, 100) 271 np = pc_tally_parent(tp, tc, np, PG_TALLY_MAX, 200) 272 np = pc_tally_parent(tp, tc, np, PG_TALLY_MAX, 100) 273 var t33: i64 = 0 274 if np == 2 { if tc[0] == 2 { if tc[1] == 1 { if tp[0] == 100 { if tp[1] == 200 { t33 = 1 } } } } } 275 gv_check("T33 pc_tally_parent adds a new parent once and increments a repeat" as *u8, t33, ctr) 276 var t34bad: i64 = 0 277 let npf: i64 = pc_tally_parent(tp, tc, PG_TALLY_MAX, PG_TALLY_MAX, 999) 278 if npf == PG_TALLY_MAX { t34bad = 1 } 279 var t34good: i64 = 1 280 if pc_tally_parent(tp, tc, 2, PG_TALLY_MAX, 300) == 3 { t34good = 0 } 281 gv_bite("T34 a FULL parent table refuses to grow, while a table with room still admits" as *u8, 282 t34bad, t34good, ctr) 283 284 // T35 -- membership, including the empty set. A seen-test that answers yes on an empty array would 285 // make every pid look old and the new-process count would be permanently zero. 286 var t35: i64 = 0 287 if pc_pid_seen(tp, 2, 100) == 1 { if pc_pid_seen(tp, 2, 555) == 0 { if pc_pid_seen(tp, 0, 100) == 0 { t35 = 1 } } } 288 gv_check("T35 pc_pid_seen finds a member, rejects a non-member, and says NO on the empty set" as *u8, t35, ctr) 289 290 // T36/T37/T38 -- the coverage ratio, which is the whole point of this rung: the attributed number is 291 // a LOWER BOUND and it is only honest beside the kernel counter. 292 gv_check("T36 pc_attrib_permil derives 250 of 1000 as 250 permil" as *u8, 293 pg_eq(pc_attrib_permil(250, 1000), 250), ctr) 294 var t37bad: i64 = 0 295 if pc_attrib_permil(5, 0) == 0 - 1 { t37bad = 1 } 296 var t37good: i64 = 1 297 if pc_attrib_permil(250, 1000) == 250 { t37good = 0 } 298 gv_bite("T37 an unusable kernel counter ABSTAINS at -1 and never reports 0 permil coverage" as *u8, 299 t37bad, t37good, ctr) 300 var t38bad: i64 = 0 301 if pc_attrib_permil(2000, 1000) == 2000 { t38bad = 1 } 302 var t38good: i64 = 1 303 if pc_attrib_permil(500, 1000) == 500 { t38good = 0 } 304 gv_bite("T38 coverage above 1000 is REPORTED not clamped, because it means the windows disagree" as *u8, 305 t38bad, t38good, ctr) 306 307 // T39/T40 -- LIVE enumeration against this very host, and its declared bound. A cap silently reached 308 // becomes a measurement nobody knows is partial, so filling it must SAY SO. 309 let pidsA: *i64 = sys_mmap(PG_PIDS_BYTES) as *i64 310 let pidsB: *i64 = sys_mmap(PG_PIDS_BYTES) as *i64 311 let nA: i64 = pc_pids(pidsA, PG_PIDCAP, fullf) 312 var t39: i64 = 0 313 if nA > 0 { if fullf[0] == 0 { t39 = 1 } } 314 gv_puts(" live: pids_enumerated=" as *u8); gv_num(nA); gv_puts(" cap_hit=" as *u8); gv_num(fullf[0]); gv_puts("\n" as *u8) 315 gv_check("T39 pc_pids enumerates this live host and does not silently hit its cap" as *u8, t39, ctr) 316 var t40bad: i64 = 0 317 let nOne: i64 = pc_pids(pidsB, 1, fullf) 318 if nOne == 1 { if fullf[0] == 1 { t40bad = 1 } } 319 var t40good: i64 = 1 320 pc_pids(pidsB, PG_PIDCAP, fullf) 321 if fullf[0] == 0 { t40good = 0 } 322 gv_bite("T40 a cap of ONE reports cap_hit so the count reads as a FLOOR, and a roomy cap does not" as *u8, 323 t40bad, t40good, ctr) 324 325 // T41 -- the incumbent stat parser reached through its named accessor, both directions. /proc/0 does 326 // not exist, and the answer for it must be -1 and never 0, because 0 is a real pid. 327 var t41bad: i64 = 0 328 if pc_ppid_of(0, pbA, pathb, stout) == 0 - 1 { t41bad = 1 } 329 var t41good: i64 = 1 330 if nA > 0 { if pc_ppid_of(pidsA[0], pbA, pathb, stout) >= 0 { t41good = 0 } } 331 gv_bite("T41 a pid that cannot exist returns -1, while a live pid resolves its real parent" as *u8, 332 t41bad, t41good, ctr) 333 334 // T42 -- THE PARTITION. Attributed and vanished must SUM to the new-process count: a pid that exits 335 // between the walk and the read is a DIFFERENT outcome from one that was never new, and folding them 336 // into one counter is how a survivor census quietly becomes a fork rate. 337 let tp2: *i64 = sys_mmap(PG_TALLY_BYTES) as *i64 338 let tc2: *i64 = sys_mmap(PG_TALLY_BYTES) as *i64 339 pc_fork_by_parent(pidsB, 0, pidsA, nA, tp2, tc2, PG_TALLY_MAX, pbA, pathb, stout, o4) 340 var t42: i64 = 0 341 if o4[0] == nA { if o4[1] + o4[3] == o4[0] { if o4[2] >= 0 { t42 = 1 } } } 342 gv_puts(" live: new=" as *u8); gv_num(o4[0]) 343 gv_puts(" attributed=" as *u8); gv_num(o4[1]) 344 gv_puts(" distinct_parents=" as *u8); gv_num(o4[2]) 345 gv_puts(" vanished_before_read=" as *u8); gv_num(o4[3]) 346 gv_puts(" coverage_permil_vs_self=" as *u8); gv_num(pc_attrib_permil(o4[1], o4[0])) 347 gv_puts("\n" as *u8) 348 gv_check("T42 attributed plus vanished SUMS to the new-process count over the live host" as *u8, t42, ctr) 349 350 let rc: i64 = gv_verdict("PROCCHURN-GATE" as *u8, ctr, "process-churn predicates proven both polarities on field data" as *u8) 351 sys_exit(rc) 352 return rc 353}