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 — 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}