gitnexus 1.6.8-rc.8 → 1.6.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (439) hide show
  1. package/README.md +3 -3
  2. package/dist/_shared/graph/types.d.ts +31 -1
  3. package/dist/_shared/graph/types.d.ts.map +1 -1
  4. package/dist/_shared/language-detection.d.ts.map +1 -1
  5. package/dist/_shared/language-detection.js +11 -1
  6. package/dist/_shared/language-detection.js.map +1 -1
  7. package/dist/_shared/lbug/schema-constants.d.ts +1 -1
  8. package/dist/_shared/lbug/schema-constants.d.ts.map +1 -1
  9. package/dist/_shared/lbug/schema-constants.js +6 -0
  10. package/dist/_shared/lbug/schema-constants.js.map +1 -1
  11. package/dist/_shared/scope-resolution/parsed-file.d.ts +21 -0
  12. package/dist/_shared/scope-resolution/parsed-file.d.ts.map +1 -1
  13. package/dist/_shared/scope-resolution/symbol-definition.d.ts +6 -0
  14. package/dist/_shared/scope-resolution/symbol-definition.d.ts.map +1 -1
  15. package/dist/cli/ai-context.d.ts +31 -1
  16. package/dist/cli/ai-context.js +18 -16
  17. package/dist/cli/analyze-config.js +11 -0
  18. package/dist/cli/analyze.d.ts +14 -0
  19. package/dist/cli/analyze.js +98 -0
  20. package/dist/cli/embedding-dims.d.ts +33 -0
  21. package/dist/cli/embedding-dims.js +39 -0
  22. package/dist/cli/eval-server.d.ts +8 -0
  23. package/dist/cli/eval-server.js +242 -2
  24. package/dist/cli/help-i18n.js +19 -0
  25. package/dist/cli/i18n/en.d.ts +15 -1
  26. package/dist/cli/i18n/en.js +15 -1
  27. package/dist/cli/i18n/resources.d.ts +29 -1
  28. package/dist/cli/i18n/zh-CN.d.ts +14 -0
  29. package/dist/cli/i18n/zh-CN.js +15 -1
  30. package/dist/cli/index.js +89 -1
  31. package/dist/cli/mcp.d.ts +6 -1
  32. package/dist/cli/mcp.js +26 -1
  33. package/dist/cli/optional-grammars.d.ts +6 -8
  34. package/dist/cli/optional-grammars.js +8 -11
  35. package/dist/cli/setup.d.ts +3 -1
  36. package/dist/cli/setup.js +67 -17
  37. package/dist/cli/skill-gen.js +2 -1
  38. package/dist/cli/tool.d.ts +19 -1
  39. package/dist/cli/tool.js +96 -3
  40. package/dist/core/embeddings/hf-env.d.ts +0 -66
  41. package/dist/core/embeddings/http-client.d.ts +7 -0
  42. package/dist/core/embeddings/http-client.js +5 -3
  43. package/dist/core/embeddings/server-mapping.d.ts +1 -1
  44. package/dist/core/embeddings/server-mapping.js +7 -3
  45. package/dist/core/graph/import-cycles.d.ts +10 -0
  46. package/dist/core/graph/import-cycles.js +103 -0
  47. package/dist/core/group/cross-impact.d.ts +2 -1
  48. package/dist/core/group/cross-impact.js +5 -1
  49. package/dist/core/group/extractors/grpc-patterns/proto.js +10 -6
  50. package/dist/core/group/extractors/http-patterns/kotlin.js +7 -7
  51. package/dist/core/group/extractors/http-route-extractor.d.ts +24 -0
  52. package/dist/core/group/extractors/http-route-extractor.js +22 -4
  53. package/dist/core/group/extractors/include-extractor.js +22 -13
  54. package/dist/core/group/sync.d.ts +27 -1
  55. package/dist/core/group/sync.js +0 -0
  56. package/dist/core/incremental/subgraph-extract.js +18 -1
  57. package/dist/core/ingestion/cfg/cfg-builder.d.ts +114 -0
  58. package/dist/core/ingestion/cfg/cfg-builder.js +196 -0
  59. package/dist/core/ingestion/cfg/collect.d.ts +51 -0
  60. package/dist/core/ingestion/cfg/collect.js +77 -0
  61. package/dist/core/ingestion/cfg/control-dependence.d.ts +58 -0
  62. package/dist/core/ingestion/cfg/control-dependence.js +182 -0
  63. package/dist/core/ingestion/cfg/control-flow-context.d.ts +106 -0
  64. package/dist/core/ingestion/cfg/control-flow-context.js +124 -0
  65. package/dist/core/ingestion/cfg/emit.d.ts +293 -0
  66. package/dist/core/ingestion/cfg/emit.js +646 -0
  67. package/dist/core/ingestion/cfg/post-dominators.d.ts +79 -0
  68. package/dist/core/ingestion/cfg/post-dominators.js +176 -0
  69. package/dist/core/ingestion/cfg/reaching-def-reason-codec.d.ts +106 -0
  70. package/dist/core/ingestion/cfg/reaching-def-reason-codec.js +133 -0
  71. package/dist/core/ingestion/cfg/reaching-defs-graph.d.ts +18 -0
  72. package/dist/core/ingestion/cfg/reaching-defs-graph.js +312 -0
  73. package/dist/core/ingestion/cfg/reaching-defs.d.ts +162 -0
  74. package/dist/core/ingestion/cfg/reaching-defs.js +785 -0
  75. package/dist/core/ingestion/cfg/synthetic-escape.d.ts +124 -0
  76. package/dist/core/ingestion/cfg/synthetic-escape.js +300 -0
  77. package/dist/core/ingestion/cfg/traversal-result.d.ts +20 -0
  78. package/dist/core/ingestion/cfg/traversal-result.js +2 -0
  79. package/dist/core/ingestion/cfg/types.d.ts +274 -0
  80. package/dist/core/ingestion/cfg/types.js +13 -0
  81. package/dist/core/ingestion/cfg/visitors/c-cpp-harvest.d.ts +111 -0
  82. package/dist/core/ingestion/cfg/visitors/c-cpp-harvest.js +541 -0
  83. package/dist/core/ingestion/cfg/visitors/c-cpp.d.ts +74 -0
  84. package/dist/core/ingestion/cfg/visitors/c-cpp.js +584 -0
  85. package/dist/core/ingestion/cfg/visitors/call-site-harvest.d.ts +195 -0
  86. package/dist/core/ingestion/cfg/visitors/call-site-harvest.js +350 -0
  87. package/dist/core/ingestion/cfg/visitors/csharp-harvest.d.ts +124 -0
  88. package/dist/core/ingestion/cfg/visitors/csharp-harvest.js +589 -0
  89. package/dist/core/ingestion/cfg/visitors/csharp.d.ts +87 -0
  90. package/dist/core/ingestion/cfg/visitors/csharp.js +867 -0
  91. package/dist/core/ingestion/cfg/visitors/dart-harvest.d.ts +278 -0
  92. package/dist/core/ingestion/cfg/visitors/dart-harvest.js +870 -0
  93. package/dist/core/ingestion/cfg/visitors/dart.d.ts +119 -0
  94. package/dist/core/ingestion/cfg/visitors/dart.js +836 -0
  95. package/dist/core/ingestion/cfg/visitors/go-harvest.d.ts +160 -0
  96. package/dist/core/ingestion/cfg/visitors/go-harvest.js +621 -0
  97. package/dist/core/ingestion/cfg/visitors/go.d.ts +108 -0
  98. package/dist/core/ingestion/cfg/visitors/go.js +638 -0
  99. package/dist/core/ingestion/cfg/visitors/java-harvest.d.ts +108 -0
  100. package/dist/core/ingestion/cfg/visitors/java-harvest.js +513 -0
  101. package/dist/core/ingestion/cfg/visitors/java.d.ts +101 -0
  102. package/dist/core/ingestion/cfg/visitors/java.js +812 -0
  103. package/dist/core/ingestion/cfg/visitors/kotlin-harvest.d.ts +253 -0
  104. package/dist/core/ingestion/cfg/visitors/kotlin-harvest.js +719 -0
  105. package/dist/core/ingestion/cfg/visitors/kotlin.d.ts +121 -0
  106. package/dist/core/ingestion/cfg/visitors/kotlin.js +809 -0
  107. package/dist/core/ingestion/cfg/visitors/php-harvest.d.ts +172 -0
  108. package/dist/core/ingestion/cfg/visitors/php-harvest.js +626 -0
  109. package/dist/core/ingestion/cfg/visitors/php.d.ts +96 -0
  110. package/dist/core/ingestion/cfg/visitors/php.js +721 -0
  111. package/dist/core/ingestion/cfg/visitors/python-harvest.d.ts +212 -0
  112. package/dist/core/ingestion/cfg/visitors/python-harvest.js +739 -0
  113. package/dist/core/ingestion/cfg/visitors/python.d.ts +103 -0
  114. package/dist/core/ingestion/cfg/visitors/python.js +558 -0
  115. package/dist/core/ingestion/cfg/visitors/ruby-harvest.d.ts +223 -0
  116. package/dist/core/ingestion/cfg/visitors/ruby-harvest.js +587 -0
  117. package/dist/core/ingestion/cfg/visitors/ruby.d.ts +112 -0
  118. package/dist/core/ingestion/cfg/visitors/ruby.js +756 -0
  119. package/dist/core/ingestion/cfg/visitors/rust-harvest.d.ts +324 -0
  120. package/dist/core/ingestion/cfg/visitors/rust-harvest.js +873 -0
  121. package/dist/core/ingestion/cfg/visitors/rust.d.ts +95 -0
  122. package/dist/core/ingestion/cfg/visitors/rust.js +558 -0
  123. package/dist/core/ingestion/cfg/visitors/scope-tree-harvest.d.ts +87 -0
  124. package/dist/core/ingestion/cfg/visitors/scope-tree-harvest.js +116 -0
  125. package/dist/core/ingestion/cfg/visitors/swift-harvest.d.ts +255 -0
  126. package/dist/core/ingestion/cfg/visitors/swift-harvest.js +679 -0
  127. package/dist/core/ingestion/cfg/visitors/swift.d.ts +116 -0
  128. package/dist/core/ingestion/cfg/visitors/swift.js +787 -0
  129. package/dist/core/ingestion/cfg/visitors/typescript-harvest.d.ts +149 -0
  130. package/dist/core/ingestion/cfg/visitors/typescript-harvest.js +1056 -0
  131. package/dist/core/ingestion/cfg/visitors/typescript.d.ts +66 -0
  132. package/dist/core/ingestion/cfg/visitors/typescript.js +583 -0
  133. package/dist/core/ingestion/import-resolvers/utils.js +2 -0
  134. package/dist/core/ingestion/language-provider.d.ts +23 -2
  135. package/dist/core/ingestion/languages/c-cpp.js +17 -5
  136. package/dist/core/ingestion/languages/cobol.js +4 -0
  137. package/dist/core/ingestion/languages/cpp/arity-metadata.js +41 -2
  138. package/dist/core/ingestion/languages/cpp/captures.js +50 -1
  139. package/dist/core/ingestion/languages/cpp/conversion-rank.d.ts +2 -0
  140. package/dist/core/ingestion/languages/cpp/conversion-rank.js +89 -0
  141. package/dist/core/ingestion/languages/cpp/header-scan.d.ts +1 -1
  142. package/dist/core/ingestion/languages/cpp/header-scan.js +2 -2
  143. package/dist/core/ingestion/languages/cpp/inline-namespaces.js +7 -2
  144. package/dist/core/ingestion/languages/cpp/member-lookup.js +2 -1
  145. package/dist/core/ingestion/languages/cpp/query.js +23 -0
  146. package/dist/core/ingestion/languages/cpp/scope-resolver.js +2 -1
  147. package/dist/core/ingestion/languages/csharp.js +2 -0
  148. package/dist/core/ingestion/languages/dart.js +2 -0
  149. package/dist/core/ingestion/languages/go.js +2 -0
  150. package/dist/core/ingestion/languages/java.js +3 -0
  151. package/dist/core/ingestion/languages/kotlin/query.js +3 -2
  152. package/dist/core/ingestion/languages/kotlin.js +8 -1
  153. package/dist/core/ingestion/languages/php.js +2 -0
  154. package/dist/core/ingestion/languages/python.js +2 -0
  155. package/dist/core/ingestion/languages/ruby.js +2 -0
  156. package/dist/core/ingestion/languages/rust.js +2 -0
  157. package/dist/core/ingestion/languages/swift.js +2 -0
  158. package/dist/core/ingestion/languages/typescript.js +5 -0
  159. package/dist/core/ingestion/languages/vue.js +6 -0
  160. package/dist/core/ingestion/method-extractors/configs/c-cpp.js +6 -13
  161. package/dist/core/ingestion/method-extractors/generic.js +1 -0
  162. package/dist/core/ingestion/method-types.d.ts +2 -0
  163. package/dist/core/ingestion/model/symbol-table.d.ts +1 -0
  164. package/dist/core/ingestion/model/symbol-table.js +1 -0
  165. package/dist/core/ingestion/mro-processor.js +109 -0
  166. package/dist/core/ingestion/parsing-processor.js +44 -0
  167. package/dist/core/ingestion/pipeline-phases/call-summaries.d.ts +26 -0
  168. package/dist/core/ingestion/pipeline-phases/call-summaries.js +46 -0
  169. package/dist/core/ingestion/pipeline-phases/index.d.ts +2 -0
  170. package/dist/core/ingestion/pipeline-phases/index.js +2 -0
  171. package/dist/core/ingestion/pipeline-phases/parse-impl.d.ts +0 -21
  172. package/dist/core/ingestion/pipeline-phases/parse-impl.js +18 -1
  173. package/dist/core/ingestion/pipeline-phases/routes.d.ts +10 -0
  174. package/dist/core/ingestion/pipeline-phases/routes.js +30 -1
  175. package/dist/core/ingestion/pipeline-phases/taint-summaries.d.ts +30 -0
  176. package/dist/core/ingestion/pipeline-phases/taint-summaries.js +81 -0
  177. package/dist/core/ingestion/pipeline.d.ts +92 -10
  178. package/dist/core/ingestion/pipeline.js +11 -2
  179. package/dist/core/ingestion/scope-extractor.js +12 -2
  180. package/dist/core/ingestion/scope-resolution/contract/scope-resolver.d.ts +9 -0
  181. package/dist/core/ingestion/scope-resolution/graph-bridge/callee-id-sink.d.ts +75 -0
  182. package/dist/core/ingestion/scope-resolution/graph-bridge/callee-id-sink.js +67 -0
  183. package/dist/core/ingestion/scope-resolution/graph-bridge/edges.d.ts +12 -2
  184. package/dist/core/ingestion/scope-resolution/graph-bridge/edges.js +14 -2
  185. package/dist/core/ingestion/scope-resolution/graph-bridge/references-to-edges.d.ts +6 -1
  186. package/dist/core/ingestion/scope-resolution/graph-bridge/references-to-edges.js +13 -1
  187. package/dist/core/ingestion/scope-resolution/passes/free-call-fallback.d.ts +9 -1
  188. package/dist/core/ingestion/scope-resolution/passes/free-call-fallback.js +28 -2
  189. package/dist/core/ingestion/scope-resolution/passes/overload-narrowing.d.ts +4 -0
  190. package/dist/core/ingestion/scope-resolution/passes/overload-narrowing.js +9 -0
  191. package/dist/core/ingestion/scope-resolution/passes/receiver-bound-calls.d.ts +6 -1
  192. package/dist/core/ingestion/scope-resolution/passes/receiver-bound-calls.js +174 -40
  193. package/dist/core/ingestion/scope-resolution/pipeline/phase.d.ts +24 -0
  194. package/dist/core/ingestion/scope-resolution/pipeline/phase.js +276 -190
  195. package/dist/core/ingestion/scope-resolution/pipeline/reconcile-ownership.js +43 -3
  196. package/dist/core/ingestion/scope-resolution/pipeline/run.d.ts +75 -0
  197. package/dist/core/ingestion/scope-resolution/pipeline/run.js +349 -1
  198. package/dist/core/ingestion/scope-resolution/resolution-outcome.d.ts +1 -1
  199. package/dist/core/ingestion/taint/call-summary-codec.d.ts +75 -0
  200. package/dist/core/ingestion/taint/call-summary-codec.js +128 -0
  201. package/dist/core/ingestion/taint/call-summary-emit.d.ts +43 -0
  202. package/dist/core/ingestion/taint/call-summary-emit.js +70 -0
  203. package/dist/core/ingestion/taint/call-summary-harvest.d.ts +77 -0
  204. package/dist/core/ingestion/taint/call-summary-harvest.js +179 -0
  205. package/dist/core/ingestion/taint/call-summary-model.d.ts +47 -0
  206. package/dist/core/ingestion/taint/call-summary-model.js +25 -0
  207. package/dist/core/ingestion/taint/emit.d.ts +125 -0
  208. package/dist/core/ingestion/taint/emit.js +208 -0
  209. package/dist/core/ingestion/taint/interproc-emit.d.ts +50 -0
  210. package/dist/core/ingestion/taint/interproc-emit.js +88 -0
  211. package/dist/core/ingestion/taint/interproc-solver.d.ts +110 -0
  212. package/dist/core/ingestion/taint/interproc-solver.js +312 -0
  213. package/dist/core/ingestion/taint/match.d.ts +153 -0
  214. package/dist/core/ingestion/taint/match.js +278 -0
  215. package/dist/core/ingestion/taint/path-codec.d.ts +134 -0
  216. package/dist/core/ingestion/taint/path-codec.js +190 -0
  217. package/dist/core/ingestion/taint/propagate.d.ts +216 -0
  218. package/dist/core/ingestion/taint/propagate.js +659 -0
  219. package/dist/core/ingestion/taint/site-safety.d.ts +29 -0
  220. package/dist/core/ingestion/taint/site-safety.js +98 -0
  221. package/dist/core/ingestion/taint/source-sink-config.d.ts +107 -23
  222. package/dist/core/ingestion/taint/source-sink-config.js +35 -12
  223. package/dist/core/ingestion/taint/source-sink-registry.d.ts +6 -4
  224. package/dist/core/ingestion/taint/source-sink-registry.js +6 -4
  225. package/dist/core/ingestion/taint/summary-harvest-driver.d.ts +80 -0
  226. package/dist/core/ingestion/taint/summary-harvest-driver.js +179 -0
  227. package/dist/core/ingestion/taint/summary-harvest.d.ts +89 -0
  228. package/dist/core/ingestion/taint/summary-harvest.js +537 -0
  229. package/dist/core/ingestion/taint/summary-model.d.ts +200 -0
  230. package/dist/core/ingestion/taint/summary-model.js +86 -0
  231. package/dist/core/ingestion/taint/typescript-model.d.ts +38 -0
  232. package/dist/core/ingestion/taint/typescript-model.js +102 -0
  233. package/dist/core/ingestion/type-extractors/c-cpp.js +21 -0
  234. package/dist/core/ingestion/utils/env.d.ts +7 -0
  235. package/dist/core/ingestion/utils/env.js +12 -0
  236. package/dist/core/ingestion/utils/method-props.js +1 -0
  237. package/dist/core/ingestion/workers/clone-safety.d.ts +109 -0
  238. package/dist/core/ingestion/workers/clone-safety.js +465 -0
  239. package/dist/core/ingestion/workers/parse-worker.d.ts +23 -0
  240. package/dist/core/ingestion/workers/parse-worker.js +81 -53
  241. package/dist/core/ingestion/workers/post-result.d.ts +22 -0
  242. package/dist/core/ingestion/workers/post-result.js +87 -0
  243. package/dist/core/ingestion/workers/result-merge.d.ts +20 -0
  244. package/dist/core/ingestion/workers/result-merge.js +43 -0
  245. package/dist/core/ingestion/workers/worker-pool.d.ts +15 -40
  246. package/dist/core/ingestion/workers/worker-pool.js +43 -16
  247. package/dist/core/lbug/csv-generator.d.ts +51 -3
  248. package/dist/core/lbug/csv-generator.js +369 -255
  249. package/dist/core/lbug/lbug-adapter.d.ts +58 -18
  250. package/dist/core/lbug/lbug-adapter.js +346 -84
  251. package/dist/core/lbug/lbug-config.d.ts +19 -0
  252. package/dist/core/lbug/lbug-config.js +29 -0
  253. package/dist/core/lbug/pdg-emit-sink.d.ts +127 -0
  254. package/dist/core/lbug/pdg-emit-sink.js +358 -0
  255. package/dist/core/lbug/pool-adapter.d.ts +35 -0
  256. package/dist/core/lbug/pool-adapter.js +90 -1
  257. package/dist/core/lbug/rel-pair-routing.d.ts +54 -0
  258. package/dist/core/lbug/rel-pair-routing.js +140 -0
  259. package/dist/core/lbug/schema.d.ts +2 -2
  260. package/dist/core/lbug/schema.js +3 -0
  261. package/dist/core/logger.d.ts +0 -5
  262. package/dist/core/run-analyze.d.ts +96 -0
  263. package/dist/core/run-analyze.js +207 -3
  264. package/dist/core/tree-sitter/parser-loader.js +5 -4
  265. package/dist/core/tree-sitter/safe-parse.d.ts +0 -5
  266. package/dist/core/tree-sitter/vendored-grammars.d.ts +39 -0
  267. package/dist/core/tree-sitter/vendored-grammars.js +57 -0
  268. package/dist/core/wiki/generator.js +3 -1
  269. package/dist/core/wiki/graph-queries.d.ts +6 -0
  270. package/dist/core/wiki/graph-queries.js +9 -1
  271. package/dist/mcp/http-transport.d.ts +134 -0
  272. package/dist/mcp/http-transport.js +503 -0
  273. package/dist/mcp/local/local-backend.d.ts +110 -24
  274. package/dist/mcp/local/local-backend.js +1225 -19
  275. package/dist/mcp/local/pdg-impact.d.ts +384 -0
  276. package/dist/mcp/local/pdg-impact.js +1972 -0
  277. package/dist/mcp/resources.js +13 -1
  278. package/dist/mcp/tools.d.ts +12 -0
  279. package/dist/mcp/tools.js +214 -7
  280. package/dist/server/analyze-launch.d.ts +29 -0
  281. package/dist/server/analyze-launch.js +137 -0
  282. package/dist/server/analyze-upload.d.ts +33 -0
  283. package/dist/server/analyze-upload.js +123 -0
  284. package/dist/server/analyze-worker-ipc.d.ts +58 -0
  285. package/dist/server/analyze-worker-ipc.js +16 -0
  286. package/dist/server/analyze-worker.d.ts +17 -1
  287. package/dist/server/analyze-worker.js +7 -1
  288. package/dist/server/api.d.ts +17 -0
  289. package/dist/server/api.js +132 -168
  290. package/dist/server/git-clone.d.ts +43 -2
  291. package/dist/server/git-clone.js +211 -16
  292. package/dist/server/mcp-http.d.ts +5 -6
  293. package/dist/server/mcp-http.js +9 -82
  294. package/dist/server/middleware.d.ts +40 -0
  295. package/dist/server/middleware.js +92 -0
  296. package/dist/server/private-ip.d.ts +1 -0
  297. package/dist/server/private-ip.js +15 -0
  298. package/dist/server/upload-ingest.d.ts +56 -0
  299. package/dist/server/upload-ingest.js +276 -0
  300. package/dist/server/upload-paths.d.ts +37 -0
  301. package/dist/server/upload-paths.js +57 -0
  302. package/dist/server/upload-sweep.d.ts +20 -0
  303. package/dist/server/upload-sweep.js +57 -0
  304. package/dist/storage/git.js +5 -8
  305. package/dist/storage/parse-cache.d.ts +22 -1
  306. package/dist/storage/parse-cache.js +44 -10
  307. package/dist/storage/repo-manager.d.ts +121 -10
  308. package/dist/storage/repo-manager.js +43 -5
  309. package/dist/types/pipeline.d.ts +9 -0
  310. package/hooks/antigravity/gitnexus-antigravity-hook.cjs +110 -10
  311. package/hooks/claude/gitnexus-hook.cjs +110 -13
  312. package/hooks/claude/hook-db-lock-probe.cjs +513 -26
  313. package/package.json +8 -2
  314. package/scripts/assert-publish-grammar-coverage.cjs +31 -0
  315. package/scripts/build-tree-sitter-grammars.cjs +16 -10
  316. package/scripts/cross-platform-tests.ts +1 -0
  317. package/skills/gitnexus-debugging.md +16 -4
  318. package/skills/gitnexus-exploring.md +3 -3
  319. package/skills/gitnexus-guide.md +33 -0
  320. package/skills/gitnexus-pdg-query.md +89 -0
  321. package/skills/gitnexus-refactoring.md +1 -1
  322. package/skills/gitnexus-taint-analysis.md +178 -0
  323. package/vendor/tree-sitter-c/package.json +1 -1
  324. package/vendor/tree-sitter-dart/package.json +1 -1
  325. package/vendor/tree-sitter-kotlin/package.json +1 -1
  326. package/vendor/tree-sitter-proto/package.json +1 -1
  327. package/vendor/tree-sitter-swift/package.json +1 -1
  328. package/web/assets/{agent-CKPMqImC.js → agent-D3Xd7zZE.js} +123 -123
  329. package/web/assets/architecture-7EHR7CIX-6QZW5X65-DxJw65fT.js +1 -0
  330. package/web/assets/architectureDiagram-UL44E2DR-ChH9xW-N.js +36 -0
  331. package/web/assets/{blockDiagram-7IZFK4PR-B4niSLvR.js → blockDiagram-7IZFK4PR-BkWhpzWB.js} +1 -1
  332. package/web/assets/{c4Diagram-Y2BXMSZH-DIzEXalR.js → c4Diagram-Y2BXMSZH-DtBvpzWD.js} +1 -1
  333. package/web/assets/{chunk-3SSMPTDK-BzGeeheI.js → chunk-3SSMPTDK-B4_etUhr.js} +2 -2
  334. package/web/assets/{chunk-5IMINLNL-CnTLsXIV.js → chunk-5IMINLNL-DOdTeQri.js} +1 -1
  335. package/web/assets/{chunk-5VCL7Z4A-w1BCx98Z.js → chunk-5VCL7Z4A-CQ-2dYWj.js} +1 -1
  336. package/web/assets/chunk-6764PJDD-DpIS7hxD.js +1 -0
  337. package/web/assets/{chunk-67TQ5CYL-CChC2cAv.js → chunk-67TQ5CYL-4sNPJU1q.js} +3 -3
  338. package/web/assets/{chunk-7W6UQGC5-CgFyfZ6k.js → chunk-7W6UQGC5-KyEG0HQg.js} +1 -1
  339. package/web/assets/{chunk-AZZRMDJM-5E9ARdDQ.js → chunk-AZZRMDJM-y-xJBuMz.js} +1 -1
  340. package/web/assets/{chunk-INKRHTLW-ELpfuk9h.js → chunk-INKRHTLW-Nu4ri9P-.js} +1 -1
  341. package/web/assets/{chunk-JQRUD6KW-Dcq_Qnyy.js → chunk-JQRUD6KW-Dbva2Z17.js} +1 -1
  342. package/web/assets/{chunk-KGFNY3KK-W-VR57xb.js → chunk-KGFNY3KK-JGMJvKCK.js} +1 -1
  343. package/web/assets/chunk-KGYTTC2M-CWC_c3H9.js +161 -0
  344. package/web/assets/{chunk-KNLZD3CH-BuZBOcso.js → chunk-KNLZD3CH-BGlP6X9R.js} +1 -1
  345. package/web/assets/{chunk-KRXBNO2N-DH2NPM7I.js → chunk-KRXBNO2N-BW5o0KUN.js} +1 -1
  346. package/web/assets/{chunk-LCXTWHL2-Dfmux4m1.js → chunk-LCXTWHL2-zoomRtWX.js} +1 -1
  347. package/web/assets/{chunk-LII3EMHJ-3X33tCpU.js → chunk-LII3EMHJ-D-jm-dLa.js} +1 -1
  348. package/web/assets/{chunk-QA3QBVWF-D5Ha3GgB.js → chunk-QA3QBVWF-BgRW3SXd.js} +1 -1
  349. package/web/assets/{chunk-RG4AUYOV-CAkzcoRj.js → chunk-RG4AUYOV-DD0B2N2B.js} +1 -1
  350. package/web/assets/{chunk-T2UQINTJ-kGYG7ppP.js → chunk-T2UQINTJ-DSBqkzH7.js} +1 -1
  351. package/web/assets/chunk-T5OCTHI4-DdZvN-9i.js +1 -0
  352. package/web/assets/{chunk-UY5QBCOK-Du-c56gs.js → chunk-UY5QBCOK-DyF0vyGd.js} +1 -1
  353. package/web/assets/{chunk-W44A43WB-lrCpuupA.js → chunk-W44A43WB-JqMLIpR0.js} +1 -1
  354. package/web/assets/{chunk-ZXARS5L4-CSZRiyOf.js → chunk-ZXARS5L4-CxN8oiwI.js} +1 -1
  355. package/web/assets/classDiagram-KGZ6W3CR-DJm9BgF-.js +1 -0
  356. package/web/assets/classDiagram-v2-72OJOZXJ-DJm9BgF-.js +1 -0
  357. package/web/assets/{context-builder-_HS0v2ma.js → context-builder-BHiFUA8O.js} +10 -2
  358. package/web/assets/{cose-bilkent-UX7MHV2Q-BHv2bbtl.js → cose-bilkent-UX7MHV2Q-D71wNYRJ.js} +1 -1
  359. package/web/assets/dagre-ND4H6XIP-BIkxmhcu.js +4 -0
  360. package/web/assets/diagram-3NCE3AQN-BTa6iH0T.js +43 -0
  361. package/web/assets/diagram-GF46GFSD-DZDV0vBj.js +24 -0
  362. package/web/assets/{diagram-HNR7UZ2L-fUWreZzx.js → diagram-HNR7UZ2L-DFCfd5LI.js} +2 -2
  363. package/web/assets/diagram-QXG6HAR7-BzM--Jj0.js +24 -0
  364. package/web/assets/diagram-WEQXMOUZ-DFFwz0k4.js +10 -0
  365. package/web/assets/{erDiagram-L5TCEMPS-QN2eEP1e.js → erDiagram-L5TCEMPS-CfHMJJqo.js} +1 -1
  366. package/web/assets/eventmodeling-FCH6USID-MREXMVOE-BQm9QzEa.js +1 -0
  367. package/web/assets/{flowDiagram-H6V6AXG4-CXbXImlN.js → flowDiagram-H6V6AXG4-Be805QiJ.js} +3 -3
  368. package/web/assets/{ganttDiagram-JCBTUEKG-BHQssTz6.js → ganttDiagram-JCBTUEKG-D3iL2Aet.js} +1 -1
  369. package/web/assets/gitGraph-WXDBUCRP-R675I2BI-Cr_Bm2Nb.js +1 -0
  370. package/web/assets/gitGraphDiagram-S2ZK5IYY-CPIDgxGm.js +106 -0
  371. package/web/assets/index-BvYev1UJ.js +635 -0
  372. package/web/assets/index-_lgn7hs5.css +2 -0
  373. package/web/assets/info-J43DQDTF-KCYPFFUO-Cs4p2oyk.js +1 -0
  374. package/web/assets/infoDiagram-3YFTVSEB-Y7BKSoke.js +2 -0
  375. package/web/assets/{ishikawaDiagram-BNXS4ZKH-6LKOvBfp.js → ishikawaDiagram-BNXS4ZKH-CT4SHFuI.js} +1 -1
  376. package/web/assets/{journeyDiagram-M6C3CM3L-DNPYCpvq.js → journeyDiagram-M6C3CM3L-CvArszLo.js} +1 -1
  377. package/web/assets/{kanban-definition-75IXJCU3-DgDi9oJT.js → kanban-definition-75IXJCU3-C6yDxr7N.js} +3 -3
  378. package/web/assets/{katex-K3KEBU37-CrVLz8l7.js → katex-K3KEBU37-CTc5BslQ.js} +1 -1
  379. package/web/assets/{mindmap-definition-2TDM6QVE-CwR5sBB-.js → mindmap-definition-2TDM6QVE-BOc2WEne.js} +1 -1
  380. package/web/assets/packet-YPE3B663-LP52Z2RK-CKCrztD2.js +1 -0
  381. package/web/assets/pie-LRSECV5Y-TCRJHUBD-BB7pHqoD.js +1 -0
  382. package/web/assets/{pieDiagram-CU6KROY3-By8g6f6B.js → pieDiagram-CU6KROY3-Cvc0f_Pd.js} +1 -1
  383. package/web/assets/{quadrantDiagram-VICAPDV7-bAm6Hi_5.js → quadrantDiagram-VICAPDV7-yXSZ2lLz.js} +1 -1
  384. package/web/assets/radar-GUYGQ44K-RDLRG3WG-DhoTOcuK.js +1 -0
  385. package/web/assets/{requirementDiagram-JXO7QTGE-7oDcJ1_J.js → requirementDiagram-JXO7QTGE-BRcZvHs4.js} +1 -1
  386. package/web/assets/{sankeyDiagram-URQDO5SZ-LFJz53u5.js → sankeyDiagram-URQDO5SZ-1qEjlFIB.js} +1 -1
  387. package/web/assets/{sequenceDiagram-VS2MUI6T-FySeKCUy.js → sequenceDiagram-VS2MUI6T-PcSCuvrB.js} +3 -3
  388. package/web/assets/stateDiagram-7D4R322I-D6qYSV1E.js +1 -0
  389. package/web/assets/stateDiagram-v2-36443NZ5-Bg-ImOSX.js +1 -0
  390. package/web/assets/{timeline-definition-O6YCAMPW-Ds2CnVZK.js → timeline-definition-O6YCAMPW-QWkh01xw.js} +1 -1
  391. package/web/assets/treeView-BLDUP644-QA4HXRO3-ODehyGKL.js +1 -0
  392. package/web/assets/treemap-LRROVOQU-LLAWBHMP-BfpgC-7o.js +1 -0
  393. package/web/assets/{vennDiagram-MWXL3ELB-DUIEwXWp.js → vennDiagram-MWXL3ELB-ak4DfwuM.js} +3 -3
  394. package/web/assets/wardley-L42UT6IY-5TKZOOLJ-CNeL6VHE.js +1 -0
  395. package/web/assets/{wardleyDiagram-CUQ6CDDI-DEiFPQih.js → wardleyDiagram-CUQ6CDDI-CTzR4Loq.js} +1 -1
  396. package/web/assets/{xychartDiagram-N2JHSOCM-BUbayhST.js → xychartDiagram-N2JHSOCM-DA1BEaQz.js} +1 -1
  397. package/web/index.html +13 -15
  398. package/scripts/materialize-vendor-grammars.cjs +0 -97
  399. package/web/assets/architecture-7EHR7CIX-6QZW5X65-BETj2x4g.js +0 -1
  400. package/web/assets/architectureDiagram-UL44E2DR-D1EXI0zA.js +0 -36
  401. package/web/assets/chunk-2T2R6R2M-n6s9JZqv.js +0 -4
  402. package/web/assets/chunk-2UTLFMKG-CMBB1TMN.js +0 -1
  403. package/web/assets/chunk-4R4BOZG6-mKhL59ul.js +0 -159
  404. package/web/assets/chunk-6764PJDD-ChwMM2z4.js +0 -1
  405. package/web/assets/chunk-7J6CGLKN-DT-b53FT.js +0 -10
  406. package/web/assets/chunk-C62D2QBJ-CDAWj26E.js +0 -1
  407. package/web/assets/chunk-CEXFNPSA-D68Tk6ls.js +0 -1
  408. package/web/assets/chunk-CilyBKbf.js +0 -1
  409. package/web/assets/chunk-J5EP6P6S-DxWW0yvu.js +0 -1
  410. package/web/assets/chunk-KGYTTC2M-C6PHeuay.js +0 -1
  411. package/web/assets/chunk-RERM46MO-DQNbXtfw.js +0 -1
  412. package/web/assets/chunk-RKZBBQEN-BmTPLSyv.js +0 -1
  413. package/web/assets/chunk-RLI5ZMPA-DExu2DOK.js +0 -1
  414. package/web/assets/chunk-T5OCTHI4--9wWpVws.js +0 -1
  415. package/web/assets/chunk-UP6H54XL-DsKdC6jC.js +0 -1
  416. package/web/assets/chunk-UXSXWOXI-DR81EqLr.js +0 -1
  417. package/web/assets/classDiagram-KGZ6W3CR-Bv93af_b.js +0 -1
  418. package/web/assets/classDiagram-v2-72OJOZXJ-CLfEqHUa.js +0 -1
  419. package/web/assets/dagre-ND4H6XIP-DsIr9MOv.js +0 -4
  420. package/web/assets/diagram-3NCE3AQN-BqAtKUpW.js +0 -43
  421. package/web/assets/diagram-GF46GFSD-CaBG6n6o.js +0 -24
  422. package/web/assets/diagram-QXG6HAR7-CZ-O3rcV.js +0 -24
  423. package/web/assets/diagram-WEQXMOUZ-P4lSL4GH.js +0 -10
  424. package/web/assets/eventmodeling-FCH6USID-MREXMVOE-B3myHUst.js +0 -1
  425. package/web/assets/gitGraph-WXDBUCRP-R675I2BI-DF3rtf4A.js +0 -1
  426. package/web/assets/gitGraphDiagram-S2ZK5IYY-CCwVLT__.js +0 -106
  427. package/web/assets/index-BKWA-m7o.css +0 -2
  428. package/web/assets/index-CG6q8eTs.js +0 -626
  429. package/web/assets/info-J43DQDTF-KCYPFFUO-R4XV_akJ.js +0 -1
  430. package/web/assets/infoDiagram-3YFTVSEB-DmLICZx1.js +0 -2
  431. package/web/assets/packet-YPE3B663-LP52Z2RK-CgQPdNZa.js +0 -1
  432. package/web/assets/pie-LRSECV5Y-TCRJHUBD-BzWOwc_c.js +0 -1
  433. package/web/assets/radar-GUYGQ44K-RDLRG3WG-B7KG0FN7.js +0 -1
  434. package/web/assets/stateDiagram-7D4R322I-CB2nABwH.js +0 -1
  435. package/web/assets/stateDiagram-v2-36443NZ5-COBGd2RL.js +0 -1
  436. package/web/assets/treeView-BLDUP644-QA4HXRO3-CRSxEwLO.js +0 -1
  437. package/web/assets/treemap-LRROVOQU-LLAWBHMP-a0PfKoVn.js +0 -1
  438. package/web/assets/wardley-L42UT6IY-5TKZOOLJ-BKQ6e5mC.js +0 -1
  439. /package/web/assets/{chunk-AQ6EADP3-CCFje6lL.js → chunk-AQ6EADP3-CZhslHi-.js} +0 -0
