nx_wflow_onerr_capacity_gate_t278.nx source
↩ module page · 116 lines · 5901 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_capacity_candidate_t278.nx"
8import "nx_gate_verdict.nx"
9
10func eg_n(led: *u8, ridtok: *u8, st: *u8) -> i64 {
11 let szp: *i64 = sys_mmap(8) as *i64
12 let b: *u8 = wf_readall(led, szp)
13 if (b as i64) == 0 { return 0 - 1 }
14 return wf_lines_with2(b, szp[0], ridtok, st)
15}
16
17func main() -> i64 {
18 p("=== NX-WFLOW-ONERR GATE (R10: on-fail routes to a later handler step; failure stays recorded) ===\n" as *u8)
19 var ok: i64 = 1
20 let now: i64 = wf_now()
21 let led: *u8 = sys_mmap(128)
22 var lo: i64 = 0
23 lo = wf_cat(led, lo, "/tmp/wfoe_" as *u8)
24 lo = wf_catn(led, lo, now)
25 lo = wf_cat(led, lo, ".log" as *u8)
26 led[lo] = 0 as u8
27
28 let flows: *i64 = sys_mmap(8 * 4) as *i64
29 flows[0] = "fe1|risky|-" as *u8 as i64
30 flows[1] = "fe2|safe|-" as *u8 as i64
31 flows[2] = "fe3|old|-" as *u8 as i64
32 let steps: *i64 = sys_mmap(8 * 12) as *i64
33 steps[0] = "fe1|1|create-task|-|Attempt the risky thing|1|-|-" as *u8 as i64
34 steps[1] = "fe1|2|probe-fail|-|9|2|-|4" as *u8 as i64
35 steps[2] = "fe1|3|notify|-|Normal path continues|1" as *u8 as i64
36 steps[3] = "fe1|4|notify|-|Recovered from {wf_error_step}|1|wf_error=yes" as *u8 as i64
37 steps[4] = "fe1|5|notify|-|Always tail|1" as *u8 as i64
38 steps[5] = "fe2|1|probe-fail|-|1|1|-|3" as *u8 as i64
39 steps[6] = "fe2|2|notify|-|Normal completes|1" as *u8 as i64
40 steps[7] = "fe2|3|notify|-|Handler never fires|1|wf_error=yes" as *u8 as i64
41 steps[8] = "fe3|1|probe-fail|-|9|1" as *u8 as i64
42 let cx: *i64 = sys_mmap(32) as *i64
43 cx[0] = steps as i64
44 cx[1] = 9
45 cx[2] = led as i64
46 cx[3] = 0
47
48 // T0 load: 8-field rows valid; backward on-fail target refused; non-numeric refused
49 let l0: i64 = wf_load(steps, 9)
50 let bad: *i64 = sys_mmap(16) as *i64
51 bad[0] = "f9|2|notify|-|x|1|-|1" as *u8 as i64
52 let lb: i64 = wf_load(bad, 1)
53 let bad2: *i64 = sys_mmap(16) as *i64
54 bad2[0] = "f9|1|notify|-|x|1|-|abc" as *u8 as i64
55 let lb2: i64 = wf_load(bad2, 1)
56 p(" T0 load=" as *u8); pn(l0); p(" backTarget=" as *u8); pn(lb); p(" nonNum=" as *u8); pn(lb2); p("\n" as *u8)
57 if l0 != 9 { ok = 0 }
58 if lb != (0 - 1) { ok = 0 }
59 if lb2 != (0 - 1) { ok = 0 }
60
61 // T1 failure -> handler -> RECOVERED: FAILSTEP+ONFAIL recorded, step3 skipped, handler ran with
62 // {wf_error_step} substituted, tail ran, run DONE (not FAILED)
63 wf_fire(cx, flows, 3, "risky~id=R1" as *u8)
64 let fs: i64 = eg_n(led, " rid=R1.fe1 " as *u8, "status=FAILSTEP" as *u8)
65 let of: i64 = eg_n(led, " rid=R1.fe1 " as *u8, "status=ONFAIL" as *u8)
66 let s3: i64 = eg_n(led, " rid=R1.fe1 " as *u8, " step=3 status=SKIP" as *u8)
67 let h4: i64 = eg_n(led, " rid=R1.fe1 " as *u8, " step=4 status=OK" as *u8)
68 let t5: i64 = eg_n(led, " rid=R1.fe1 " as *u8, " step=5 status=OK" as *u8)
69 let ev: i64 = eg_n(led, " rid=R1.fe1 " as *u8, "k=wf_error_step v=step2" as *u8)
70 let d1: i64 = eg_n(led, " rid=R1.fe1 " as *u8, "status=DONE" as *u8)
71 let f1: i64 = eg_n(led, " rid=R1.fe1 " as *u8, "status=FAILED" as *u8)
72 p(" T1 recover failstep=" as *u8); pn(fs); p(" onfail=" as *u8); pn(of); p(" s3skip=" as *u8); pn(s3)
73 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)
74 if fs != 1 { ok = 0 }
75 if of != 1 { ok = 0 }
76 if s3 != 1 { ok = 0 }
77 if h4 != 1 { ok = 0 }
78 if t5 != 1 { ok = 0 }
79 if ev != 1 { ok = 0 }
80 if d1 != 1 { ok = 0 }
81 if f1 != 0 { ok = 0 }
82
83 // T2 SUCCESS path: handler (wf_error guard) skips naturally, no ONFAIL, DONE
84 wf_fire(cx, flows, 3, "safe~id=R2" as *u8)
85 let of2: i64 = eg_n(led, " rid=R2.fe2 " as *u8, "status=ONFAIL" as *u8)
86 let h3: i64 = eg_n(led, " rid=R2.fe2 " as *u8, " step=3 status=SKIP" as *u8)
87 let d2: i64 = eg_n(led, " rid=R2.fe2 " as *u8, "status=DONE" as *u8)
88 p(" T2 success onfail=" as *u8); pn(of2); p(" handlerSkipped=" as *u8); pn(h3); p(" done=" as *u8); pn(d2); p("\n" as *u8)
89 if of2 != 0 { ok = 0 }
90 if h3 != 1 { ok = 0 }
91 if d2 != 1 { ok = 0 }
92
93 // T3 no on-fail field = the old hard-stop contract, unchanged
94 wf_fire(cx, flows, 3, "old~id=R3" as *u8)
95 let f3: i64 = eg_n(led, " rid=R3.fe3 " as *u8, "status=FAILED" as *u8)
96 let d3: i64 = eg_n(led, " rid=R3.fe3 " as *u8, "status=DONE" as *u8)
97 p(" T3 hardstop failed=" as *u8); pn(f3); p(" done=" as *u8); pn(d3); p("\n" as *u8)
98 if f3 != 1 { ok = 0 }
99 if d3 != 0 { ok = 0 }
100
101 // T4 negctl
102 let ban: i64 = eg_n(led, "WFRUN" as *u8, "status=BANANA" as *u8)
103 p(" T4 negctl nonsense=" as *u8); pn(ban); p("\n" as *u8)
104 if ban != 0 { ok = 0 }
105
106 p("NX-WFLOW-ONERR-GATE ledger=" as *u8); p(led); p(" forks=0 " as *u8)
107 // MIGRATED onto nx_gate_verdict by nx_gate_dry_apply (D001, minimal form): every check
108 // row above is untouched, so the PASS/FAIL vector cannot change; only the hand-rolled
109 // verdict emission is replaced by the ONE shared base class. Proven by nx_gate_migrate verify.
110 let ctr__dry: *i64 = gv_ctr()
111 ctr__dry[0] = ok
112 ctr__dry[1] = 1
113 let rc__dry: i64 = gv_verdict("WFLOW-ONERR-GATE" as *u8, ctr__dry, "teeth unchanged; verdict emission migrated onto the shared base class" as *u8)
114 sys_exit(rc__dry)
115 return rc__dry
116}