code wiki / _hdl_build / nx_release_master.nx
nx_release_master.nx
buildroot/runtime/_hdl_build/nx_release_master.nx
about
nx_release_master.nx -- the RELEASE-MASTER role (verb = BLESS): the ONE owner of coordinated, safe deploys
so parallel workstreams STOP CRASHING the shared live site. Today the team has deploy PRIMITIVES but no role
owns "bless an artifact -> deploy it"; publishes bypass the arbiter lease and race the shared sink -> corrupt
content / dropped site. This organ closes that gap by composing the existing primitives into ONE blessed,
LEASED, rollback-safe, serving-aware, audited lifecycle. Per deploy, holding the resource lease the whole time:
1. LEASE fl_acquire(resource) -- serialize: two workstreams can't swap the same sink at once
2. BLESS gate_passed==1 precondition -- NEVER deploy an un-gated artifact (no-bless-without-pass)
3. SNAPSHOT live -> live.bak -- the rollback point (never deploy without one)
4. SWAP candidate -> live.new -> renameat(live.new, live) -- atomic: no half-written live file
5. HEALTH rm_health(live) -- serving-aware: is the swapped artifact actually good?
6. ROLLBACK on unhealthy: live.bak -> live -- restore; production survives a bad deploy
7. LEDGER append the verdict to a DURABLE release ledger (what was deployed, with what outcome)
8. RELEASE fl_release -- siblings proceed
Returns the nx_deploy verdict: DEP_ABORTED (prod untouched) / DEP_DEPLOYED / DEP_ROLLED_BACK.
HEALTH NOTE: this rung's rm_health is a content-marker proxy (deterministic, gate-testable). The production
upgrade swaps rm_health's body for nx_url_probe (a real HTTPS/TLS GET of the BARE served URL) -- same shape
("is the deployed thing actually serving?"), killing the sites.elf-outage class. license_tier: ORIGINAL
dependencies 3 imports · 1 importers
imports: nx_arbiter.nxnx_deploy.nxnx_syscalls.nx
imported by: nx_release_master_gate.nx
structs
| none |
consts
| 21 | const K_MAGIC_262144: i64 = 262144 |
| 22 | const K_MAGIC_1280: i64 = 1280 |
functions
| 24 | func rm_len(s: *u8) -> i64 { var i: i64=0; while s[i]!=(0 as u8){i=i+1} return i } |
| 25 | func rm_puts(dst: *u8, off: i64, s: *u8) -> i64 { var i: i64=0; while s[i]!=(0 as u8){ dst[off+i]=s[i]; i=i+1 } return off+i } |
| 26 | func rm_putn(dst: *u8, off: i64, v: i64) -> i64 |
| 35 | func rm_cat(base: *u8, suf: *u8, out: *u8) -> i64 { var o: i64 = rm_puts(out,0,base); o = rm_puts(out,o,suf); out[o]=0 as u8; return o } |
| 38 | func rm_nonempty(path: *u8) -> i64 |
| 45 | func rm_copy(src: *u8, dst: *u8) -> i64 |
| 57 | func rm_contains(path: *u8, marker: *u8) -> i64 |
| 74 | func rm_health(live: *u8, marker: *u8) -> i64 |
| 80 | func rm_ledger(ledger: *u8, verdict: i64, tag: *u8) -> i64 |
| 90 | func rm_deploy(candidate: *u8, live: *u8, gate_passed: i64, resource: *u8, ledger: *u8, marker: *u8) -> i64 |