code wiki / _hdl_build / nx_lease_wedge_gate.nx
nx_lease_wedge_gate.nx
buildroot/runtime/_hdl_build/nx_lease_wedge_gate.nx
about
nx_lease_wedge_gate.nx -- THE LEASE-WEDGE DETECTOR (2026-09-04).
WHY THIS EXISTS. On 2026-09-04 all four knowledge/lease/heavyio-slot-N.lock slots were found
PERMANENTLY WEDGED. The crawler AND the shard-compactor had been dead for 18 HOURS and NOTHING in
the estate noticed: /search kept answering 200, every daemon read UP, and the only symptom was a
status log whose mtime stopped advancing. The operator's report was "search still searches nothing".
THE MECHANISM, read out of buildroot/runtime/nx_lease_lib.nx rather than guessed. A takeover is
arbitrated by mkdir on a monotonic generation: ls_acquire_root parses the stamp, and for a released
or expired lease calls ls_claim(dir, owner, ttl, g_nonce + 1, g_nonce + 1), whose FIRST act is
if ls_mkdir(dir + "/g" + gate) != 0 { return 0 } // 0 == LOST == "busy"
and whose stamp write is a SEPARATE, LATER, NON-ATOMIC step:
let tfd = sys_openat_wr(tp, LS_MODE) ... sys_write ... sys_renameat(tp, sp)
A process killed between the mkdir and the rename leaves g<N> ON DISK with the stamp still reading
N-1. Every later acquirer then re-derives the SAME gate from the SAME stamp, retries mkdir g<N>,
gets EEXIST, and correctly reports BUSY -- forever, with no recovery path and no diagnostic.
The host bugchecked 3x in 72 h (GPU driver), which is exactly the kill this window needs.
THE TEST IS THE FAILING CALL ITSELF, NOT A PROXY. This gate does not ask "does maxdir exceed the
stamp"; it asks the one question that decides the outcome: DOES THE DIRECTORY THE NEXT TAKEOVER
WILL TRY TO CREATE ALREADY EXIST? That is stat of <lease>/g<stamp_gen + 1>. A proxy could be right
for the wrong reason; this cannot.
THE PROBE PATH IS NEVER CREATED. Calling mkdir on g<gen+1> to test for it WOULD ITSELF WEDGE THE
LEASE -- the detector would manufacture the defect it reports. Existence is read with fstatat and
nothing here writes to a live lease, ever.
CHECK-BEFORE-BUILD (rule: "I didn't know it existed" is a retrieval failure). nx_spendgate reports
presubmit=FREE and nx_capsearch over 7,341 organs (corpus_complete=1) returns nx_lease and
nx_lease_probe -- the PRIMITIVE itself -- plus nx_lease_lib and nx_vault_lease. None censuses lease
HEALTH; there is no acquire/release verb that can even express "this lease can never be claimed
again". This is a new capability, not a duplicate ruler.
SCOPE, STATED SO NOBODY TRUSTS IT AS EXACT: this detects the WEDGE. It does not detect a lease held
by a dead process (that is a TTL question and ls_acquire already expires it), and it says nothing
about whether the holder is making progress.
OWED, DELIBERATELY NOT ATTEMPTED HERE: ls_claim mkdir-then-stamp has no crash recovery. Fixing a
shared estate-wide mutex is not a safe act under load, and that file own comments record TWO prior
attempts at exactly this which wedged it or double-admitted. A detector first is the right order.
dependencies 3 imports · 0 importers
imports: nx_gate_verdict.nxnx_syscalls.nxnx_lease_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
| 44 | const LW_ROOT: *u8 = "knowledge/lease" |
| 45 | const LW_PATHCAP: i64 = 1024 |
| 46 | const LW_STAMPCAP: i64 = 512 |
| 47 | const LW_DENTBUF: i64 = 65536 |
| 48 | const LW_STATBUF: i64 = 160 |
| 49 | const LW_TAB: i64 = 9 |
| 50 | const LW_NL: i64 = 10 |
| 51 | const LW_D0: i64 = 48 |
| 52 | const LW_D9: i64 = 57 |
| 53 | const LW_B10: i64 = 10 |
| 54 | const LW_GEN_FIELD: i64 = 4 |
| 55 | const LW_DOT: i64 = 46 |
| 56 | const LW_SLASH: i64 = 47 |
| 57 | const LW_SCRATCH: i64 = 32 |
| 58 | const LW_SMALL: i64 = 64 |
| 59 | const LW_BOX: i64 = 16 |
| 61 | const LW_HEALTHY: i64 = 0 |
| 62 | const LW_WEDGED: i64 = 1 |
| 63 | const LW_UNREADABLE: i64 = 2 |
functions
| 65 | func lw_cat(d: *u8, o: i64, s: *u8) -> i64 |
| 71 | func lw_catn(d: *u8, o: i64, v: i64) -> i64 |
| 83 | func lw_pos(v: i64) -> i64 { if v > 0 { return 1 } return 0 } called by 1: main |
| 85 | func lw_exists(path: *u8) -> i64 |
| 95 | func lw_stamp_gen(dir: *u8) -> i64 |
| 133 | func lw_classify(dir: *u8, genout: *i64) -> i64 |
| 150 | func lw_census(root: *u8, counts: *i64, verbose: i64) -> i64 called by 1: main calls 12: sys_openat_rdsys_mmapsys_getdents64dirent_reclendirent_typedirent_name+6 |
| 213 | func lw_clearlock(dir: *u8) -> i64 called by 1: lw_clearroot calls 11: sys_openat_rdsys_mmapsys_getdents64dirent_reclendirent_namelw_cat+5 |
| 249 | func lw_clearroot(root: *u8) -> i64 called by 1: main calls 11: sys_openat_rdsys_mmapsys_getdents64dirent_reclendirent_typedirent_name+5 |
| 286 | func lw_rootcount(root: *u8) -> i64 |
| 309 | func lw_mkfix(base: *u8, name: *u8, stamp: *u8, topgen: i64, out: *u8) -> i64 |
| 344 | func main(argc: i64, argv: *i64) -> i64 |