@@ -74,16 +74,18 @@ export interface RepoMeta {
74
74
  */
75
75
  fileHashes?: Record<string, string>;
76
76
  /**
77
- * Crash-recovery dirty flag. Written to meta.json BEFORE any
78
- * destructive DB mutation in an incremental run; cleared on success
79
- * by overwriting meta.json. If a run crashes between, the next run
80
- * sees the flag and forces a full rebuild the cheapest path back
81
- * to a known-good index.
77
+ * Crash-recovery dirty flag a generic marker written to meta.json
78
+ * BEFORE any destructive DB mutation by BOTH writeback branches
79
+ * (incremental since its introduction; full rebuilds over an existing
80
+ * meta since #2099 F1); cleared on success by overwriting meta.json.
81
+ * If a run crashes between, the next run sees the flag and forces a
82
+ * full rebuild — the cheapest path back to a known-good index.
82
83
  */
83
84
  incrementalInProgress?: {
84
- /** When the incremental run started (epoch ms). */
85
+ /** When the run started (epoch ms). */
85
86
  startedAt: number;
86
- /** Number of files in the writable set, for diagnostic logs. */
87
+ /** Number of files in the writable set, for diagnostic logs.
88
+ * `0` on the full-rebuild path (no incremental write set exists). */
87
89
  toWriteCount: number;
88
90
  };
89
91
  /**
@@ -103,11 +105,113 @@ export interface RepoMeta {
103
105
  * branch's still-live shards. Additive/optional; absent in legacy metas.
104
106
  */
105
107
  cacheKeys?: string[];
108
+ /**
109
+ * The effective `--pdg` configuration this index's DB rows were built
110
+ * under (#2099 F1). Presence ≡ the BasicBlock/CFG layer exists in the DB;
111
+ * ABSENT ≡ pdg-off — which covers every legacy meta, since `--pdg`
112
+ * shipped opt-in. Caps are recorded RESOLVED (defaults applied) so an
113
+ * explicit-default run compares equal to a default run. run-analyze
114
+ * compares this against the requested options and forces a full
115
+ * writeback on any mismatch — the incremental path only persists
116
+ * changed-file nodes and would otherwise silently drop (or strand) the
117
+ * CFG layer on a mode flip. Additive/optional, no
118
+ * INCREMENTAL_SCHEMA_VERSION bump (a bump would force a one-time full
119
+ * rebuild for every user). NOTE the removal mechanism is load-bearing:
120
+ * the end-of-run meta is a fresh object literal, NOT a spread of the
121
+ * prior meta, so omitting this field on a pdg-off run is what clears
122
+ * the stamp after an on→off flip.
123
+ */
124
+ pdg?: {
125
+ /** Worker-side per-function source-line cap, resolved (0 = unlimited). */
126
+ maxFunctionLines: number;
127
+ /** Emit-side per-function CFG edge cap, resolved (0 = unlimited). */
128
+ maxEdgesPerFunction: number;
129
+ /**
130
+ * Emit-side per-function REACHING_DEF edge cap, resolved (0 = unlimited;
131
+ * #2082 M2). ABSENT on an M1-era stamp — which is exactly what makes
132
+ * `pdgModeMismatch` trip on the first M2 run over an M1 index and force
133
+ * the full writeback that populates REACHING_DEF rows. Optional in the
134
+ * type for that reason; resolved (always present) on every M2+ write.
135
+ */
136
+ maxReachingDefEdgesPerFunction?: number;
137
+ /**
138
+ * Emit-side per-function CDG (control-dependence) edge cap, resolved
139
+ * (0 = unlimited; #2085 M5). ABSENT on any pre-M5 stamp — that absence is
140
+ * what trips `pdgModeMismatch` on the first CDG-aware run and forces the
141
+ * full writeback that materialises CDG edges. Optional for that upgrade
142
+ * reason; resolved (always present) on every M5+ write.
143
+ */
144
+ maxCdgEdgesPerFunction?: number;
145
+ /**
146
+ * Per-function taint findings cap, resolved (0 = unlimited; #2083 M3).
147
+ * ABSENT on an M1/M2-era stamp — like `maxReachingDefEdgesPerFunction`,
148
+ * that absence is what trips `pdgModeMismatch` on the first M3 run and
149
+ * forces the full writeback that populates TAINTED/SANITIZES rows.
150
+ */
151
+ maxTaintFindingsPerFunction?: number;
152
+ /** Per-finding taint hop cap, resolved (0 = unlimited; #2083 M3 KTD6 —
153
+ * bounds the persisted hop-encoded `reason`). Optional for the same
154
+ * M2-era-stamp upgrade reason as the findings cap. */
155
+ maxTaintHops?: number;
156
+ /**
157
+ * Per-run cross-function caps, resolved (0 = unlimited; #2084 M4 review
158
+ * P1-3). ABSENT on an M3-era stamp — that absence trips `pdgModeMismatch`
159
+ * on the first run that adds them and forces the full writeback that
160
+ * re-materialises TAINT_PATH within bounds. Optional for that upgrade
161
+ * reason; resolved (always present) on every post-fix write.
162
+ */
163
+ maxInterprocFindings?: number;
164
+ maxInterprocHops?: number;
165
+ maxInterprocEdges?: number;
166
+ /**
167
+ * Digest of the built-in taint model the persisted findings were
168
+ * produced under (#2083 M3 KTD7/R7). Any model-content change ships a
169
+ * new digest → mismatch → full writeback repopulates taint edges
170
+ * without `--force`. Optional: absent on pre-M3 stamps.
171
+ */
172
+ taintModelVersion?: string;
173
+ /**
174
+ * Identity of the reaching-definitions solver the persisted REACHING_DEF
175
+ * rows were produced under (#2201 review R3). The SSA-sparse rewrite computes
176
+ * FULL facts for deep-loop functions the old dense worklist truncated to
177
+ * empty (the blocks×64 ceiling no longer fires) — but an existing `--pdg`
178
+ * index built under the old solver carries those truncated rows. ABSENT on
179
+ * any pre-#2201 stamp, so that absence trips `pdgModeMismatch` on the first
180
+ * upgraded run and forces the full writeback that recomputes the now-fuller
181
+ * REACHING_DEF coverage without `--force`. Bump the tag on any future change
182
+ * that alters which facts the solver emits. Optional for that upgrade reason;
183
+ * resolved (always present) on every post-#2201 write.
184
+ */
185
+ reachingDefSolver?: string;
186
+ /**
187
+ * Whether this `--pdg` index recorded the FU-C `CALL_SUMMARY` return-value
188
+ * ascent layer (per-callee param→return summary edges). `true` on every
189
+ * FU-C+ (v4) write. ABSENT on any pre-FU-C (v3) `--pdg` stamp — that absence
190
+ * is what tells `impact`'s PDG mode the index predates CALL_SUMMARY, so it
191
+ * surfaces a "no return-value ascent (re-index for CALL_SUMMARY)" note while
192
+ * STILL serving the intra slice. CALL_SUMMARY is deliberately NOT a required
193
+ * sub-layer for `pdgLayerStatus` to report `'ready'`: a v3 index stays fully
194
+ * usable for the intra-procedural statement slice; only the ascent upgrade is
195
+ * unavailable. Optional for that back-compat reason.
196
+ */
197
+ hasCallSummary?: boolean;
198
+ };
106
199
  }
