code wiki / _hdl_build / nx_link_auto.nx

nx_link_auto.nx source

↩ module page · 126 lines · 6843 B

1// nx_link_auto.nx -- LIB: SELF-POPULATING unifier (R-LINK-R1). Instead of hand-registering each item's facets, 2// AUTO-DETECT them by probing each store for the item's canonical key: impact (food:impact:<id>:nishi), price 3// (any observation in the area), swap (swap:species:<id>). So adding an item to ANY catalog/store makes it appear 4// in the unified view automatically -- derive from the SSOT, don't hand-maintain. Renders a browsable index that 5// links each item to its R-LINK view. HONEST: a facet absent from its store -> "-" (auto, never fabricated); the 6// lineage facet stays explicit (bio org-ids are per-individual, not the canonical name). Composes nx_link. 7// Sovereign seg-store (knowledge/store/link-*). license_tier: ORIGINAL 8import "nx_link.nx" 9import "nx_seg_store.nx" 10import "nx_syscalls.nx" 11 12// ---- facet detectors (probe each store by the canonical key) ---- 13func lk_has_impact(food_pfx: *u8, canonical: *u8) -> i64 { 14 if im_field_int(food_pfx, canonical, "nishi" as *u8, 1) < 0 { return 0 } 15 return 1 16} 17func lk_has_price(price_pfx: *u8, canonical: *u8, area: *u8) -> i64 { 18 let sid: *u8 = sys_mmap(48) 19 if pr_cheapest(price_pfx, area, canonical, sid) < 0 { return 0 } 20 return 1 21} 22func lk_has_swap(swap_pfx: *u8, canonical: *u8) -> i64 { 23 let key: *u8 = sys_mmap(96); var o: i64 = 0 24 o = as_append(key, o, "swap:species:" as *u8); o = as_append(key, o, canonical); key[o] = 0 as u8 25 let pq: *i64 = sys_mmap(16) as *i64 26 let lq: *i64 = sys_mmap(16) as *i64 27 if ss_get(swap_pfx, key, pq, lq) != 1 { return 0 } 28 return 1 29} 30 31// auto-register one item, DETECTING impact/price/swap; bio_hint explicit ("-" if no lineage linked). 32func lk_auto_register(link_pfx: *u8, food_pfx: *u8, price_pfx: *u8, swap_pfx: *u8, canonical: *u8, display: *u8, area: *u8, bio_hint: *u8) -> i64 { 33 var imp: *u8 = "-" as *u8 34 if lk_has_impact(food_pfx, canonical) == 1 { imp = canonical } 35 var prc: *u8 = "-" as *u8 36 if lk_has_price(price_pfx, canonical, area) == 1 { prc = canonical } 37 var swp: *u8 = "-" as *u8 38 if lk_has_swap(swap_pfx, canonical) == 1 { swp = canonical } 39 lk_register(link_pfx, canonical, display, bio_hint, imp, prc, swp) 40 return 1 41} 42 43// split a TAB list into NUL-terminated tokens; returns count. 44func lka_split(buf: *u8, len: i64, out: *i64) -> i64 { 45 var c: i64 = 0 46 var i: i64 = 0 47 var ls: i64 = 0 48 while i <= len { 49 var sep: i64 = 0 50 if i == len { sep = 1 } else { if buf[i] == (9 as u8) { sep = 1 } } 51 if sep == 1 { 52 let tl: i64 = i - ls 53 if tl > 0 { 54 let tok: *u8 = sys_mmap(48) 55 var t: i64 = 0 56 while t < tl { tok[t] = buf[ls + t]; t = t + 1 } tok[tl] = 0 as u8 57 out[c] = tok as i64; c = c + 1 58 } 59 ls = i + 1 60 } 61 i = i + 1 62 } 63 return c 64} 65 66// auto-register every item listed in a catalog tier index (e.g. food:tier:dirty, read from food_pfx). Returns count. 67func lk_auto_from_tier(link_pfx: *u8, food_pfx: *u8, price_pfx: *u8, swap_pfx: *u8, tier_key: *u8, area: *u8) -> i64 { 68 let pq: *i64 = sys_mmap(16) as *i64 69 let lq: *i64 = sys_mmap(16) as *i64 70 if ss_get(food_pfx, tier_key, pq, lq) != 1 { return 0 } 71 let ids: *i64 = sys_mmap(8 * 256) as *i64 72 let n: i64 = lka_split(pq[0] as *u8, lq[0], ids) 73 var i: i64 = 0 74 while i < n { 75 let canonical: *u8 = ids[i] as *u8 76 lk_auto_register(link_pfx, food_pfx, price_pfx, swap_pfx, canonical, canonical, area, "-" as *u8) 77 i = i + 1 78 } 79 return n 80} 81 82// render a browsable index of a tier's items, each with facet badges + a link to its unified R-LINK view. 83func lk_render_index(link_pfx: *u8, food_pfx: *u8, tier_key: *u8, title: *u8, out: *u8) -> i64 { 84 var o: i64 = 0 85 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>" as *u8) 86 o = as_append_escaped(out, o, title, as_len(title)) 87 o = as_append(out, o, "</title><style>body{margin:0;font-family:system-ui,sans-serif;color:#1c2316;background:#eef4ea;line-height:1.5}header{background:#33502f;color:#fff;padding:22px}header h1{margin:0;font-size:1.4rem}main{max-width:680px;margin:0 auto;padding:16px}ul{list-style:none;padding:0;margin:0}li{background:#fff;border-radius:10px;padding:12px 14px;margin-bottom:10px;box-shadow:0 1px 0 #dde8d3}a{color:#2f6b2a;text-decoration:none;font-weight:700}.b{display:inline-block;font-size:.7rem;text-transform:uppercase;letter-spacing:.03em;padding:2px 7px;border-radius:6px;margin-left:6px}.on{background:#e6efe1;color:#2f6b2a}.off{background:#f1efe8;color:#b0aa98}.muted{color:#5b6a52;font-size:.88rem}</style></head><body><header><h1>" as *u8) 88 o = as_append_escaped(out, o, title, as_len(title)) 89 o = as_append(out, o, "</h1></header><main><ul>" as *u8) 90 let pq: *i64 = sys_mmap(16) as *i64 91 let lq: *i64 = sys_mmap(16) as *i64 92 if ss_get(food_pfx, tier_key, pq, lq) == 1 { 93 let ids: *i64 = sys_mmap(8 * 256) as *i64 94 let n: i64 = lka_split(pq[0] as *u8, lq[0], ids) 95 var i: i64 = 0 96 while i < n { 97 let canonical: *u8 = ids[i] as *u8 98 let disp: *u8 = sys_mmap(64); lk_field(link_pfx, canonical, 0, disp) 99 let bio: *u8 = sys_mmap(48); lk_field(link_pfx, canonical, 1, bio) 100 let imp: *u8 = sys_mmap(48); lk_field(link_pfx, canonical, 2, imp) 101 let prc: *u8 = sys_mmap(48); lk_field(link_pfx, canonical, 3, prc) 102 let swp: *u8 = sys_mmap(48); lk_field(link_pfx, canonical, 4, swp) 103 o = as_append(out, o, "<li><a href='" as *u8) 104 o = as_append_escaped(out, o, canonical, as_len(canonical)) 105 o = as_append(out, o, ".html'>" as *u8) 106 o = as_append_escaped(out, o, disp, as_len(disp)) 107 o = as_append(out, o, "</a>" as *u8) 108 o = lk_badge(out, o, "Lineage" as *u8, lk_present(bio)) 109 o = lk_badge(out, o, "Clean" as *u8, lk_present(imp)) 110 o = lk_badge(out, o, "Price" as *u8, lk_present(prc)) 111 o = lk_badge(out, o, "Swap" as *u8, lk_present(swp)) 112 o = as_append(out, o, "</li>" as *u8) 113 i = i + 1 114 } 115 } 116 o = as_append(out, o, "</ul><p class='muted'>Each item auto-links to its full story. Badges show which facets are on record &mdash; lit if present, dim if not (honest, never faked).</p></main></body></html>" as *u8) 117 out[o] = 0 as u8 118 return o 119} 120func lk_badge(out: *u8, off: i64, label: *u8, on: i64) -> i64 { 121 var o: i64 = off 122 if on == 1 { o = as_append(out, o, "<span class='b on'>" as *u8) } else { o = as_append(out, o, "<span class='b off'>" as *u8) } 123 o = as_append(out, o, label) 124 o = as_append(out, o, "</span>" as *u8) 125 return o 126}