@backbencher/brain 0.0.0-stage → 0.1.0

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 (319) hide show
  1. package/CHANGELOG.md +298 -0
  2. package/EMBEDDINGS.md +355 -0
  3. package/LICENSE +21 -0
  4. package/README.md +415 -2
  5. package/bin/bb +13 -0
  6. package/dist/analysis-exclusions-7ZJDXOVZ.js +35 -0
  7. package/dist/brain-index-health-KY7K552E.js +17 -0
  8. package/dist/brain-relationship-enrichment-QH7OOHUF.js +558 -0
  9. package/dist/brain.sql-EIM4WS4D.js +29 -0
  10. package/dist/chunk-2BSKD7O3.js +40 -0
  11. package/dist/chunk-2DE27DVC.js +1314 -0
  12. package/dist/chunk-2RRBMNBQ.js +322 -0
  13. package/dist/chunk-2RTN2DFU.js +711 -0
  14. package/dist/chunk-2WXYNLBA.js +29 -0
  15. package/dist/chunk-3CTFIJJB.js +17 -0
  16. package/dist/chunk-3LFTSMIV.js +174 -0
  17. package/dist/chunk-47HKX4AJ.js +930 -0
  18. package/dist/chunk-4H22TLOT.js +543 -0
  19. package/dist/chunk-5SD45FLC.js +818 -0
  20. package/dist/chunk-66A5ZFYA.js +1758 -0
  21. package/dist/chunk-6AIRWAO2.js +247 -0
  22. package/dist/chunk-6WNGD3NN.js +196 -0
  23. package/dist/chunk-7AN7U5IZ.js +371 -0
  24. package/dist/chunk-BHB7BYYI.js +626 -0
  25. package/dist/chunk-BQ3OVQ3P.js +125 -0
  26. package/dist/chunk-CW4XXSNN.js +1479 -0
  27. package/dist/chunk-D2Q4Y47A.js +53 -0
  28. package/dist/chunk-DIYAGQJL.js +34 -0
  29. package/dist/chunk-DYM4FQEE.js +90 -0
  30. package/dist/chunk-EWMWK7WN.js +75 -0
  31. package/dist/chunk-FVVQTSIM.js +3427 -0
  32. package/dist/chunk-FWSL4VG6.js +1290 -0
  33. package/dist/chunk-GBI7V7KY.js +69 -0
  34. package/dist/chunk-GEFFO6O2.js +152 -0
  35. package/dist/chunk-HOWAQXJO.js +236 -0
  36. package/dist/chunk-HQSPJDHI.js +613 -0
  37. package/dist/chunk-IFZNR5UJ.js +2863 -0
  38. package/dist/chunk-J4PMBXQQ.js +336 -0
  39. package/dist/chunk-KAET47ZL.js +125 -0
  40. package/dist/chunk-KCDECRJY.js +440 -0
  41. package/dist/chunk-KLK3PBTO.js +1119 -0
  42. package/dist/chunk-L5TDYKYK.js +76 -0
  43. package/dist/chunk-MLKGABMK.js +9 -0
  44. package/dist/chunk-OWISBAOF.js +61 -0
  45. package/dist/chunk-PJTNGD3Z.js +6924 -0
  46. package/dist/chunk-QLK6ED4Q.js +235 -0
  47. package/dist/chunk-R2GW4F6R.js +19 -0
  48. package/dist/chunk-RCMTFSEF.js +87 -0
  49. package/dist/chunk-RH7KC5HU.js +12050 -0
  50. package/dist/chunk-RM3PY6TG.js +376 -0
  51. package/dist/chunk-ROMM6KMC.js +433 -0
  52. package/dist/chunk-SK6YVHFZ.js +211 -0
  53. package/dist/chunk-SM7RFQRO.js +214 -0
  54. package/dist/chunk-UFE77L67.js +782 -0
  55. package/dist/chunk-UGR4QIGS.js +67 -0
  56. package/dist/chunk-UUNHHX4M.js +13 -0
  57. package/dist/chunk-V44PGPA6.js +2104 -0
  58. package/dist/chunk-VL52PL2T.js +71 -0
  59. package/dist/chunk-VURYFIHW.js +201 -0
  60. package/dist/chunk-XJKJYIPP.js +7436 -0
  61. package/dist/chunk-YI6FF2ZR.js +340 -0
  62. package/dist/cli/index.js +37 -0
  63. package/dist/config-HZAAYDP3.js +10 -0
  64. package/dist/content-search-642F7E5V.js +593 -0
  65. package/dist/database-TCTZDLE5.js +9 -0
  66. package/dist/doctor-GXCKSJOX.js +395 -0
  67. package/dist/edit-engine-KM7MPFEC.js +51 -0
  68. package/dist/engine-42TZFNIZ.js +11 -0
  69. package/dist/engine-LO6L4JLQ.js +18 -0
  70. package/dist/fingerprint-XDXFRWO6.js +33 -0
  71. package/dist/framework-intelligence-DWFCKV44.js +860 -0
  72. package/dist/freshness-3K6VU5OT.js +174 -0
  73. package/dist/graph-engine-PL5YA7BA.js +21 -0
  74. package/dist/graph_request-MM4REP6H.js +350 -0
  75. package/dist/impact_request-WDE47IZ5.js +68 -0
  76. package/dist/index-space-IUUN5WYV.js +15 -0
  77. package/dist/index-status-6BD7UBHR.js +34 -0
  78. package/dist/index.js +159 -0
  79. package/dist/instance-FO6QZRLH.js +19 -0
  80. package/dist/language-detection-DFCAU5DZ.js +11 -0
  81. package/dist/lsp/server.js +4301 -0
  82. package/dist/mcp/server.js +132 -0
  83. package/dist/onboard-DIQZV2NW.js +161 -0
  84. package/dist/override-companion-pass-XR7MHTP7.js +117 -0
  85. package/dist/parallel-indexer-4PW3AFXP.js +88 -0
  86. package/dist/pool-worker.js +1153 -0
  87. package/dist/project-health-ZS5TS2Z6.js +94 -0
  88. package/dist/project-index-5SDPHITE.js +57 -0
  89. package/dist/project-registry-DGZBIZS7.js +355 -0
  90. package/dist/real-bash-analyzer-SXSV67E2.js +2201 -0
  91. package/dist/real-c-analyzer-SY7FTZ6W.js +5942 -0
  92. package/dist/real-clean-analyzer-IGDHHLZK.js +3470 -0
  93. package/dist/real-clojure-analyzer-4OH7IWLB.js +2818 -0
  94. package/dist/real-cpp-analyzer-7LTDRJRJ.js +4101 -0
  95. package/dist/real-csharp-analyzer-KICU3TLH.js +3298 -0
  96. package/dist/real-css-analyzer-HPU277Q6.js +15 -0
  97. package/dist/real-dart-analyzer-7LZ5LCMW.js +3944 -0
  98. package/dist/real-elixir-analyzer-BE3MEVZO.js +2192 -0
  99. package/dist/real-erlang-analyzer-BZMAKYBK.js +1731 -0
  100. package/dist/real-fsharp-analyzer-5QLTOV3E.js +2390 -0
  101. package/dist/real-go-analyzer-POD7MZQR.js +4126 -0
  102. package/dist/real-graphql-analyzer-MAQRZ6QW.js +1442 -0
  103. package/dist/real-groovy-analyzer-MEWSUPMJ.js +2285 -0
  104. package/dist/real-haskell-analyzer-I5L2GR3Y.js +2533 -0
  105. package/dist/real-hcl-analyzer-DBOPXSWJ.js +725 -0
  106. package/dist/real-html-analyzer-O63XZLZD.js +1759 -0
  107. package/dist/real-java-analyzer-CHCW3EKA.js +4677 -0
  108. package/dist/real-javascript-analyzer-QAAJQYZE.js +14 -0
  109. package/dist/real-json-analyzer-UGBR7YQN.js +1640 -0
  110. package/dist/real-julia-analyzer-35Q4GHOZ.js +2085 -0
  111. package/dist/real-kotlin-analyzer-GRAYCWW2.js +3956 -0
  112. package/dist/real-lua-analyzer-5BAPDZDF.js +1957 -0
  113. package/dist/real-makefile-analyzer-YJKAHNAS.js +920 -0
  114. package/dist/real-markdown-analyzer-UKUQZO4F.js +1215 -0
  115. package/dist/real-matlab-analyzer-FVIKQZKG.js +480 -0
  116. package/dist/real-nim-analyzer-M7FAIABG.js +3603 -0
  117. package/dist/real-objective-c-analyzer-XMYQIGQI.js +1518 -0
  118. package/dist/real-perl-analyzer-ZLY6M2DZ.js +1865 -0
  119. package/dist/real-php-analyzer-KI2ZAM7X.js +9368 -0
  120. package/dist/real-powershell-analyzer-B3T5ZP6U.js +2915 -0
  121. package/dist/real-protobuf-analyzer-23OZ75XV.js +867 -0
  122. package/dist/real-python-analyzer-I4TIUB6D.js +4880 -0
  123. package/dist/real-r-analyzer-FJZJXXS6.js +2596 -0
  124. package/dist/real-ruby-analyzer-M3UFIVTQ.js +2429 -0
  125. package/dist/real-rust-analyzer-LVSONPAN.js +3359 -0
  126. package/dist/real-scala-analyzer-CWPI33Q2.js +3293 -0
  127. package/dist/real-scss-analyzer-TGRJQ7TH.js +1515 -0
  128. package/dist/real-solidity-analyzer-4P2VBVWA.js +2608 -0
  129. package/dist/real-sql-analyzer-J7DYZOZR.js +3840 -0
  130. package/dist/real-svelte-analyzer-NHEN2SX5.js +2532 -0
  131. package/dist/real-swift-analyzer-2NSYULWI.js +2311 -0
  132. package/dist/real-toml-analyzer-L3C66L7Q.js +929 -0
  133. package/dist/real-typescript-analyzer-FTC6ETRQ.js +14 -0
  134. package/dist/real-vb-analyzer-ORY7LAQS.js +3145 -0
  135. package/dist/real-vba-analyzer-JH2TTUFI.js +466 -0
  136. package/dist/real-vue-analyzer-OO4FUGBV.js +2680 -0
  137. package/dist/real-xml-analyzer-6CQVR477.js +2405 -0
  138. package/dist/real-yaml-analyzer-J6MQG3YX.js +3528 -0
  139. package/dist/real-zig-analyzer-EFKCPJNU.js +2430 -0
  140. package/dist/regex-search-OPTLKUN5.js +239 -0
  141. package/dist/rules-I453JTRC.js +152 -0
  142. package/dist/scoped-path-MJYWJZQX.js +11 -0
  143. package/dist/setup-show-Y5GB5KXA.js +15 -0
  144. package/dist/setup-wizard-G5YYR5T6.js +24 -0
  145. package/dist/symbol-search-KB4MU4SI.js +16 -0
  146. package/dist/taint-YOTN5X55.js +202 -0
  147. package/dist/taint-analyzer-N7YLZU3N.js +163 -0
  148. package/dist/tool-handlers-G4NAGJIH.js +72 -0
  149. package/dist/tool-registry-BPEJNSZG.js +17 -0
  150. package/dist/tool-validation-RF675A3C.js +32 -0
  151. package/dist/type-inference-4Y7WTMFE.js +13 -0
  152. package/dist/vector-binary-LMY4QGAN.js +19 -0
  153. package/dist/version-LXGNFO37.js +9 -0
  154. package/dist/wasm-NMWO3WXY.js +16 -0
  155. package/docs/EMBEDDINGS.md +132 -0
  156. package/docs/README.md +178 -0
  157. package/docs/data/m10-baseline.json +602 -0
  158. package/docs/data/m10-benchmark-baseline.json +57 -0
  159. package/docs/data/m10-benchmark-last-run.json +127 -0
  160. package/docs/data/m10-final-audit.json +215 -0
  161. package/docs/data/m12-final-audit.json +138 -0
  162. package/docs/data/m12-surface-matrix.json +50 -0
  163. package/docs/data/public-tools.json +1902 -0
  164. package/docs/indexing/DEAD-ASSETS.md +88 -0
  165. package/docs/indexing/INDEXER-REVIEW.md +634 -0
  166. package/docs/indexing/PERFORMANCE-FINDINGS.md +106 -0
  167. package/docs/indexing/README.md +427 -0
  168. package/docs/indexing/discovery-matrix.md +41 -0
  169. package/docs/indexing/embeddings.md +325 -0
  170. package/docs/indexing/environment-variables.md +77 -0
  171. package/docs/indexing/performance.md +323 -0
  172. package/docs/indexing/resume.md +345 -0
  173. package/docs/indexing/troubleshooting.md +391 -0
  174. package/docs/man/bb.1 +190 -0
  175. package/docs/tools/bb_analyze.md +147 -0
  176. package/docs/tools/bb_annotate.md +110 -0
  177. package/docs/tools/bb_annotations.md +106 -0
  178. package/docs/tools/bb_ask.md +101 -0
  179. package/docs/tools/bb_cross_language.md +103 -0
  180. package/docs/tools/bb_doc.md +169 -0
  181. package/docs/tools/bb_edit.md +185 -0
  182. package/docs/tools/bb_graph.md +169 -0
  183. package/docs/tools/bb_health.md +156 -0
  184. package/docs/tools/bb_impact.md +117 -0
  185. package/docs/tools/bb_index.md +108 -0
  186. package/docs/tools/bb_migrate.md +135 -0
  187. package/docs/tools/bb_patterns.md +140 -0
  188. package/docs/tools/bb_search.md +150 -0
  189. package/docs/tools/bb_security.md +100 -0
  190. package/docs/tools/bb_visualize.md +184 -0
  191. package/grammars/README.md +57 -0
  192. package/grammars/THIRD-PARTY-NOTICES.md +50 -0
  193. package/grammars/tree-sitter-c/LICENSE +21 -0
  194. package/grammars/tree-sitter-clojure/LICENSE.md +21 -0
  195. package/grammars/tree-sitter-cpp/LICENSE +21 -0
  196. package/grammars/tree-sitter-csharp/LICENSE +21 -0
  197. package/grammars/tree-sitter-css/LICENSE +21 -0
  198. package/grammars/tree-sitter-css/README.md +21 -0
  199. package/grammars/tree-sitter-dart/LICENSE +20 -0
  200. package/grammars/tree-sitter-dart-upstream/LICENSE +20 -0
  201. package/grammars/tree-sitter-dart-upstream/README.md +18 -0
  202. package/grammars/tree-sitter-elixir/LICENSE +176 -0
  203. package/grammars/tree-sitter-elixir/README.md +11 -0
  204. package/grammars/tree-sitter-fsharp/LICENSE +21 -0
  205. package/grammars/tree-sitter-fsharp/README.md +45 -0
  206. package/grammars/tree-sitter-graphql/LICENSE +21 -0
  207. package/grammars/tree-sitter-graphql/README.md +106 -0
  208. package/grammars/tree-sitter-groovy/LICENSE +21 -0
  209. package/grammars/tree-sitter-groovy/README.md +4 -0
  210. package/grammars/tree-sitter-haskell/LICENSE +21 -0
  211. package/grammars/tree-sitter-haskell/README.md +394 -0
  212. package/grammars/tree-sitter-hcl/CHANGELOG.md +102 -0
  213. package/grammars/tree-sitter-hcl/LICENSE +201 -0
  214. package/grammars/tree-sitter-hcl/README.md +39 -0
  215. package/grammars/tree-sitter-html/LICENSE +21 -0
  216. package/grammars/tree-sitter-html/README.md +21 -0
  217. package/grammars/tree-sitter-julia/LICENSE +21 -0
  218. package/grammars/tree-sitter-julia/README.md +24 -0
  219. package/grammars/tree-sitter-kotlin/LICENSE +9 -0
  220. package/grammars/tree-sitter-lua/LICENSE.md +21 -0
  221. package/grammars/tree-sitter-lua/README.md +29 -0
  222. package/grammars/tree-sitter-make/LICENSE +21 -0
  223. package/grammars/tree-sitter-matlab/LICENSE +19 -0
  224. package/grammars/tree-sitter-matlab/README.md +99 -0
  225. package/grammars/tree-sitter-nim/LICENSE +373 -0
  226. package/grammars/tree-sitter-nim/README.md +46 -0
  227. package/grammars/tree-sitter-objc/LICENSE +21 -0
  228. package/grammars/tree-sitter-objc/README.md +20 -0
  229. package/grammars/tree-sitter-perl/LICENSE +7 -0
  230. package/grammars/tree-sitter-perl/README.md +100 -0
  231. package/grammars/tree-sitter-powershell/LICENSE +21 -0
  232. package/grammars/tree-sitter-powershell/README.md +7 -0
  233. package/grammars/tree-sitter-proto/LICENSE +21 -0
  234. package/grammars/tree-sitter-proto/README.md +105 -0
  235. package/grammars/tree-sitter-r/LICENSE +9 -0
  236. package/grammars/tree-sitter-r/README.md +66 -0
  237. package/grammars/tree-sitter-ruby/LICENSE +22 -0
  238. package/grammars/tree-sitter-scss/LICENSE +21 -0
  239. package/grammars/tree-sitter-scss/README.md +17 -0
  240. package/grammars/tree-sitter-solidity/LICENSE +7 -0
  241. package/grammars/tree-sitter-sql/LICENSE +21 -0
  242. package/grammars/tree-sitter-typescript/LICENSE +21 -0
  243. package/grammars/tree-sitter-vba/LICENSE +21 -0
  244. package/grammars/tree-sitter-vba/README.md +738 -0
  245. package/grammars/tree-sitter-vbnet/LICENSE +21 -0
  246. package/grammars/tree-sitter-vbnet/README.md +322 -0
  247. package/grammars/tree-sitter-xml/LICENSE +19 -0
  248. package/grammars/tree-sitter-yaml/LICENSE +20 -0
  249. package/grammars/tree-sitter-yaml/README.md +21 -0
  250. package/package.json +184 -4
  251. package/wasm/dart.wasm +0 -0
  252. package/wasm/tree-sitter-bash.wasm +0 -0
  253. package/wasm/tree-sitter-c.wasm +0 -0
  254. package/wasm/tree-sitter-c_sharp.wasm +0 -0
  255. package/wasm/tree-sitter-clean.wasm +0 -0
  256. package/wasm/tree-sitter-clojure.wasm +0 -0
  257. package/wasm/tree-sitter-core_schema.wasm +0 -0
  258. package/wasm/tree-sitter-cpp.wasm +0 -0
  259. package/wasm/tree-sitter-css.wasm +0 -0
  260. package/wasm/tree-sitter-dart.wasm +0 -0
  261. package/wasm/tree-sitter-elisp.wasm +0 -0
  262. package/wasm/tree-sitter-elixir.wasm +0 -0
  263. package/wasm/tree-sitter-elm.wasm +0 -0
  264. package/wasm/tree-sitter-embedded_template.wasm +0 -0
  265. package/wasm/tree-sitter-erlang.wasm +0 -0
  266. package/wasm/tree-sitter-fsharp.wasm +0 -0
  267. package/wasm/tree-sitter-fsharp_signature.wasm +0 -0
  268. package/wasm/tree-sitter-go.wasm +0 -0
  269. package/wasm/tree-sitter-graphql.wasm +0 -0
  270. package/wasm/tree-sitter-groovy.wasm +0 -0
  271. package/wasm/tree-sitter-haskell.wasm +0 -0
  272. package/wasm/tree-sitter-hcl.wasm +0 -0
  273. package/wasm/tree-sitter-html.wasm +0 -0
  274. package/wasm/tree-sitter-java.wasm +0 -0
  275. package/wasm/tree-sitter-javascript.wasm +0 -0
  276. package/wasm/tree-sitter-json.wasm +0 -0
  277. package/wasm/tree-sitter-json_schema.wasm +0 -0
  278. package/wasm/tree-sitter-julia.wasm +0 -0
  279. package/wasm/tree-sitter-kotlin.wasm +0 -0
  280. package/wasm/tree-sitter-lua.wasm +0 -0
  281. package/wasm/tree-sitter-make.wasm +0 -0
  282. package/wasm/tree-sitter-markdown.wasm +0 -0
  283. package/wasm/tree-sitter-markdown_inline.wasm +0 -0
  284. package/wasm/tree-sitter-matlab.wasm +0 -0
  285. package/wasm/tree-sitter-nim.wasm +0 -0
  286. package/wasm/tree-sitter-objc.wasm +0 -0
  287. package/wasm/tree-sitter-ocaml.wasm +0 -0
  288. package/wasm/tree-sitter-perl.wasm +0 -0
  289. package/wasm/tree-sitter-php.wasm +0 -0
  290. package/wasm/tree-sitter-php_only.wasm +0 -0
  291. package/wasm/tree-sitter-powershell.wasm +0 -0
  292. package/wasm/tree-sitter-protobuf.wasm +0 -0
  293. package/wasm/tree-sitter-python.wasm +0 -0
  294. package/wasm/tree-sitter-ql.wasm +0 -0
  295. package/wasm/tree-sitter-r.wasm +0 -0
  296. package/wasm/tree-sitter-rescript.wasm +0 -0
  297. package/wasm/tree-sitter-ruby.wasm +0 -0
  298. package/wasm/tree-sitter-rust.wasm +0 -0
  299. package/wasm/tree-sitter-scala.wasm +0 -0
  300. package/wasm/tree-sitter-scss.wasm +0 -0
  301. package/wasm/tree-sitter-solidity.wasm +0 -0
  302. package/wasm/tree-sitter-sql.wasm +0 -0
  303. package/wasm/tree-sitter-svelte.wasm +0 -0
  304. package/wasm/tree-sitter-swift.wasm +0 -0
  305. package/wasm/tree-sitter-systemrdl.wasm +0 -0
  306. package/wasm/tree-sitter-terraform.wasm +0 -0
  307. package/wasm/tree-sitter-tlaplus.wasm +0 -0
  308. package/wasm/tree-sitter-toml.wasm +0 -0
  309. package/wasm/tree-sitter-tsx.wasm +0 -0
  310. package/wasm/tree-sitter-typescript.wasm +0 -0
  311. package/wasm/tree-sitter-vba.wasm +0 -0
  312. package/wasm/tree-sitter-vbnet.wasm +0 -0
  313. package/wasm/tree-sitter-vue.wasm +0 -0
  314. package/wasm/tree-sitter-xml.wasm +0 -0
  315. package/wasm/tree-sitter-yaml.wasm +0 -0
  316. package/wasm/tree-sitter-zig.wasm +0 -0
  317. package/wasm/tree-sitter.wasm +0 -0
  318. package/wasm/tsx.wasm +0 -0
  319. package/wasm/typescript.wasm +0 -0
