nx_undopath_lib.nx
buildroot/runtime/nx_undopath_lib.nx
about
nx_undopath_lib.nx -- DOES EACH DEPLOY TARGET'S REVERSE GEAR REVERSE ITS OWN SUBJECT?
THE QUESTION NOTHING ELSE ASKED. nx_deploycover_gate asks whether the deploy plane COVERS the fleet
(is there a row at all); nx_deploy_listen_gate asks whether the post-deploy check verified the INCOMING
listener. Neither asks the third question in that family: when the row's reverse gear FIRES, does it
reverse THIS target -- or somebody else's?
MEASURED 2026-09-03, and this is why the lib exists: 16 of 31 rows in deploy_targets.conf declared
`rollback` in field 5, and nx_hostctl.cmd_rollback() TAKES NO TARGET ARGUMENT -- it unconditionally
renames sites.elf.prev over sites.elf and kills sites.elf. So the declared reverse gear of 16 daemons
reverted THE PUBLIC FRONT DOOR and left the bad daemon live. And /api/deploy's health watchdog invokes
field 5, so that wrong-subject destruction was AUTOMATIC, not merely a manual footgun.
★THE ESTATE HAD ALREADY DIAGNOSED THIS TWICE BY HAND -- docportal corrected 2026-09-02, comparegw
dodging it with a deliberately unknown verb -- with the sentence "every gdeploy row above carries that
word" sitting in the same file. A DEFECT NAMED IN A COMMENT BESIDE THE ROWS THAT STILL HAVE IT IS NOT
DOCUMENTED, IT IS ADVERTISED. When a comment says "every row above has this", that sentence IS the
census and it belongs in an exit code.
FOUR STATES, and the fourth is the one that keeps this honest:
UP_OWN -- the gear provably acts on this row's own subject.
UP_WRONG -- the gear provably acts on a DIFFERENT subject. The finding.
UP_FAILSAFE -- the verb is not implemented at all, so the sub is a proven no-op
(nx_hostctl's dispatcher tail: hc_puts("unknown subcommand"); sys_exit(2)).
comparegw chose this DELIBERATELY, and it is strictly safer than a wrong subject.
UP_UNPROVEN -- a verb exists but its subject could not be resolved from source. ABSTAIN, NEVER ACQUIT:
an unreadable reverse gear must not read as a correct one.
The decision is PURE over already-resolved booleans so a gate can drive every branch without a host,
and so /api/deploy can one day REFUSE a wrong-subject rollback at the door using the SAME ruler that
censuses it -- one ruler, never two.
license_tier: ORIGINAL Read-only. No hw writes (Rule 26). lib (no main)
dependencies 1 imports · 1 importers
imports: nx_syscalls.nx
imported by: nx_undopath_gate.nx
structs
| none |
consts
| 34 | const UP_OWN: i64 = 0 |
| 35 | const UP_WRONG: i64 = 1 |
| 36 | const UP_FAILSAFE: i64 = 2 |
| 37 | const UP_UNPROVEN: i64 = 3 |
| 40 | const UP_EDGE_GEAR: *u8 = "rollback" |
| 41 | const UP_PERROW_PFX: *u8 = "gdeployrb@" |
| 44 | const UP_PERROW_VERB: *u8 = "gdeploy_rollback" |
| 45 | const UP_PERROW_PFXLEN: i64 = 10 |
| 46 | const UP_EDGE_ROW: *u8 = "sites" |
| 47 | const UP_FUNC_PFX: *u8 = "func cmd_" |
| 48 | const UP_FUNC_HEAD: *u8 = "\nfunc " |
| 49 | const UP_CONST_PFX: *u8 = "const " |
| 52 | const UP_FUNC_CLOSE: *u8 = "\n}" |
functions
| 54 | func up_state_name(s: i64) -> *u8 called by 1: main |
| 61 | func up_len(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } |
| 63 | func up_streq(a: *u8, b: *u8) -> i64 called by 1: main |
| 70 | func up_prefix(s: *u8, p: *u8) -> i64 called by 1: main |
| 77 | func up_find(hay: *u8, hn: i64, needle: *u8) -> i64 |
| 96 | func up_basename(path: *u8, out: *u8, cap: i64) -> i64 |
| 120 | func up_verb_body(src: *u8, n: i64, verb: *u8, box: *i64) -> i64 |
| 162 | func up_stem(src: *u8, out: *u8, cap: i64) -> i64 |
| 173 | func up_const_value(src: *u8, n: i64, name: *u8, out: *u8, cap: i64) -> i64 |
| 213 | func up_body_names(src: *u8, n: i64, bs: i64, be: i64, stem: *u8) -> i64 |
| 265 | func up_classify(is_edge: i64, rb_is_edge_gear: i64, rb_perrow_self: i64, rb_perrow_other: i64, |
| 312 | func up_artifact_name(path: *u8, out: *u8, cap: i64) -> i64 |
| 333 | func up_pair_common(src: *u8, n: i64, fs: i64, fe: i64, bs: i64, be: i64) -> i64 |
| 382 | func up_classify_pair(is_edge: i64, rb_is_edge_gear: i64, rb_perrow_self: i64, rb_perrow_other: i64, |
| 392 | func up_ratchet_next(floor: i64, wrong: i64) -> i64 called by 1: main |