code wiki / _hdl_build / nx_capgraph_edges.nx

nx_capgraph_edges.nx source

↩ module page · 458 lines · 20222 B

1// nx_capgraph_edges.nx -- DERIVES the capability graph's prerequisite edges FROM THE IMPORT CLOSURE. 2// 3// WHY (debt 1785518444, filed by me 2026-07-31): nx_capgraph_derive shipped reading a HAND-DECLARED 4// edge file. Declared edges are a seed, not a measurement, and a MISSING edge is the dangerous case -- 5// it lets a dependent read healthier than the layer it stands on. This organ replaces the declaration 6// with a measurement. 7// 8// THE MEASUREMENT, end to end, no taste anywhere in it: 9// 1. OWNERSHIP comes from knowledge/compare/<domain>.matrix, which already maps every domain to the 10// real organ SOURCE PATHS backing each of its capabilities (field2), with field3 = the symbol. 11// Rows whose symbol is _ABSENT_ are declared GAPS -- skipped, they own nothing. 12// 2. DEPENDENCY comes from the source itself: every `import "<module>.nx"` in an owned source. 13// 3. EDGE: if a source owned by domain A imports a module owned by domain B (B != A), then B is a 14// PREREQUISITE of A. That is a fact about the build, not an opinion about the architecture. 15// 16// ⚠THE MEASURED GRAPH IS NOT ACYCLIC. Probed 2026-07-31: search>webscraping, browser>webscraping AND 17// webscraping>browser, search>deepresearch AND deepresearch>search, comms>videoops AND videoops>comms. 18// Mutually-importing domains are REAL. This is not a defect in the measurement and must not be 19// "cleaned up" by dropping edges: a cycle is a genuine finding -- it names a CO-DEPENDENT CLUSTER that 20// can only be raised together. The consumer's min-relaxation is a fixpoint iteration bounded by node 21// count, so it converges on a general digraph; the cycle members simply share a floor. 22// 23// HONEST ENVELOPE, emitted into the file itself so no reader has to trust this comment: 24// - coverage is bounded by the matrices, not by this organ: a domain with few matrix rows yields few 25// edges. That is a matrix-completeness gap, and it is REPORTED, never silently treated as "no deps". 26// - matrix rows pointing at sources that do not exist on disk are COUNTED and reported (missing=N). 27// - first-wins ownership when two domains claim the same module; ambiguity is COUNTED and reported. 28// 29// nx_capgraph_edges [outfile] exit 0 ok | 4 capture-fail | 5 write-fail 30// license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0 31import "nx_capgraph_edges_lib.nx" 32 33func main(argc: i64, argv: *i64) -> i64 { 34 ce_init() 35 ce_depthscan = 0 36 ce_load_depth() 37 var outp: *u8 = CE_OUTDEF 38 var ai2: i64 = 1 39 while ai2 < argc { 40 let a: *u8 = argv[ai2] as *u8 41 if cg_streq(a, "--transitive" as *u8) == 1 { ce_trans = 1 } 42 else { 43 if cg_streq(a, "--direct" as *u8) == 1 { ce_trans = 0 } 44 else { 45 if cg_streq(a, "--depthscan" as *u8) == 1 { ce_depthscan = 1 } 46 else { outp = a } 47 } 48 } 49 ai2 = ai2 + 1 50 } 51 52 // ---- domain list, from the live honesty gate (never a hardcoded roster) ---- 53 let sout: *u8 = sys_mmap(CE_CAP + 16) 54 let solen: *i64 = sys_mmap(16) as *i64 55 let rc: i64 = tr_run1(CE_SOTA, 0 as *u8, sout, CE_CAP, solen) 56 let sn: i64 = solen[0] 57 if rc == 127 { return 4 } 58 if sn <= 0 { return 4 } 59 var ls: i64 = 0 60 var i: i64 = 0 61 while i <= sn { 62 var isend: i64 = 0 63 if i == sn { isend = 1 } 64 else { if sout[i] == (10 as u8) { isend = 1 } } 65 if isend == 1 { 66 var covp: i64 = 0 - 1 67 var j: i64 = ls 68 while j < i { 69 if j + 4 <= i { 70 if sout[j] == (99 as u8) { 71 if sout[j + 1] == (111 as u8) { 72 if sout[j + 2] == (118 as u8) { 73 if sout[j + 3] == (61 as u8) { 74 covp = j 75 j = i 76 } 77 } 78 } 79 } 80 } 81 j = j + 1 82 } 83 if covp > 0 { 84 var start: i64 = ls 85 var found: i64 = 0 86 var s: i64 = ls 87 while s < i { 88 if found == 0 { 89 if sout[s] != (32 as u8) { 90 start = s 91 found = 1 92 } 93 } 94 s = s + 1 95 } 96 if found == 1 { 97 var w: i64 = 0 98 var q: i64 = start 99 var d2: i64 = 0 100 while d2 == 0 { 101 if q >= i { d2 = 1 } 102 else { 103 if sout[q] == (32 as u8) { d2 = 1 } 104 else { 105 if w < CE_NAMEW - 1 { 106 ce_scr2[w] = sout[q] 107 w = w + 1 108 } 109 q = q + 1 110 } 111 } 112 } 113 ce_scr2[w] = 0 as u8 114 if w > 0 { ce_dom_add(ce_scr2) } 115 } 116 } 117 ls = i + 1 118 } 119 i = i + 1 120 } 121 122 // ---- PHASE 1: ownership from the matrices ---- 123 var d: i64 = 0 124 while d < ce_ndom { 125 ce_cpy(ce_path, "knowledge/compare/" as *u8, CE_PATHW) 126 var pl: i64 = 0 127 while ce_path[pl] != (0 as u8) { pl = pl + 1 } 128 let dn: *u8 = ce_dom_name(d) 129 var k: i64 = 0 130 while dn[k] != (0 as u8) { 131 if pl < CE_PATHW - 8 { 132 ce_path[pl] = dn[k] 133 pl = pl + 1 134 } 135 k = k + 1 136 } 137 ce_path[pl] = 46 as u8 138 ce_path[pl + 1] = 109 as u8 139 ce_path[pl + 2] = 97 as u8 140 ce_path[pl + 3] = 116 as u8 141 ce_path[pl + 4] = 114 as u8 142 ce_path[pl + 5] = 105 as u8 143 ce_path[pl + 6] = 120 as u8 144 ce_path[pl + 7] = 0 as u8 145 let mn: i64 = ce_read_into_buf(ce_path, CE_CAP) 146 if mn > 0 { 147 var mls: i64 = 0 148 var m: i64 = 0 149 while m <= mn { 150 var me: i64 = 0 151 if m == mn { me = 1 } 152 else { if ce_buf[m] == (10 as u8) { me = 1 } } 153 if me == 1 { 154 var skip: i64 = 0 155 if mls >= m { skip = 1 } 156 else { 157 if ce_buf[mls] == (35 as u8) { skip = 1 } 158 if ce_buf[mls] == (64 as u8) { skip = 1 } 159 } 160 if skip == 0 { 161 let plen: i64 = ce_field(mls, m, 1) 162 if plen > 0 { 163 ce_cpy(ce_path, ce_scr, CE_PATHW) 164 let slen: i64 = ce_field(mls, m, 2) 165 var absent: i64 = 0 166 if slen == 0 { absent = 1 } 167 if cg_streq(ce_scr, "_ABSENT_" as *u8) == 1 { absent = 1 } 168 if absent == 0 { 169 ce_basename(ce_path) 170 ce_own_add(ce_scr2, d) 171 ce_src_add(d, ce_path) 172 } 173 } 174 } 175 mls = m + 1 176 } 177 m = m + 1 178 } 179 } 180 d = d + 1 181 } 182 183 // ---- PHASE 2: edges from the import closure ---- 184 var scan_lo: i64 = ce_maxdepth 185 var scan_hi: i64 = ce_maxdepth 186 if ce_depthscan == 1 { 187 scan_lo = 1 188 scan_hi = CE_DEPTH_SCANMAX 189 cax_puts("=== DEPTH CURVE: edges per transitive depth -- the cut must be MEASURED, not chosen ===\n" as *u8) 190 cax_puts(" depth 1 == the strict one-hop (direct) subset. Pick the depth where the curve FLATTENS.\n\n" as *u8) 191 } 192 var dcur: i64 = scan_lo 193 while dcur <= scan_hi { 194 ce_maxdepth = dcur 195 ce_ne = 0 196 ce_nie = 0 197 ce_transedges = 0 198 ce_scanned = 0 199 ce_nonnx = 0 200 ce_altres = 0 201 ce_missing = 0 202 ce_nenc = 0 203 var si: i64 = 0 204 while si < ce_nsrc { 205 let sd: i64 = ce_srcd[si] 206 let sp: *u8 = ((ce_srcp as i64) + si * CE_PATHW) as *u8 207 // RESOLUTION IS MULTI-ROOT BY MEASUREMENT: matrix paths are relative to buildroot/ for sources 208 // but to the SERVING ROOT for site/knowledge artifacts, and two rows are stale renames that 209 // still exist under the other source dir. A single-prefix probe reported 23 "missing" files 210 // that were mostly PRESENT -- the tool was wrong, not the corpus. 211 var fn2: i64 = 0 - 1 212 if ce_is_nx(sp) == 0 { 213 ce_nonnx = ce_nonnx + 1 214 } else { 215 ce_join("buildroot/" as *u8, sp) 216 fn2 = ce_read_into_buf(ce_path, CE_HEAD) 217 if fn2 >= 0 { ce_res_bld = ce_res_bld + 1 } 218 if fn2 < 0 { 219 ce_join("\x00" as *u8, sp) 220 fn2 = ce_read_into_buf(ce_path, CE_HEAD) 221 if fn2 >= 0 { 222 ce_altres = ce_altres + 1 223 ce_res_srv = ce_res_srv + 1 224 } 225 } 226 if fn2 < 0 { 227 ce_basename(sp) 228 ce_join("buildroot/runtime/" as *u8, ce_scr2) 229 fn2 = ce_read_into_buf(ce_path, CE_HEAD) 230 if fn2 >= 0 { 231 ce_altres = ce_altres + 1 232 ce_res_base = ce_res_base + 1 233 } 234 } 235 if fn2 < 0 { 236 ce_basename(sp) 237 ce_join("buildroot/runtime/_hdl_build/" as *u8, ce_scr2) 238 fn2 = ce_read_into_buf(ce_path, CE_HEAD) 239 if fn2 >= 0 { 240 ce_altres = ce_altres + 1 241 ce_res_base = ce_res_base + 1 242 } 243 } 244 if fn2 < 0 { ce_missing = ce_missing + 1 } 245 } 246 if fn2 >= 0 { 247 ce_scanned = ce_scanned + 1 248 ce_qh = 0 249 ce_qt = 0 250 ce_nseen = 0 251 ce_scan_buf_imports(sd, 1, fn2) 252 while ce_qh < ce_qt { 253 let qi: i64 = ce_qh 254 ce_qh = ce_qh + 1 255 let qdep: i64 = ce_qd[qi] 256 ce_cpy(ce_scr, ((ce_q as i64) + qi * CE_NAMEW) as *u8, CE_NAMEW) 257 let qn: i64 = ce_resolve_base(ce_scr) 258 if qn > 0 { ce_scan_buf_imports(sd, qdep, qn) } 259 } 260 } 261 si = si + 1 262 } 263 if ce_depthscan == 1 { 264 cax_puts(" " as *u8) 265 cax_kv("depth" as *u8, dcur) 266 cax_kv("domain_edges" as *u8, ce_ne) 267 cax_kv("infra_edges" as *u8, ce_nie) 268 cax_kv("via_infra" as *u8, ce_transedges) 269 cax_puts("\n" as *u8) 270 } 271 dcur = dcur + 1 272 } 273 if ce_depthscan == 1 { 274 cax_puts("\nDEPTH-SCAN done -- set transitive_depth=<d> in knowledge/status/capgraph.conf.\n" as *u8) 275 return 0 276 } 277 278 // ---- PHASE 3: emit ---- 279 ce_fd = sys_openat_wr(outp, 0x1A4) 280 if ce_fd < 0 { 281 cax_puts("CAPGRAPH-EDGES verdict=WRITE-FAIL\n" as *u8) 282 return 5 283 } 284 ce_w("# capgraph_edges.conf -- MEASURED prerequisite edges. GENERATED by nx_capgraph_edges.\n" as *u8) 285 ce_w("# DO NOT HAND-EDIT: regenerate instead, or the file stops being a measurement.\n" as *u8) 286 ce_w("#\n# METHOD: ownership from knowledge/compare/<domain>.matrix field2 (source path), rows whose\n" as *u8) 287 ce_w("# field3 symbol is _ABSENT_ skipped as declared gaps; dependency from each owned source's\n" as *u8) 288 ce_w("# `import \"<module>.nx\"` lines; edge B>A when a source owned by A imports a module owned by B.\n" as *u8) 289 ce_w("# That is a fact about the build, not an opinion about the architecture.\n#\n" as *u8) 290 ce_w("# ENVELOPE (read this before trusting the graph):\n" as *u8) 291 ce_w("# domains=" as *u8) 292 ce_wi(ce_ndom) 293 ce_w(" owned_modules=" as *u8) 294 ce_wi(ce_nown) 295 ce_w(" sources_scanned=" as *u8) 296 ce_wi(ce_scanned) 297 ce_w("\n# non_source_rows=" as *u8) 298 ce_wi(ce_nonnx) 299 ce_w(" (rows citing .js/.tsv/.md/.html evidence -- carry no imports, can never yield an edge;\n" as *u8) 300 ce_w("# counted SEPARATELY because 'not a source' is not the same defect as 'absent')\n" as *u8) 301 ce_w("# resolved_via_alt_root=" as *u8) 302 ce_wi(ce_altres) 303 ce_w(" (found at the serving root or under the other source dir, not buildroot/)\n" as *u8) 304 ce_w("# sources_missing=" as *u8) 305 ce_wi(ce_missing) 306 ce_w(" (.nx rows genuinely absent from every root -- a real matrix-quality gap)\n" as *u8) 307 ce_w("# shared_modules_EXCLUDED=" as *u8) 308 ce_wi(ce_ambig) 309 ce_w(" (claimed by >1 domain = SHARED INFRA, not owned: importing one implies\n" as *u8) 310 ce_w("# NO directional dependency, so they derive no edge. Including them made edge DIRECTION\n" as *u8) 311 ce_w("# order-dependent -- both llm>modelwright and modelwright>llm were derivable. Excluding\n" as *u8) 312 ce_w("# them makes this file DETERMINISTIC. Under-counts edges; never fabricates one.)\n" as *u8) 313 ce_w("# OWNERSHIP COVERAGE = " as *u8) 314 ce_wi(ce_enc_owned()) 315 ce_w(" owned of " as *u8) 316 ce_wi(ce_nenc) 317 ce_w(" modules the closure actually touches. THIS IS THE REAL BOUND ON THIS GRAPH:\n" as *u8) 318 ce_w("# an UNOWNED module is where dependency information DIES -- the walk passes through it and\n" as *u8) 319 ce_w("# can attribute nothing on the far side. Every edge below is real; the edge SET is a FLOOR.\n" as *u8) 320 ce_w("# Raising this number is purely a matter of adding matrix rows -- no code change.\n" as *u8) 321 ce_w("# edges=" as *u8) 322 ce_wi(ce_ne) 323 ce_w("\n#\n# COVERAGE IS BOUNDED BY THE MATRICES, not by this organ: a domain with few matrix rows\n" as *u8) 324 ce_w("# yields few edges. A missing edge lets a dependent read healthier than what it stands on.\n" as *u8) 325 ce_w("# ⚠THE MEASURED GRAPH IS NOT ACYCLIC -- mutually-importing domains are real and must NOT be\n" as *u8) 326 ce_w("# pruned: a cycle names a CO-DEPENDENT CLUSTER that can only be raised together.\n\n" as *u8) 327 var e: i64 = 0 328 while e < ce_ne { 329 ce_w(ce_dom_name(ce_ef[e])) 330 ce_w(">" as *u8) 331 ce_w(ce_dom_name(ce_et[e])) 332 ce_w("\n" as *u8) 333 e = e + 1 334 } 335 ce_w("\n# SHARED INFRASTRUCTURE as FIRST-CLASS NODES (infra:<module>). A module claimed by more\n" as *u8) 336 ce_w("# than one domain is a prerequisite of every domain that imports it -- direction is never\n" as *u8) 337 ce_w("# ambiguous here, so nothing is discarded. A node many domains stand on IS the chokepoint.\n" as *u8) 338 ce_w("# These carry NO measured level yet, and UNMEASURED never drags a dependent down (L3).\n" as *u8) 339 var g: i64 = 0 340 while g < ce_nie { 341 ce_w("infra:" as *u8) 342 ce_w(((ce_ownname as i64) + ce_if[g] * CE_NAMEW) as *u8) 343 ce_w(">" as *u8) 344 ce_w(ce_dom_name(ce_it[g])) 345 ce_w("\n" as *u8) 346 g = g + 1 347 } 348 sys_close(ce_fd) 349 ce_fd = 1 350 351 cax_puts("=== CAPGRAPH-EDGES: prerequisite edges MEASURED from the import closure ===\n" as *u8) 352 cax_kv("domains" as *u8, ce_ndom) 353 cax_kv("owned_modules" as *u8, ce_nown) 354 cax_kv("sources_scanned" as *u8, ce_scanned) 355 cax_kv("non_source_rows" as *u8, ce_nonnx) 356 cax_kv("alt_root_resolved" as *u8, ce_altres) 357 cax_puts("\n" as *u8) 358 // A resolver that silently absorbs TWO path conventions makes the corpus drift INVISIBLE -- the 359 // exact "papers over the defect" pattern this arc keeps finding. Robust resolution is right; hiding 360 // WHICH root won is not. Two nonzero buckets = the matrices disagree about how to write a path. 361 cax_kv("resolved_via_buildroot" as *u8, ce_res_bld) 362 cax_kv("resolved_via_serving_root" as *u8, ce_res_srv) 363 cax_kv("resolved_via_basename_search" as *u8, ce_res_base) 364 var conv: i64 = 0 365 if ce_res_bld > 0 { conv = conv + 1 } 366 if ce_res_srv > 0 { conv = conv + 1 } 367 if ce_res_base > 0 { conv = conv + 1 } 368 if conv > 1 { 369 cax_puts("\n ⚠PATH-CONVENTION DRIFT: the matrices do NOT agree on how to write a source path.\n" as *u8) 370 cax_puts(" Resolution succeeds anyway, which is precisely why this must be REPORTED and not\n" as *u8) 371 cax_puts(" absorbed -- a tolerant reader is how a corpus drifts apart without anyone noticing.\n" as *u8) 372 } 373 cax_kv("sources_missing" as *u8, ce_missing) 374 cax_kv("shared_modules" as *u8, ce_ambig) 375 cax_kv("domain_edges" as *u8, ce_ne) 376 cax_kv("infra_edges" as *u8, ce_nie) 377 cax_kv("transitive_mode" as *u8, ce_trans) 378 cax_kv("depth" as *u8, ce_maxdepth) 379 if ce_depthsrc == 1 { cax_puts("(from capgraph.conf) " as *u8) } 380 else { cax_puts("(FALLBACK -- capgraph.conf absent, run --depthscan then set it) " as *u8) } 381 cax_kv("edges_found_via_infra" as *u8, ce_transedges) 382 cax_puts("\n" as *u8) 383 let seen_tot: i64 = ce_nenc 384 let seen_own: i64 = ce_enc_owned() 385 var cov_permil: i64 = 0 386 if seen_tot > 0 { cov_permil = seen_own * 1000 / seen_tot } 387 cax_kv("modules_touched" as *u8, seen_tot) 388 cax_kv("owned_by_a_domain" as *u8, seen_own) 389 cax_kv("ownership_coverage_permil" as *u8, cov_permil) 390 cax_puts("<- THE REAL BOUND: an UNOWNED module is where dependency info dies\n" as *u8) 391 392 // Turn the coverage debt from "add 548 rows" into a RANKED worklist. An unowned module imported many 393 // times is carrying the most invisible dependency; claiming it in a matrix converts the most surface 394 // per row. This is the cheapest possible ordering of a pure-content task, and it is measured. 395 var substrate: i64 = 0 396 var sz: i64 = 0 397 while sz < ce_nenc { 398 if ce_encown[sz] == 0 { 399 if ce_encdom[sz] == CE_SHARED { substrate = substrate + 1 } 400 } 401 sz = sz + 1 402 } 403 cax_kv("unowned_SUBSTRATE" as *u8, substrate) 404 cax_puts("(imported by MANY domains -- leave unowned; claiming one would fabricate edges to all)\n" as *u8) 405 cax_puts("\n-- CLAIM THESE FIRST: unowned modules imported by EXACTLY ONE domain --\n" as *u8) 406 cax_puts(" single-domain => unambiguously that domain's to claim, so a matrix row here is SAFE and\n" as *u8) 407 cax_puts(" converts invisible surface into measurable edges. Ranked by import hits.\n\n" as *u8) 408 let picked: *i64 = sys_mmap(CE_MAXOWN * 8 + 64) as *i64 409 var pz: i64 = 0 410 while pz < ce_nenc { 411 picked[pz] = 0 412 pz = pz + 1 413 } 414 var pshown: i64 = 0 415 while pshown < 15 { 416 var pb: i64 = 0 - 1 417 var pi: i64 = 0 418 while pi < ce_nenc { 419 if picked[pi] == 0 { 420 if ce_encown[pi] == 0 { 421 if ce_encdom[pi] >= 0 { 422 if pb < 0 { pb = pi } 423 else { if ce_enccnt[pi] > ce_enccnt[pb] { pb = pi } } 424 } 425 } 426 } 427 pi = pi + 1 428 } 429 if pb < 0 { pshown = 15 } 430 else { 431 picked[pb] = 1 432 cax_puts(" " as *u8) 433 cax_puts(((ce_enc as i64) + pb * CE_NAMEW) as *u8) 434 cax_puts(" " as *u8) 435 cax_kv("import_hits" as *u8, ce_enccnt[pb]) 436 cax_puts("claim_for=" as *u8) 437 cax_puts(ce_dom_name(ce_encdom[pb])) 438 cax_puts("\n" as *u8) 439 pshown = pshown + 1 440 } 441 } 442 cax_puts("\n" as *u8) 443 var p: i64 = 0 444 while p < ce_ne { 445 cax_puts(" " as *u8) 446 cax_puts(ce_dom_name(ce_ef[p])) 447 cax_puts(" > " as *u8) 448 cax_puts(ce_dom_name(ce_et[p])) 449 cax_puts("\n" as *u8) 450 p = p + 1 451 } 452 cax_puts("\nwrote " as *u8) 453 cax_puts(outp) 454 cax_puts("\nenvelope: ownership=matrix field2 (_ABSENT_ rows skipped) dependency=import lines;\n" as *u8) 455 cax_puts(" modules claimed by >1 domain are SHARED INFRA and derive NO edge (deterministic by\n" as *u8) 456 cax_puts(" construction, under-counts rather than fabricates); coverage bounded by matrix completeness.\n" as *u8) 457 return 0 458}