code wiki / _hdl_build / nx_cron_reconcile_gate.nx

nx_cron_reconcile_gate.nx source

↩ module page · 423 lines · 22456 B

1// nx_cron_reconcile_gate.nx -- THE REFEREE nx_cron_reconcile NEVER HAD, WHICH IS WHY IT SURVIVED. 2// 3// WHAT IT EXISTS TO CATCH. For at least two weeks this organ applied a PREFIX of its own SSOT and 4// reported it as the whole: cr_read did ONE sys_read of CR_REGCAP-1 = 16383 bytes with no truncation 5// check while cron.reg had grown to 24356, so 11 declared rows were silently inert -- including the 6// estate's only compensating control over a fail-open authentication path. Nothing caught it because 7// nx_catalog nx_cron_reconcile_gate read ABSENT: there was no gate at all. 8// **** THE DECISIVE TOOTH IS T1: A REGISTRY BIGGER THAN THE OLD CAP, EVERY ROW APPLIED. **** 9// THE PRE-FIX BINARY IS THE FREE MUTANT. Point argv[1] at it and T1/T2/T9 must go RED; point argv[1] at 10// the fixed binary and they must go GREEN. A gate whose decisive tooth has only ever seen the fixed 11// binary has not been shown to fire. 12// 13// ⚠TRUNCATION HAS TWO MANIFESTATIONS AND ONLY ONE OF THEM IS THE PRODUCTION ONE. MEASURED HERE 14// 2026-08-20 while building this gate: where the 16383-byte cut lands INSIDE a row decides which. 15// Cut EARLY in a row and the surviving fragment has lost "/nishihost/", so R3 fires and the organ 16// REFUSES exit 5 -- loud, safe, and NOT what happened in production. Cut LATE in a row and the 17// fragment still carries the mark, so the organ counts it, writes a crontab missing every later row, 18// and reports CHANGED with exit 0. THAT is the production shape: a success message over a prefix. 19// The first draft of this fixture hit the refusal by luck and its decisive tooth went RED for the 20// WRONG REASON -- a red that would have read as proof while measuring something else entirely. 21// **** A TOOTH THAT FAILS FOR A DIFFERENT REASON THAN THE ONE IT NAMES IS NOT EVIDENCE. **** 22// So the header pad is now SOLVED FOR, not chosen: rows are uniform length and the comment header is 23// sized by modular arithmetic so the old cut lands CRG_CUT_MARGIN bytes before a row end. T0 asserts 24// that condition arithmetically before any outcome is asserted, and T1 requires exit 0 AND the last 25// row present -- so the broken binary cannot pass by refusing either. 26// 27// THE VACUITY GUARD COMES FIRST AND IT IS NOT DECORATION. A fixture registry that does not actually 28// EXCEED the old 16384-byte cap makes T1 pass against the BROKEN binary too, and the gate would then 29// certify the defect. So T0 asserts the fixture reached the condition -- total bytes over the cap AND 30// the last declared row STARTING past it -- before any outcome is asserted. The estate has shipped four 31// vacuous fixtures in one day before (a 900 B trigger with an 836 B fixture); this is that lesson. 32// 33// SCRATCH IS /tmp/nx_cron_reconcile_gate/ AND THE SUBJECT NEVER SEES A REAL CRONTAB. The organ's own 34// usage line already says "gate runs it on COPIES; prod = /etc/crontab". The fixture rows name 35// nx_gatefixture_*.sh, which does not exist and is never installed anywhere -- they live and die in /tmp. 36// Setup creates and clears; there is no teardown, because a teardown does not run when a run crashes. 37// 38// ⚠ONE HONEST SIDE EFFECT, NAMED RATHER THAN HIDDEN: on a CHANGED result the subject walks /proc and 39// SIGHUPs every `crond`. Running this gate on the NAS therefore reloads the real crond. That reload is 40// of an UNCHANGED /etc/crontab and is the same standard, non-destructive signal the organ already sends 41// on every production CHANGED -- but a gate with a production side effect must say so out loud. 42// 43// expect_exit: 0 license_tier: ORIGINAL No hw writes (Rule 26). 44import "nx_syscalls.nx" 45import "nx_gate_verdict.nx" 46import "nx_tool_run.nx" 47 48const CRG_DIR: *u8 = "/tmp/nx_cron_reconcile_gate" as *u8 49const CRG_CT: *u8 = "/tmp/nx_cron_reconcile_gate/crontab" as *u8 50const CRG_REG_BIG: *u8 = "/tmp/nx_cron_reconcile_gate/reg.big" as *u8 51const CRG_REG_SMALL:*u8 = "/tmp/nx_cron_reconcile_gate/reg.small" as *u8 52const CRG_REG_EMPTY:*u8 = "/tmp/nx_cron_reconcile_gate/reg.empty" as *u8 53const CRG_REG_TAINT:*u8 = "/tmp/nx_cron_reconcile_gate/reg.taint" as *u8 54const CRG_REG_GONE: *u8 = "/tmp/nx_cron_reconcile_gate/reg.does-not-exist" as *u8 55 56// THE OLD CAP, quoted here as the BAR THE FIXTURE MUST CLEAR -- not as a limit this code imposes. 57// If the fixture does not exceed it, T1 proves nothing, so T0 refuses to let the run continue silently. 58const CRG_OLD_CAP: i64 = 16384 59// The broken reader called sys_read(fd, buf, cap - 1), so the bytes it actually held were [0, 16383). 60// That off-by-one is the real cut point and the arithmetic below solves against IT, not against 16384. 61const CRG_OLD_READ: i64 = 16383 62const CRG_ROWS: i64 = 140 63// How far before a row end the old cut must land. Any value comfortably above the mark end works; 8 64// keeps the surviving fragment obviously a fragment while guaranteeing "/nishihost/" is inside it. 65const CRG_CUT_MARGIN:i64 = 8 66const CRG_SPACE: i64 = 32 67const CRG_DIR_MODE: i64 = 493 68const CRG_MODE_644: i64 = 420 69const CRG_BUF: i64 = 262144 70const CRG_OUT: i64 = 65536 71const CRG_TIMEOUT_MS:i64 = 30000 72const CRG_ARGV_SLOTS:i64 = 64 73const CRG_ASCII_0: i64 = 48 74const CRG_ASCII_9: i64 = 57 75const CRG_B10: i64 = 10 76const CRG_NL: i64 = 10 77const CRG_HASH: i64 = 35 78// exit codes the subject is contracted to return (its own header declares these) 79const CRG_EXIT_OK: i64 = 0 80const CRG_EXIT_REGREF: i64 = 3 81const CRG_EXIT_TAINT: i64 = 5 82 83func crg_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } 84func crg_cat(d: *u8, o: i64, s: *u8) -> i64 { var i: i64 = 0; var p: i64 = o; while s[i] != (0 as u8) { d[p] = s[i]; p = p + 1; i = i + 1 } return p } 85func crg_catn(d: *u8, o: i64, v: i64) -> i64 { 86 let t: *u8 = sys_mmap(32) 87 var m: i64 = v 88 var p: i64 = o 89 var k: i64 = 0 90 if m == 0 { t[0] = CRG_ASCII_0 as u8; k = 1 } 91 while m > 0 { t[k] = (CRG_ASCII_0 + (m % CRG_B10)) as u8; m = m / CRG_B10; k = k + 1 } 92 var i: i64 = k - 1 93 while i >= 0 { d[p] = t[i]; p = p + 1; i = i - 1 } 94 sys_munmap(t, 32) 95 return p 96} 97func crg_contains(buf: *u8, n: i64, needle: *u8) -> i64 { 98 let nl: i64 = crg_slen(needle) 99 if nl == 0 { return 1 } 100 var i: i64 = 0 101 while i + nl <= n { 102 var m: i64 = 1 103 var j: i64 = 0 104 while j < nl { if buf[i+j] != needle[j] { m = 0; j = nl } else { j = j + 1 } } 105 if m == 1 { return 1 } 106 i = i + 1 107 } 108 return 0 109} 110// LAST MATCH WINS, deliberately mirroring nx_cron_watch's cw_num_after: a merged stdout+stderr capture 111// puts the freshest value last, and OFFSET 0 IS NOT THE MESSAGE. Returns -1 when the marker is absent, 112// which is its own answer and must never be folded into 0. 113func crg_num_after(buf: *u8, n: i64, marker: *u8) -> i64 { 114 let ml: i64 = crg_slen(marker) 115 if ml == 0 { return 0 - 1 } 116 var last: i64 = 0 - 1 117 var i: i64 = 0 118 while i + ml <= n { 119 var ok: i64 = 1 120 var j: i64 = 0 121 while j < ml { if buf[i+j] != marker[j] { ok = 0; j = ml } else { j = j + 1 } } 122 if ok == 1 { 123 var p: i64 = i + ml 124 var v: i64 = 0 125 var got: i64 = 0 126 var go: i64 = 1 127 while go == 1 { 128 if p >= n { go = 0 } else { 129 let c: i64 = buf[p] as i64 130 if c >= CRG_ASCII_0 { if c <= CRG_ASCII_9 { v = v * CRG_B10 + (c - CRG_ASCII_0); got = 1; p = p + 1 } else { go = 0 } } else { go = 0 } 131 } 132 } 133 if got == 1 { last = v } 134 } 135 i = i + 1 136 } 137 return last 138} 139// THREE-DIGIT, ZERO-PADDED, so every fixture row is the SAME LENGTH. Uniform rows are what make the 140// cut position solvable in closed form instead of guessed at. 141func crg_catn3(d: *u8, o: i64, v: i64) -> i64 { 142 d[o] = (CRG_ASCII_0 + ((v / 100) % CRG_B10)) as u8 143 d[o + 1] = (CRG_ASCII_0 + ((v / CRG_B10) % CRG_B10)) as u8 144 d[o + 2] = (CRG_ASCII_0 + (v % CRG_B10)) as u8 145 return o + 3 146} 147// index just past "/nishihost/" inside one row, DERIVED from the row itself -- never a hand-counted 148// number sitting beside the literal it describes. 149func crg_mark_end(row: *u8, n: i64) -> i64 { 150 let m: *u8 = "/nishihost/" as *u8 151 let ml: i64 = crg_slen(m) 152 var i: i64 = 0 153 while i + ml <= n { 154 var ok: i64 = 1 155 var j: i64 = 0 156 while j < ml { if row[i+j] != m[j] { ok = 0; j = ml } else { j = j + 1 } } 157 if ok == 1 { return i + ml } 158 i = i + 1 159 } 160 return 0 - 1 161} 162// A comment header of EXACTLY h bytes: the note, space-padded, newline-terminated. Its only job is to 163// place the rows at the offset the arithmetic asked for; the subject skips it as a comment. 164func crg_hdr(d: *u8, h: i64) -> i64 { 165 let note: *u8 = "# fixture registry assembled at RUNTIME and padded so the old cut lands late in a row" as *u8 166 let nl: i64 = crg_slen(note) 167 var p: i64 = 0 168 while p < nl { if p < h - 1 { d[p] = note[p]; p = p + 1 } else { p = nl } } 169 while p < h - 1 { d[p] = CRG_SPACE as u8; p = p + 1 } 170 d[h - 1] = CRG_NL as u8 171 return h 172} 173func crg_write(path: *u8, buf: *u8, n: i64) -> i64 { 174 let fd: i64 = sys_openat_wr(path, CRG_MODE_644) 175 if fd < 0 { return 0 - 1 } 176 var w: i64 = 0 177 while w < n { 178 let r: i64 = sys_write(fd, ((buf as i64) + w) as *u8, n - w) 179 if r <= 0 { w = n } else { w = w + r } 180 } 181 sys_close(fd) 182 return n 183} 184func crg_slurp(path: *u8, dst: *u8, cap: i64, outlen: *i64) -> i64 { 185 outlen[0] = 0 186 let fd: i64 = sys_openat_rd(path) 187 if fd < 0 { return 0 - 1 } 188 var t: i64 = 0 189 var go: i64 = 1 190 while go == 1 { 191 if t >= cap { go = 0 } else { 192 let r: i64 = sys_read(fd, ((dst as i64) + t) as *u8, cap - t) 193 if r <= 0 { go = 0 } else { t = t + r } 194 } 195 } 196 sys_close(fd) 197 outlen[0] = t 198 return t 199} 200// one fixture registry row, byte-identical in shape to a real cron.reg row (it MUST carry /nishihost/ 201// or the subject's own R3 taint guard refuses the whole file -- which is a different tooth, below). 202func crg_row(d: *u8, o: i64, idx: i64) -> i64 { 203 var p: i64 = crg_cat(d, o, "*/5 * * * * elderwesto /volume1/homes/elderwesto/nishihost/nx_gatefixture_" as *u8) 204 p = crg_catn3(d, p, idx) 205 p = crg_cat(d, p, ".sh >> /volume1/homes/elderwesto/nishihost/logs/gatefixture.log 2>&1" as *u8) 206 d[p] = CRG_NL as u8 207 return p + 1 208} 209// run the subject against the fixture pair; returns its exit code, capture in out/outlen 210func crg_run(subject: *u8, ctpath: *u8, regpath: *u8, out: *u8, outlen: *i64) -> i64 { 211 let av: *i64 = sys_mmap(CRG_ARGV_SLOTS) as *i64 212 av[0] = subject as i64 213 av[1] = ctpath as i64 214 av[2] = regpath as i64 215 av[3] = 0 216 return tr_run_capture_to(subject, av, out, CRG_OUT, outlen, CRG_TIMEOUT_MS) 217} 218func crg_exists(path: *u8) -> i64 { let fd: i64 = sys_openat_rd(path); if fd < 0 { return 0 } sys_close(fd); return 1 } 219 220func main(argc: i64, argv: *i64) -> i64 { 221 gv_head("nx_cron_reconcile_gate -- an applier that reads a PREFIX of its SSOT must be impossible, not merely unlikely" as *u8) 222 let ctr: *i64 = gv_ctr() 223 224 // ---- SUBJECT RESOLUTION, PROBED NOT ASSUMED. Printed, so the verdict names what it judged. ---- 225 var subject: *u8 = "" as *u8 226 if argc >= 2 { subject = argv[1] as *u8 } 227 if crg_exists(subject) == 0 { subject = "./nx_cron_reconcile.elf" as *u8 } 228 if crg_exists(subject) == 0 { subject = "_offc/nx_cron_reconcile.elf" as *u8 } 229 if crg_exists(subject) == 0 { subject = "./_build/nx_cron_reconcile.sov.elf" as *u8 } 230 let have_subject: i64 = crg_exists(subject) 231 gv_puts(" subject=" as *u8); gv_puts(subject); gv_puts("\n" as *u8) 232 gv_need("the reconciler binary under test is present and readable" as *u8, have_subject, ctr) 233 234 sys_mkdir(CRG_DIR, CRG_DIR_MODE) 235 let probe: i64 = sys_openat_wr("/tmp/nx_cron_reconcile_gate/.writecheck" as *u8, CRG_MODE_644) 236 var dirw: i64 = 0 237 if probe >= 0 { dirw = 1; sys_close(probe) } 238 gv_need("fixture dir /tmp/nx_cron_reconcile_gate is writable" as *u8, dirw, ctr) 239 240 var can: i64 = 0 241 if have_subject == 1 { if dirw == 1 { can = 1 } } 242 if can == 0 { 243 let rcs: i64 = gv_verdict("CRON-RECONCILE-GATE" as *u8, ctr, "unreachable" as *u8) 244 sys_exit(rcs) 245 return rcs 246 } 247 248 let big: *u8 = sys_mmap(CRG_BUF) 249 let out: *u8 = sys_mmap(CRG_OUT) 250 let rd: *u8 = sys_mmap(CRG_BUF) 251 let onp: *i64 = sys_mmap(16) as *i64 252 let rdn: *i64 = sys_mmap(16) as *i64 253 254 // ---- BUILD THE OVERSIZE REGISTRY, SOLVING FOR WHERE THE OLD CUT LANDS ---------------------- 255 // Rows are uniform length L. Row r occupies [H + r*L, H + (r+1)*L). A reader holding only 256 // [0, CRG_OLD_READ) therefore cuts row (CRG_OLD_READ - H)/L at within-row offset 257 // w = (CRG_OLD_READ - H) mod L 258 // and the fragment keeps "/nishihost/" exactly when w >= mark_end. Solve H for a chosen w: 259 // w = target => H = (CRG_OLD_READ - target) mod L, plus any multiple of L. 260 let probe_row: *u8 = sys_mmap(1024) 261 let rl: i64 = crg_row(probe_row, 0, 0) 262 let mark_end: i64 = crg_mark_end(probe_row, rl) 263 let target: i64 = rl - CRG_CUT_MARGIN 264 var hdr: i64 = (CRG_OLD_READ - target) % rl 265 while hdr < 96 { hdr = hdr + rl } 266 var bo: i64 = crg_hdr(big, hdr) 267 var last_row_off: i64 = 0 268 var r: i64 = 0 269 while r < CRG_ROWS { 270 last_row_off = bo 271 bo = crg_row(big, bo, r) 272 r = r + 1 273 } 274 crg_write(CRG_REG_BIG, big, bo) 275 let cut_w: i64 = (CRG_OLD_READ - hdr) % rl 276 277 // ---- T0: ANTI-VACUITY, FIRST. THE FIXTURE MUST BE ABLE TO FAIL THE BROKEN BINARY. ---------- 278 // Two conditions, because total size alone is not enough: a registry can exceed the cap while every 279 // row still fits under it, and then the broken binary applies all of them and T1 certifies the defect. 280 var t0: i64 = 0 281 if bo > CRG_OLD_CAP { if last_row_off > CRG_OLD_CAP { t0 = 1 } } 282 gv_puts(" fixture reg bytes=" as *u8); gv_num(bo) 283 gv_puts(" last_row_starts_at=" as *u8); gv_num(last_row_off) 284 gv_puts(" old_cap=" as *u8); gv_num(CRG_OLD_CAP); gv_puts("\n" as *u8) 285 gv_check("anti-vacuity-the-fixture-registry-EXCEEDS-the-old-cap-and-its-last-row-STARTS-past-it" as *u8, t0, ctr) 286 287 // ---- T0b: AND IT REPRODUCES THE PRODUCTION MANIFESTATION, NOT THE OTHER ONE --------------- 288 // Without this the decisive tooth can go RED because the broken reader REFUSED (loud, safe) rather 289 // than because it silently applied a prefix (quiet, dangerous) -- and nobody reading the vector 290 // would ever know the difference. 291 var t0b: i64 = 0 292 if mark_end > 0 { if cut_w >= mark_end { t0b = 1 } } 293 gv_puts(" row_len=" as *u8); gv_num(rl) 294 gv_puts(" hdr_pad=" as *u8); gv_num(hdr) 295 gv_puts(" mark_ends_at=" as *u8); gv_num(mark_end) 296 gv_puts(" old_cut_lands_at_row_offset=" as *u8); gv_num(cut_w) 297 gv_puts(" (>= mark_end means the fragment KEEPS the nishi mark, so a broken reader applies a\n prefix with exit 0 instead of refusing -- the production shape)\n" as *u8) 298 gv_check("anti-vacuity-the-old-cut-lands-PAST-the-nishi-mark-so-this-tests-the-SILENT-prefix-not-a-refusal" as *u8, t0b, ctr) 299 300 // ---- the fixture crontab: non-nishi rows that must survive byte-exact, plus a stale nishi row ---- 301 var co: i64 = crg_cat(rd, 0, "SHELL=/bin/sh\n" as *u8) 302 co = crg_cat(rd, co, "PATH=/usr/bin:/bin\n" as *u8) 303 co = crg_cat(rd, co, "0 4 * * * root /usr/syno/bin/synoservice --hard-restart-nothing\n" as *u8) 304 co = crg_cat(rd, co, "*/9 * * * * elderwesto /volume1/homes/elderwesto/nishihost/nx_stale_fixture_row.sh\n" as *u8) 305 co = crg_cat(rd, co, "17 2 * * * root /bin/true\n" as *u8) 306 crg_write(CRG_CT, rd, co) 307 308 // ================= T1 THE DECISIVE TOOTH ===================================================== 309 let rc1: i64 = crg_run(subject, CRG_CT, CRG_REG_BIG, out, onp) 310 let on1: i64 = onp[0] 311 crg_slurp(CRG_CT, rd, CRG_BUF, rdn) 312 let cn1: i64 = rdn[0] 313 // the LAST fixture row is the one that lives past the old cap; if it is in the applied crontab, the 314 // reader saw the whole registry. 315 let tail: *u8 = sys_mmap(1024) 316 let tl: i64 = crg_row(tail, 0, CRG_ROWS - 1) 317 tail[tl - 1] = 0 as u8 318 // BOTH CONJUNCTS, AND THEY ARE NAMED SEPARATELY IN THE DIAGNOSTIC ABOVE: a run that REFUSED did 319 // not apply a prefix, and a run that applied everything did not refuse. Requiring exit 0 as well 320 // as the row means neither manifestation of a short read can score. 321 var t1: i64 = 0 322 var t1_row: i64 = 0 323 if crg_contains(rd, cn1, tail) == 1 { t1_row = 1 } 324 if rc1 == CRG_EXIT_OK { if t1_row == 1 { t1 = 1 } } 325 gv_puts(" last_row_present=" as *u8); gv_num(t1_row) 326 gv_puts(" exit_was_clean=" as *u8) 327 if rc1 == CRG_EXIT_OK { gv_num(1) } else { gv_num(0) } 328 gv_puts("\n" as *u8) 329 gv_puts(" subject exit=" as *u8); gv_num(rc1) 330 gv_puts(" applied crontab bytes=" as *u8); gv_num(cn1); gv_puts("\n" as *u8) 331 gv_check("every-row-of-an-OVERSIZE-registry-reaches-the-crontab-incl-the-one-past-the-old-cap" as *u8, t1, ctr) 332 333 // ================= T2 the count must be of rows that EXIST, not rows that FIT =============== 334 let decl: i64 = crg_num_after(out, on1, "declared=" as *u8) 335 var t2: i64 = 0 336 if decl == CRG_ROWS { t2 = 1 } 337 gv_puts(" declared=" as *u8); gv_num(decl) 338 gv_puts(" fixture rows=" as *u8); gv_num(CRG_ROWS); gv_puts("\n" as *u8) 339 gv_check("the-declared-count-equals-the-rows-that-EXIST-not-the-rows-that-FIT" as *u8, t2, ctr) 340 341 // ================= T3 the evidence line carries its denominators ============================ 342 let rb: i64 = crg_num_after(out, on1, "reg_bytes=" as *u8) 343 var t3: i64 = 0 344 if rb == bo { t3 = 1 } 345 gv_puts(" reg_bytes reported=" as *u8); gv_num(rb) 346 gv_puts(" actual=" as *u8); gv_num(bo); gv_puts("\n" as *u8) 347 gv_check("the-run-PUBLISHES-the-registry-size-it-read-so-a-prefix-is-visible-in-the-evidence" as *u8, t3, ctr) 348 349 // ================= T4 non-nishi rows survive BYTE-EXACT (R1, the blast-radius bound) ======== 350 var t4: i64 = 0 351 if crg_contains(rd, cn1, "0 4 * * * root /usr/syno/bin/synoservice --hard-restart-nothing" as *u8) == 1 { 352 if crg_contains(rd, cn1, "17 2 * * * root /bin/true" as *u8) == 1 { 353 if crg_contains(rd, cn1, "SHELL=/bin/sh" as *u8) == 1 { t4 = 1 } 354 } 355 } 356 gv_check("non-nishi-rows-survive-byte-exact-so-the-blast-radius-stays-bounded" as *u8, t4, ctr) 357 358 // ================= T5 the stale nishi row is GONE (dead rows vanish by construction) ======== 359 var t5: i64 = 0 360 if crg_contains(rd, cn1, "nx_stale_fixture_row.sh" as *u8) == 0 { t5 = 1 } 361 gv_check("a-nishi-row-absent-from-the-registry-is-REMOVED-from-the-crontab" as *u8, t5, ctr) 362 363 // ================= T6 idempotence: a second run reports NO-CHANGE and rewrites nothing ====== 364 let rc2: i64 = crg_run(subject, CRG_CT, CRG_REG_BIG, out, onp) 365 let on2: i64 = onp[0] 366 var t6: i64 = 0 367 if rc2 == CRG_EXIT_OK { if crg_contains(out, on2, "NO-CHANGE" as *u8) == 1 { t6 = 1 } } 368 gv_check("running-twice-over-its-own-result-reports-NO-CHANGE-so-any-cadence-is-safe" as *u8, t6, ctr) 369 370 // ================= T7 POSITIVE CONTROL: a SMALL registry must still be applied ============== 371 // Without this an implementation that refuses everything scores full marks on the negatives below. 372 var so: i64 = crg_cat(big, 0, "# small fixture\n" as *u8) 373 so = crg_row(big, so, 900) 374 crg_write(CRG_REG_SMALL, big, so) 375 let rc3: i64 = crg_run(subject, CRG_CT, CRG_REG_SMALL, out, onp) 376 crg_slurp(CRG_CT, rd, CRG_BUF, rdn) 377 var t7: i64 = 0 378 if rc3 == CRG_EXIT_OK { if crg_contains(rd, rdn[0], "nx_gatefixture_900.sh" as *u8) == 1 { t7 = 1 } } 379 gv_check("pos-control-an-ordinary-small-registry-is-still-applied-normally" as *u8, t7, ctr) 380 381 // ================= T8-T9 neg-control: an EMPTY registry refuses and does NOT wipe =========== 382 crg_write(CRG_REG_EMPTY, big, 0) 383 crg_slurp(CRG_CT, rd, CRG_BUF, rdn) 384 let before: i64 = rdn[0] 385 let rc4: i64 = crg_run(subject, CRG_CT, CRG_REG_EMPTY, out, onp) 386 let on4: i64 = onp[0] 387 crg_slurp(CRG_CT, rd, CRG_BUF, rdn) 388 var t8: i64 = 0 389 if rc4 == CRG_EXIT_REGREF { if crg_contains(out, on4, "REFUSED" as *u8) == 1 { t8 = 1 } } 390 gv_check("neg-control-an-EMPTY-registry-REFUSES-LOUDLY-instead-of-applying-nothing-quietly" as *u8, t8, ctr) 391 var t9: i64 = 0 392 if rdn[0] == before { t9 = 1 } 393 gv_puts(" crontab bytes before=" as *u8); gv_num(before) 394 gv_puts(" after=" as *u8); gv_num(rdn[0]); gv_puts("\n" as *u8) 395 gv_check("neg-control-an-EMPTY-registry-leaves-the-boot-file-BYTE-UNCHANGED" as *u8, t9, ctr) 396 397 // ================= T10 neg-control: an ABSENT registry refuses ============================= 398 let rc5: i64 = crg_run(subject, CRG_CT, CRG_REG_GONE, out, onp) 399 var t10: i64 = 0 400 if rc5 == CRG_EXIT_REGREF { t10 = 1 } 401 gv_check("neg-control-an-UNREADABLE-registry-REFUSES-rather-than-emptying-the-boot-file" as *u8, t10, ctr) 402 403 // ================= T11 neg-control: a TAINTED row refuses (R3) ============================== 404 var to: i64 = crg_cat(big, 0, "# taint fixture\n" as *u8) 405 to = crg_row(big, to, 1) 406 to = crg_cat(big, to, "*/5 * * * * root /usr/bin/somebody-elses-job --not-ours\n" as *u8) 407 crg_write(CRG_REG_TAINT, big, to) 408 let rc6: i64 = crg_run(subject, CRG_CT, CRG_REG_TAINT, out, onp) 409 var t11: i64 = 0 410 if rc6 == CRG_EXIT_TAINT { t11 = 1 } 411 gv_check("neg-control-a-row-without-the-nishi-mark-REFUSES-exit-5-so-the-organ-cannot-inject-foreign-rows" as *u8, t11, ctr) 412 413 // ================= T12 anti-vacuity on the harness itself ================================== 414 // Every negative above is an exit code. If the harness could not launch the subject at all it would 415 // return its own negative sentinel and several of those teeth would pass for the wrong reason. 416 var t12: i64 = 0 417 if rc1 >= 0 { if rc3 >= 0 { if rc4 >= 0 { if rc6 >= 0 { t12 = 1 } } } } 418 gv_check("anti-vacuity-every-run-above-actually-LAUNCHED-no-harness-sentinel-masquerading-as-a-verdict" as *u8, t12, ctr) 419 420 let rc: i64 = gv_verdict("CRON-RECONCILE-GATE" as *u8, ctr, "each tooth name carries its own strength; read the vector, not this line" as *u8) 421 sys_exit(rc) 422 return rc 423}