nx_jobclaim_reap_gate.nx
buildroot/runtime/nx_jobclaim_reap_gate.nx
about
nx_jobclaim_reap_gate.nx -- BITE-PROOF for the dead-claim reaper, both directions.
IT DRIVES THE SHIPPING CODE. Every tooth calls nx_jobclaim_lib directly -- the same jr_state_of,
jr_decide, jr_examine and jr_tombstone that nx_jobclaim_reap and nx_joblost_gate call. A tooth
that tests a re-implementation proves nothing about what ships.
THE ANTI-VACUITY TOOTH IS FIRST AND IT IS THE AGE AXIS. Two claims with byte-identical contents,
differing ONLY in age, must decide differently. A reaper that ignored age would fire on both; a
reaper that refused everything would fire on neither -- and a guard that refuses everything passes
every negative test, which is why T10 carries a POSITIVE control beside its refusals.
T3 IS THE TOOTH THIS WHOLE CHANGE EXISTS FOR. The tombstone is APPENDED, so a reaped claim still
contains `state=CLAIMED`. T3 asserts BOTH markers are present in the same bytes AND that the
shared classifier still answers REAPED. If the classifier ever tests CLAIMED before REAPED, T3 is
the tooth that goes red -- and without it the reaper is a no-op that looks like a fix.
FIXTURES ARE BUILT AT RUNTIME UNDER /tmp/<gate>/ and their ids are DERIVED FROM `now`, so the age
axis under test is real rather than frozen. Setup unlinks every fixture path before creating it,
so the gate is idempotent: a gate that is not idempotent reports on its first run and lies about
every run after.
license_tier: ORIGINAL expect_exit: 0
dependencies 3 imports · 0 importers
imports: nx_syscalls.nxnx_gate_verdict.nxnx_jobclaim_lib.nx
imported by: nobody (leaf or entry point)
call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown
structs
| none |
consts
| 27 | const JG_DIR: *u8 = "/tmp/nx_jobclaim_reap_gate" as *u8 |
| 28 | const JG_FIX: *u8 = "/tmp/nx_jobclaim_reap_gate/f" as *u8 |
| 29 | const JG_CLAIMED: *u8 = "state=CLAIMED ts=fixture\n" as *u8 |
| 30 | const JG_DONE: *u8 = "state=DONE rc=0 exit=0 bytes=12\n" as *u8 |
| 31 | const JG_GARBAGE: *u8 = "this claim matches no marker the classifier knows\n" as *u8 |
| 32 | const JG_OUTBODY: *u8 = "the worker produced this\n" as *u8 |
| 33 | const JG_EMPTY: *u8 = "" as *u8 |
| 38 | const JG_OFF_CLAIMED: i64 = 0 |
| 39 | const JG_OFF_EMPTYCLM: i64 = 1 |
| 40 | const JG_OFF_DONE: i64 = 2 |
| 41 | const JG_OFF_HASOUT: i64 = 3 |
| 42 | const JG_OFF_GARBAGE: i64 = 4 |
| 43 | const JG_OFF_ABSENT: i64 = 5 |
| 44 | const JG_AGE_MULT: i64 = 2 // old_id sits maxage*JG_AGE_MULT in the past: unambiguously OLD |
| 45 | const JG_YOUNG_DIV: i64 = 2 // young_id sits maxage/JG_YOUNG_DIV in the past: unambiguously YOUNG |
functions
| 47 | func jg_write(path: *u8, body: *u8) -> i64 |
| 57 | func jg_size(path: *u8, sc: *i64) -> i64 |
| 66 | func jg_holds(path: *u8, pat: *u8, sc: *i64) -> i64 |
| 76 | func jg_plant(pbuf: *u8, id: i64, body: *u8) -> i64 |
| 82 | func main(argc: i64, argv: *i64) -> i64 |