nx_deployjrnl_lib.nx
buildroot/runtime/nx_deployjrnl_lib.nx
about
nx_deployjrnl_lib.nx -- THE ONE RULER for deploy history and ROLLBACK SURVIVABILITY.
WHY THIS EXISTS. On 2026-08-25 verification established that nx_docportal_admin_daemon had been
deployed at least TWICE, and that the second write EVICTED the pre-change binary from its .prev
rollback slot. Attribution came back UNVERIFIED for a STRUCTURAL reason: the estate has no deploy
journal. No instrument could answer "was a deploy performed, on what, and what did it destroy".
The effect was readable from artifact mtimes; the CALL was not readable at all.
WHAT THIS IS, STATED PLAINLY: a RECONSTRUCTION, not a source-of-truth record. This capability is
NOT written by the deploy path (that path is a daemon and is out of scope). It infers deploys by
comparing the artifacts a deploy leaves behind, between one scan and the next. What that costs in
fidelity is enumerated at dj_transition below and printed on every status artifact -- A
RECONSTRUCTION THAT DECLARES ITSELF IS WORTH FAR MORE THAN ONE THAT IMPLIES IT WAS WRITTEN AT THE
SOURCE, so the method line travels with the data and is never separated from it.
WHY A LIB AND NOT A FUNCTION IN THE ORGAN: the organ and its gate must classify identically, or
the gate is testing something the organ does not do. Every judgement below is a PURE function of
already-measured numbers, so the gate exercises the SHIPPING ruler rather than a paraphrase of
it. There is exactly one copy, so the two cannot disagree.
license_tier: ORIGINAL
dependencies 2 imports · 2 importers
imports: nx_syscalls.nxnx_sha256.nx
imported by: nx_deployjrnl.nxnx_deployjrnl_gate.nx
structs
| none |
consts
| 38 | const DJ_SYS_NEWFSTATAT: i64 = 262 |
| 40 | const DJ_AT_FDCWD_L: i64 = 0 - 100 |
| 41 | const DJ_STATBUF_BYTES: i64 = 256 |
| 42 | const DJ_STAT_OFF_SIZE: i64 = 48 |
| 43 | const DJ_STAT_OFF_MTIME: i64 = 88 |
| 45 | const DJ_DENTS_BUF_BYTES: i64 = 65536 |
| 46 | const DJ_DIGEST_BYTES: i64 = 32 |
| 47 | const DJ_HEX_BYTES: i64 = 64 |
| 48 | const DJ_HEXSLOT: i64 = 72 |
| 49 | const DJ_LENSLOT: i64 = 16 |
| 50 | const DJ_NAME_SLOT: i64 = 256 |
| 51 | const DJ_PATH_SLOT: i64 = 512 |
| 52 | const DJ_MODE_644: i64 = 420 |
| 53 | const DJ_NL: i64 = 10 |
| 54 | const DJ_SPACE: i64 = 32 |
| 55 | const DJ_DOT_B: i64 = 46 |
| 56 | const DJ_DASH: i64 = 45 |
| 57 | const DJ_ZERO_B: i64 = 48 |
| 58 | const DJ_HEXA: i64 = 87 |
| 59 | const DJ_NIBBLE: i64 = 15 |
| 60 | const DJ_TEN: i64 = 10 |
| 65 | const DJ_T_NEW: i64 = 0 |
| 66 | const DJ_T_UNCHANGED: i64 = 1 |
| 67 | const DJ_T_DEPLOY_WITNESSED: i64 = 2 |
| 68 | const DJ_T_DEPLOY_MULTI: i64 = 3 |
| 69 | const DJ_T_PREV_ONLY: i64 = 4 |
| 70 | const DJ_T_GONE: i64 = 5 |
| 90 | const DJ_R_OK: i64 = 0 |
| 91 | const DJ_R_AT_RISK: i64 = 1 |
| 92 | const DJ_R_NO_ROLLBACK: i64 = 2 |
| 113 | const DJ_V_GREEN: i64 = 0 |
| 114 | const DJ_V_AMBER: i64 = 1 |
| 115 | const DJ_V_RED: i64 = 2 |
| 116 | const DJ_V_UNPROVEN: i64 = 3 |
| 271 | const DJ_W_OPENFAIL: i64 = 0 |
| 272 | const DJ_W_OK: i64 = 1 |
| 273 | const DJ_W_CAP: i64 = 2 |
| 274 | const DJ_W_READERR: i64 = 3 |
functions
| 79 | func dj_transition(seen: i64, live_changed: i64, prev_is_was_live: i64, prev_changed: i64) -> i64 |
| 94 | func dj_risk(prev_present: i64, prev_banked: i64) -> i64 |
| 105 | func dj_would_destroy_only_rollback(prev_present: i64, prev_banked: i64) -> i64 |
| 122 | func dj_verdict(irreplaceable: i64, unwitnessed: i64, atrisk: i64, floor: i64, observed: i64) -> i64 |
| 133 | func dj_new_floor(atrisk: i64, floor: i64) -> i64 |
| 138 | func dj_verdict_name(v: i64) -> *u8 called by 1: dj_scan |
| 145 | func dj_transition_name(t: i64) -> *u8 called by 1: dj_scan |
| 155 | func dj_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } |
| 156 | func dj_puts(s: *u8) -> i64 { sys_write(1, s, dj_slen(s)); return 0 } |
| 158 | func dj_streq(a: *u8, b: *u8) -> i64 |
| 168 | func dj_ends_with(s: *u8, suf: *u8) -> i64 |
| 180 | func dj_cat(d: *u8, o: i64, s: *u8) -> i64 |
| 189 | func dj_catn(d: *u8, o: i64, v: i64) -> i64 |
| 204 | func dj_num(v: i64) -> i64 |
| 217 | func dj_stat(path: *u8, outs: *i64) -> i64 |
| 234 | func dj_hex_into(d: *u8, out: *u8) -> i64 called by 1: dj_hash_file |
| 253 | func dj_hash_file(path: *u8, outhex: *u8) -> i64 called by 4: dj_bank_loaddj_checkdj_scanmain calls 5: sys_mmapsys_read_filesys_munmapsha256_digestdj_hex_into |
| 286 | func dj_walk(dir: *u8, suffix: *u8, names: *u8, slot: i64, cap: i64, outn: *i64, outskip: *i64) -> i64 called by 3: dj_bank_loaddj_scanmain calls 10: sys_openat_rdsys_mmapsys_getdents64dirent_reclendirent_typedirent_name+4 |
| 361 | func dj_bank_has(bankhex: *u8, nbank: i64, hex: *u8) -> i64 |
| 380 | func dj_atoi(s: *u8) -> i64 |
| 394 | func dj_field(buf: *u8, ls: i64, le: i64, key: *u8, out: *u8, outcap: i64) -> i64 |