code wiki / _hdl_build / nx_wflow_onerr_gate.nx

nx_wflow_onerr_gate.nx source

↩ module page · 109 lines · 5399 B

1// nx_wflow_onerr_gate.nx -- R10 ON-ERROR gate: optional 8th step field = forward on-fail target. On 2// exhausted attempts the failure stays RECORDED (FAILSTEP + ONFAIL), wf_error=yes + wf_error_step land on 3// the variable plane, remaining normal-path steps SKIP (recorded), execution lands at the handler -- which 4// is guarded by an R9 condition (wf_error=yes) so the SUCCESS path skips it naturally. Composition of 5// R8 vars + R9 conds, not a new mechanism. Hard failures (bad subst, denied approval) still hard-stop. 6// ZERO forks. license_tier: ORIGINAL expect_exit: 0 7import "nx_wflow_engine.nx" 8 9func eg_n(led: *u8, ridtok: *u8, st: *u8) -> i64 { 10 let szp: *i64 = sys_mmap(8) as *i64 11 let b: *u8 = wf_readall(led, szp) 12 if (b as i64) == 0 { return 0 - 1 } 13 return wf_lines_with2(b, szp[0], ridtok, st) 14} 15 16func main() -> i64 { 17 p("=== NX-WFLOW-ONERR GATE (R10: on-fail routes to a later handler step; failure stays recorded) ===\n" as *u8) 18 var ok: i64 = 1 19 let now: i64 = wf_now() 20 let led: *u8 = sys_mmap(128) 21 var lo: i64 = 0 22 lo = wf_cat(led, lo, "/tmp/wfoe_" as *u8) 23 lo = wf_catn(led, lo, now) 24 lo = wf_cat(led, lo, ".log" as *u8) 25 led[lo] = 0 as u8 26 27 let flows: *i64 = sys_mmap(8 * 4) as *i64 28 flows[0] = "fe1|risky|-" as *u8 as i64 29 flows[1] = "fe2|safe|-" as *u8 as i64 30 flows[2] = "fe3|old|-" as *u8 as i64 31 let steps: *i64 = sys_mmap(8 * 12) as *i64 32 steps[0] = "fe1|1|create-task|-|Attempt the risky thing|1|-|-" as *u8 as i64 33 steps[1] = "fe1|2|probe-fail|-|9|2|-|4" as *u8 as i64 34 steps[2] = "fe1|3|notify|-|Normal path continues|1" as *u8 as i64 35 steps[3] = "fe1|4|notify|-|Recovered from {wf_error_step}|1|wf_error=yes" as *u8 as i64 36 steps[4] = "fe1|5|notify|-|Always tail|1" as *u8 as i64 37 steps[5] = "fe2|1|probe-fail|-|1|1|-|3" as *u8 as i64 38 steps[6] = "fe2|2|notify|-|Normal completes|1" as *u8 as i64 39 steps[7] = "fe2|3|notify|-|Handler never fires|1|wf_error=yes" as *u8 as i64 40 steps[8] = "fe3|1|probe-fail|-|9|1" as *u8 as i64 41 let cx: *i64 = sys_mmap(32) as *i64 42 cx[0] = steps as i64 43 cx[1] = 9 44 cx[2] = led as i64 45 cx[3] = 0 46 47 // T0 load: 8-field rows valid; backward on-fail target refused; non-numeric refused 48 let l0: i64 = wf_load(steps, 9) 49 let bad: *i64 = sys_mmap(16) as *i64 50 bad[0] = "f9|2|notify|-|x|1|-|1" as *u8 as i64 51 let lb: i64 = wf_load(bad, 1) 52 let bad2: *i64 = sys_mmap(16) as *i64 53 bad2[0] = "f9|1|notify|-|x|1|-|abc" as *u8 as i64 54 let lb2: i64 = wf_load(bad2, 1) 55 p(" T0 load=" as *u8); pn(l0); p(" backTarget=" as *u8); pn(lb); p(" nonNum=" as *u8); pn(lb2); p("\n" as *u8) 56 if l0 != 9 { ok = 0 } 57 if lb != (0 - 1) { ok = 0 } 58 if lb2 != (0 - 1) { ok = 0 } 59 60 // T1 failure -> handler -> RECOVERED: FAILSTEP+ONFAIL recorded, step3 skipped, handler ran with 61 // {wf_error_step} substituted, tail ran, run DONE (not FAILED) 62 wf_fire(cx, flows, 3, "risky~id=R1" as *u8) 63 let fs: i64 = eg_n(led, " rid=R1.fe1 " as *u8, "status=FAILSTEP" as *u8) 64 let of: i64 = eg_n(led, " rid=R1.fe1 " as *u8, "status=ONFAIL" as *u8) 65 let s3: i64 = eg_n(led, " rid=R1.fe1 " as *u8, " step=3 status=SKIP" as *u8) 66 let h4: i64 = eg_n(led, " rid=R1.fe1 " as *u8, " step=4 status=OK" as *u8) 67 let t5: i64 = eg_n(led, " rid=R1.fe1 " as *u8, " step=5 status=OK" as *u8) 68 let ev: i64 = eg_n(led, " rid=R1.fe1 " as *u8, "k=wf_error_step v=step2" as *u8) 69 let d1: i64 = eg_n(led, " rid=R1.fe1 " as *u8, "status=DONE" as *u8) 70 let f1: i64 = eg_n(led, " rid=R1.fe1 " as *u8, "status=FAILED" as *u8) 71 p(" T1 recover failstep=" as *u8); pn(fs); p(" onfail=" as *u8); pn(of); p(" s3skip=" as *u8); pn(s3) 72 p(" handler=" as *u8); pn(h4); p(" tail=" as *u8); pn(t5); p(" errvar=" as *u8); pn(ev); p(" done=" as *u8); pn(d1); p(" failed=" as *u8); pn(f1); p("\n" as *u8) 73 if fs != 1 { ok = 0 } 74 if of != 1 { ok = 0 } 75 if s3 != 1 { ok = 0 } 76 if h4 != 1 { ok = 0 } 77 if t5 != 1 { ok = 0 } 78 if ev != 1 { ok = 0 } 79 if d1 != 1 { ok = 0 } 80 if f1 != 0 { ok = 0 } 81 82 // T2 SUCCESS path: handler (wf_error guard) skips naturally, no ONFAIL, DONE 83 wf_fire(cx, flows, 3, "safe~id=R2" as *u8) 84 let of2: i64 = eg_n(led, " rid=R2.fe2 " as *u8, "status=ONFAIL" as *u8) 85 let h3: i64 = eg_n(led, " rid=R2.fe2 " as *u8, " step=3 status=SKIP" as *u8) 86 let d2: i64 = eg_n(led, " rid=R2.fe2 " as *u8, "status=DONE" as *u8) 87 p(" T2 success onfail=" as *u8); pn(of2); p(" handlerSkipped=" as *u8); pn(h3); p(" done=" as *u8); pn(d2); p("\n" as *u8) 88 if of2 != 0 { ok = 0 } 89 if h3 != 1 { ok = 0 } 90 if d2 != 1 { ok = 0 } 91 92 // T3 no on-fail field = the old hard-stop contract, unchanged 93 wf_fire(cx, flows, 3, "old~id=R3" as *u8) 94 let f3: i64 = eg_n(led, " rid=R3.fe3 " as *u8, "status=FAILED" as *u8) 95 let d3: i64 = eg_n(led, " rid=R3.fe3 " as *u8, "status=DONE" as *u8) 96 p(" T3 hardstop failed=" as *u8); pn(f3); p(" done=" as *u8); pn(d3); p("\n" as *u8) 97 if f3 != 1 { ok = 0 } 98 if d3 != 0 { ok = 0 } 99 100 // T4 negctl 101 let ban: i64 = eg_n(led, "WFRUN" as *u8, "status=BANANA" as *u8) 102 p(" T4 negctl nonsense=" as *u8); pn(ban); p("\n" as *u8) 103 if ban != 0 { ok = 0 } 104 105 p("NX-WFLOW-ONERR-GATE ledger=" as *u8); p(led); p(" forks=0 " as *u8) 106 if ok == 1 { p("verdict=GREEN\n" as *u8); return 0 } 107 p("verdict=RED\n" as *u8) 108 return 1 109}