nx_idea_genealogist.nx source
↩ module page · 387 lines · 18054 B
1// nx_idea_genealogist.nx -- the IDEA/ATTRIBUTION genealogist (top-down): records WHO/WHAT/WHERE/
2// WHY/WHEN/HOW an insight came from and the idea->idea chain that produced it, then BRIDGES each
3// idea into the bottom-up code/math tree via realized_in (an id that must resolve in lineage.tsv
4// or math_genealogy.tsv). Sibling to nx_math_genealogist / nx_oracle_genealogist / nx_genesis_lineage.
5//
6// AUTHOR=ORGAN: this organ authors the registry rows; Claude does NOT hand-write idea_genealogy.tsv.
7// The 5W1H + edges are SOURCED DATA in knowledge/specs/idea_genealogy.spec.tsv (transcribed from
8// well-established public attributions). This organ, modelled on nx_genesis_lineage:
9// 1. reads the spec (field delimiter '|', rewritten to TAB on emit),
10// 2. loads idea_ids already in idea_genealogy.tsv (idempotency: present idea = SKIPPED),
11// 3. loads the BRIDGE universe = lineage.tsv field0 (child ids) + math_genealogy.tsv field1 (foundation ids),
12// 4. validates each row and REFUSES only a real lie -- a broken descends_from (idea-chain to
13// nothing) or a SOURCED row with an empty source (fabricated citation). An unresolved
14// realized_in is NOT refused: it is a RECORD-HINT that names a no-orphans gap.
15// 5. appends the surviving rows to idea_genealogy.tsv and logs an IDEAGENEAL verdict.
16// Idempotent (rerun = emitted=0 skipped=N), additive-only (append, never overwrite -- rule 13).
17// Sovereign syscalls only.
18//
19// module: nishi-core.genealogy.idea_genealogist
20// capability: GENEALOGY
21// license_tier: ORIGINAL
22import "nx_syscalls.nx"
23const IG_MAGIC_8192: i64 = 8192
24const IG_MAGIC_1048576: i64 = 1048576
25const IG_MAGIC_1048575: i64 = 1048575
26const IG_MAGIC_262144: i64 = 262144
27const IG_MAGIC_262143: i64 = 262143
28const IG_MAGIC_1024: i64 = 1024
29
30const IG_SPEC: *u8 = "knowledge/specs/idea_genealogy.spec.tsv"
31const IG_OUT: *u8 = "knowledge/registry/idea_genealogy.tsv"
32const IG_LIN: *u8 = "knowledge/registry/lineage.tsv"
33const IG_MATHG: *u8 = "knowledge/registry/math_genealogy.tsv"
34const IG_LOG: *u8 = "knowledge/status/idea_genealogy.log"
35const IG_IDCAP: i64 = 64
36
37func ig_w(fd: i64, s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(fd, s, n); return 0 }
38func ig_wn(fd: i64, v: i64) -> i64 { let bb: *u8 = sys_mmap(28); var m: i64=v; if m<0 {m=0-m; sys_write(fd,"-" as *u8,1)}; let t: *u8 = sys_mmap(28); var k: i64=0; if m==0 {t[0]=48 as u8;k=1}; while m>0 {t[k]=(48+(m%10)) as u8; m=m/10; k=k+1}; var i: i64=0; while i<k {bb[i]=t[k-1-i]; i=i+1}; sys_write(fd, bb, k); return 0 }
39
40// write the canonical 2-line registry header (tabs as byte 9 -- no reliance on \t in string literals).
41func ig_wheader(fd: i64) -> i64 {
42 ig_w(fd, "# AUTHORED BY nx_idea_genealogist -- the TOP-DOWN idea/attribution tree (who/what/where/why/when/how + the idea->idea chain), bridged into the BOTTOM-UP code/math genealogy via realized_in. Sibling to math_genealogy.tsv / oracle_genealogy.tsv; obeys the genealogist SOURCED-or-RECORD-HINT law (never fabricate an attribution). CREDIT != LICENSE: credit is honest, always license-neutral; credit_class declares only the source's ingestion posture (credit-only = acknowledge + cite, never ingest; else an nx_provenance allowed class, ingested ONLY through the nx_provenance gate). Source spec = knowledge/specs/idea_genealogy.spec.tsv. realized_in MUST resolve to a real id in lineage.tsv or math_genealogy.tsv, else the row is a RECORD-HINT naming a no-orphans gap.\n" as *u8)
43 let tb: *u8 = sys_mmap(4); tb[0] = 9 as u8; tb[1] = 0 as u8
44 ig_w(fd, "# columns: idea_id" as *u8)
45 ig_w(fd, tb); ig_w(fd, "what" as *u8)
46 ig_w(fd, tb); ig_w(fd, "who" as *u8)
47 ig_w(fd, tb); ig_w(fd, "where" as *u8)
48 ig_w(fd, tb); ig_w(fd, "when" as *u8)
49 ig_w(fd, tb); ig_w(fd, "why" as *u8)
50 ig_w(fd, tb); ig_w(fd, "how" as *u8)
51 ig_w(fd, tb); ig_w(fd, "descends_from" as *u8)
52 ig_w(fd, tb); ig_w(fd, "realized_in" as *u8)
53 ig_w(fd, tb); ig_w(fd, "source" as *u8)
54 ig_w(fd, tb); ig_w(fd, "source_status" as *u8)
55 ig_w(fd, tb); ig_w(fd, "credit_class" as *u8)
56 ig_w(fd, "\n" as *u8)
57 return 0
58}
59
60func ig_streq(a: *u8, b: *u8) -> i64 {
61 var i: i64 = 0
62 while i < IG_IDCAP { if a[i] != b[i] { return 0 } if a[i] == (0 as u8) { return 1 } i = i + 1 }
63 return 1
64}
65
66func ig_in_set(arena: i64, cnt: i64, idcap: i64, name: *u8) -> i64 {
67 var i: i64 = 0
68 while i < cnt { if ig_streq((arena + i * idcap) as *u8, name) == 1 { return 1 } i = i + 1 }
69 return 0
70}
71
72// copy field `idx` (0-based, '|'-delimited) of line [ls,le) into out (NUL-terminated, bounded).
73func ig_field(buf: *u8, ls: i64, le: i64, idx: i64, out: *u8, outcap: i64) -> i64 {
74 var fi: i64 = 0
75 var p: i64 = ls
76 while fi < idx {
77 if p >= le { out[0] = 0 as u8; return 0 }
78 if buf[p] == (124 as u8) { fi = fi + 1 }
79 p = p + 1
80 }
81 var k: i64 = 0
82 while p < le {
83 if buf[p] == (124 as u8) { p = le } else {
84 if k < outcap - 1 { out[k] = buf[p]; k = k + 1 }
85 p = p + 1
86 }
87 }
88 out[k] = 0 as u8
89 return k
90}
91
92// descends_from validation: '-' = root (ok). else every comma token must be an existing idea_id or a batch idea_id.
93func ig_desc_valid(parents: *u8, ea: i64, ec: i64, ba: i64, bc: i64, idcap: i64) -> i64 {
94 if parents[0] == (45 as u8) { if parents[1] == (0 as u8) { return 1 } }
95 let tok: *u8 = sys_mmap(IG_IDCAP)
96 var i: i64 = 0
97 var k: i64 = 0
98 var okall: i64 = 1
99 var go: i64 = 1
100 while go == 1 {
101 let ch: i64 = parents[i] as i64
102 var fin: i64 = 0
103 if ch == 0 { fin = 1 }
104 if ch == 44 { fin = 1 }
105 if fin == 1 {
106 if k > 0 {
107 tok[k] = 0 as u8
108 var found: i64 = 0
109 if ig_in_set(ea, ec, idcap, tok) == 1 { found = 1 }
110 if ig_in_set(ba, bc, idcap, tok) == 1 { found = 1 }
111 if found == 0 { okall = 0 }
112 k = 0
113 }
114 if ch == 0 { go = 0 }
115 } else { if k < idcap - 1 { tok[k] = ch as u8; k = k + 1 } }
116 i = i + 1
117 }
118 return okall
119}
120
121// realized_in bridge check: returns 2=bridged (a token resolves), 1=none ('-'/empty), 0=record-hint (a token is unresolved).
122func ig_bridge(realized: *u8, br: i64, brc: i64, idcap: i64) -> i64 {
123 if realized[0] == (0 as u8) { return 1 }
124 if realized[0] == (45 as u8) { if realized[1] == (0 as u8) { return 1 } }
125 let tok: *u8 = sys_mmap(IG_IDCAP)
126 var i: i64 = 0
127 var k: i64 = 0
128 var resolved: i64 = 0
129 var unresolved: i64 = 0
130 var go: i64 = 1
131 while go == 1 {
132 let ch: i64 = realized[i] as i64
133 var fin: i64 = 0
134 if ch == 0 { fin = 1 }
135 if ch == 44 { fin = 1 }
136 if fin == 1 {
137 if k > 0 {
138 tok[k] = 0 as u8
139 var isdash: i64 = 0
140 if tok[0] == (45 as u8) { if tok[1] == (0 as u8) { isdash = 1 } }
141 if isdash == 0 {
142 if ig_in_set(br, brc, idcap, tok) == 1 { resolved = resolved + 1 } else { unresolved = unresolved + 1 }
143 }
144 k = 0
145 }
146 if ch == 0 { go = 0 }
147 } else { if k < idcap - 1 { tok[k] = ch as u8; k = k + 1 } }
148 i = i + 1
149 }
150 if unresolved > 0 { return 0 }
151 if resolved > 0 { return 2 }
152 return 1
153}
154
155// append line [ls,le) to fd, rewriting '|' -> TAB, then a newline.
156func ig_append(fd: i64, buf: *u8, ls: i64, le: i64) -> i64 {
157 let ob: *u8 = sys_mmap(IG_MAGIC_8192)
158 var i: i64 = ls
159 var o: i64 = 0
160 while i < le {
161 if buf[i] == (124 as u8) { ob[o] = 9 as u8 } else { ob[o] = buf[i] }
162 o = o + 1
163 i = i + 1
164 }
165 ob[o] = 10 as u8; o = o + 1
166 sys_write(fd, ob, o)
167 return 0
168}
169
170// load TAB-field `fidx` of every non-comment row of `path` into arena (appended); returns new count.
171func ig_load_field(path: *u8, fidx: i64, arena: i64, base: i64, idcap: i64, maxc: i64) -> i64 {
172 let buf: *u8 = sys_mmap(IG_MAGIC_1048576)
173 let fd: i64 = sys_openat_rd(path)
174 if fd < 0 { return base }
175 var n: i64 = 0
176 var r: i64 = sys_read(fd, buf, IG_MAGIC_1048575)
177 while r > 0 { n = n + r; r = sys_read(fd, buf + n, IG_MAGIC_1048575 - n) }
178 sys_close(fd)
179 var cnt: i64 = base
180 var i: i64 = 0
181 while i < n {
182 if buf[i] == (35 as u8) {
183 var sk: i64 = 1
184 while sk == 1 { if i >= n { sk = 0 } else { if buf[i] == (10 as u8) { sk = 0 } i = i + 1 } }
185 } else {
186 var p: i64 = i
187 var f: i64 = 0
188 var stop: i64 = 0
189 while f < fidx {
190 if p >= n { f = fidx; stop = 1 } else {
191 if buf[p] == (10 as u8) { f = fidx; stop = 1 } else {
192 if buf[p] == (9 as u8) { f = f + 1 }
193 p = p + 1
194 }
195 }
196 }
197 if stop == 0 {
198 var fe: i64 = p
199 var scan: i64 = 1
200 while scan == 1 {
201 if fe >= n { scan = 0 } else {
202 if buf[fe] == (9 as u8) { scan = 0 } else { if buf[fe] == (10 as u8) { scan = 0 } else { fe = fe + 1 } }
203 }
204 }
205 let flen: i64 = fe - p
206 if flen > 0 { if flen < idcap { if cnt < maxc {
207 let dst: *u8 = (arena + cnt * idcap) as *u8
208 var k: i64 = 0
209 while k < flen { dst[k] = buf[p + k]; k = k + 1 }
210 dst[flen] = 0 as u8
211 cnt = cnt + 1
212 } } }
213 }
214 var le: i64 = i
215 var s2: i64 = 1
216 while s2 == 1 { if le >= n { s2 = 0 } else { if buf[le] == (10 as u8) { s2 = 0 } else { le = le + 1 } } }
217 i = le + 1
218 }
219 }
220 return cnt
221}
222
223func ig_report(fd: i64, nl: i64, emitted: i64, skipped: i64, refused: i64, hints: i64, bridged: i64, credit_only: i64, epoch: i64, ok: i64) -> i64 {
224 ig_w(fd, "IDEAGENEAL authored=organ source=idea_genealogy.spec.tsv spec_rows=" as *u8); ig_wn(fd, nl)
225 ig_w(fd, " emitted=" as *u8); ig_wn(fd, emitted)
226 ig_w(fd, " skipped_idempotent=" as *u8); ig_wn(fd, skipped)
227 ig_w(fd, " refused=" as *u8); ig_wn(fd, refused)
228 ig_w(fd, " record_hints=" as *u8); ig_wn(fd, hints)
229 ig_w(fd, " bridged=" as *u8); ig_wn(fd, bridged)
230 ig_w(fd, " credit_only=" as *u8); ig_wn(fd, credit_only)
231 ig_w(fd, " epoch=" as *u8); ig_wn(fd, epoch)
232 if ok == 1 { ig_w(fd, " verdict=GREEN\n" as *u8) } else { ig_w(fd, " verdict=RED\n" as *u8) }
233 return 0
234}
235
236func main(argc: i64, argv: *i64) -> i64 {
237 // argv path-override (gate hook): argv[1]=spec argv[2]=out argv[3]=log argv[4]=lineage argv[5]=math_genealogy.
238 // No args -> the canonical registry paths. Lets _idea_genealogy_gate drive the REAL elf over a /tmp
239 // scratch world WITHOUT touching the real registry (no-mocks). Defaults are the consts.
240 var spec_path: *u8 = IG_SPEC
241 var out_path: *u8 = IG_OUT
242 var log_path: *u8 = IG_LOG
243 var lin_path: *u8 = IG_LIN
244 var mathg_path: *u8 = IG_MATHG
245 if argc > 1 { spec_path = (argv[1]) as *u8 }
246 if argc > 2 { out_path = (argv[2]) as *u8 }
247 if argc > 3 { log_path = (argv[3]) as *u8 }
248 if argc > 4 { lin_path = (argv[4]) as *u8 }
249 if argc > 5 { mathg_path = (argv[5]) as *u8 }
250 // regen mode (argv[6]=="regen"): REBUILD the registry from the current spec so corrected facts
251 // propagate (default append-mode is idempotent-on-id and cannot UPDATE). Default unchanged.
252 var regen: i64 = 0
253 if argc > 6 { if ig_streq((argv[6]) as *u8, "regen" as *u8) == 1 { regen = 1 } }
254 // read the spec
255 let buf: *u8 = sys_mmap(IG_MAGIC_262144)
256 let fd: i64 = sys_openat_rd(spec_path)
257 if fd < 0 { ig_w(1, "IDEAGENEAL verdict=RED reason=spec-missing\n" as *u8); sys_exit(1); return 1 }
258 var n: i64 = 0
259 var r: i64 = sys_read(fd, buf, IG_MAGIC_262143)
260 while r > 0 { n = n + r; r = sys_read(fd, buf + n, IG_MAGIC_262143 - n) }
261 sys_close(fd)
262
263 // pass A: record line bounds + batch idea_ids
264 let lss: *i64 = sys_mmap(64 * 8) as *i64
265 let les: *i64 = sys_mmap(64 * 8) as *i64
266 let batch: i64 = sys_mmap(64 * IG_IDCAP) as i64
267 var nl: i64 = 0
268 var bc: i64 = 0
269 var i: i64 = 0
270 while i < n {
271 var le: i64 = i
272 var s: i64 = 1
273 while s == 1 { if le >= n { s = 0 } else { if buf[le] == (10 as u8) { s = 0 } else { le = le + 1 } } }
274 if le > i { if buf[i] != (35 as u8) {
275 if nl < 64 {
276 lss[nl] = i; les[nl] = le
277 let cb: *u8 = (batch + bc * IG_IDCAP) as *u8
278 ig_field(buf, i, le, 0, cb, IG_IDCAP)
279 if cb[0] != (0 as u8) { bc = bc + 1 }
280 nl = nl + 1
281 }
282 } }
283 i = le + 1
284 }
285
286 // existing idea_ids (idempotency)
287 let exist: i64 = sys_mmap(512 * IG_IDCAP) as i64
288 var ec: i64 = ig_load_field(out_path, 0, exist, 0, IG_IDCAP, 512)
289 if regen == 1 { ec = 0 }
290
291 // bridge universe = lineage.tsv field0 (child) + math_genealogy.tsv field1 (id)
292 let bridge: i64 = sys_mmap(IG_MAGIC_1024 * IG_IDCAP) as i64
293 var brc: i64 = ig_load_field(lin_path, 0, bridge, 0, IG_IDCAP, IG_MAGIC_1024)
294 brc = ig_load_field(mathg_path, 1, bridge, brc, IG_IDCAP, IG_MAGIC_1024)
295
296 // pass B: validate + emit. DEFAULT = append (idempotent). regen = rebuild the registry from the
297 // current spec (corrections propagate) via the proven tmp+sys_renameat hot-swap (no torn reads).
298 let tmppath: *u8 = sys_mmap(512)
299 var ofd: i64 = 0
300 if regen == 1 {
301 var tp: i64 = 0
302 while out_path[tp] != (0 as u8) { tmppath[tp] = out_path[tp]; tp = tp + 1 }
303 let sfx: *u8 = ".tmp"
304 var y: i64 = 0
305 while sfx[y] != (0 as u8) { tmppath[tp] = sfx[y]; tp = tp + 1; y = y + 1 }
306 tmppath[tp] = 0 as u8
307 ofd = sys_openat_wr(tmppath, 420)
308 if ofd >= 0 { ig_wheader(ofd) }
309 } else {
310 ofd = sys_openat_append(out_path, 420)
311 }
312 if ofd < 0 { ig_w(1, "IDEAGENEAL verdict=RED reason=registry-unwritable\n" as *u8); sys_exit(1); return 1 }
313 var emitted: i64 = 0
314 var skipped: i64 = 0
315 var refused: i64 = 0
316 var hints: i64 = 0
317 var bridged: i64 = 0
318 var credit_only: i64 = 0
319 let cbuf: *u8 = sys_mmap(IG_IDCAP)
320 let dbuf: *u8 = sys_mmap(512)
321 let rbuf: *u8 = sys_mmap(512)
322 let sbuf: *u8 = sys_mmap(512)
323 let stbuf: *u8 = sys_mmap(64)
324 let ccbuf: *u8 = sys_mmap(64)
325 var j: i64 = 0
326 while j < nl {
327 ig_field(buf, lss[j], les[j], 0, cbuf, IG_IDCAP)
328 ig_field(buf, lss[j], les[j], 7, dbuf, 512)
329 ig_field(buf, lss[j], les[j], 8, rbuf, 512)
330 ig_field(buf, lss[j], les[j], 9, sbuf, 512)
331 ig_field(buf, lss[j], les[j], 10, stbuf, 64)
332 ig_field(buf, lss[j], les[j], 11, ccbuf, 64)
333 if ig_in_set(exist, ec, IG_IDCAP, cbuf) == 1 { skipped = skipped + 1 }
334 else {
335 // sourcing discipline (liar-kill): status must be SOURCED or RECORD-HINT; SOURCED needs a source.
336 var is_sourced: i64 = 0
337 var is_hint: i64 = 0
338 if ig_streq(stbuf, "SOURCED" as *u8) == 1 { is_sourced = 1 }
339 if ig_streq(stbuf, "RECORD-HINT" as *u8) == 1 { is_hint = 1 }
340 var bad: i64 = 0
341 if is_sourced == 0 { if is_hint == 0 { bad = 1 } }
342 if is_sourced == 1 { if sbuf[0] == (0 as u8) { bad = 1 } }
343 if ig_desc_valid(dbuf, exist, ec, batch, bc, IG_IDCAP) == 0 { bad = 1 }
344 // credit/license boundary (honesty): credit_class must be a DECLARED, valid posture --
345 // 'credit-only' (acknowledge + cite, never ingest) OR an nx_provenance allowed class
346 // (the source MAY be ingested, but ONLY through the nx_provenance gate -- never decided here).
347 var cc_ok: i64 = 0
348 var cc_credit_only: i64 = 0
349 if ig_streq(ccbuf, "credit-only" as *u8) == 1 { cc_ok = 1; cc_credit_only = 1 }
350 if ig_streq(ccbuf, "pd_classical" as *u8) == 1 { cc_ok = 1 }
351 if ig_streq(ccbuf, "pd_explicit" as *u8) == 1 { cc_ok = 1 }
352 if ig_streq(ccbuf, "pd_govdoc" as *u8) == 1 { cc_ok = 1 }
353 if ig_streq(ccbuf, "academic_open" as *u8) == 1 { cc_ok = 1 }
354 if ig_streq(ccbuf, "expired_patent" as *u8) == 1 { cc_ok = 1 }
355 if cc_ok == 0 { bad = 1 }
356 if bad == 1 {
357 refused = refused + 1
358 ig_w(1, "IDEAGENEAL REFUSE idea=" as *u8); ig_w(1, cbuf); ig_w(1, "\n" as *u8)
359 } else {
360 let b: i64 = ig_bridge(rbuf, bridge, brc, IG_IDCAP)
361 if b == 2 { bridged = bridged + 1 }
362 if b == 0 { hints = hints + 1; ig_w(1, "IDEAGENEAL HINT unresolved-bridge idea=" as *u8); ig_w(1, cbuf); ig_w(1, " realized_in=" as *u8); ig_w(1, rbuf); ig_w(1, "\n" as *u8) }
363 if is_hint == 1 { if b != 0 { hints = hints + 1 } }
364 if cc_credit_only == 1 { credit_only = credit_only + 1 }
365 ig_append(ofd, buf, lss[j], les[j])
366 if ec < 512 { let d: *u8 = (exist + ec * IG_IDCAP) as *u8; var k: i64 = 0; while cbuf[k] != (0 as u8) { d[k] = cbuf[k]; k = k + 1 } d[k] = 0 as u8; ec = ec + 1 }
367 emitted = emitted + 1
368 }
369 }
370 j = j + 1
371 }
372 sys_close(ofd)
373
374 let epoch: i64 = sys_now_realtime_sec()
375 var ok: i64 = 1
376 if refused != 0 { ok = 0 }
377 if emitted + skipped != nl { ok = 0 }
378 // regen hot-swap: only replace the real registry if every row validated (a RED run leaves it untouched).
379 if regen == 1 { if ok == 1 { sys_renameat(tmppath, out_path) } }
380
381 ig_report(1, nl, emitted, skipped, refused, hints, bridged, credit_only, epoch, ok)
382 let glog: i64 = sys_openat_append(log_path, 420)
383 if glog >= 0 { ig_report(glog, nl, emitted, skipped, refused, hints, bridged, credit_only, epoch, ok); sys_close(glog) }
384
385 if ok == 1 { sys_exit(0); return 0 }
386 sys_exit(1); return 1
387}