107
200
  /**
108
201
  * Bumped whenever incremental-indexing invariants change incompatibly.
109
- */
110
- export declare const INCREMENTAL_SCHEMA_VERSION = 1;
202
+ * v2: `BasicBlock.callees` column added (statement-precise inter-procedural
203
+ * reach substrate) an index built before this lacks the column, so a full
204
+ * re-analyze is required rather than an incremental top-up.
205
+ * v3: `BasicBlock.calleeIds` column added (sound resolved-callee-id parallel
206
+ * to `callees`, #2227) — same contract: an index built before this lacks the
207
+ * column, so a full re-analyze is forced rather than an incremental top-up.
208
+ * v4: `CALL_SUMMARY` relation type added (per-callee RETURN-VALUE ASCENT
209
+ * summary edges, PDG FU-C). A pre-v4 `--pdg` index has NO CALL_SUMMARY edges,
210
+ * so the engine would silently UNDER-REPORT return-value ascent on an
211
+ * incremental top-up; force a full re-analyze instead (same contract as v2/v3).
212
+ * This single bump covers the whole FU-C re-index window (and the later FU-B-2).
213
+ */
214
+ export declare const INCREMENTAL_SCHEMA_VERSION = 4;
111
215
  export interface IndexedRepo {
112
216
  repoPath: string;
113
217
  storagePath: string;
@@ -459,7 +563,14 @@ export declare const assertSafeStoragePath: (entry: RegistryEntry) => void;
459
563
  export declare const resolveRegistryEntry: (entries: RegistryEntry[], target: string) => RegistryEntry;
460
564
  /**
461
565
  * List all registered repos from the global registry.
462
- * Optionally validates that each entry's .gitnexus/ still exists.
566
+ *
567
+ * With `validate: true`, prunes only entries whose index is *provably* gone
568
+ * (fs.access on .gitnexus/meta.json fails with ENOENT or ENOTDIR) and persists
569
+ * the result. Entries that are merely "not provably absent" — any other
570
+ * fs.access failure (EIO/EAGAIN/EBUSY/EACCES, etc.) — are KEPT, so a transient
571
+ * I/O storm cannot wipe the registry. A kept entry is therefore "not confirmed
572
+ * present," not "confirmed present"; downstream DB opens are independently and
573
+ * lazily guarded.
463
574
  */
464
575
  export declare const listRegisteredRepos: (opts?: {
465
576
  validate?: boolean;
@@ -56,8 +56,19 @@ export const canonicalizePath = (p) => {
56
56
  };
57
57
  /**
58
58
  * Bumped whenever incremental-indexing invariants change incompatibly.
59
- */
60
- export const INCREMENTAL_SCHEMA_VERSION = 1;
59
+ * v2: `BasicBlock.callees` column added (statement-precise inter-procedural
60
+ * reach substrate) — an index built before this lacks the column, so a full
61
+ * re-analyze is required rather than an incremental top-up.
62
+ * v3: `BasicBlock.calleeIds` column added (sound resolved-callee-id parallel
63
+ * to `callees`, #2227) — same contract: an index built before this lacks the
64
+ * column, so a full re-analyze is forced rather than an incremental top-up.
65
+ * v4: `CALL_SUMMARY` relation type added (per-callee RETURN-VALUE ASCENT
66
+ * summary edges, PDG FU-C). A pre-v4 `--pdg` index has NO CALL_SUMMARY edges,
67
+ * so the engine would silently UNDER-REPORT return-value ascent on an
68
+ * incremental top-up; force a full re-analyze instead (same contract as v2/v3).
69
+ * This single bump covers the whole FU-C re-index window (and the later FU-B-2).
70
+ */
71
+ export const INCREMENTAL_SCHEMA_VERSION = 4;
61
72
  const GITNEXUS_DIR = '.gitnexus';
62
73
  const GITNEXUS_EXCLUDE_ENTRY = `${GITNEXUS_DIR}/`;
63
74
  // ─── Local Storage Helpers ─────────────────────────────────────────────
@@ -862,7 +873,14 @@ export const resolveRegistryEntry = (entries, target) => {
862
873
  };
863
874
  /**
864
875
  * List all registered repos from the global registry.
865
- * Optionally validates that each entry's .gitnexus/ still exists.
876
+ *
877
+ * With `validate: true`, prunes only entries whose index is *provably* gone
878
+ * (fs.access on .gitnexus/meta.json fails with ENOENT or ENOTDIR) and persists
879
+ * the result. Entries that are merely "not provably absent" — any other
880
+ * fs.access failure (EIO/EAGAIN/EBUSY/EACCES, etc.) — are KEPT, so a transient
881
+ * I/O storm cannot wipe the registry. A kept entry is therefore "not confirmed
882
+ * present," not "confirmed present"; downstream DB opens are independently and
883
+ * lazily guarded.
866
884
  */
867
885
  export const listRegisteredRepos = async (opts) => {
868
886
  const entries = await readRegistry();
@@ -875,8 +893,28 @@ export const listRegisteredRepos = async (opts) => {
875
893
  await fs.access(path.join(entry.storagePath, 'meta.json'));
876
894
  valid.push(entry);
877
895
  }
878
- catch {
879
- // Index no longer exists skip
896
+ catch (err) {
897
+ // Prune ONLY when the index is provably gone: ENOENT (file absent) or
898
+ // ENOTDIR (a path component is no longer a directory). Every other
899
+ // fs.access failure keeps the entry, because the file may well still
900
+ // exist and we must not wipe the registry on a transient I/O storm
901
+ // (EIO/EAGAIN/EBUSY under swap pressure, NFS hiccups, etc.).
902
+ //
903
+ // Note: some kept codes are NOT necessarily transient — EACCES, for
904
+ // example, can be permanent (a chmod'd directory). Keeping is still the
905
+ // correct conservative choice: a stale-but-kept entry is harmless (DB
906
+ // opens are lazily guarded) and removable via `gitnexus remove`, whereas
907
+ // an over-eager prune destroys data. When in doubt, keep.
908
+ if (err?.code === 'ENOENT' || err?.code === 'ENOTDIR') {
909
+ // Index genuinely removed — safe to prune
910
+ }
911
+ else {
912
+ // Not provably absent — keep entry to prevent mass registry wipe.
913
+ // Warn so an I/O storm becomes observable instead of silently
914
+ // keeping (or, pre-fix, silently wiping) entries.
915
+ logger.warn({ name: entry.name, storagePath: entry.storagePath, code: err?.code }, 'Keeping registry entry despite fs.access failure (not provably absent); not pruning to avoid mass registry wipe.');
916
+ valid.push(entry);
917
+ }
880
918
  }
881
919
  }
882
920
  // If we pruned any entries, save the cleaned registry
@@ -2,6 +2,7 @@ import type { KnowledgeGraph } from '../core/graph/types.js';
2
2
  import { CommunityDetectionResult } from '../core/ingestion/community-processor.js';
3
3
  import { ProcessDetectionResult } from '../core/ingestion/process-processor.js';
4
4
  import type { ResolutionOutcome } from '../core/ingestion/scope-resolution/resolution-outcome.js';
5
+ import type { PdgEmitManifest } from '../core/lbug/pdg-emit-sink.js';
5
6
  export interface PipelineResult {
6
7
  graph: KnowledgeGraph;
7
8
  /** Absolute path to the repo root — used for lazy file reads during LadybugDB loading */
@@ -25,4 +26,12 @@ export interface PipelineResult {
25
26
  * affordance so regression suites can prove the pool engaged.
26
27
  */
27
28
  usedWorkerPool: boolean;
29
+ /**
30
+ * Streamed PDG-emit COPY manifest (#2202). Present only when streaming/chunked
31
+ * PDG emit was active (full rebuild + `--pdg` + enabled): the BasicBlock node
32
+ * CSV + per-pair PDG-edge CSVs flushed to disk during the emit loop, for
33
+ * `loadGraphToLbug` to COPY alongside the structural CSVs. Absent ⇒ the PDG
34
+ * layer (if any) is resident in `graph` and persists via the whole-graph emit.
35
+ */
36
+ pdgEmitManifest?: PdgEmitManifest;
28
37
  }
@@ -24,7 +24,10 @@ const fs = require('fs');
24
24
  const path = require('path');
25
25
  const { spawnSync } = require('child_process');
26
26
  const { acquireHookSlot } = require('./hook-lock.cjs');
27
- const { hasGitNexusDbLockedByGitNexusServer } = require('./hook-db-lock-probe.cjs');
27
+ const {
28
+ hasGitNexusDbLockedByGitNexusServer,
29
+ resolveUnixGuardTimeout,
30
+ } = require('./hook-db-lock-probe.cjs');
28
31
  const { formatAnalyzeCommand } = require('./resolve-analyze-cmd.cjs');
29
32
 
30
33
  function readInput() {
@@ -198,10 +201,73 @@ function resolveCliPath() {
198
201
  return cliPath;
199
202
  }
200
203
 
204
+ // Debounce for the unguarded-CLI diagnostic below (#2163 follow-up review):
205
+ // at most one line per (short-lived) hook process, even if a future change
206
+ // runs the CLI more than once.
207
+ let unguardedCliWarned = false;
208
+
209
+ /**
210
+ * Unix orphan containment (#2163 follow-up): the augment CLI is the
211
+ * longest-lived hook child (inner spawnSync timeout 7s locally, 12s via
212
+ * npx), so on Unix it gets the same SIGKILL-surviving coreutils `timeout`
213
+ * wrapper as the probe's lsof/ps. The wrapper budget is ceil(inner/1000)+1
214
+ * seconds — STRICTLY greater than the inner spawnSync timeout, so on the
215
+ * supervised path Node's SIGTERM always fires first and the existing
216
+ * error/status contract is untouched. Once the hook itself has been
217
+ * SIGKILLed (exactly the orphan case the wrapper exists for), the guard
218
+ * semantics differ per branch:
219
+ * - direct exec (the CLI is the guard's CHILD): `-k 1` TERM-first — a
220
+ * SIGTERM-immune CLI can hold the guard ~1s past the inner timeout
221
+ * before the `-k` SIGKILL escalation reaps it.
222
+ * - npx (the CLI is a GRANDCHILD: guard → npx → CLI): `-s KILL` — the
223
+ * budget expiry SIGKILLs the whole process group outright. TERM-first
224
+ * would kill only the obedient npx parent, making `timeout` reap it and
225
+ * return before the `-k` escalation ever fires, stranding a
226
+ * SIGTERM-immune CLI grandchild unbounded (reproduced on coreutils
227
+ * 9.x). `-k 1` is retained alongside `-s KILL` as a harmless belt: with
228
+ * `-s KILL` the `-k` escalation signal is also KILL. Two residual gaps
229
+ * on this branch, both bounded by "no worse than pre-fix" (where the
230
+ * grandchild received no signal at all): the group-wide SIGKILL is
231
+ * coreutils semantics — a busybox `timeout` passes the self-test (it
232
+ * has `-k` and propagates exit status) but signals only its direct
233
+ * child, so a busybox guard cannot reach the grandchild; and on the
234
+ * SUPERVISED path (hook alive, inner spawnSync timeout SIGTERMs the
235
+ * guard) coreutils forwards TERM rather than the `-s` signal, npx dies,
236
+ * and the guard exits before any KILL fires — so a SIGTERM-immune CLI
237
+ * grandchild still escapes in those two cases.
238
+ * If the sibling probe predates the resolveUnixGuardTimeout export (version
239
+ * skew), the adapter degrades to the unwrapped invocation instead of
240
+ * throwing. Windows is deliberately NOT wrapped — there is no coreutils
241
+ * timeout to resolve there and the resolver's self-test spawns /bin/sh — so
242
+ * on win32 (the npx.cmd path) and whenever the guard resolves to null (e.g.
243
+ * macOS without Homebrew coreutils — reported once under GITNEXUS_DEBUG)
244
+ * the argv stays byte-identical to the pre-wrap invocation.
245
+ */
201
246
  function runGitNexusCli(cliPath, args, cwd, timeout) {
202
247
  const isWin = process.platform === 'win32';
248
+ // Version-skew guard (#2163 follow-up review): an older sibling probe
249
+ // without the resolveUnixGuardTimeout export must degrade to the unwrapped
250
+ // invocation — a TypeError here would be swallowed by the caller's catch
251
+ // and silently kill the augment.
252
+ const guard =
253
+ isWin || typeof resolveUnixGuardTimeout !== 'function' ? null : resolveUnixGuardTimeout();
254
+ if (!isWin && !guard && !unguardedCliWarned && isDebugEnabled()) {
255
+ // Diagnose the "stays unwrapped" Unix paths once per hook process: no
256
+ // usable coreutils timeout/gtimeout (e.g. macOS without Homebrew
257
+ // coreutils), GITNEXUS_HOOK_TIMEOUT_PATH=disabled, or probe skew above.
258
+ unguardedCliWarned = true;
259
+ process.stderr.write(
260
+ '[GitNexus hook] no usable timeout/gtimeout guard; augment CLI child runs unguarded\n',
261
+ );
262
+ }
203
263
  if (cliPath) {
204
- return spawnSync(process.execPath, [cliPath, ...args], {
264
+ const [cmd, cmdArgs] = guard
265
+ ? [
266
+ guard,
267
+ ['-k', '1', String(Math.ceil(timeout / 1000) + 1), process.execPath, cliPath, ...args],
268
+ ]
269
+ : [process.execPath, [cliPath, ...args]];
270
+ return spawnSync(cmd, cmdArgs, {
205
271
  encoding: 'utf-8',
206
272
  timeout,
207
273
  cwd,
@@ -209,7 +275,27 @@ function runGitNexusCli(cliPath, args, cwd, timeout) {
209
275
  windowsHide: true,
210
276
  });
211
277
  }
212
- return spawnSync(isWin ? 'npx.cmd' : 'npx', ['-y', 'gitnexus', ...args], {
278
+ // A non-null guard implies non-Windows, so the wrapped arm can hardcode
279
+ // plain `npx`. The wrapped arm leads with `-s KILL` (NOT TERM-first like
280
+ // the direct branch above): the CLI here is a grandchild behind npx — see
281
+ // the docblock.
282
+ const [cmd, cmdArgs] = guard
283
+ ? [
284
+ guard,
285
+ [
286
+ '-s',
287
+ 'KILL',
288
+ '-k',
289
+ '1',
290
+ String(Math.ceil((timeout + 5000) / 1000) + 1),
291
+ 'npx',
292
+ '-y',
293
+ 'gitnexus',
294
+ ...args,
295
+ ],
296
+ ]
297
+ : [isWin ? 'npx.cmd' : 'npx', ['-y', 'gitnexus', ...args]];
298
+ return spawnSync(cmd, cmdArgs, {
213
299
  encoding: 'utf-8',
214
300
  timeout: timeout + 5000,
215
301
  cwd,
@@ -284,18 +370,32 @@ function buildAfterToolContext(input) {
284
370
  }
285
371
 
286
372
  function runAugment(gitNexusDir, cwd, pattern) {
287
- if (hasGitNexusServerOwner(gitNexusDir)) {
288
- // Normal skip path: the MCP server owns the DB. Stay silent for strict
289
- // hook runners (issue #1913); surface the reason only under GITNEXUS_DEBUG.
373
+ // Acquire the per-repo slot BEFORE the DB-owner probe (#2163): the probe
374
+ // itself spawns lsof/ps, so it must be bounded by the same ≤3-per-repo cap
375
+ // as the augment, or concurrent sessions fan out unbounded probe
376
+ // subprocesses. The cheap guards (extractPattern, gitNexusDir lookup) run in
377
+ // buildAfterToolContext before this — moving the acquire any earlier would
378
+ // churn slot files on tool calls that never probe.
379
+ const release = acquireHookSlot(gitNexusDir);
380
+ if (!release) {
381
+ // Normal skip path: all per-repo hook slots are held by concurrent
382
+ // sessions. Stay silent for strict hook runners (issue #1913); surface
383
+ // the reason only under GITNEXUS_DEBUG.
290
384
  if (isDebugEnabled()) {
291
- process.stderr.write('[GitNexus] augment skipped: MCP server owns DB\n');
385
+ process.stderr.write('[GitNexus] augment skipped: hook slots saturated\n');
292
386
  }
293
387
  return '';
294
388
  }
295
- const release = acquireHookSlot(gitNexusDir);
296
- if (!release) return '';
297
- const cliPath = resolveCliPath();
298
389
  try {
390
+ if (hasGitNexusServerOwner(gitNexusDir)) {
391
+ // Normal skip path: the MCP server owns the DB. Stay silent for strict
392
+ // hook runners (issue #1913); surface the reason only under GITNEXUS_DEBUG.
393
+ if (isDebugEnabled()) {
394
+ process.stderr.write('[GitNexus] augment skipped: MCP server owns DB\n');
395
+ }
396
+ return '';
397
+ }
398
+ const cliPath = resolveCliPath();
299
399
  const child = runGitNexusCli(cliPath, ['augment', '--', pattern], cwd, 7000);
300
400
  if (!child.error && child.status === 0) {
301
401
  return extractAugmentContext(child.stderr || '');
@@ -15,7 +15,10 @@ const fs = require('fs');
15
15
  const path = require('path');
16
16
  const { spawnSync } = require('child_process');
17
17
  const { acquireHookSlot } = require('./hook-lock.cjs');
18
- const { hasGitNexusDbLockedByGitNexusServer } = require('./hook-db-lock-probe.cjs');
18
+ const {
19
+ hasGitNexusDbLockedByGitNexusServer,
20
+ resolveUnixGuardTimeout,
21
+ } = require('./hook-db-lock-probe.cjs');
19
22
  const { formatAnalyzeCommand } = require('./resolve-analyze-cmd.cjs');
20
23
 
21
24
  /**
@@ -218,14 +221,76 @@ function resolveCliPath() {
218
221
  return cliPath;
219
222
  }
220
223
 
224
+ // Debounce for the unguarded-CLI diagnostic below (#2163 follow-up review):
225
+ // at most one line per (short-lived) hook process, even if a future change
226
+ // runs the CLI more than once.
227
+ let unguardedCliWarned = false;
228
+
221
229
  /**
222
230
  * Spawn a gitnexus CLI command synchronously.
223
231
  * Returns the stderr output (KuzuDB captures stdout at OS level).
232
+ *
233
+ * Unix orphan containment (#2163 follow-up): the augment CLI is the
234
+ * longest-lived hook child (inner spawnSync timeout 7s locally, 12s via
235
+ * npx), so on Unix it gets the same SIGKILL-surviving coreutils `timeout`
236
+ * wrapper as the probe's lsof/ps. The wrapper budget is ceil(inner/1000)+1
237
+ * seconds — STRICTLY greater than the inner spawnSync timeout, so on the
238
+ * supervised path Node's SIGTERM always fires first and the existing
239
+ * error/status contract is untouched. Once the hook itself has been
240
+ * SIGKILLed (exactly the orphan case the wrapper exists for), the guard
241
+ * semantics differ per branch:
242
+ * - direct exec (the CLI is the guard's CHILD): `-k 1` TERM-first — a
243
+ * SIGTERM-immune CLI can hold the guard ~1s past the inner timeout
244
+ * before the `-k` SIGKILL escalation reaps it.
245
+ * - npx (the CLI is a GRANDCHILD: guard → npx → CLI): `-s KILL` — the
246
+ * budget expiry SIGKILLs the whole process group outright. TERM-first
247
+ * would kill only the obedient npx parent, making `timeout` reap it and
248
+ * return before the `-k` escalation ever fires, stranding a
249
+ * SIGTERM-immune CLI grandchild unbounded (reproduced on coreutils
250
+ * 9.x). `-k 1` is retained alongside `-s KILL` as a harmless belt: with
251
+ * `-s KILL` the `-k` escalation signal is also KILL. Two residual gaps
252
+ * on this branch, both bounded by "no worse than pre-fix" (where the
253
+ * grandchild received no signal at all): the group-wide SIGKILL is
254
+ * coreutils semantics — a busybox `timeout` passes the self-test (it
255
+ * has `-k` and propagates exit status) but signals only its direct
256
+ * child, so a busybox guard cannot reach the grandchild; and on the
257
+ * SUPERVISED path (hook alive, inner spawnSync timeout SIGTERMs the
258
+ * guard) coreutils forwards TERM rather than the `-s` signal, npx dies,
259
+ * and the guard exits before any KILL fires — so a SIGTERM-immune CLI
260
+ * grandchild still escapes in those two cases.
261
+ * If the sibling probe predates the resolveUnixGuardTimeout export (version
262
+ * skew), the adapter degrades to the unwrapped invocation instead of
263
+ * throwing. Windows is deliberately NOT wrapped — there is no coreutils
264
+ * timeout to resolve there and the resolver's self-test spawns /bin/sh — so
265
+ * on win32 (the npx.cmd path) and whenever the guard resolves to null (e.g.
266
+ * macOS without Homebrew coreutils — reported once under GITNEXUS_DEBUG)
267
+ * the argv stays byte-identical to the pre-wrap invocation.
224
268
  */
225
269
  function runGitNexusCli(cliPath, args, cwd, timeout) {
226
270
  const isWin = process.platform === 'win32';
271
+ // Version-skew guard (#2163 follow-up review): an older sibling probe
272
+ // without the resolveUnixGuardTimeout export must degrade to the unwrapped
273
+ // invocation — a TypeError here would be swallowed by the caller's catch
274
+ // and silently kill the augment.
275
+ const guard =
276
+ isWin || typeof resolveUnixGuardTimeout !== 'function' ? null : resolveUnixGuardTimeout();
277
+ if (!isWin && !guard && !unguardedCliWarned && isDebugEnabled()) {
278
+ // Diagnose the "stays unwrapped" Unix paths once per hook process: no
279
+ // usable coreutils timeout/gtimeout (e.g. macOS without Homebrew
280
+ // coreutils), GITNEXUS_HOOK_TIMEOUT_PATH=disabled, or probe skew above.
281
+ unguardedCliWarned = true;
282
+ process.stderr.write(
283
+ '[GitNexus hook] no usable timeout/gtimeout guard; augment CLI child runs unguarded\n',
284
+ );
285
+ }
227
286
  if (cliPath) {
228
- return spawnSync(process.execPath, [cliPath, ...args], {
287
+ const [cmd, cmdArgs] = guard
288
+ ? [
289
+ guard,
290
+ ['-k', '1', String(Math.ceil(timeout / 1000) + 1), process.execPath, cliPath, ...args],
291
+ ]
292
+ : [process.execPath, [cliPath, ...args]];
293
+ return spawnSync(cmd, cmdArgs, {
229
294
  encoding: 'utf-8',
230
295
  timeout,
231
296
  cwd,
@@ -233,8 +298,27 @@ function runGitNexusCli(cliPath, args, cwd, timeout) {
233
298
  windowsHide: true,
234
299
  });
235
300
  }
236
- // On Windows, invoke npx.cmd directly (no shell needed)
237
- return spawnSync(isWin ? 'npx.cmd' : 'npx', ['-y', 'gitnexus', ...args], {
301
+ // On Windows, invoke npx.cmd directly (no shell needed). A non-null guard
302
+ // implies non-Windows, so the wrapped arm can hardcode plain `npx`. The
303
+ // wrapped arm leads with `-s KILL` (NOT TERM-first like the direct branch
304
+ // above): the CLI here is a grandchild behind npx — see the docblock.
305
+ const [cmd, cmdArgs] = guard
306
+ ? [
307
+ guard,
308
+ [
309
+ '-s',
310
+ 'KILL',
311
+ '-k',
312
+ '1',
313
+ String(Math.ceil((timeout + 5000) / 1000) + 1),
314
+ 'npx',
315
+ '-y',
316
+ 'gitnexus',
317
+ ...args,
318
+ ],
319
+ ]
320
+ : [isWin ? 'npx.cmd' : 'npx', ['-y', 'gitnexus', ...args]];
321
+ return spawnSync(cmd, cmdArgs, {
238
322
  encoding: 'utf-8',
239
323
  timeout: timeout + 5000,
240
324
  cwd,
@@ -259,22 +343,35 @@ function handlePreToolUse(input) {
259
343
 
260
344
  const pattern = extractPattern(toolName, toolInput);
261
345
  if (!pattern || pattern.length < 3) return;
262
- if (hasGitNexusServerOwner(gitNexusDir)) {
263
- // Normal skip path: the MCP server owns the DB, so the CLI augment would
264
- // contend on the lock. Stay silent for strict hook runners (issue #1913);
265
- // surface the reason only when diagnostics are explicitly requested.
346
+
347
+ // Acquire the per-repo slot BEFORE the DB-owner probe (#2163): the probe
348
+ // itself spawns lsof/ps, so it must be bounded by the same ≤3-per-repo cap
349
+ // as the augment, or concurrent sessions fan out unbounded probe
350
+ // subprocesses. Keep the acquire right after the cheap guards above —
351
+ // moving it earlier would churn slot files on tool calls that never probe.
352
+ const release = acquireHookSlot(gitNexusDir);
353
+ if (!release) {
354
+ // Normal skip path: all per-repo hook slots are held by concurrent
355
+ // sessions. Stay silent for strict hook runners (issue #1913); surface
356
+ // the reason only when diagnostics are explicitly requested.
266
357
  if (isDebugEnabled()) {
267
- process.stderr.write('[GitNexus] augment skipped: MCP server owns DB\n');
358
+ process.stderr.write('[GitNexus] augment skipped: hook slots saturated\n');
268
359
  }
269
360
  return;
270
361
  }
271
362
 
272
- const release = acquireHookSlot(gitNexusDir);
273
- if (!release) return;
274
-
275
- const cliPath = resolveCliPath();
276
363
  let result = '';
277
364
  try {
365
+ if (hasGitNexusServerOwner(gitNexusDir)) {
366
+ // Normal skip path: the MCP server owns the DB, so the CLI augment would
367
+ // contend on the lock. Stay silent for strict hook runners (issue #1913);
368
+ // surface the reason only when diagnostics are explicitly requested.
369
+ if (isDebugEnabled()) {
370
+ process.stderr.write('[GitNexus] augment skipped: MCP server owns DB\n');
371
+ }
372
+ return;
373
+ }
374
+ const cliPath = resolveCliPath();
278
375
  const child = runGitNexusCli(cliPath, ['augment', '--', pattern], cwd, 7000);
279
376
  if (!child.error && child.status === 0) {
280
377
  result = extractAugmentContext(child.stderr || '');