@@ -0,0 +1,163 @@
1
+ import "./chunk-MLKGABMK.js";
2
+
3
+ // src/ast/taint-analyzer.ts
4
+ var TaintAnalyzer = class {
5
+ static enrichSymbols(symbols, content, language) {
6
+ for (const symbol of symbols) {
7
+ if (symbol.range.startIndex !== void 0 && symbol.range.endIndex !== void 0) {
8
+ const snippet = content.slice(symbol.range.startIndex, symbol.range.endIndex);
9
+ const sources = this.extractSources(snippet, language);
10
+ if (sources.length > 0) {
11
+ symbol.taintSources = symbol.taintSources ? [...symbol.taintSources, ...sources] : sources;
12
+ }
13
+ const sinks = this.extractSinks(snippet, language);
14
+ if (sinks.length > 0) {
15
+ symbol.taintSinks = symbol.taintSinks ? [...symbol.taintSinks, ...sinks] : sinks;
16
+ }
17
+ if (symbol.taintSources) {
18
+ symbol.taintSources = Array.from(new Set(symbol.taintSources.map((s) => s.snippet))).map(
19
+ (snippet2) => symbol.taintSources.find((s) => s.snippet === snippet2)
20
+ );
21
+ }
22
+ if (symbol.taintSinks) {
23
+ symbol.taintSinks = Array.from(new Set(symbol.taintSinks.map((s) => s.snippet))).map(
24
+ (snippet2) => symbol.taintSinks.find((s) => s.snippet === snippet2)
25
+ );
26
+ }
27
+ }
28
+ }
29
+ }
30
+ static extractSources(snippet, language) {
31
+ const sources = [];
32
+ if (/(?:req\.body|req\.query|req\.params|req\.headers|req\.cookies|request\.json|request\.args|request\.form|request\.files|\$_GET|\$_POST|\$_REQUEST|\$_COOKIE|\$_FILES|Request\.Query|Request\.Form|\[FromBody\]|\[FromQuery\]|params\[|request\.body|request\.url|request\.uri|URLSession\.shared)/i.test(
33
+ snippet
34
+ )) {
35
+ sources.push({ type: "user_input", snippet: "Web Request Data" });
36
+ }
37
+ if (/(?:process\.env|os\.environ|sys\.argv|System\/getenv|getenv\(|Sys\.getenv|std::env::args|getArgs|getEnv|commandArgs|command-line-args|\$1|\$2|\$@|\$\*)/.test(
38
+ snippet
39
+ )) {
40
+ sources.push({ type: "user_input", snippet: "Environment / CLI Argument" });
41
+ }
42
+ if (/(?:prompt\(|readLine|Scanner\(|input\(|scanf\(|gets\(|cin\s*>>|stdin\.readLineSync|io\.read|getLine)/.test(
43
+ snippet
44
+ )) {
45
+ sources.push({ type: "user_input", snippet: "Interactive Console Input" });
46
+ }
47
+ if (
48
+ // `\.Query\s*\(`, `\.QueryRow\s*\(`, `\.Exec\s*\(` — see the sink rule's
49
+ // comment. Requiring the call is what stops `req.query` from being read as
50
+ // a database READ; the same property read was previously classified as both
51
+ // a `database_read` source and a `sql_injection` sink.
52
+ /(?:db\.query|db\.find|findOne\(|findAll\(|select\(|\.Exec\s*\(|\.QueryRow\s*\(|\.Query\s*\(|ExecuteReader|executeQuery)/i.test(
53
+ snippet
54
+ )
55
+ ) {
56
+ sources.push({ type: "database_read", snippet: "Database Query Result" });
57
+ }
58
+ if (/(?:fs\.readFileSync|fs\.readFile|fs\.createReadStream|open\(|File\.ReadAllText|File\.ReadAllBytes|ioutil\.ReadFile|os\.ReadFile|file_get_contents|fopen\(|File\.open)/.test(
59
+ snippet
60
+ )) {
61
+ sources.push({ type: "file_system", snippet: "File System Read" });
62
+ }
63
+ if (/(?:password|passwd|pwd|secret|token|api_key|apikey|access_token|auth_token|client_secret|session_id|jwt|private_key|ssh_key|certificate|ssn|credit_card|cc_number)/i.test(
64
+ snippet
65
+ )) {
66
+ sources.push({ type: "sensitive_data", snippet: "Extracted Sensitive Credentials or PII" });
67
+ }
68
+ if (language === "java" || language === "kotlin") {
69
+ if (/(?:HttpServletRequest|request\.getParameter|@RequestParam|@RequestBody|@PathVariable|@RequestHeader|@CookieValue)/.test(
70
+ snippet
71
+ )) {
72
+ sources.push({ type: "user_input", snippet: "Java/Spring Web Request Context" });
73
+ }
74
+ } else if (language === "go") {
75
+ if (/(?:r\.URL\.Query|r\.FormValue|r\.Body|r\.PostFormValue|c\.Bind|c\.Param|c\.Query)/.test(snippet)) {
76
+ sources.push({ type: "user_input", snippet: "Go HTTP Request" });
77
+ }
78
+ } else if (language === "rust") {
79
+ if (/(?:req\.query|req\.body|Query\(|Json\(|Path\()/.test(snippet)) {
80
+ sources.push({ type: "user_input", snippet: "Rust Axum/Actix Request" });
81
+ }
82
+ } else if (language === "php") {
83
+ if (/(?:php\:\/\/input|file_get_contents\('php\:\/\/input'\))/.test(snippet)) {
84
+ sources.push({ type: "user_input", snippet: "PHP Raw Input Stream" });
85
+ }
86
+ } else if (language === "elixir") {
87
+ if (/(?:conn\.params|conn\.query_params|conn\.body_params)/.test(snippet)) {
88
+ sources.push({ type: "user_input", snippet: "Elixir Plug/Phoenix Conn" });
89
+ }
90
+ } else if (language === "scala") {
91
+ if (/(?:request\.getQueryString|request\.body|request\.headers)/.test(snippet)) {
92
+ sources.push({ type: "user_input", snippet: "Scala Play Request" });
93
+ }
94
+ } else if (language === "lua") {
95
+ if (/(?:ngx\.req\.get_uri_args|ngx\.req\.get_post_args)/.test(snippet)) {
96
+ sources.push({ type: "user_input", snippet: "Lua Nginx Request" });
97
+ }
98
+ }
99
+ return Array.from(new Set(sources.map((s) => s.snippet))).map(
100
+ (snippet2) => sources.find((s) => s.snippet === snippet2)
101
+ );
102
+ }
103
+ static extractSinks(snippet, language) {
104
+ const sinks = [];
105
+ if (/(?:db\.query|db\.execute|\bexecute\b|executeQuery|mysql_query|execute_query|query_row|\.Exec\s*\(|\.QueryRow\s*\(|\.Query\s*\(|ExecuteReader|ExecuteScalar|ExecuteNonQuery|sp_executesql|EXECUTE\s+IMMEDIATE)/i.test(
106
+ snippet
107
+ )) {
108
+ sinks.push({ type: "database_write", snippet: "Raw SQL Execution", vulnerability_type: "sql_injection" });
109
+ }
110
+ if (/(?:\bexec\(|\bspawn\(|\bexecSync|\bspawnSync|\bsystem\(|os\.system|subprocess\.|exec\.Command|Runtime\.getRuntime\(\)\.exec|Process\.Start|shell_exec\(|passthru\(|popen\(|os\.execute|io\.popen|System\.cmd|System\.Process|clojure\.java\.shell\/sh|system2\()/.test(
111
+ snippet
112
+ ) || language === "ruby" && /(?:Kernel\.exec|`.*`)/.test(snippet)) {
113
+ sinks.push({
114
+ type: "shell_execution",
115
+ snippet: "System Command Execution",
116
+ vulnerability_type: "command_injection"
117
+ });
118
+ }
119
+ if (/(?:fs\.readFile|fs\.writeFile|\bopen\(|File\.ReadAllText|File\.WriteAllText|ioutil\.ReadFile|os\.ReadFile|file_get_contents|\bfopen\(|File\.open|fs\.unlink|fs\.rmdir)/.test(
120
+ snippet
121
+ )) {
122
+ sinks.push({ type: "file_system", snippet: "File System Operation", vulnerability_type: "path_traversal" });
123
+ }
124
+ if (/(?:res\.send|res\.html|res\.write|innerHTML|document\.write|\becho |\bprint\s+|<script>|dangerouslySetInnerHTML)/.test(
125
+ snippet
126
+ )) {
127
+ sinks.push({ type: "http_response", snippet: "Raw HTTP/HTML Output", vulnerability_type: "xss" });
128
+ }
129
+ if (/(?:\beval\(|\bexec\(|loadstring\(|Code\.eval_string|Function\()/.test(snippet)) {
130
+ sinks.push({ type: "code_execution", snippet: "Dynamic Code Evaluation", vulnerability_type: "code_injection" });
131
+ }
132
+ if (/(?:pickle\.loads|pickle\.load|yaml\.load|marshal\.load|ObjectInputStream|readObject|unserialize\(|JSON\.parse|JSON\.parseObject|Bson\.parse)/.test(
133
+ snippet
134
+ )) {
135
+ sinks.push({
136
+ type: "deserialization",
137
+ snippet: "Object Deserialization",
138
+ vulnerability_type: "insecure_deserialization"
139
+ });
140
+ }
141
+ if (/(?:fetch\(|axios\.|requests\.get|requests\.post|urllib\.request|http\.Get|http\.Post|curl_exec|HttpClient|RestTemplate|WebClient|Net::HTTP)/.test(
142
+ snippet
143
+ )) {
144
+ sinks.push({ type: "network_request", snippet: "Outbound Network Request", vulnerability_type: "ssrf" });
145
+ }
146
+ if (/(?:res\.redirect|res\.set|res\.header|header\(|Location:|Redirect\()/.test(snippet)) {
147
+ sinks.push({
148
+ type: "http_response",
149
+ snippet: "HTTP Redirect / Header Setup",
150
+ vulnerability_type: "open_redirect"
151
+ });
152
+ }
153
+ if (/(?:md5\(|sha1\(|crypto\.createHash\("md5"\)|hashlib\.md5\(|MessageDigest\.getInstance\("MD5"\)|MD5\.Create|Digest::MD5)/i.test(
154
+ snippet
155
+ )) {
156
+ sinks.push({ type: "cryptography", snippet: "Weak Hashing Function", vulnerability_type: "weak_crypto" });
157
+ }
158
+ return Array.from(new Set(sinks.map((s) => s.snippet))).map((snippet2) => sinks.find((s) => s.snippet === snippet2));
159
+ }
160
+ };
161
+ export {
162
+ TaintAnalyzer
163
+ };
@@ -0,0 +1,72 @@
1
+ import {
2
+ ANALYZE_GRAPH_WALK_CEILING_MS,
3
+ SECURITY_FINDINGS_WINDOW,
4
+ SECURITY_RECORD_RUN_CENSUS_CAP,
5
+ SECURITY_SCAN_CAP,
6
+ SECURITY_SUSPICIOUS_WINDOW,
7
+ autoRefreshFile,
8
+ canonicalImpactReport,
9
+ createToolHandlers,
10
+ derivedStaleness,
11
+ describeUnknownFilters,
12
+ ensureWithinProject,
13
+ readIndexedFile,
14
+ readSnippet,
15
+ resolveProjectPath,
16
+ resolveSafeReadPath,
17
+ textResult
18
+ } from "./chunk-RH7KC5HU.js";
19
+ import "./chunk-BHB7BYYI.js";
20
+ import "./chunk-VL52PL2T.js";
21
+ import "./chunk-HOWAQXJO.js";
22
+ import "./chunk-CW4XXSNN.js";
23
+ import "./chunk-3CTFIJJB.js";
24
+ import "./chunk-HQSPJDHI.js";
25
+ import "./chunk-66A5ZFYA.js";
26
+ import "./chunk-J4PMBXQQ.js";
27
+ import "./chunk-2RRBMNBQ.js";
28
+ import "./chunk-2RTN2DFU.js";
29
+ import "./chunk-PJTNGD3Z.js";
30
+ import "./chunk-4H22TLOT.js";
31
+ import "./chunk-5SD45FLC.js";
32
+ import "./chunk-7AN7U5IZ.js";
33
+ import "./chunk-UGR4QIGS.js";
34
+ import "./chunk-GEFFO6O2.js";
35
+ import "./chunk-VURYFIHW.js";
36
+ import "./chunk-DYM4FQEE.js";
37
+ import "./chunk-RM3PY6TG.js";
38
+ import "./chunk-RCMTFSEF.js";
39
+ import "./chunk-47HKX4AJ.js";
40
+ import "./chunk-YI6FF2ZR.js";
41
+ import "./chunk-UUNHHX4M.js";
42
+ import "./chunk-QLK6ED4Q.js";
43
+ import "./chunk-KLK3PBTO.js";
44
+ import "./chunk-V44PGPA6.js";
45
+ import "./chunk-BQ3OVQ3P.js";
46
+ import "./chunk-SK6YVHFZ.js";
47
+ import "./chunk-2BSKD7O3.js";
48
+ import "./chunk-KAET47ZL.js";
49
+ import "./chunk-KCDECRJY.js";
50
+ import "./chunk-D2Q4Y47A.js";
51
+ import "./chunk-SM7RFQRO.js";
52
+ import "./chunk-L5TDYKYK.js";
53
+ import "./chunk-ROMM6KMC.js";
54
+ import "./chunk-MLKGABMK.js";
55
+ export {
56
+ ANALYZE_GRAPH_WALK_CEILING_MS,
57
+ SECURITY_FINDINGS_WINDOW,
58
+ SECURITY_RECORD_RUN_CENSUS_CAP,
59
+ SECURITY_SCAN_CAP,
60
+ SECURITY_SUSPICIOUS_WINDOW,
61
+ autoRefreshFile,
62
+ canonicalImpactReport,
63
+ createToolHandlers,
64
+ derivedStaleness,
65
+ describeUnknownFilters,
66
+ ensureWithinProject,
67
+ readIndexedFile,
68
+ readSnippet,
69
+ resolveProjectPath,
70
+ resolveSafeReadPath,
71
+ textResult
72
+ };
@@ -0,0 +1,17 @@
1
+ import {
2
+ PUBLIC_TOOL_DESCRIPTORS,
3
+ TOOL_DESCRIPTORS,
4
+ deriveToolContracts,
5
+ serializeToolMetadata,
6
+ toMcpToolList,
7
+ validateToolDescriptors
8
+ } from "./chunk-HQSPJDHI.js";
9
+ import "./chunk-MLKGABMK.js";
10
+ export {
11
+ PUBLIC_TOOL_DESCRIPTORS,
12
+ TOOL_DESCRIPTORS,
13
+ deriveToolContracts,
14
+ serializeToolMetadata,
15
+ toMcpToolList,
16
+ validateToolDescriptors
17
+ };
@@ -0,0 +1,32 @@
1
+ import {
2
+ EDIT_OPTIONS_BY_MODE,
3
+ PARAMETER_ALIASES,
4
+ resolveParameterAliases,
5
+ validateToolArguments
6
+ } from "./chunk-6AIRWAO2.js";
7
+ import "./chunk-CW4XXSNN.js";
8
+ import "./chunk-PJTNGD3Z.js";
9
+ import "./chunk-4H22TLOT.js";
10
+ import "./chunk-GEFFO6O2.js";
11
+ import "./chunk-VURYFIHW.js";
12
+ import "./chunk-DYM4FQEE.js";
13
+ import "./chunk-YI6FF2ZR.js";
14
+ import "./chunk-QLK6ED4Q.js";
15
+ import "./chunk-KLK3PBTO.js";
16
+ import "./chunk-V44PGPA6.js";
17
+ import "./chunk-BQ3OVQ3P.js";
18
+ import "./chunk-SK6YVHFZ.js";
19
+ import "./chunk-2BSKD7O3.js";
20
+ import "./chunk-KAET47ZL.js";
21
+ import "./chunk-KCDECRJY.js";
22
+ import "./chunk-D2Q4Y47A.js";
23
+ import "./chunk-SM7RFQRO.js";
24
+ import "./chunk-L5TDYKYK.js";
25
+ import "./chunk-ROMM6KMC.js";
26
+ import "./chunk-MLKGABMK.js";
27
+ export {
28
+ EDIT_OPTIONS_BY_MODE,
29
+ PARAMETER_ALIASES,
30
+ resolveParameterAliases,
31
+ validateToolArguments
32
+ };
@@ -0,0 +1,13 @@
1
+ import {
2
+ TypeInference
3
+ } from "./chunk-UFE77L67.js";
4
+ import "./chunk-V44PGPA6.js";
5
+ import "./chunk-BQ3OVQ3P.js";
6
+ import "./chunk-SK6YVHFZ.js";
7
+ import "./chunk-2BSKD7O3.js";
8
+ import "./chunk-KAET47ZL.js";
9
+ import "./chunk-KCDECRJY.js";
10
+ import "./chunk-MLKGABMK.js";
11
+ export {
12
+ TypeInference
13
+ };
@@ -0,0 +1,19 @@
1
+ import {
2
+ cosineFloat32,
3
+ decodeVectorBlob,
4
+ encodeVectorBlob,
5
+ l2Norm,
6
+ readRowVector,
7
+ scanJsonVectorInto,
8
+ vectorBlobBytes
9
+ } from "./chunk-GEFFO6O2.js";
10
+ import "./chunk-MLKGABMK.js";
11
+ export {
12
+ cosineFloat32,
13
+ decodeVectorBlob,
14
+ encodeVectorBlob,
15
+ l2Norm,
16
+ readRowVector,
17
+ scanJsonVectorInto,
18
+ vectorBlobBytes
19
+ };
@@ -0,0 +1,9 @@
1
+ import {
2
+ BACKBENCHER_BRAIN_VERSION,
3
+ PKG_NAME
4
+ } from "./chunk-6WNGD3NN.js";
5
+ import "./chunk-MLKGABMK.js";
6
+ export {
7
+ BACKBENCHER_BRAIN_VERSION,
8
+ PKG_NAME
9
+ };
@@ -0,0 +1,16 @@
1
+ import {
2
+ ensureWasmRegistry,
3
+ hasWasmInRegistry,
4
+ isWasmRegistryLoaded,
5
+ loadWebTreeSitter,
6
+ resolveWasmAsset
7
+ } from "./chunk-SK6YVHFZ.js";
8
+ import "./chunk-2BSKD7O3.js";
9
+ import "./chunk-MLKGABMK.js";
10
+ export {
11
+ ensureWasmRegistry,
12
+ hasWasmInRegistry,
13
+ isWasmRegistryLoaded,
14
+ loadWebTreeSitter,
15
+ resolveWasmAsset
16
+ };
@@ -0,0 +1,132 @@
1
+ # EMBEDDINGS — how semantic embeddings work in the brain
2
+
3
+ > Status: verified against real evidence — M18 (Semantic Intelligence & Retrieval
4
+ > Truth): `validation/m18/results/Q1..Q5.json`. Every claim below is either a
5
+ > code invariant or a number measured on real corpora in M18. Nothing here is
6
+ > aspirational.
7
+
8
+ ## What embeddings are
9
+
10
+ The brain stores one dense vector per indexed symbol in
11
+ `brain_semantic_embedding`:
12
+
13
+ | Column | Meaning |
14
+ | --- | --- |
15
+ | `entity_id` | The symbol this embedding belongs to |
16
+ | `embedding_model` | Canonical model label **that actually produced the vector** |
17
+ | `vector_dimension` | Dimension of that model's vectors |
18
+ | `embedding_blob` | little-endian float32, authoritative for dense vectors (`vector_dimension * 4` bytes) |
19
+ | `embedding_vector` | empty string for dense rows; JSON numeric array for legacy rows and sparse token lists (`tfidf-v1`) |
20
+ | `content_hash` | Hash of the snippet that produced the embedding (insert-time dedupe; **not** consulted at query time) |
21
+ | `similarity_threshold` | Per-row threshold hint (insert-time) |
22
+
23
+ Embeddings are generated in the background after indexing, batched through
24
+ `SemanticEngine.embedMany`. They are **additive**: an index run flushes new
25
+ batches; coverage is never a one-shot snapshot.
26
+
27
+ ## 2. Model labels & vector spaces (the correctness invariant)
28
+
29
+ - The **query vector** is produced by `SemanticEngine.embed(query)`. The model
30
+ that actually produced it (`getLastEmbeddingModel()`) is authoritative —
31
+ the API layer may transparently fall back to local word vectors, so the
32
+ configured model name is never trusted.
33
+ - Semantic vector search compares **only** stored embeddings whose
34
+ `embedding_model` equals the query model **and** whose `vector_dimension`
35
+ equals the query vector length. Cross-model comparison is **prohibited**
36
+ even at equal dimension, because different models occupy different vector
37
+ spaces (verified: Q4 inserts a fake foreign-model row; it is never compared;
38
+ Q5 model-mismatch case re-verifies it deterministically).
39
+ - `tfidf-v1` rows are sparse `{token, weight}` maps — structurally
40
+ incompatible with dense cosine. They carry a distinct model label and are
41
+ excluded from the dense path (`non-dense-query-model`). Verified in Q5.
42
+ - Any stored vector that is not a finite numeric array is skipped (corrupt
43
+ rows — malformed JSON, non-numeric, `Infinity` — are skipped without crash;
44
+ Q5 case 1). Zero/norm-0 vectors never produce NaN similarity (Q5 case 9).
45
+
46
+ ## 3. Coverage semantics — volatile, per-run, never hidden
47
+
48
+ **Coverage is a per-run, post-flush statistic, not a fixed product number.**
49
+ Measured on the rake corpus in M18:
50
+
51
+ | Run | Embeddings | Symbols | Coverage | Phase |
52
+ | --- | --- | --- | --- | --- |
53
+ | Q2 rake | 445 / 779 | 445 | 57.1% | post-flush (flush 15.4s) |
54
+ | Q4 rake | 445 / 779 | 445 | 57.1% | post-flush (flush 15.4s) |
55
+ | Q4 pre-flush | 0 / 779 | 0 | 0.0% | during background drain |
56
+
57
+ The **pre-flush `0 of N` line is distinguishable from the post-flush number**:
58
+ evidence records which phase a number was measured in, and the health line
59
+ labels it. Coverage is reported through `bb_health` (machine-checkable) and is
60
+ **never hidden — even when 0** (Q4: a zero-coverage index reports `0 of N`
61
+ explicitly, and `bb_ask` surfaces the degradation note instead of presenting
62
+ lexical matches as semantic).
63
+
64
+ Coverage is **volatile by design**: the embedding API batches and rate-limits,
65
+ so one run may embed 62.2% of lodash and another 10.0% of the same corpus (both
66
+ post-flush). The product therefore never claims a fixed coverage target — it
67
+ reports what it measured, per run (see Q4 negative line).
68
+
69
+ ## 4. Fallback ladder (explicit, never silent)
70
+
71
+ When no usable vector result exists, retrieval falls back to lexical search
72
+ (FTS5/BM25 content search) with an explicit `fallbackReason`:
73
+
74
+ `embedding-error` · `no-query-vector` · `non-dense-query-model` ·
75
+ `no-matching-model-embeddings` · `no-vector-above-threshold` ·
76
+ `no-resolvable-entities`
77
+
78
+ Each of these is a real, reachable path — the deterministic wire‑tests in Q5
79
+ prove the `embedding-error`, `no-query-vector`, `no-matching-model-embeddings`,
80
+ `non-dense-query-model`, and degenerate-row paths offline.
81
+
82
+ ## 5. Retrieval quality (measured, bounded, honest)
83
+
84
+ On the M18 benchmark (rake + lodash + element-plus, gold answers with
85
+ provenance in `validation/m18/benchmark/benchmark.json`):
86
+
87
+ | Metric | Measured | Floor asserted |
88
+ | --- | --- | --- |
89
+ | Vector recall@10 (median over query runs) | **71.4%** (10/14) | >= 50% |
90
+ | Vector recall@5 | **57.1%** (8/14) | >= 0.3 |
91
+ | `bb_ask` warm precision (answer cites gold symbol) | **71.4%** (10/14) | >= 0.5 |
92
+ | `bb_ask` cold-start precision (no embeddings) | **42.9%** (6/14) | >= 0.3 |
93
+ | cold/warm delta | -28.6 pts | reported, not hidden |
94
+
95
+ The deltas exists for a reason: cold start has **zero** stored embeddings, so
96
+ `bb_ask` falls back to lexical symbol/content search — symbol-name queries
97
+ still land, natural-language paraphrases degrade (Q3 measured the full delta;
98
+ Q3's "does not know" honesty floor: all negative queries return confidence
99
+ < 0.5, zero fabrication).
100
+
101
+ These are **candidate-discovery** numbers — they prove the correct symbol is
102
+ *retrieved*; they do not prove behavioral semantics. Ranks are per-embedding-model
103
+ and per-run; a gold embedded under a different model than the query is an
104
+ out-of-domain (coverage) miss, not a retrieval defect (Q2 negative line).
105
+
106
+ ## 6. What embeddings do NOT do
107
+
108
+ - Embeddings are **not** stored file source; content search covers the indexed
109
+ symbol + docstring corpus, not full file text.
110
+ - Embeddings do **not** rank `bb_search`: `bb_search` has **no semantic mode**
111
+ (modes: `symbols` / `content` / `symbol` / `file`). Semantic retrieval is
112
+ `bb_ask`-only. No doc or UI may imply `bb_search` ranks semantically.
113
+ - Embedding rows are **not** validated against `content_hash` at query time —
114
+ staleness is proven by the file-level hash (`checkResultsFreshness`), and
115
+ semantic results are flagged `stale` when the underlying file changed on
116
+ disk. Verified in Q5 case 10.
117
+
118
+ ## 7. Scalability
119
+
120
+ The candidate scan is capped at `BB_VECTOR_SCAN_CAP` (default 20000) rows,
121
+ ordered deterministically by `entity_id`, so truncation is stable; when the
122
+ cap is hit, `provenance.truncated` is `true` and `metadata.scannedRows` reports
123
+ exactly how many rows were loaded (Q5 case 11 proves this with a closed set).
124
+
125
+ ## 8. Verification references
126
+
127
+ - `script/m18/verify-recall.ts` — recall@k / rank / latency / model labels
128
+ - `script/m18/verify-ask.ts` — bb_ask warm/cold precision + honesty floors
129
+ - `script/m18/verify-coverage.ts` — coverage reporting + phase labeling
130
+ - `script/m18/verify-edge-cases.ts` — corrupt / stale / empty / mismatch
131
+ - `script/m18/verify-scan-cap.ts` — scan-cap truncation (child process)
132
+ - Evidence: `validation/m18/results/Q1.json .. Q5.json`
package/docs/README.md ADDED
@@ -0,0 +1,178 @@
1
+ # Documentation index
2
+
3
+ `bb`'s documentation lives in the repository. This page is the map. The pages that ship with the npm package
4
+ are `README.md`, `EMBEDDINGS.md`, `CHANGELOG.md`, `docs/man/`, `docs/tools/`, `docs/indexing/` and
5
+ `docs/data/public-tools.json`; everything else is repository documentation and internal evidence.
6
+
7
+ ## Repository map
8
+
9
+ Where things live, and what each top-level directory is for (this is the folder-level index — one map, kept
10
+ in one place, instead of a README in every directory that can drift from the code):
11
+
12
+ | Path | What it is |
13
+ | --- | --- |
14
+ | `src/` | The product source. `src/ast/` parses languages into evidence; `src/storage/` owns the SQLite layer; `src/intelligence/` contains the search/semantic/graph/analysis/pattern/security/doc/visualization/migration/edit/health engines; `src/mcp/` (registry, descriptors, handlers) and `src/cli/` are the adapters; `src/lsp/` is the language server; `src/setup/` and `src/config/` own setup, doctor and configuration. Module contracts: [`ARCHITECTURE.md`](./ARCHITECTURE.md). |
15
+ | `script/` | The verification machinery: top-level `script/verify-*.ts` gates for shipped surfaces, `script/mNN/` milestone gates and instruments, `script/m14/` the analyzer suite (specs, fixtures, instrument sets), `script/tool-docs/` the curation sources for the generated tool references, `script/perf/` measurement probes, `script/lib/` shared harness. What is a gate vs an instrument, and which runtime each needs: [`../script/README.md`](../script/README.md). |
16
+ | `validation/` | Evidence: gate results (JSON) and human-readable review/verification pages, organised by milestone (`validation/m14/`, `m25/`, …). Gate-produced, not hand-edited; provenance and re-run rules: [`../validation/README.md`](../validation/README.md). |
17
+ | `docs/` | This documentation tree (indexing, tools, analyzers, architecture and the historical milestone records). |
18
+ | `ide/` | Editor integrations: VS Code-family extension, Zed extension, LSP4IJ template for JetBrains IDEs, Helix config. Start at [`../ide/README.md`](../ide/README.md). |
19
+ | `grammars/` | Vendored/pinned Tree-sitter grammar sources and their `PIN.md`/`PROVENANCE.md` records; the pinned WASM binaries live in `wasm/`. |
20
+ | `wasm/` | The pinned Tree-sitter WASM artifacts the engine loads; digest pins live in `src/ast/engine.ts`. |
21
+ | `bin/` | The `bb` launcher; `dist/` is build output (ignored), and the compiled path is what npm/Node runs. |
22
+ | `test/` | Harness suites and fixtures that are not part of the gate suite (CLI surface, indexing lifecycle, demo fixtures): [`../test/README.md`](../test/README.md). |
23
+ | `plans/` | Small machine-readable plan inputs still read by milestone instruments (for example the M11 corpus plan). |
24
+
25
+ `node_modules/`, `dist/`, local worktrees and other
26
+ machine-local directories are ignored; they are not repository content.
27
+
28
+ ## Start here
29
+
30
+ | If you want to… | Read |
31
+ | --- | --- |
32
+ | index a project, or understand what each flag actually does | [`indexing/README.md`](./indexing/README.md) |
33
+ | recover an interrupted index run | [`indexing/resume.md`](./indexing/resume.md) |
34
+ | understand why indexing is slow | [`indexing/performance.md`](./indexing/performance.md) |
35
+ | fix "the workers don't start" | [`indexing/troubleshooting.md`](./indexing/troubleshooting.md) |
36
+ | configure embeddings, `bb setup`, `bb doctor` | [`indexing/embeddings.md`](./indexing/embeddings.md) and [`../EMBEDDINGS.md`](../EMBEDDINGS.md) |
37
+ | see what discovery actually scans | [`indexing/discovery-matrix.md`](./indexing/discovery-matrix.md) |
38
+ | look up a tool | [`tools/`](./tools/) (one page per tool), or [`data/public-tools.json`](./data/public-tools.json) for machine-readable contracts |
39
+ | understand the module layout | [`ARCHITECTURE.md`](./ARCHITECTURE.md) and [`GRAPH_ENGINE.md`](./GRAPH_ENGINE.md) |
40
+ | read an analyzer's contract | [`analyzers/README.md`](./analyzers/README.md) — one canonical page per analyzer |
41
+ | use the IDE extension (VS Code, Cursor, Antigravity, Windsurf, Zed, Helix, JetBrains) | [`IDE-PROGRAM-STATUS.md`](./IDE-PROGRAM-STATUS.md) for the current evidence-backed state; [`IDE-LAUNCH-TEST-PLAN.md`](./IDE-LAUNCH-TEST-PLAN.md) for the gates and the human test pass |
42
+
43
+ ## Indexing
44
+
45
+ `bb index` is the deepest surface here, and the one most likely to be wrong in a way that costs you time rather
46
+ than failing loudly. It has its own directory, and those pages are gated against the code
47
+ (`script/verify-docs-indexing.ts` asserts every env var, flag, default and quoted output line exists in `src/`):
48
+
49
+ - [`indexing/README.md`](./indexing/README.md) — the legal flag combinations, and how to read a run's report on itself
50
+ - [`indexing/resume.md`](./indexing/resume.md) — what survives Ctrl-C, and the `skipped-unchanged` trap
51
+ - [`indexing/performance.md`](./indexing/performance.md) — measured timings, each citing an evidence file, plus what has *not* been measured
52
+ - [`indexing/troubleshooting.md`](./indexing/troubleshooting.md) — the worker pool: causes, env vars and which are test-only
53
+ - [`indexing/embeddings.md`](./indexing/embeddings.md) — provider precedence, every `BB_EMBEDDING_*` variable, retries
54
+ - [`indexing/environment-variables.md`](./indexing/environment-variables.md) — every `BB_*` variable and whether it is a user knob
55
+ - [`indexing/discovery-matrix.md`](./indexing/discovery-matrix.md) — what is scanned and what is not, case by case, verified by its gate
56
+ - [`indexing/PERFORMANCE-FINDINGS.md`](./indexing/PERFORMANCE-FINDINGS.md) — local measurements with no evidence file; read its provenance warning first
57
+
58
+ ## Per-tool references
59
+
60
+ The sixteen public tools are documented individually and generated from the tool registry so the two cannot
61
+ drift (`script/verify-tool-docs.ts` writes [`data/public-tools.json`](./data/public-tools.json) and
62
+ [`tools/`](./tools/)):
63
+
64
+ | Tool | Documentation | | Tool | Documentation |
65
+ | --- | --- | --- | --- | --- |
66
+ | `bb_analyze` | [`tools/bb_analyze.md`](./tools/bb_analyze.md) | | | `bb_annotate` | [`tools/bb_annotate.md`](./tools/bb_annotate.md) |
67
+ | `bb_annotations` | [`tools/bb_annotations.md`](./tools/bb_annotations.md) | | | `bb_ask` | [`tools/bb_ask.md`](./tools/bb_ask.md) |
68
+ | `bb_cross_language` | [`tools/bb_cross_language.md`](./tools/bb_cross_language.md) | | | `bb_doc` | [`tools/bb_doc.md`](./tools/bb_doc.md) |
69
+ | `bb_edit` | [`tools/bb_edit.md`](./tools/bb_edit.md) | | | `bb_graph` | [`tools/bb_graph.md`](./tools/bb_graph.md) |
70
+ | `bb_health` | [`tools/bb_health.md`](./tools/bb_health.md) | | | `bb_impact` | [`tools/bb_impact.md`](./tools/bb_impact.md) |
71
+ | `bb_index` | [`tools/bb_index.md`](./tools/bb_index.md) | | | `bb_migrate` | [`tools/bb_migrate.md`](./tools/bb_migrate.md) |
72
+ | `bb_patterns` | [`tools/bb_patterns.md`](./tools/bb_patterns.md) | | | `bb_search` | [`tools/bb_search.md`](./tools/bb_search.md) |
73
+ | `bb_security` | [`tools/bb_security.md`](./tools/bb_security.md) | | | `bb_visualize` | [`tools/bb_visualize.md`](./tools/bb_visualize.md) |
74
+
75
+ The public surface is **exactly these sixteen tools**. Test intelligence is not a separate
76
+ tool: it is the `test_mapping`, `test_gaps`, `test_impact` and `test_quality` modes of
77
+ `bb_analyze` (deep guides: [`BB_TEST_INTEL.md`](./BB_TEST_INTEL.md),
78
+ [`BB_TEST_QUALITY.md`](./BB_TEST_QUALITY.md)). The per-mode names retired before 0.3.0
79
+ (`bb_select`, `bb_write`, `bb_test_quality`, …) are not callable; they are listed only in the
80
+ retired-name tables of [`TOOL-REGISTRY.md`](./TOOL-REGISTRY.md) and
81
+ the tool pages under [`docs/tools/`](./tools/) so readers can migrate off them.
82
+
83
+ `npm run docs:verify` regenerates the artifact set and fails on drift. `man bb` ships with the package and
84
+ points at these directories, so an installed user has the same reference. There are no hidden tools or aliases:
85
+ the `0.3.0` release removed them, and `bb --help` lists exactly these sixteen.
86
+
87
+ Ownership and scope for future changes is tracked in the private ownership ledger; the public
88
+ contract for each tool is its page under `docs/tools/`.
89
+
90
+ ### Deep guides
91
+
92
+ Each generated reference page links its hand-written deep guides under **Deep guides**; they carry the
93
+ operational detail the generated contract does not: worked runs, measured costs, refusal behaviour and the
94
+ limits a caller must carry forward.
95
+
96
+ | Tool | Deep guide(s) |
97
+ | --- | --- |
98
+ | `bb_analyze` | [`BB_ANALYZE.md`](./BB_ANALYZE.md), [`BB_TEST_INTEL.md`](./BB_TEST_INTEL.md), [`BB_TEST_QUALITY.md`](./BB_TEST_QUALITY.md), [`BB_ANALYSIS_HISTORY.md`](./BB_ANALYSIS_HISTORY.md) |
99
+ | `bb_annotate` | [`BB_ANNOTATE.md`](./BB_ANNOTATE.md) |
100
+ | `bb_annotations` | [`BB_ANNOTATIONS.md`](./BB_ANNOTATIONS.md) |
101
+ | `bb_ask` | [`BB_ASK.md`](./BB_ASK.md) |
102
+ | `bb_cross_language` | [`BB_CROSS_LANGUAGE.md`](./BB_CROSS_LANGUAGE.md) |
103
+ | `bb_doc` | [`BB_DOC.md`](./BB_DOC.md), [`BB_DOC_REFERENCE.md`](./BB_DOC_REFERENCE.md), [`BB_DOC_EXAMPLES.md`](./BB_DOC_EXAMPLES.md) |
104
+ | `bb_edit` | [`BB_EDIT.md`](./BB_EDIT.md) |
105
+ | `bb_graph` | [`GRAPH_ENGINE.md`](./GRAPH_ENGINE.md) — the graph model rather than a per-tool guide |
106
+ | `bb_health` | [`BB_HEALTH.md`](./BB_HEALTH.md) |
107
+ | `bb_impact` | [`BB_IMPACT.md`](./BB_IMPACT.md) |
108
+ | `bb_index` | [`indexing/README.md`](./indexing/README.md) — flags, resume, performance, troubleshooting |
109
+ | `bb_migrate` | [`BB_MIGRATE.md`](./BB_MIGRATE.md) |
110
+ | `bb_patterns` | [`BB_PATTERNS.md`](./BB_PATTERNS.md) |
111
+ | `bb_search` | [`BB_SEARCH.md`](./BB_SEARCH.md) |
112
+ | `bb_security` | [`BB_SECURITY.md`](./BB_SECURITY.md) |
113
+ | `bb_visualize` | [`BB_VISUALIZE.md`](./BB_VISUALIZE.md) |
114
+
115
+ The deep-guide set is itself gated: `script/m31/verify-bb-docs-truth.ts` extracts every testable claim from
116
+ these pages (JSON invocations validated against the live registry, mode lists, parameter tables, output
117
+ fields against the behavioural corpus, mutability claims) and records the claims it cannot verify as declared
118
+ unverifiable in `validation/m31/results/D2.json`.
119
+
120
+ ### Historical documents at this level
121
+
122
+ Milestone records are evidence of what was checked when, not current behaviour. That applies to `docs/m*/`
123
+ directories and equally to the legacy milestone records kept directly under `docs/` (`M10-*`, `M13-*`,
124
+ `M14-*`, `M26-*`, `M55-*`, `MCP_*`). They are not contracts and should not be read as current tool
125
+ documentation; the per-tool pages and deep guides above are. Older plans and migration guides that no longer
126
+ describe the shipped surface are kept in the private release archive rather than mixed into the
127
+ live set.
128
+
129
+ ## Analyzers
130
+
131
+ One canonical page per analyzer: [`analyzers/README.md`](./analyzers/README.md) indexes all fifty
132
+ (`docs/analyzers/<language>.md`). Those pages are measured by `script/m14/verify-analyzer-docs.ts` against
133
+ [`analyzers/TEMPLATE.md`](./analyzers/TEMPLATE.md) (eight measured sections, plus an explained
134
+ relationship-ontology table; the measured worklist is on the analyzer index). Older analyzer journals
135
+ that tracked code and validation evidence are kept in the private archive rather than
136
+ mixed into the canonical set.
137
+
138
+ ## Architecture and programs
139
+
140
+ - [`ARCHITECTURE.md`](./ARCHITECTURE.md) — module layout, evidence and mutation contracts
141
+ - [`GRAPH_ENGINE.md`](./GRAPH_ENGINE.md) — the relationship graph: what each edge means and how it is resolved
142
+ - [`../EMBEDDINGS.md`](../EMBEDDINGS.md) — the shipped embeddings guide (vector spaces, coverage, retrieval)
143
+ - [`IDE-HONESTY-CONTRACT.md`](./IDE-HONESTY-CONTRACT.md) — what the IDE integration promises and does not
144
+ - [`TOOL-REGISTRY.md`](./TOOL-REGISTRY.md) and [`TOOLS_OVERVIEW.md`](./TOOLS_OVERVIEW.md) — registry and surface overview
145
+
146
+ ## Records and evidence
147
+
148
+ - `docs/m*/` — milestone records (M10–M63) and their audits. They are evidence of what was checked when, not
149
+ current behaviour; prefer the per-topic pages above.
150
+ - `validation/` — gate results and measurement evidence (JSON and markdown). Tracked evidence is referenced by
151
+ gates; `script/m14/verify-self-contained.ts` checks the parts the machinery actually reads.
152
+ - [`validation/languages/results/tool-matrix.json`](../validation/languages/results/tool-matrix.json) — the language × tool
153
+ matrix evidence: every analyzer language indexed from a real fixture and exercised through the public tools.
154
+ Contract and extension steps: [`LANGUAGE-TOOL-MATRIX.md`](./LANGUAGE-TOOL-MATRIX.md).
155
+
156
+ ### Superseded copies
157
+
158
+ A page may keep its previous revision as `<name>.superseded-<commit>.md` next to it. That is allowed only
159
+ while tracked evidence still cites the old content; the copy is evidence, not documentation, and it is
160
+ removed from the live set once no gate or ledger references it. The current revision is always the unsuffixed
161
+ file. Do not treat a superseded copy as the contract when both exist.
162
+
163
+ ## Verifying a doc
164
+
165
+ If a doc tells you something and you have reason to doubt it, check rather than trust:
166
+
167
+ ```bash
168
+ npx tsx script/verify-docs-indexing.ts # indexing pages, against src/
169
+ npx tsx script/verify-tool-docs.ts # regenerates and compares the tool references
170
+ npx tsx script/m14/verify-analyzer-docs.ts # analyzer pages, sections and ontology cells
171
+ npm run verify:language-matrix # every analyzer language × the public tool layer
172
+ ```
173
+
174
+ The matrix's contract page ([LANGUAGE-TOOL-MATRIX.md](./LANGUAGE-TOOL-MATRIX.md)) also explains how to add a
175
+ language or a new tool check without rewriting the gate.
176
+
177
+ Docs that assert behaviour the code does not implement are worse than no docs: they cost time while looking
178
+ authoritative.