nx_deployjrnl.nx
buildroot/runtime/nx_deployjrnl.nx
about
nx_deployjrnl.nx -- THE DEPLOY AUDIT THE ESTATE DID NOT HAVE.
verbs:
scan reconstruct deploy history since the last scan; append the journal, rewrite the
status artifact, ratchet the rollback-risk floor.
exit 0 GREEN | 1 AMBER | 2 RED | 3 UNPROVEN (the nx_sizeguard ladder)
check <target> WOULD DEPLOYING THIS RIGHT NOW DESTROY THE ONLY ROLLBACK?
exit 0 SAFE | 1 WOULD-DESTROY | 2 usage | 3 UNPROVEN
status print the current status artifact
---------------------------------------------------------------------------------------------
HONESTY, UP FRONT, BECAUSE IT CHANGES HOW EVERY NUMBER BELOW SHOULD BE READ.
THIS JOURNAL IS RECONSTRUCTED FROM ARTIFACTS. IT IS NOT WRITTEN BY THE DEPLOY.
The deploy path is a daemon and is out of scope for this lane, so nothing here observes the call.
What it observes is the residue: the live binary and the .prev rollback slot, hashed, compared
against what the previous scan recorded. That buys a great deal and it costs four things, each
named rather than implied:
1. NO ACTOR. It can say a deploy happened and what it destroyed. It CANNOT say who called it,
through which surface, or why. "Was /api/deploy called, and by whom" stays unanswerable
until the deploy path itself writes a record.
2. NO TIME OF CALL. mtime is the artifact's WRITE time. A deploy that installs by rename
carries the staged file's mtime, so mtime is a proxy that can predate the deploy by any
amount. The scan epoch is what orders the journal; mtime is carried as evidence, labelled.
3. RESOLUTION IS BOUNDED BY THE SCAN CADENCE -- but NOT silently. Two deploys inside one window
would collapse into one row, so the reconstruction checks the invariant that a single deploy
must satisfy (the new prev equals the live seen last scan) and reports
DEPLOY-MULTI-UNWITNESSED when it does not. It proves its own blindness instead of reporting
a clean deploy it cannot justify.
4. IT CANNOT SEE BACKWARDS. The first scan establishes a BASELINE and reports no deploys,
because there is nothing to compare against. Everything before the first scan is invisible
and is declared so rather than counted as zero.
WHAT IT DOES DO THAT NOTHING ELSE DID: it records the sha of the artifact sitting in the rollback
slot BEFORE that slot is overwritten. That is the whole point. Once a second deploy evicts it the
bytes may be unrecoverable -- an older-generation binary cannot be rebuilt -- so the sha recorded
in advance is the only evidence that the artifact ever existed, and the only way to say whether
its loss mattered.
dependencies 2 imports · 0 importers
imports: nx_syscalls.nxnx_deployjrnl_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
| 56 | const DJ_MAX_TARGETS: i64 = 4096 |
| 57 | const DJ_MAX_BANK: i64 = 2048 |
| 58 | const DJ_ROW_MAX: i64 = 768 |
| 59 | const DJ_HDR_ROWS: i64 = 32 |
| 60 | const DJ_SLASH_C: i64 = 47 |
| 61 | const DJ_PREVSUF_LEN: i64 = 5 |
| 62 | const DJ_I64: i64 = 8 |
| 64 | const DJ_ROOT: *u8 = "." as *u8 |
| 65 | const DJ_BANKDIR: *u8 = "knowledge/bank" as *u8 |
| 66 | const DJ_PREV_SUF: *u8 = ".elf.prev" as *u8 |
| 67 | const DJ_ELF_SUF: *u8 = ".elf" as *u8 |
| 68 | const DJ_STATUS_PATH: *u8 = "knowledge/status/deployjrnl.status" as *u8 |
| 69 | const DJ_JRNL_PATH: *u8 = "knowledge/status/deployjrnl.jrnl" as *u8 |
| 70 | const DJ_CONF_PATH: *u8 = "knowledge/status/deployjrnl_ratchet.conf" as *u8 |
functions
| 82 | func dj_bank_load(bankhex: *u8, outn: *i64, sizes: *i64, nsizes: i64, outscan: *i64) -> i64 |
| 121 | func dj_find(names: *u8, n: i64, want: *u8) -> i64 |
| 131 | func dj_check(target: *u8) -> i64 |
| 211 | func dj_scan() -> i64 |
| 599 | func main(argc: i64, argv: *i64) -> i64 |