code wiki / _hdl_build / nx_pipeline_spine.nx

nx_pipeline_spine.nx source

↩ module page · 118 lines · 4903 B

1// nx_pipeline_spine.nx -- R1: the SOVEREIGN PIPELINE SPINE (the missing chain). One seg-store 2// state machine that every stage organ plugs into, so discover->research->spec->build is ONE 3// system, not 23 scattered ones. A work-item advances ONE stage at a time and -- the load-bearing 4// invariant -- CANNOT skip: a capability can never reach BUILT/EXCEEDED without passing RESEARCH 5// and SPEC in order. That mechanically forbids fabricated completion (the discipline the scattered 6// organs lacked: any of them could just claim done). Reuses the proven ws_put_p/ws_get_p/ws_field 7// (idempotent, atomic commit) under a dedicated prefix -- NO TSV, sovereign. license_tier: ORIGINAL 8import "nx_workstream_store.nx" 9import "nx_seg_store.nx" 10import "nx_framed_append.nx" 11import "nx_syscalls.nx" 12const PL_MAGIC_1024: i64 = 1024 13 14const PL_PREFIX: *u8 = "knowledge/store/pl-" 15// ordered stages (data-driven, no magic numbers buried at call sites) 16const PL_DISCOVERED: i64 = 1 17const PL_RESEARCHED: i64 = 2 18const PL_SPECED: i64 = 3 19const PL_BUILT: i64 = 4 20const PL_EXCEEDED: i64 = 5 21 22func pl_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } 23 24// parse the first `n` bytes of `s` as a non-negative decimal. 25func pl_atoi(s: *u8, n: i64) -> i64 { 26 var v: i64 = 0 27 var i: i64 = 0 28 while i < n { 29 if s[i] >= (48 as u8) { if s[i] <= (57 as u8) { v = v * 10 + ((s[i] as i64) - 48) } } 30 i = i + 1 31 } 32 return v 33} 34 35// "pl:" + id -> out (NUL-term). returns length. 36func pl_build_key(id: *u8, out: *u8) -> i64 { 37 out[0] = 112 as u8 // 'p' 38 out[1] = 108 as u8 // 'l' 39 out[2] = 58 as u8 // ':' 40 var t: i64 = 0 41 while id[t] != (0 as u8) { out[3 + t] = id[t]; t = t + 1 } 42 out[3 + t] = 0 as u8 43 return 3 + t 44} 45 46// build the 5-field record: id \t stage \t gap \t artifact \t ts (NUL-term). returns length. 47func pl_build_rec(id: *u8, stage: i64, gap: *u8, artifact: *u8, ts: i64, out: *u8) -> i64 { 48 var o: i64 = 0 49 o = fa_cat(out, o, id) 50 out[o] = 9 as u8; o = o + 1 51 o = fa_catn(out, o, stage) 52 out[o] = 9 as u8; o = o + 1 53 o = fa_cat(out, o, gap) 54 out[o] = 9 as u8; o = o + 1 55 o = fa_cat(out, o, artifact) 56 out[o] = 9 as u8; o = o + 1 57 o = fa_catn(out, o, ts) 58 out[o] = 0 as u8 59 return o 60} 61 62// current stage of `id` under `prefix`: 0 = never seeded (the honest UNKNOWN), else 1..5. 63func pl_stage_p(prefix: *u8, id: *u8) -> i64 { 64 let key: *u8 = sys_mmap(256) 65 pl_build_key(id, key) 66 let pq: *i64 = sys_mmap(16) as *i64 67 let lq: *i64 = sys_mmap(16) as *i64 68 if ws_get_p(prefix, key, pq, lq) != 1 { return 0 } 69 let fld: *u8 = sys_mmap(64) 70 let fl: i64 = ws_field(pq[0] as *u8, lq[0], 1, fld) 71 return pl_atoi(fld, fl) 72} 73 74// read field `f` of `id`'s record into out (for gap preservation across advances). returns len, -1 absent. 75func pl_field_p(prefix: *u8, id: *u8, f: i64, out: *u8) -> i64 { 76 let key: *u8 = sys_mmap(256) 77 pl_build_key(id, key) 78 let pq: *i64 = sys_mmap(16) as *i64 79 let lq: *i64 = sys_mmap(16) as *i64 80 if ws_get_p(prefix, key, pq, lq) != 1 { out[0] = 0 as u8; return 0 - 1 } 81 return ws_field(pq[0] as *u8, lq[0], f, out) 82} 83 84// seed a work-item at DISCOVERED (idempotent: if already present, returns its current stage). 85func pl_seed_p(prefix: *u8, id: *u8, gap: *u8) -> i64 { 86 let cur: i64 = pl_stage_p(prefix, id) 87 if cur > 0 { return cur } 88 let key: *u8 = sys_mmap(256) 89 pl_build_key(id, key) 90 let rec: *u8 = sys_mmap(PL_MAGIC_1024) 91 pl_build_rec(id, PL_DISCOVERED, gap, "-" as *u8, sys_now_realtime_sec(), rec) 92 ws_put_p(prefix, key, rec) 93 return PL_DISCOVERED 94} 95 96// THE INVARIANT: advance `id` from exactly `expect_from` to `expect_from`+1, attaching `artifact`. 97// Returns the new stage, or -1 if the item is NOT at `expect_from` (refuses skips / out-of-order / 98// re-advance) or is already at EXCEEDED. This is what forbids fabricated completion. 99func pl_advance_p(prefix: *u8, id: *u8, expect_from: i64, artifact: *u8) -> i64 { 100 let cur: i64 = pl_stage_p(prefix, id) 101 if cur != expect_from { return 0 - 1 } 102 if cur >= PL_EXCEEDED { return 0 - 1 } 103 let gap: *u8 = sys_mmap(512) 104 pl_field_p(prefix, id, 2, gap) // preserve the original gap desc 105 let key: *u8 = sys_mmap(256) 106 pl_build_key(id, key) 107 let rec: *u8 = sys_mmap(PL_MAGIC_1024) 108 pl_build_rec(id, cur + 1, gap, artifact, sys_now_realtime_sec(), rec) 109 ws_put_p(prefix, key, rec) 110 return cur + 1 111} 112 113// production-prefix conveniences. 114func pl_seed(id: *u8, gap: *u8) -> i64 { return pl_seed_p(PL_PREFIX, id, gap) } 115func pl_advance(id: *u8, expect_from: i64, artifact: *u8) -> i64 { return pl_advance_p(PL_PREFIX, id, expect_from, artifact) } 116func pl_stage(id: *u8) -> i64 { return pl_stage_p(PL_PREFIX, id) } 117 118// pure LIB (no main) so the gate + the future nx_pipeline_run driver import it.