code wiki / wiki / nx_pipeline_walker.nx

nx_pipeline_walker.nx source

↩ module page · 456 lines · 20313 B

1// nx_pipeline_walker.nx -- V2.0 P-1 pipeline-walker (Cardinal B FIRST goal). 2// 3// Walks operator-supplied artifact paths; reads each file via sys_read_file; 4// parses the V5 living-docs 6-field taxonomy (Quadrant / Topic Type / Status / 5// Trust State / Competitive State + Composes count); populates NxArtifactStore; 6// derives pipeline_stage per V2_0_PIPELINE_BOOTSTRAP_ARC_PLAN ยง2.0 mapping. 7// 8// COMPOSES (zero new parsers; ZERO bash + sed; per operator "from zero 9// everything nishi" cardinal): 10// wiki/nx_artifact_store (NxArtifactStore data model) 11// nx_html_extract (nx_he_match_ci case-insensitive byte match) 12// nx_search_inverted (nx_inv_hash_bytes_lower) 13// nx_syscalls (sys_read_file) 14// 15// COMPOSED BY: 16// wiki/nx_pipeline_route.nx (P-3 queued; renders this store) 17// wiki/nx_wiki_main.nx (P-5; startup integration) 18// 19// Per operator cardinal 2026-05-27: the V5 living-docs system already 20// exists at nxc2/docs/dashboards/* with bash + sed scaffolding. This 21// walker is the BITS-UP NishiLang replacement for the taxonomy-extraction 22// step (taxonomy parse + pipeline-stage derive). The bash pre-commit 23// rebuilder is queued for nx_git_hook + nx_markdown_render replacement 24// in a follow-on commit. 25// 26// V2.0 SCOPE: 27// - Per-artifact: sys_read_file -> parse 6-field front-matter -> 28// populate NxArtifactStore -> derive stage 29// - Bounded by NX_PWALK_MAX_BYTES_PER_FILE 30// - Skips files larger than cap (rare; flagged as EXEMPT_TOO_LARGE) 31// 32// V2.5+ SCOPE (TODO): 33// - sys_getdents recursive walker (V2.0 takes operator-supplied path list) 34// - nx_git_hook sovereign replacement for pre-commit bash 35// - Incremental walk (only re-process changed files; content-hash diff) 36// 37// Status: V2.0. 2026-05-27. 38 39import "nx_syscalls.nx" 40import "nx_html_extract.nx" 41import "nx_search_inverted.nx" 42import "wiki/nx_artifact_store.nx" 43import "hub/nx_doc_extractor_nx.nx" 44import "hub/nx_doc_extractor_md.nx" 45 46// ===== Sealed verdict surface (codes 2950-2969) ================================================= 47const NX_PWALK_OK: i64 = 0 48const NX_PWALK_BAD_INPUT: i64 = 2950 49const NX_PWALK_READ_FAILED: i64 = 2951 50const NX_PWALK_FILE_TOO_LARGE: i64 = 2952 51const NX_PWALK_STORE_OVERFLOW: i64 = 2953 52const NX_PWALK_LOOP_BUDGET: i64 = 2954 53const NX_PWALK_PARSE_FAILED: i64 = 2955 54 55// ===== Named constants (M7) ================================================= 56const NX_PWALK_MAX_BYTES_PER_FILE: i64 = 1048576 // 1 MB scan cap 57const NX_PWALK_HEAD_SCAN_LIMIT: i64 = 16384 // front-matter in first 16 KB 58const NX_PWALK_LOOP_BUDGET_CAP: i64 = 10000000 59 60// ASCII (M7) 61const NX_PWALK_ASCII_NL: i64 = 0x0A // '\n' 62const NX_PWALK_ASCII_COLON: i64 = 0x3A // ':' 63const NX_PWALK_ASCII_OPEN: i64 = 0x5B // '[' 64const NX_PWALK_ASCII_CLOSE: i64 = 0x5D // ']' 65 66// ===== Find a "**Field:** value" line in front-matter ================================================= 67// 68// Returns 1 + fills out_val_off/out_val_len if found; 0 otherwise. 69// Searches first NX_PWALK_HEAD_SCAN_LIMIT bytes; case-insensitive on 70// field name; skips leading "**" markdown bold markers. 71 72func nx_pwalk_find_field(src: *u8, src_n: i64, 73 field_z: *u8, field_n: i64, 74 out_val_off: *i64, out_val_len: *i64) -> i64 { 75 if (out_val_off as i64) == 0 { return 0 } 76 if (out_val_len as i64) == 0 { return 0 } 77 out_val_off[0] = 0 78 out_val_len[0] = 0 79 if src_n < 1 { return 0 } 80 var limit: i64 = src_n 81 if limit > NX_PWALK_HEAD_SCAN_LIMIT { limit = NX_PWALK_HEAD_SCAN_LIMIT } 82 83 var i: i64 = 0 84 var iter: i64 = 0 85 while i < limit { 86 if iter >= NX_PWALK_LOOP_BUDGET_CAP { return 0 } 87 iter = iter + 1 88 // Skip whitespace + leading markdown bold markers (`**`). 89 // We look for: optional **, field name, optional **, ':', value, newline. 90 var p: i64 = i 91 if p + 2 < limit { 92 if (src[p] as i64) == 0x2A { // '*' 93 if (src[p + 1] as i64) == 0x2A { p = p + 2 } 94 } 95 } 96 // Compare field name case-insensitively. 97 if nx_he_match_ci(src, p, src_n, field_z, field_n) == 1 { 98 let after_name: i64 = p + field_n 99 var q: i64 = after_name 100 // Optional closing ** 101 if q + 1 < limit { 102 if (src[q] as i64) == 0x2A { 103 if (src[q + 1] as i64) == 0x2A { q = q + 2 } 104 } 105 } 106 // Expect ':' next (possibly preceded by whitespace). 107 while q < limit { 108 let c: i64 = src[q] as i64 109 if c == NX_PWALK_ASCII_COLON { 110 // Skip ':' + whitespace; capture until newline. 111 let val_start: i64 = q + 1 112 var v: i64 = val_start 113 while v < limit { 114 let cv: i64 = src[v] as i64 115 if cv != 0x20 { if cv != 0x09 { v = limit + 1 } } 116 if v <= limit { if v < limit { v = v + 1 } } 117 } 118 let real_v: i64 = if v > limit then limit else v - 1 119 // Walk to newline. 120 var e: i64 = real_v 121 while e < limit { 122 if (src[e] as i64) == NX_PWALK_ASCII_NL { e = limit + 1 } 123 if e <= limit { if e < limit { e = e + 1 } } 124 } 125 let real_e: i64 = if e > limit then limit else e - 1 126 out_val_off[0] = real_v 127 out_val_len[0] = real_e - real_v 128 return 1 129 } 130 if c == NX_PWALK_ASCII_NL { q = limit + 1 } // EOL before ':'; not this line 131 if q < limit { q = q + 1 } 132 } 133 } 134 // Skip to next line. 135 while i < limit { 136 if (src[i] as i64) == NX_PWALK_ASCII_NL { i = limit + 1 } 137 if i <= limit { if i < limit { i = i + 1 } } 138 } 139 if i > limit { i = limit } 140 i = i + 1 141 if i <= p { i = p + 1 } 142 } 143 return 0 144} 145 146// ===== Per-field value classifier (sealed-enum mapping) ================================================= 147 148func nx_pwalk_classify_quadrant(src: *u8, off: i64, n: i64) -> i64 { 149 if n < 1 { return NX_ART_QUAD_NONE } 150 if nx_he_match_ci(src, off, off + n, "TUTORIAL" as *u8, 8) == 1 { return NX_ART_QUAD_TUTORIAL } 151 if nx_he_match_ci(src, off, off + n, "HOW-TO" as *u8, 6) == 1 { return NX_ART_QUAD_HOWTO } 152 if nx_he_match_ci(src, off, off + n, "HOWTO" as *u8, 5) == 1 { return NX_ART_QUAD_HOWTO } 153 if nx_he_match_ci(src, off, off + n, "REFERENCE" as *u8, 9) == 1 { return NX_ART_QUAD_REFERENCE } 154 if nx_he_match_ci(src, off, off + n, "EXPLANATION" as *u8, 11) == 1 { return NX_ART_QUAD_EXPLANATION } 155 return NX_ART_QUAD_NONE 156} 157 158func nx_pwalk_classify_topic_type(src: *u8, off: i64, n: i64) -> i64 { 159 if n < 1 { return NX_ART_DITA_NONE } 160 if nx_he_match_ci(src, off, off + n, "TASK" as *u8, 4) == 1 { return NX_ART_DITA_TASK } 161 if nx_he_match_ci(src, off, off + n, "CONCEPT" as *u8, 7) == 1 { return NX_ART_DITA_CONCEPT } 162 if nx_he_match_ci(src, off, off + n, "REFERENCE" as *u8, 9) == 1 { return NX_ART_DITA_REFERENCE } 163 if nx_he_match_ci(src, off, off + n, "GLOSSARY" as *u8, 8) == 1 { return NX_ART_DITA_GLOSSARY } 164 return NX_ART_DITA_NONE 165} 166 167func nx_pwalk_classify_status(src: *u8, off: i64, n: i64) -> i64 { 168 if n < 1 { return NX_ART_STATUS_NONE } 169 if nx_he_match_ci(src, off, off + n, "CANONICAL" as *u8, 9) == 1 { return NX_ART_STATUS_CANONICAL } 170 if nx_he_match_ci(src, off, off + n, "WIP" as *u8, 3) == 1 { return NX_ART_STATUS_WIP } 171 if nx_he_match_ci(src, off, off + n, "DEPRECATED" as *u8, 10) == 1 { return NX_ART_STATUS_DEPRECATED } 172 return NX_ART_STATUS_NONE 173} 174 175func nx_pwalk_classify_trust(src: *u8, off: i64, n: i64) -> i64 { 176 if n < 1 { return NX_ART_TRUST_NONE } 177 if nx_he_match_ci(src, off, off + n, "PERSONALLY_MEASURED" as *u8, 19) == 1 { return NX_ART_TRUST_PERSONALLY_MEASURED } 178 if nx_he_match_ci(src, off, off + n, "WEBSEARCH-VERIFIED" as *u8, 18) == 1 { return NX_ART_TRUST_WEBSEARCH_VERIFIED } 179 if nx_he_match_ci(src, off, off + n, "WEBSEARCH_VERIFIED" as *u8, 18) == 1 { return NX_ART_TRUST_WEBSEARCH_VERIFIED } 180 if nx_he_match_ci(src, off, off + n, "EXPERT-VERIFIED" as *u8, 15) == 1 { return NX_ART_TRUST_EXPERT_VERIFIED } 181 if nx_he_match_ci(src, off, off + n, "EXPERT_VERIFIED" as *u8, 15) == 1 { return NX_ART_TRUST_EXPERT_VERIFIED } 182 if nx_he_match_ci(src, off, off + n, "WRITTEN_UNTESTED" as *u8, 16) == 1 { return NX_ART_TRUST_WRITTEN_UNTESTED } 183 if nx_he_match_ci(src, off, off + n, "WRITTEN-UNTESTED" as *u8, 16) == 1 { return NX_ART_TRUST_WRITTEN_UNTESTED } 184 return NX_ART_TRUST_NONE 185} 186 187func nx_pwalk_classify_competitive(src: *u8, off: i64, n: i64) -> i64 { 188 if n < 1 { return NX_ART_COMP_NONE } 189 // Value formats per V5 doctrine: "BEATS_[INCUMBENT]" / "MATCHES_[INCUMBENT]" / 190 // "UNDER_[INCUMBENT]" / "UNCLASSIFIED" / "UNCLASSIFIED (reason)". 191 if nx_he_match_ci(src, off, off + n, "BEATS" as *u8, 5) == 1 { return NX_ART_COMP_BEATS } 192 if nx_he_match_ci(src, off, off + n, "MATCHES" as *u8, 7) == 1 { return NX_ART_COMP_MATCHES } 193 if nx_he_match_ci(src, off, off + n, "UNDER" as *u8, 5) == 1 { return NX_ART_COMP_UNDER } 194 if nx_he_match_ci(src, off, off + n, "UNCLASSIFIED" as *u8, 12) == 1 { return NX_ART_COMP_UNCLASSIFIED } 195 return NX_ART_COMP_NONE 196} 197 198// ===== Count [[X]] refs in body (composes V5 nx_doc_xref signal) ================================================= 199// 200// Walks body bytes; counts '[[' tokens that close with ']]' within 201// NX_PWALK_MAX_BYTES_PER_FILE; bounded. 202 203func nx_pwalk_count_composes(src: *u8, src_n: i64) -> i64 { 204 if src_n < 4 { return 0 } 205 var count: i64 = 0 206 var i: i64 = 0 207 var iter: i64 = 0 208 while i + 3 < src_n { 209 if iter >= NX_PWALK_LOOP_BUDGET_CAP { return count } 210 iter = iter + 1 211 if (src[i] as i64) == NX_PWALK_ASCII_OPEN { 212 if (src[i + 1] as i64) == NX_PWALK_ASCII_OPEN { 213 // Find closing ]] 214 var j: i64 = i + 2 215 while j + 1 < src_n { 216 if (src[j] as i64) == NX_PWALK_ASCII_CLOSE { 217 if (src[j + 1] as i64) == NX_PWALK_ASCII_CLOSE { 218 count = count + 1 219 i = j + 1 220 j = src_n + 1 221 } 222 } 223 if j < src_n { j = j + 1 } 224 } 225 } 226 } 227 i = i + 1 228 } 229 return count 230} 231 232// ===== Count lines (for line_count stat) ================================================= 233 234func nx_pwalk_count_lines(src: *u8, src_n: i64) -> i64 { 235 if src_n < 1 { return 0 } 236 var n: i64 = 1 // at least one line if any bytes 237 var i: i64 = 0 238 while i < src_n { 239 if (src[i] as i64) == NX_PWALK_ASCII_NL { n = n + 1 } 240 i = i + 1 241 } 242 return n 243} 244 245// ===== Classify artifact kind from path ================================================= 246 247func nx_pwalk_classify_kind(path: *u8, path_n: i64) -> i64 { 248 if path_n < 1 { return NX_ART_KIND_UNKNOWN } 249 // _test.nx 250 if path_n > 8 { 251 if nx_he_match_ci(path, path_n - 8, path_n, "_test.nx" as *u8, 8) == 1 { return NX_ART_KIND_TEST_NX } 252 } 253 // .nx (runtime) 254 if path_n > 3 { 255 if nx_he_match_ci(path, path_n - 3, path_n, ".nx" as *u8, 3) == 1 { 256 // Distinguish silicon arcs by path prefix (heuristic). 257 if path_n > 7 { 258 if nx_he_match_ci(path, 0, path_n, "silicon" as *u8, 7) == 1 { return NX_ART_KIND_SILICON_ARC } 259 } 260 return NX_ART_KIND_RUNTIME_NX 261 } 262 } 263 // .sh (bench) 264 if path_n > 3 { 265 if nx_he_match_ci(path, path_n - 3, path_n, ".sh" as *u8, 3) == 1 { return NX_ART_KIND_BENCH_SH } 266 } 267 // .md classification by path heuristic 268 if path_n > 3 { 269 if nx_he_match_ci(path, path_n - 3, path_n, ".md" as *u8, 3) == 1 { 270 // dashboards/ -> DASHBOARD_MD 271 if nx_he_match_ci(path, 0, path_n, "nxc2/docs/dashboards/" as *u8, 21) == 1 { return NX_ART_KIND_DASHBOARD_MD } 272 // /memory/ -> MEMORY_MD 273 if nx_he_match_ci(path, 0, path_n, "memory/" as *u8, 7) == 1 { return NX_ART_KIND_MEMORY_MD } 274 // _DOCTRINE_ or _ROADMAP -> RFC_MD 275 // (simple substring match) 276 var i: i64 = 0 277 while i + 10 < path_n { 278 if nx_he_match_ci(path, i, path_n, "_DOCTRINE_" as *u8, 10) == 1 { return NX_ART_KIND_RFC_MD } 279 i = i + 1 280 } 281 // Default .md -> CHARTER_MD (nishi-silicon charters) 282 return NX_ART_KIND_CHARTER_MD 283 } 284 } 285 return NX_ART_KIND_OTHER 286} 287 288// ===== Top-level: walk one artifact + populate store ================================================= 289 290func nx_pipeline_walker_walk_one(store: *NxArtifactStore, 291 path_z: *u8, path_n: i64) -> i64 { 292 if store.valid != 1 { return 0 - NX_PWALK_BAD_INPUT } 293 if (path_z as i64) == 0 { return 0 - NX_PWALK_BAD_INPUT } 294 if path_n < 1 { return 0 - NX_PWALK_BAD_INPUT } 295 if path_n > 512 { return 0 - NX_PWALK_BAD_INPUT } 296 297 // Read file 298 let lenbox: *u8 = sys_mmap(8) 299 let lp: *i64 = lenbox as *i64 300 lp[0] = 0 301 let body: *u8 = sys_read_file(path_z, lp) 302 if (body as i64) == 0 { return 0 - NX_PWALK_READ_FAILED } 303 let body_n: i64 = lp[0] 304 if body_n < 1 { return 0 - NX_PWALK_READ_FAILED } 305 if body_n > NX_PWALK_MAX_BYTES_PER_FILE { return 0 - NX_PWALK_FILE_TOO_LARGE } 306 307 // Classify kind from path 308 let kind: i64 = nx_pwalk_classify_kind(path_z, path_n) 309 310 // Add to store (commit hash empty V2.0; V2.5 reads from git via nx_git_walk) 311 let rowid: i64 = nx_artifact_store_add(store, path_z, path_n, kind, 312 0 as *u8, 0, 313 nx_pwalk_count_lines(body, body_n)) 314 if rowid < 0 { return rowid } 315 316 // Parse 6-field front-matter 317 let val_off: *i64 = (sys_mmap(8)) as *i64 318 let val_len: *i64 = (sys_mmap(8)) as *i64 319 320 var quad: i64 = NX_ART_QUAD_NONE 321 val_off[0] = 0; val_len[0] = 0 322 if nx_pwalk_find_field(body, body_n, "Quadrant" as *u8, 8, val_off, val_len) == 1 { 323 quad = nx_pwalk_classify_quadrant(body, val_off[0], val_len[0]) 324 } 325 326 var topic: i64 = NX_ART_DITA_NONE 327 val_off[0] = 0; val_len[0] = 0 328 if nx_pwalk_find_field(body, body_n, "Topic Type" as *u8, 10, val_off, val_len) == 1 { 329 topic = nx_pwalk_classify_topic_type(body, val_off[0], val_len[0]) 330 } 331 332 var st: i64 = NX_ART_STATUS_NONE 333 val_off[0] = 0; val_len[0] = 0 334 if nx_pwalk_find_field(body, body_n, "Status" as *u8, 6, val_off, val_len) == 1 { 335 st = nx_pwalk_classify_status(body, val_off[0], val_len[0]) 336 } 337 338 var trust: i64 = NX_ART_TRUST_NONE 339 val_off[0] = 0; val_len[0] = 0 340 if nx_pwalk_find_field(body, body_n, "Trust State" as *u8, 11, val_off, val_len) == 1 { 341 trust = nx_pwalk_classify_trust(body, val_off[0], val_len[0]) 342 } 343 344 var comp: i64 = NX_ART_COMP_NONE 345 val_off[0] = 0; val_len[0] = 0 346 if nx_pwalk_find_field(body, body_n, "Competitive State" as *u8, 17, val_off, val_len) == 1 { 347 comp = nx_pwalk_classify_competitive(body, val_off[0], val_len[0]) 348 } 349 350 let rc_tax: i64 = nx_artifact_store_set_taxonomy(store, rowid, 351 quad, topic, st, trust, comp) 352 if rc_tax != NX_ART_OK { return rc_tax } 353 354 // Composes count (signal for STAGE_MEANINGFUL) 355 let composes: i64 = nx_pwalk_count_composes(body, body_n) 356 357 // V2.0 P-6 + P-7: per-kind deep extraction (composes hub primitives). 358 // For .nx kinds: import_count + export_count via nx_doc_extract_nx_stats 359 // For .md kinds: heading_count -> import slot; code_block_count -> export slot 360 // (semantic re-use of i64 slots; sealed-enum kind makes interpretation safe) 361 var imports: i64 = 0 362 var exports: i64 = 0 363 if kind == NX_ART_KIND_RUNTIME_NX { 364 let imp_p: *i64 = (sys_mmap(8)) as *i64 365 let exp_p: *i64 = (sys_mmap(8)) as *i64 366 imp_p[0] = 0; exp_p[0] = 0 367 let rc_x: i64 = nx_doc_extract_nx_stats(body, body_n, imp_p, exp_p) 368 if rc_x == NX_DXNX_OK { imports = imp_p[0]; exports = exp_p[0] } 369 } 370 if kind == NX_ART_KIND_TEST_NX { 371 let imp_p: *i64 = (sys_mmap(8)) as *i64 372 let exp_p: *i64 = (sys_mmap(8)) as *i64 373 imp_p[0] = 0; exp_p[0] = 0 374 let rc_x: i64 = nx_doc_extract_nx_stats(body, body_n, imp_p, exp_p) 375 if rc_x == NX_DXNX_OK { imports = imp_p[0]; exports = exp_p[0] } 376 } 377 if kind == NX_ART_KIND_SILICON_ARC { 378 let imp_p: *i64 = (sys_mmap(8)) as *i64 379 let exp_p: *i64 = (sys_mmap(8)) as *i64 380 imp_p[0] = 0; exp_p[0] = 0 381 let rc_x: i64 = nx_doc_extract_nx_stats(body, body_n, imp_p, exp_p) 382 if rc_x == NX_DXNX_OK { imports = imp_p[0]; exports = exp_p[0] } 383 } 384 if kind == NX_ART_KIND_CHARTER_MD { 385 let h_p: *i64 = (sys_mmap(8)) as *i64 386 let c_p: *i64 = (sys_mmap(8)) as *i64 387 h_p[0] = 0; c_p[0] = 0 388 let rc_x: i64 = nx_doc_extract_md_stats(body, body_n, h_p, c_p) 389 if rc_x == NX_DXMD_OK { imports = h_p[0]; exports = c_p[0] } 390 } 391 if kind == NX_ART_KIND_RFC_MD { 392 let h_p: *i64 = (sys_mmap(8)) as *i64 393 let c_p: *i64 = (sys_mmap(8)) as *i64 394 h_p[0] = 0; c_p[0] = 0 395 let rc_x: i64 = nx_doc_extract_md_stats(body, body_n, h_p, c_p) 396 if rc_x == NX_DXMD_OK { imports = h_p[0]; exports = c_p[0] } 397 } 398 if kind == NX_ART_KIND_DASHBOARD_MD { 399 let h_p: *i64 = (sys_mmap(8)) as *i64 400 let c_p: *i64 = (sys_mmap(8)) as *i64 401 h_p[0] = 0; c_p[0] = 0 402 let rc_x: i64 = nx_doc_extract_md_stats(body, body_n, h_p, c_p) 403 if rc_x == NX_DXMD_OK { imports = h_p[0]; exports = c_p[0] } 404 } 405 if kind == NX_ART_KIND_MEMORY_MD { 406 let h_p: *i64 = (sys_mmap(8)) as *i64 407 let c_p: *i64 = (sys_mmap(8)) as *i64 408 h_p[0] = 0; c_p[0] = 0 409 let rc_x: i64 = nx_doc_extract_md_stats(body, body_n, h_p, c_p) 410 if rc_x == NX_DXMD_OK { imports = h_p[0]; exports = c_p[0] } 411 } 412 413 let rc_stats: i64 = nx_artifact_store_set_stats(store, rowid, imports, exports, composes) 414 if rc_stats != NX_ART_OK { return rc_stats } 415 416 // Derive pipeline stage from taxonomy + stats 417 let stage: i64 = nx_artifact_store_derive_stage(store, rowid) 418 if stage < 0 { return stage } 419 420 return rowid 421} 422 423// ===== Top-level: walk a list of paths ================================================= 424// 425// Caller supplies an array of NUL-terminated path pointers + count. 426// Returns NX_PWALK_OK on success; first error verdict on failure. 427 428func nx_pipeline_walker_walk_list(store: *NxArtifactStore, 429 paths: *i64, paths_count: i64) -> i64 { 430 if store.valid != 1 { return 0 - NX_PWALK_BAD_INPUT } 431 if (paths as i64) == 0 { return 0 - NX_PWALK_BAD_INPUT } 432 if paths_count < 1 { return NX_PWALK_OK } // empty list is valid 433 434 var i: i64 = 0 435 while i < paths_count { 436 let path_ptr: *u8 = paths[i] as *u8 437 if (path_ptr as i64) == 0 { i = i + 1 } 438 if (path_ptr as i64) != 0 { 439 // Compute path length (NUL-terminated) 440 var n: i64 = 0 441 while n < 512 { 442 if path_ptr[n] == (0 as u8) { n = 512 + 1 } 443 if n <= 512 { if n < 512 { n = n + 1 } } 444 } 445 let real_n: i64 = if n > 512 then n - 513 else n 446 // Walk one; ignore per-file errors (continue walking; surface 447 // each error via store record's missing fields). 448 let rc: i64 = nx_pipeline_walker_walk_one(store, path_ptr, real_n) 449 if rc < 0 { 450 // Per Cardinal 14 (graceful degradation): record absence + continue 451 } 452 i = i + 1 453 } 454 } 455 return NX_PWALK_OK 456}