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}