nx_cronwatch_put.nx
buildroot/runtime/nx_cronwatch_put.nx
about
nx_cronwatch_put.nx -- THE MISSING PRODUCER for the cron dead-man's-switch registry (2026-08-15).
WHY THIS EXISTS. nx_cron_watch is the estate's dead-man's switch: every scheduled job pings by
leaving a `ts=<epoch>` in its own evidence log, and a check-in missed beyond grace reports STALE.
Its manifest moved to the seg-store plane knowledge/store/cronwatch- -- and NOTHING COULD WRITE IT.
nx_store_put projects its own row shape onto a foreign grammar (the exact hazard nx_clockjob was
built for on the clock plane, where a half-written row still sits in the live registry with no name
at all, skipped by the dispatcher on every window).
A RECONCILER WITH NO PRODUCER IS A CONSUMER WITH NOTHING TO CONSUME, and THE ABSENCE OF A
SANCTIONED WRITER DOES NOT STOP WRITES -- IT ONLY MAKES THEM MALFORMED.
nx_cronwatch_put put <name> <heartbeat-file> <ts-marker> <max-age-secs> <remediation>
nx_cronwatch_put selftest
Grammar is EXACTLY nx_cron_watch's: name<TAB>heartbeat-file<TAB>ts-marker<TAB>max-age<TAB>remediation.
Validated at the boundary so a malformed row never reaches the plane, because a consumer can only
SKIP a bad row after the fact.
MAX-AGE IS NOT A NUMBER TO GUESS. It is expected-interval + grace, and the caller derives it from
the interval it registered on the clock. interval + interval/4 is the recommended shape: it absorbs
scheduler jitter while still catching the FIRST missed fire, because a single miss puts age at two
intervals which is already past the bound. This organ does not invent it -- it refuses a
non-positive one and records what it was given.
TWO GUARDS THIS ORGAN HAS THAT ITS CLOCK-PLANE SIBLING DOES NOT, both earned from the same law --
A DETECTOR WITH FALSE POSITIVES IS WORSE THAN NONE, BECAUSE IT TEACHES EVERYONE TO IGNORE IT:
1. the heartbeat file must EXIST, and
2. the ts-marker must be FINDABLE IN IT RIGHT NOW.
A watch declared over a missing file, or over a marker that never appears, reports STALE from the
moment it is written and never stops. That is not a dead-man's switch, it is a stuck alarm, and it
is worse than no watch at all because it trains the reader to skip the whole board.
ONE SUBJECT PER ROW: a duplicate name is refused. Two rows for one job means the check reports
whichever it happened to read, which is a race wearing a registry's clothes.
license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0
dependencies 2 imports · 0 importers
imports: nx_syscalls.nxnx_store_seed_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
| 40 | const CWP_PREFIX: *u8 = "knowledge/store/cronwatch-" |
| 41 | const CWP_ROOT: *u8 = "/volume1/homes/elderwesto/nishihost/" |
| 42 | const CWP_ROWCAP: i64 = 4096 |
| 47 | const CWP_PLANECAP: i64 = 8388608 |
| 48 | const CWP_TAB: i64 = 9 |
| 49 | const CWP_NL: i64 = 10 |
| 50 | const CWP_SLASH: i64 = 47 |
| 51 | const CWP_MINUS: i64 = 45 |
| 52 | const CWP_D0: i64 = 48 |
| 53 | const CWP_D9: i64 = 57 |
| 54 | const CWP_SPACE: i64 = 32 |
| 55 | const CWP_EXIT_USAGE: i64 = 2 |
| 56 | const CWP_EXIT_REFUSED: i64 = 1 |
functions
| 58 | func cwp_len(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } |
| 59 | func cwp_out(s: *u8) -> i64 { sys_write(1, s, cwp_len(s)); return 0 } |
| 60 | func cwp_err(s: *u8) -> i64 { sys_write(2, s, cwp_len(s)); return 0 } |
| 61 | func cwp_cat(d: *u8, o: i64, s: *u8) -> i64 { var x: i64 = o; var i: i64 = 0; while s[i] != (0 as u8) { d[x] = s[i]; x = x + 1; i = i + 1 } return x } |
| 66 | func cwp_num(d: *u8, o: i64, v: i64) -> i64 |
| 78 | func cwp_tabfree(s: *u8) -> i64 { var i: i64 = 0; while s[i] != (0 as u8) { if s[i] == (CWP_TAB as u8) { return 0 } i = i + 1 } return 1 } |
| 80 | func cwp_atoi(s: *u8) -> i64 |
| 94 | func cwp_resolve(p: *u8, dst: *u8) -> i64 |
| 101 | func cwp_exists(p: *u8) -> i64 |
| 108 | func cwp_contains(buf: *u8, n: i64, pat: *u8) -> i64 |
| 127 | func cwp_dup(plane: *u8, n: i64, name: *u8) -> i64 |
| 151 | func cwp_t(nm: *u8, got: i64, want: i64, ctr: *i64) -> i64 |
| 166 | func cwp_plane_fixture(d: *u8) -> i64 |
| 178 | func cwp_selftest() -> i64 |
| 231 | func main(argc: i64, argv: *i64) -> i64 |