code wiki / _hdl_build / nx_lineage_deep.nx

nx_lineage_deep.nx source

↩ module page · 189 lines · 10330 B

1// nx_lineage_deep.nx -- LIB: DEEPER provenance (R-DEEP). Two real-world traceability gaps closed: 2// (1) MULTI-PARENT CROSSES -- a hybrid traces to BOTH parents (parent_a x parent_b), and a cross is detected 3// as such. nx_lineage stored parent_b but only walked parent_a; this reads both. 4// (2) HARVEST-LOT SPLITTING -- one harvest is a LOT that splits into many child lots (sauce, fresh, seed, 5// jars, plates), each linked to its parent lot. ANY leaf (a jar on the table) traces back through the 6// split chain to the harvest -> the plant -> its full seed-to-feed lineage + genetics. "One harvest -> 7// many plates, each individually traceable to the exact plant and its seed." Conservation: a lot can't 8// be split beyond what remains. Additive (rule 13). Same bio- store as nx_lineage. license_tier: ORIGINAL 9import "nx_lineage.nx" 10import "nx_seg_store.nx" 11import "nx_syscalls.nx" 12 13func ld_put(prefix: *u8, key: *u8, val: *u8) -> i64 { 14 let vl: i64 = as_len(val) 15 if fd_streq_store(prefix, key, val, vl) == 1 { return 0 } 16 let w: *i64 = ss_begin() 17 ss_add(w, 1, key, val, vl) 18 let seg: i64 = fd_seg_next(prefix) 19 ss_commit(prefix, w, seg) 20 return 1 21} 22 23// ---- (1) multi-parent crosses ---- 24func ld_parents(prefix: *u8, id: *u8, out_a: *u8, out_b: *u8) -> i64 { 25 ln_field_str(prefix, id, 4, out_a) 26 ln_field_str(prefix, id, 5, out_b) 27 return 0 28} 29// 1 if `id` is a hybrid cross: two distinct, present parents. 30func ld_is_cross(prefix: *u8, id: *u8) -> i64 { 31 let a: *u8 = sys_mmap(64); let b: *u8 = sys_mmap(64) 32 ld_parents(prefix, id, a, b) 33 if a[0] == (0 as u8) { return 0 } 34 if b[0] == (0 as u8) { return 0 } 35 if fd_streq(a, "-" as *u8) == 1 { return 0 } 36 if fd_streq(b, "-" as *u8) == 1 { return 0 } 37 if fd_streq(a, b) == 1 { return 0 } 38 return 1 39} 40// "<name> = <parentA name> x <parentB name>" for a cross; just "<name>" otherwise. NUL-terminated. 41func ld_cross_label(prefix: *u8, id: *u8, out: *u8) -> i64 { 42 let nm: *u8 = sys_mmap(96); ln_field_str(prefix, id, 0, nm) 43 var o: i64 = 0 44 o = as_append(out, o, nm) 45 if ld_is_cross(prefix, id) == 1 { 46 let a: *u8 = sys_mmap(64); let b: *u8 = sys_mmap(64) 47 ld_parents(prefix, id, a, b) 48 let an: *u8 = sys_mmap(96); ln_field_str(prefix, a, 0, an) 49 let bn: *u8 = sys_mmap(96); ln_field_str(prefix, b, 0, bn) 50 o = as_append(out, o, " = " as *u8) 51 o = as_append(out, o, an) 52 o = as_append(out, o, " x " as *u8) 53 o = as_append(out, o, bn) 54 } 55 out[o] = 0 as u8 56 return o 57} 58 59// ---- (2) harvest-lot splitting ---- 60// lot:<lotid> -> org_id <t> parent_lot <t> quantity <t> unit <t> purpose <t> day (org_id "-" on splits; "-" parent_lot = root) 61func ld_lot_key(lotid: *u8, out: *u8) -> i64 { var o: i64 = 0; o = as_append(out, o, "lot:" as *u8); o = as_append(out, o, lotid); out[o] = 0 as u8; return o } 62func ld_alloc_key(lotid: *u8, out: *u8) -> i64 { var o: i64 = 0; o = as_append(out, o, "lot:alloc:" as *u8); o = as_append(out, o, lotid); out[o] = 0 as u8; return o } 63 64func ld_lot_str(prefix: *u8, lotid: *u8, f: i64, out: *u8) -> i64 { 65 let key: *u8 = sys_mmap(96); ld_lot_key(lotid, key) 66 let pq: *i64 = sys_mmap(16) as *i64 67 let lq: *i64 = sys_mmap(16) as *i64 68 if ss_get(prefix, key, pq, lq) != 1 { out[0] = 0 as u8; return 0 } 69 return fd_field(pq[0] as *u8, lq[0], f, out) 70} 71func ld_lot_int(prefix: *u8, lotid: *u8, f: i64) -> i64 { 72 let fb: *u8 = sys_mmap(24) 73 let fl: i64 = ld_lot_str(prefix, lotid, f, fb) 74 if fl == 0 { return 0 } 75 return fd_atoi(fb, fl) 76} 77func ld_lot_exists(prefix: *u8, lotid: *u8) -> i64 { 78 let key: *u8 = sys_mmap(96); ld_lot_key(lotid, key) 79 let pq: *i64 = sys_mmap(16) as *i64 80 let lq: *i64 = sys_mmap(16) as *i64 81 if ss_get(prefix, key, pq, lq) != 1 { return 0 } 82 return 1 83} 84// a root harvest lot from an org's harvest. 85func ld_create_lot(prefix: *u8, lotid: *u8, org_id: *u8, quantity: i64, unit: *u8, day: i64) -> i64 { 86 let key: *u8 = sys_mmap(96); ld_lot_key(lotid, key) 87 let val: *u8 = sys_mmap(256); var v: i64 = 0 88 v = as_append(val, v, org_id); val[v] = 9 as u8; v = v + 1 89 val[v] = 45 as u8; v = v + 1; val[v] = 9 as u8; v = v + 1 // parent_lot "-" (root) 90 v = fd_apnum(val, v, quantity); val[v] = 9 as u8; v = v + 1 91 v = as_append(val, v, unit); val[v] = 9 as u8; v = v + 1 92 v = as_append(val, v, "harvest" as *u8); val[v] = 9 as u8; v = v + 1 93 v = fd_apnum(val, v, day); val[v] = 0 as u8 94 return ld_put(prefix, key, val) 95} 96func ld_alloc(prefix: *u8, lotid: *u8) -> i64 { 97 let key: *u8 = sys_mmap(96); ld_alloc_key(lotid, key) 98 let pq: *i64 = sys_mmap(16) as *i64 99 let lq: *i64 = sys_mmap(16) as *i64 100 if ss_get(prefix, key, pq, lq) != 1 { return 0 } 101 return fd_atoi(pq[0] as *u8, lq[0]) 102} 103func ld_lot_remaining(prefix: *u8, lotid: *u8) -> i64 { return ld_lot_int(prefix, lotid, 2) - ld_alloc(prefix, lotid) } 104// split a child lot off a parent. Refuses (0) if it would exceed what remains (conservation). Returns 1 on success. 105func ld_split_lot(prefix: *u8, parent_lotid: *u8, child_lotid: *u8, quantity: i64, unit: *u8, purpose: *u8, day: i64) -> i64 { 106 if quantity <= 0 { return 0 } 107 if ld_lot_exists(prefix, parent_lotid) == 0 { return 0 } 108 if ld_lot_remaining(prefix, parent_lotid) < quantity { return 0 } 109 let key: *u8 = sys_mmap(96); ld_lot_key(child_lotid, key) 110 let val: *u8 = sys_mmap(256); var v: i64 = 0 111 val[v] = 45 as u8; v = v + 1; val[v] = 9 as u8; v = v + 1 // org_id "-" (inherit via the chain) 112 v = as_append(val, v, parent_lotid); val[v] = 9 as u8; v = v + 1 113 v = fd_apnum(val, v, quantity); val[v] = 9 as u8; v = v + 1 114 v = as_append(val, v, unit); val[v] = 9 as u8; v = v + 1 115 v = as_append(val, v, purpose); val[v] = 9 as u8; v = v + 1 116 v = fd_apnum(val, v, day); val[v] = 0 as u8 117 ld_put(prefix, key, val) 118 let ak: *u8 = sys_mmap(96); ld_alloc_key(parent_lotid, ak) 119 let nv: *u8 = sys_mmap(16); var no: i64 = fd_apnum(nv, 0, ld_alloc(prefix, parent_lotid) + quantity); nv[no] = 0 as u8 120 ld_put(prefix, ak, nv) 121 return 1 122} 123// trace a lot back to its root harvest: "lotid <- parent <- ... <- root"; returns hop count. 124func ld_lot_trace(prefix: *u8, lotid: *u8, out: *u8) -> i64 { 125 var o: i64 = 0 126 let cur: *u8 = sys_mmap(64) 127 var t: i64 = 0 128 while lotid[t] != (0 as u8) { cur[t] = lotid[t]; t = t + 1 } cur[t] = 0 as u8 129 var hops: i64 = 0 130 var guard: i64 = 0 131 var go: i64 = 1 132 while go == 1 { 133 if guard >= 64 { go = 0 } else { 134 o = as_append(out, o, cur) 135 let p: *u8 = sys_mmap(64); ld_lot_str(prefix, cur, 1, p) 136 if p[0] == (0 as u8) { go = 0 } else { 137 if fd_streq(p, "-" as *u8) == 1 { go = 0 } else { 138 o = as_append(out, o, " <- " as *u8) 139 var u: i64 = 0; while p[u] != (0 as u8) { cur[u] = p[u]; u = u + 1 } cur[u] = 0 as u8 140 hops = hops + 1 141 } 142 } 143 guard = guard + 1 144 } 145 } 146 out[o] = 0 as u8 147 return hops 148} 149// the origin organism of any lot: walk parent_lot to the root, return the root's org_id. ""/empty if broken. 150func ld_lot_origin_org(prefix: *u8, lotid: *u8, out: *u8) -> i64 { 151 let cur: *u8 = sys_mmap(64) 152 var t: i64 = 0 153 while lotid[t] != (0 as u8) { cur[t] = lotid[t]; t = t + 1 } cur[t] = 0 as u8 154 var guard: i64 = 0 155 while guard < 64 { 156 let p: *u8 = sys_mmap(64); ld_lot_str(prefix, cur, 1, p) 157 if p[0] == (0 as u8) { ld_lot_str(prefix, cur, 0, out); return 1 } 158 if fd_streq(p, "-" as *u8) == 1 { ld_lot_str(prefix, cur, 0, out); return 1 } 159 var u: i64 = 0; while p[u] != (0 as u8) { cur[u] = p[u]; u = u + 1 } cur[u] = 0 as u8 160 guard = guard + 1 161 } 162 out[0] = 0 as u8 163 return 0 164} 165 166// render a lot's provenance: the split chain -> the plant -> its lineage + genetics. Sovereign no-JS. 167func ld_render_lot(prefix: *u8, lotid: *u8, out: *u8) -> i64 { 168 let org: *u8 = sys_mmap(64); ld_lot_origin_org(prefix, lotid, org) 169 let orgnm: *u8 = sys_mmap(96); ln_field_str(prefix, org, 0, orgnm) 170 let variety: *u8 = sys_mmap(96); ln_field_str(prefix, org, 2, variety) 171 var o: i64 = 0 172 o = as_append(out, o, "<!doctype html><html lang='en'><head><meta charset='utf-8'><meta name='viewport' content='width=device-width,initial-scale=1'><title>Lot provenance</title><style>body{margin:0;font-family:system-ui,sans-serif;color:#22301d;background:#f3f7ee;line-height:1.5}header{background:#3a5a2a;color:#fff;padding:22px}header h1{margin:0;font-size:1.4rem}main{max-width:680px;margin:0 auto;padding:16px}section{background:#fff;border-radius:12px;padding:16px 18px;margin-top:14px;box-shadow:0 1px 0 #e2e8d6}h2{font-size:1.05rem;margin:0 0 8px;color:#3a5a2a}.chain{font-family:ui-monospace,monospace;background:#eef3e6;padding:8px 10px;border-radius:8px}.good{color:#2c6b1f;font-weight:700}.muted{color:#54614a;font-size:.88rem}</style></head><body><header><h1>This lot &mdash; where it came from</h1></header><main>" as *u8) 173 o = as_append(out, o, "<section><h2>Split chain back to the harvest</h2><p class='chain'>" as *u8) 174 let chain: *u8 = sys_mmap(512); ld_lot_trace(prefix, lotid, chain) 175 o = as_append_escaped(out, o, chain, as_len(chain)) 176 o = as_append(out, o, "</p></section><section><h2>The plant it grew on</h2><p><b>" as *u8) 177 o = as_append_escaped(out, o, orgnm, as_len(orgnm)) 178 o = as_append(out, o, "</b> &mdash; " as *u8) 179 o = as_append_escaped(out, o, variety, as_len(variety)) 180 o = as_append(out, o, "<br>Genetic quality: <b>" as *u8); o = fd_apnum(out, o, ln_quality_score(prefix, org)); o = as_append(out, o, "/100</b> " as *u8) 181 if ln_is_superior(prefix, org) == 1 { o = as_append(out, o, "<span class='good'>(superior strain)</span>" as *u8) } 182 if ld_is_cross(prefix, org) == 1 { 183 let cl: *u8 = sys_mmap(256); ld_cross_label(prefix, org, cl) 184 o = as_append(out, o, "<br>Cross: " as *u8); o = as_append_escaped(out, o, cl, as_len(cl)) 185 } 186 o = as_append(out, o, "</p></section><p class='muted'>Every plate traces to the exact plant and its seed &mdash; one harvest, many plates, all accounted for.</p></main></body></html>" as *u8) 187 out[o] = 0 as u8 188 return o 189}