code wiki / _hdl_build / nx_cron_reconcile.nx
nx_cron_reconcile.nx
buildroot/runtime/_hdl_build/nx_cron_reconcile.nx
about
nx_cron_reconcile.nx -- SOVEREIGN crontab reconciler (operator directive 2026-07-16: "make the
capabilities native to the nishi ecosystem, don't make me do it"). The nishi-managed block of a crontab
becomes DATA: cron.reg declares exactly the nishi rows that must exist; this organ rewrites the crontab
so its nishi rows (any line containing /nishihost/) equal EXACTLY the declared set, leaving every
non-nishi row BYTE-EXACT. Dead rows (retired reconcilers) vanish by construction; new rows = a registry
line. Runs as root with ZERO operator action by piggybacking on the existing root cron row
(nx_edge443_reconcile.sh -- the same proven pattern as the vsz_watchdog on the rail).
NEVER-BRICK BY CONSTRUCTION (this writes a root-owned BOOT FILE):
R1 only lines containing /nishihost/ are ever touched -- the filter IS the blast-radius bound
R2 refuse (exit 3, no write) if the registry is missing/empty -- an absent SSOT must never wipe rows
R3 refuse (exit 5, no write) if ANY declared row lacks /nishihost/ -- the organ cannot inject
non-nishi rows even if the registry is corrupted/hostile
R4 refuse (exit 4, no write) if the crontab is unreadable or EMPTY -- a boot file is never empty
R5 idempotent: byte-identical result -> NO-CHANGE, zero writes (safe at any frequency)
R6 atomic: write <crontab>.nxnew then renameat over -- no torn boot file ever exists on disk
After a real change, SIGHUP every `crond` (reload -- standard, non-destructive; if crond ignores it,
stale in-memory entries keep harmlessly firing removed paths until its next restart = no regression).
---- THE SILENT-TRUNCATION DEFECT, FIXED 2026-08-20 (debt 1787260381) ---------------------------
THIS ORGAN SPENT AT LEAST TWO WEEKS APPLYING A PREFIX OF ITS OWN SSOT AND REPORTING IT AS THE WHOLE.
cr_read used to do ONE sys_read of CR_REGCAP-1 = 16383 bytes with no truncation check, while cron.reg
had grown to 24356. Every declared row past 16 KiB was invisible; the organ then counted what it had
SEEN into decl and printed "NO-CHANGE (crontab already matches cron.reg; declared=55)" -- a number that
reads exactly like a complete count. MEASURED: 66 rows declared, 55 applied, 11 silently inert, among
them the estate's only compensating control over a fail-open authentication path.
**** A CAP REACHED IN SILENCE BECOMES A MEASUREMENT NOBODY KNOWS IS PARTIAL. ****
The fingerprint was in this organ's own log the whole time and nobody had a reason to look: `declared`
FELL 58 -> 57 -> 55 across 1346 runs while the registry only ever GREW. A registry that only grows
whose applied count only shrinks is a byte cap being crossed, one comment block at a time. And R5
(idempotence) hid it perfectly: the crontab genuinely DID match the truncated view, so CHANGED events
over that entire window numbered ZERO and every run looked healthy.
THE FIX IS THE REMOVAL OF THE CAP, NOT A BIGGER CAP. A raised ceiling is the same defect with a later
trigger date, and this file's history is three variants of the same class already. cr_slurp composes
sys_read_file (nx_syscalls.nx), which sizes its buffer from the file itself via lseek END and cannot
short-read -- the estate primitive that already ate this exact debt twice (a 9 GB gguf 2026-07-15, and
the address-space regression 2026-08-19). There is no length constant left to outgrow.
AND REMOVAL ALONE IS NOT ENOUGH, BECAUSE THE OLD BUG WAS UNDETECTABLE RATHER THAN MERELY WRONG. Three
dependencies 1 imports · 0 importers
imports: nx_syscalls.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
| 59 | const CR_MAGIC_65536: i64 = 65536 |
| 68 | const CR_OUT_SLACK: i64 = 16 |
| 69 | const CR_SEEK_END: i64 = 2 |
| 70 | const CR_EXIT_PARTIAL_READ: i64 = 7 |
| 71 | const CR_EXIT_PARTITION: i64 = 8 |
| 72 | const CR_MARK: *u8 = "/nishihost/" as *u8 |
functions
| 74 | func cr_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } |
| 75 | func cr_p(s: *u8) -> i64 { sys_write(1, s, cr_slen(s)); return 0 } |
| 76 | func cr_decw(v: i64, out: *u8) -> i64 called by 1: cr_pn |
| 88 | func cr_pn(v: i64) -> i64 { let b: *u8 = sys_mmap(28); let n: i64 = cr_decw(v, b); sys_write(1, b, n); sys_munmap(b, 28); return 0 } |
| 89 | func cr_contains(hay: *u8, hlen: i64, needle: *u8) -> i64 |
| 103 | func cr_line_end(buf: *u8, pos: i64, end: i64) -> i64 called by 1: main |
| 111 | func cr_fsize(path: *u8) -> i64 |
| 122 | func cr_slurp(path: *u8, out_len: *i64) -> *u8 |
| 130 | func main(argc: i64, argv: *i64) -> i64 |