code wiki / (root) / nx_wflow_diagnostics_t240.nx

nx_wflow_diagnostics_t240.nx source

↩ module page · 114 lines · 6167 B

1// nx_wflow.nx -- the PRODUCTION CLI over the pure-core workflow engine (nx_wflow_engine.nx). This is how 2// the ecosystem drives workflows: definitions live as DATA FILES (flows: `flowid|event-kind|cond`, steps: 3// `flowid|idx|action|channel|arg|max-attempts`), the run ledger is append-only event-sourced, connectors 4// come from the GREEN fail-closed catalog. The tickless scheduler / dispatcher / vizsla can fork this elf. 5// Commands: 6// fire <flows> <steps> <ledger> <catalog|-> <event> event = kind~k=v~...~id=EN 7// resume <flows> <steps> <ledger> <catalog|-> complete every in-flight run 8// decide <ledger> <rid> <step> <APPROVED|DENIED> <who> unblock or fail a parked approval 9// board <ledger> console run board (ledger replay) 10// html <ledger> <out.html> 0-JS run board page 11// Argless = usage (exit 0 so the build lane passes). license_tier: ORIGINAL expect_exit: 0 12import "nx_wflow_engine.nx" 13 14func wu() -> i64 { 15 p("nx_wflow -- sovereign workflow automation CLI (durable runs, retries, approvals, connectors)\n" as *u8) 16 p(" fire <flows> <steps> <ledger> <catalog|-> <event>\n" as *u8) 17 p(" resume <flows> <steps> <ledger> <catalog|->\n" as *u8) 18 p(" decide <ledger> <rid> <step> <APPROVED|DENIED> <who>\n" as *u8) 19 p(" board <ledger>\n" as *u8) 20 p(" html <ledger> <out.html>\n" as *u8) 21 p(" verify <flows> <steps> validate a draft definition set without firing\n" as *u8) 22 p(" templates [dir] list the template gallery (default knowledge/wflow/templates)\n" as *u8) 23 p(" instantiate <name> <destflows> <deststeps> [dir] adopt a gallery template (validated whole)\n" as *u8) 24 return 0 25} 26 27// Preserve the native failure code without inventing an effect/rollback outcome. 28// A command can fail after an external effect; callers must reconcile its ledger. 29func wu_failure(command:*u8,code:i64)->i64 { 30 p("{\"schema\":\"nishi-workflow-error/1\",\"owner\":\"nx_wflow\",\"command\":\"" as *u8) 31 p(command) 32 p("\",\"native_code\":" as *u8);pn(code) 33 p(",\"state\":\"failed\",\"effects\":\"unverified\",\"retry\":\"reconcile-first\",\"next\":\"Inspect command input, durable run ledger and connector receipts before retrying\"}\n" as *u8) 34 return 1 35} 36 37func main(argc: i64, argv: *i64) -> i64 { 38 if argc < 2 { return wu() } 39 let cmd: *u8 = argv[1] as *u8 40 if seq(cmd, "fire" as *u8) == 1 { 41 if argc < 7 { p("WFLOW fire needs flows steps ledger catalog event -- fail loud\n" as *u8); return 2 } 42 let rc: i64 = wf_fire_files(argv[2] as *u8, argv[3] as *u8, argv[4] as *u8, argv[5] as *u8, argv[6] as *u8) 43 if rc == (0 - 100) { p("WFLOW-FIRE dedup: already started\n" as *u8); return 0 } 44 if rc < 0 { return wu_failure(cmd,rc) } 45 p("WFLOW-FIRE started=" as *u8); pn(rc); p("\n" as *u8) 46 return 0 47 } 48 if seq(cmd, "resume" as *u8) == 1 { 49 if argc < 6 { p("WFLOW resume needs flows steps ledger catalog -- fail loud\n" as *u8); return 2 } 50 let rc: i64 = wf_resume_files(argv[2] as *u8, argv[3] as *u8, argv[4] as *u8, argv[5] as *u8) 51 if rc < 0 { return wu_failure(cmd,rc) } 52 p("WFLOW-RESUME resumed=" as *u8); pn(rc); p("\n" as *u8) 53 return 0 54 } 55 if seq(cmd, "decide" as *u8) == 1 { 56 if argc < 7 { p("WFLOW decide needs ledger rid step decision who -- fail loud\n" as *u8); return 2 } 57 let cx: *i64 = sys_mmap(32) as *i64 58 cx[2] = argv[2] as i64 59 let idx: i64 = wf_atoi(argv[4] as *u8) 60 if idx < 1 { p("WFLOW decide ERROR bad step -- fail loud\n" as *u8); return 2 } 61 let rc: i64 = wf_decide(cx, argv[3] as *u8, idx, argv[5] as *u8, argv[6] as *u8) 62 if rc != 0 { return wu_failure(cmd,rc) } 63 p("WFLOW-DECIDE recorded\n" as *u8) 64 return 0 65 } 66 if seq(cmd, "board" as *u8) == 1 { 67 if argc < 3 { p("WFLOW board needs ledger -- fail loud\n" as *u8); return 2 } 68 let rc: i64 = wf_obs_board(argv[2] as *u8) 69 if rc < 0 { return wu_failure(cmd,rc) } 70 return 0 71 } 72 if seq(cmd, "html" as *u8) == 1 { 73 if argc < 4 { p("WFLOW html needs ledger out -- fail loud\n" as *u8); return 2 } 74 let rc: i64 = wf_obs_html(argv[2] as *u8, argv[3] as *u8) 75 if rc < 0 { return wu_failure(cmd,rc) } 76 p("WFLOW-HTML runs=" as *u8); pn(rc); p("\n" as *u8) 77 return 0 78 } 79 if seq(cmd, "verify" as *u8) == 1 { 80 if argc < 4 { p("WFLOW verify needs flows steps -- fail loud\n" as *u8); return 2 } 81 let fl: *i64 = sys_mmap(8 * 64) as *i64 82 let st2: *i64 = sys_mmap(8 * 128) as *i64 83 let nf: i64 = wf_lines_load(argv[2] as *u8, fl, 64) 84 if nf < 1 { return 1 } 85 let nst: i64 = wf_lines_load(argv[3] as *u8, st2, 128) 86 if nst < 1 { return 1 } 87 if wf_load_flows(fl, nf) < 0 { return 1 } 88 if wf_load(st2, nst) < 0 { return 1 } 89 let v: i64 = wf_defs_version(argv[2] as *u8) 90 p("WFLOW-VERIFY version=" as *u8); pn(v); p(" flows=" as *u8); pn(nf); p(" steps=" as *u8); pn(nst); p(" verdict=VALID\n" as *u8) 91 return 0 92 } 93 if seq(cmd, "templates" as *u8) == 1 { 94 let dirp: *u8 = sys_mmap(512) 95 var dd: i64 = 0 96 if argc >= 3 { dd = wf_cat(dirp, dd, argv[2] as *u8) } else { dd = wf_cat(dirp, dd, "knowledge/wflow/templates" as *u8) } 97 dirp[dd] = 0 as u8 98 let rc: i64 = wf_tpl_list(dirp) 99 if rc < 0 { return wu_failure(cmd,rc) } 100 return 0 101 } 102 if seq(cmd, "instantiate" as *u8) == 1 { 103 if argc < 5 { p("WFLOW instantiate needs name destflows deststeps -- fail loud\n" as *u8); return 2 } 104 let dirp: *u8 = sys_mmap(512) 105 var dd: i64 = 0 106 if argc >= 6 { dd = wf_cat(dirp, dd, argv[5] as *u8) } else { dd = wf_cat(dirp, dd, "knowledge/wflow/templates" as *u8) } 107 dirp[dd] = 0 as u8 108 let rc: i64 = wf_tpl_instantiate(dirp, argv[2] as *u8, argv[3] as *u8, argv[4] as *u8) 109 if rc < 0 { return wu_failure(cmd,rc) } 110 return 0 111 } 112 p("WFLOW unknown command -- fail loud\n" as *u8) 113 return 2 114}