@descryy/core 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 (366) hide show
  1. package/LICENSE +21 -0
  2. package/dist/capabilities/index.d.ts +3 -0
  3. package/dist/capabilities/index.d.ts.map +1 -0
  4. package/dist/capabilities/index.js +2 -0
  5. package/dist/capabilities/index.js.map +1 -0
  6. package/dist/capabilities/preconditions.d.ts +99 -0
  7. package/dist/capabilities/preconditions.d.ts.map +1 -0
  8. package/dist/capabilities/preconditions.js +94 -0
  9. package/dist/capabilities/preconditions.js.map +1 -0
  10. package/dist/contracts/engine.d.ts +90 -0
  11. package/dist/contracts/engine.d.ts.map +1 -0
  12. package/dist/contracts/engine.js +291 -0
  13. package/dist/contracts/engine.js.map +1 -0
  14. package/dist/contracts/index.d.ts +9 -0
  15. package/dist/contracts/index.d.ts.map +1 -0
  16. package/dist/contracts/index.js +5 -0
  17. package/dist/contracts/index.js.map +1 -0
  18. package/dist/contracts/orphans.d.ts +96 -0
  19. package/dist/contracts/orphans.d.ts.map +1 -0
  20. package/dist/contracts/orphans.js +241 -0
  21. package/dist/contracts/orphans.js.map +1 -0
  22. package/dist/contracts/paths.d.ts +132 -0
  23. package/dist/contracts/paths.d.ts.map +1 -0
  24. package/dist/contracts/paths.js +245 -0
  25. package/dist/contracts/paths.js.map +1 -0
  26. package/dist/contracts/shapes.d.ts +99 -0
  27. package/dist/contracts/shapes.d.ts.map +1 -0
  28. package/dist/contracts/shapes.js +196 -0
  29. package/dist/contracts/shapes.js.map +1 -0
  30. package/dist/governance/budget.d.ts +89 -0
  31. package/dist/governance/budget.d.ts.map +1 -0
  32. package/dist/governance/budget.js +101 -0
  33. package/dist/governance/budget.js.map +1 -0
  34. package/dist/governance/candidate-boundary.d.ts +49 -0
  35. package/dist/governance/candidate-boundary.d.ts.map +1 -0
  36. package/dist/governance/candidate-boundary.js +51 -0
  37. package/dist/governance/candidate-boundary.js.map +1 -0
  38. package/dist/governance/escalation.d.ts +63 -0
  39. package/dist/governance/escalation.d.ts.map +1 -0
  40. package/dist/governance/escalation.js +72 -0
  41. package/dist/governance/escalation.js.map +1 -0
  42. package/dist/governance/fact-boundary.d.ts +77 -0
  43. package/dist/governance/fact-boundary.d.ts.map +1 -0
  44. package/dist/governance/fact-boundary.js +91 -0
  45. package/dist/governance/fact-boundary.js.map +1 -0
  46. package/dist/governance/finding-funnel.d.ts +109 -0
  47. package/dist/governance/finding-funnel.d.ts.map +1 -0
  48. package/dist/governance/finding-funnel.js +137 -0
  49. package/dist/governance/finding-funnel.js.map +1 -0
  50. package/dist/governance/index.d.ts +11 -0
  51. package/dist/governance/index.d.ts.map +1 -0
  52. package/dist/governance/index.js +6 -0
  53. package/dist/governance/index.js.map +1 -0
  54. package/dist/graph/build.d.ts +127 -0
  55. package/dist/graph/build.d.ts.map +1 -0
  56. package/dist/graph/build.js +0 -0
  57. package/dist/graph/build.js.map +1 -0
  58. package/dist/graph/cross-language.d.ts +70 -0
  59. package/dist/graph/cross-language.d.ts.map +1 -0
  60. package/dist/graph/cross-language.js +104 -0
  61. package/dist/graph/cross-language.js.map +1 -0
  62. package/dist/graph/index.d.ts +11 -0
  63. package/dist/graph/index.d.ts.map +1 -0
  64. package/dist/graph/index.js +6 -0
  65. package/dist/graph/index.js.map +1 -0
  66. package/dist/graph/merge.d.ts +95 -0
  67. package/dist/graph/merge.d.ts.map +1 -0
  68. package/dist/graph/merge.js +131 -0
  69. package/dist/graph/merge.js.map +1 -0
  70. package/dist/graph/persist.d.ts +42 -0
  71. package/dist/graph/persist.d.ts.map +1 -0
  72. package/dist/graph/persist.js +52 -0
  73. package/dist/graph/persist.js.map +1 -0
  74. package/dist/graph/runtime-confirmation.d.ts +169 -0
  75. package/dist/graph/runtime-confirmation.d.ts.map +1 -0
  76. package/dist/graph/runtime-confirmation.js +318 -0
  77. package/dist/graph/runtime-confirmation.js.map +1 -0
  78. package/dist/index.d.ts +18 -0
  79. package/dist/index.d.ts.map +1 -0
  80. package/dist/index.js +19 -0
  81. package/dist/index.js.map +1 -0
  82. package/dist/ledger/index.d.ts +5 -0
  83. package/dist/ledger/index.d.ts.map +1 -0
  84. package/dist/ledger/index.js +3 -0
  85. package/dist/ledger/index.js.map +1 -0
  86. package/dist/ledger/mint.d.ts +81 -0
  87. package/dist/ledger/mint.d.ts.map +1 -0
  88. package/dist/ledger/mint.js +138 -0
  89. package/dist/ledger/mint.js.map +1 -0
  90. package/dist/ledger/resolve.d.ts +124 -0
  91. package/dist/ledger/resolve.d.ts.map +1 -0
  92. package/dist/ledger/resolve.js +290 -0
  93. package/dist/ledger/resolve.js.map +1 -0
  94. package/dist/multipr/fingerprint.d.ts +56 -0
  95. package/dist/multipr/fingerprint.d.ts.map +1 -0
  96. package/dist/multipr/fingerprint.js +169 -0
  97. package/dist/multipr/fingerprint.js.map +1 -0
  98. package/dist/multipr/hidden-dependency.d.ts +120 -0
  99. package/dist/multipr/hidden-dependency.d.ts.map +1 -0
  100. package/dist/multipr/hidden-dependency.js +185 -0
  101. package/dist/multipr/hidden-dependency.js.map +1 -0
  102. package/dist/multipr/index.d.ts +14 -0
  103. package/dist/multipr/index.d.ts.map +1 -0
  104. package/dist/multipr/index.js +8 -0
  105. package/dist/multipr/index.js.map +1 -0
  106. package/dist/multipr/mechanical.d.ts +239 -0
  107. package/dist/multipr/mechanical.d.ts.map +1 -0
  108. package/dist/multipr/mechanical.js +333 -0
  109. package/dist/multipr/mechanical.js.map +1 -0
  110. package/dist/multipr/migration-heads.d.ts +160 -0
  111. package/dist/multipr/migration-heads.d.ts.map +1 -0
  112. package/dist/multipr/migration-heads.js +212 -0
  113. package/dist/multipr/migration-heads.js.map +1 -0
  114. package/dist/multipr/overlap.d.ts +186 -0
  115. package/dist/multipr/overlap.d.ts.map +1 -0
  116. package/dist/multipr/overlap.js +254 -0
  117. package/dist/multipr/overlap.js.map +1 -0
  118. package/dist/multipr/scope-store.d.ts +105 -0
  119. package/dist/multipr/scope-store.d.ts.map +1 -0
  120. package/dist/multipr/scope-store.js +182 -0
  121. package/dist/multipr/scope-store.js.map +1 -0
  122. package/dist/multipr/superseded.d.ts +133 -0
  123. package/dist/multipr/superseded.d.ts.map +1 -0
  124. package/dist/multipr/superseded.js +128 -0
  125. package/dist/multipr/superseded.js.map +1 -0
  126. package/dist/query/confirmed-facts.d.ts +56 -0
  127. package/dist/query/confirmed-facts.d.ts.map +1 -0
  128. package/dist/query/confirmed-facts.js +64 -0
  129. package/dist/query/confirmed-facts.js.map +1 -0
  130. package/dist/query/declared-value-closure.d.ts +126 -0
  131. package/dist/query/declared-value-closure.d.ts.map +1 -0
  132. package/dist/query/declared-value-closure.js +156 -0
  133. package/dist/query/declared-value-closure.js.map +1 -0
  134. package/dist/query/index.d.ts +28 -0
  135. package/dist/query/index.d.ts.map +1 -0
  136. package/dist/query/index.js +15 -0
  137. package/dist/query/index.js.map +1 -0
  138. package/dist/query/memory.d.ts +20 -0
  139. package/dist/query/memory.d.ts.map +1 -0
  140. package/dist/query/memory.js +55 -0
  141. package/dist/query/memory.js.map +1 -0
  142. package/dist/query/provider.d.ts +127 -0
  143. package/dist/query/provider.d.ts.map +1 -0
  144. package/dist/query/provider.js +54 -0
  145. package/dist/query/provider.js.map +1 -0
  146. package/dist/query/queries.d.ts +119 -0
  147. package/dist/query/queries.d.ts.map +1 -0
  148. package/dist/query/queries.js +267 -0
  149. package/dist/query/queries.js.map +1 -0
  150. package/dist/query/refusal-fetch.d.ts +114 -0
  151. package/dist/query/refusal-fetch.d.ts.map +1 -0
  152. package/dist/query/refusal-fetch.js +200 -0
  153. package/dist/query/refusal-fetch.js.map +1 -0
  154. package/dist/query/refusal-questions.d.ts +123 -0
  155. package/dist/query/refusal-questions.d.ts.map +1 -0
  156. package/dist/query/refusal-questions.js +122 -0
  157. package/dist/query/refusal-questions.js.map +1 -0
  158. package/dist/query/root-cause-score.d.ts +218 -0
  159. package/dist/query/root-cause-score.d.ts.map +1 -0
  160. package/dist/query/root-cause-score.js +251 -0
  161. package/dist/query/root-cause-score.js.map +1 -0
  162. package/dist/query/row-closure-picture.d.ts +108 -0
  163. package/dist/query/row-closure-picture.d.ts.map +1 -0
  164. package/dist/query/row-closure-picture.js +131 -0
  165. package/dist/query/row-closure-picture.js.map +1 -0
  166. package/dist/query/similar-incidents.d.ts +76 -0
  167. package/dist/query/similar-incidents.d.ts.map +1 -0
  168. package/dist/query/similar-incidents.js +169 -0
  169. package/dist/query/similar-incidents.js.map +1 -0
  170. package/dist/query/sqlite.d.ts +13 -0
  171. package/dist/query/sqlite.d.ts.map +1 -0
  172. package/dist/query/sqlite.js +54 -0
  173. package/dist/query/sqlite.js.map +1 -0
  174. package/dist/query/traverse.d.ts +110 -0
  175. package/dist/query/traverse.d.ts.map +1 -0
  176. package/dist/query/traverse.js +0 -0
  177. package/dist/query/traverse.js.map +1 -0
  178. package/dist/query/unresolved.d.ts +195 -0
  179. package/dist/query/unresolved.d.ts.map +1 -0
  180. package/dist/query/unresolved.js +225 -0
  181. package/dist/query/unresolved.js.map +1 -0
  182. package/dist/query/verification-status.d.ts +134 -0
  183. package/dist/query/verification-status.d.ts.map +1 -0
  184. package/dist/query/verification-status.js +163 -0
  185. package/dist/query/verification-status.js.map +1 -0
  186. package/dist/recording/index.d.ts +26 -0
  187. package/dist/recording/index.d.ts.map +1 -0
  188. package/dist/recording/index.js +30 -0
  189. package/dist/recording/index.js.map +1 -0
  190. package/dist/recording/migrate.d.ts +22 -0
  191. package/dist/recording/migrate.d.ts.map +1 -0
  192. package/dist/recording/migrate.js +51 -0
  193. package/dist/recording/migrate.js.map +1 -0
  194. package/dist/recording/reader.d.ts +27 -0
  195. package/dist/recording/reader.d.ts.map +1 -0
  196. package/dist/recording/reader.js +55 -0
  197. package/dist/recording/reader.js.map +1 -0
  198. package/dist/recording/redact.d.ts +63 -0
  199. package/dist/recording/redact.d.ts.map +1 -0
  200. package/dist/recording/redact.js +98 -0
  201. package/dist/recording/redact.js.map +1 -0
  202. package/dist/recording/schema.d.ts +41 -0
  203. package/dist/recording/schema.d.ts.map +1 -0
  204. package/dist/recording/schema.js +104 -0
  205. package/dist/recording/schema.js.map +1 -0
  206. package/dist/recording/writer.d.ts +120 -0
  207. package/dist/recording/writer.d.ts.map +1 -0
  208. package/dist/recording/writer.js +81 -0
  209. package/dist/recording/writer.js.map +1 -0
  210. package/dist/scoping/fanout.d.ts +86 -0
  211. package/dist/scoping/fanout.d.ts.map +1 -0
  212. package/dist/scoping/fanout.js +95 -0
  213. package/dist/scoping/fanout.js.map +1 -0
  214. package/dist/scoping/index.d.ts +10 -0
  215. package/dist/scoping/index.d.ts.map +1 -0
  216. package/dist/scoping/index.js +6 -0
  217. package/dist/scoping/index.js.map +1 -0
  218. package/dist/scoping/score.d.ts +83 -0
  219. package/dist/scoping/score.d.ts.map +1 -0
  220. package/dist/scoping/score.js +125 -0
  221. package/dist/scoping/score.js.map +1 -0
  222. package/dist/scoping/tiers.d.ts +32 -0
  223. package/dist/scoping/tiers.d.ts.map +1 -0
  224. package/dist/scoping/tiers.js +35 -0
  225. package/dist/scoping/tiers.js.map +1 -0
  226. package/dist/scoping/traverse.d.ts +60 -0
  227. package/dist/scoping/traverse.d.ts.map +1 -0
  228. package/dist/scoping/traverse.js +172 -0
  229. package/dist/scoping/traverse.js.map +1 -0
  230. package/dist/scoping/weights.d.ts +97 -0
  231. package/dist/scoping/weights.d.ts.map +1 -0
  232. package/dist/scoping/weights.js +167 -0
  233. package/dist/scoping/weights.js.map +1 -0
  234. package/dist/sources/git/diff.d.ts +53 -0
  235. package/dist/sources/git/diff.d.ts.map +1 -0
  236. package/dist/sources/git/diff.js +140 -0
  237. package/dist/sources/git/diff.js.map +1 -0
  238. package/dist/sources/git/env.d.ts +2 -0
  239. package/dist/sources/git/env.d.ts.map +1 -0
  240. package/dist/sources/git/env.js +21 -0
  241. package/dist/sources/git/env.js.map +1 -0
  242. package/dist/sources/git/history.d.ts +140 -0
  243. package/dist/sources/git/history.d.ts.map +1 -0
  244. package/dist/sources/git/history.js +314 -0
  245. package/dist/sources/git/history.js.map +1 -0
  246. package/dist/sources/git/index.d.ts +7 -0
  247. package/dist/sources/git/index.d.ts.map +1 -0
  248. package/dist/sources/git/index.js +4 -0
  249. package/dist/sources/git/index.js.map +1 -0
  250. package/dist/sources/git/source.d.ts +95 -0
  251. package/dist/sources/git/source.d.ts.map +1 -0
  252. package/dist/sources/git/source.js +0 -0
  253. package/dist/sources/git/source.js.map +1 -0
  254. package/dist/sources/migrations/dialects.d.ts +59 -0
  255. package/dist/sources/migrations/dialects.d.ts.map +1 -0
  256. package/dist/sources/migrations/dialects.js +84 -0
  257. package/dist/sources/migrations/dialects.js.map +1 -0
  258. package/dist/sources/migrations/index.d.ts +3 -0
  259. package/dist/sources/migrations/index.d.ts.map +1 -0
  260. package/dist/sources/migrations/index.js +2 -0
  261. package/dist/sources/migrations/index.js.map +1 -0
  262. package/dist/sources/migrations/read.d.ts +113 -0
  263. package/dist/sources/migrations/read.d.ts.map +1 -0
  264. package/dist/sources/migrations/read.js +270 -0
  265. package/dist/sources/migrations/read.js.map +1 -0
  266. package/dist/sources/workspace/index.d.ts +3 -0
  267. package/dist/sources/workspace/index.d.ts.map +1 -0
  268. package/dist/sources/workspace/index.js +2 -0
  269. package/dist/sources/workspace/index.js.map +1 -0
  270. package/dist/sources/workspace/workspace.d.ts +64 -0
  271. package/dist/sources/workspace/workspace.d.ts.map +1 -0
  272. package/dist/sources/workspace/workspace.js +294 -0
  273. package/dist/sources/workspace/workspace.js.map +1 -0
  274. package/dist/store/driver/driver.d.ts +82 -0
  275. package/dist/store/driver/driver.d.ts.map +1 -0
  276. package/dist/store/driver/driver.js +31 -0
  277. package/dist/store/driver/driver.js.map +1 -0
  278. package/dist/store/driver/node-sqlite.d.ts +28 -0
  279. package/dist/store/driver/node-sqlite.d.ts.map +1 -0
  280. package/dist/store/driver/node-sqlite.js +188 -0
  281. package/dist/store/driver/node-sqlite.js.map +1 -0
  282. package/dist/store/index.d.ts +33 -0
  283. package/dist/store/index.d.ts.map +1 -0
  284. package/dist/store/index.js +46 -0
  285. package/dist/store/index.js.map +1 -0
  286. package/dist/store/migrate.d.ts +68 -0
  287. package/dist/store/migrate.d.ts.map +1 -0
  288. package/dist/store/migrate.js +140 -0
  289. package/dist/store/migrate.js.map +1 -0
  290. package/dist/store/reader.d.ts +127 -0
  291. package/dist/store/reader.d.ts.map +1 -0
  292. package/dist/store/reader.js +269 -0
  293. package/dist/store/reader.js.map +1 -0
  294. package/dist/store/schema.d.ts +87 -0
  295. package/dist/store/schema.d.ts.map +1 -0
  296. package/dist/store/schema.js +322 -0
  297. package/dist/store/schema.js.map +1 -0
  298. package/dist/store/writer.d.ts +116 -0
  299. package/dist/store/writer.d.ts.map +1 -0
  300. package/dist/store/writer.js +279 -0
  301. package/dist/store/writer.js.map +1 -0
  302. package/dist/tiers/certify.d.ts +375 -0
  303. package/dist/tiers/certify.d.ts.map +1 -0
  304. package/dist/tiers/certify.js +434 -0
  305. package/dist/tiers/certify.js.map +1 -0
  306. package/dist/tiers/index.d.ts +5 -0
  307. package/dist/tiers/index.d.ts.map +1 -0
  308. package/dist/tiers/index.js +3 -0
  309. package/dist/tiers/index.js.map +1 -0
  310. package/dist/tiers/ladder.d.ts +73 -0
  311. package/dist/tiers/ladder.d.ts.map +1 -0
  312. package/dist/tiers/ladder.js +197 -0
  313. package/dist/tiers/ladder.js.map +1 -0
  314. package/dist/validation/config-graph.d.ts +104 -0
  315. package/dist/validation/config-graph.d.ts.map +1 -0
  316. package/dist/validation/config-graph.js +205 -0
  317. package/dist/validation/config-graph.js.map +1 -0
  318. package/dist/validation/env.d.ts +243 -0
  319. package/dist/validation/env.d.ts.map +1 -0
  320. package/dist/validation/env.js +447 -0
  321. package/dist/validation/env.js.map +1 -0
  322. package/dist/validation/index.d.ts +16 -0
  323. package/dist/validation/index.d.ts.map +1 -0
  324. package/dist/validation/index.js +9 -0
  325. package/dist/validation/index.js.map +1 -0
  326. package/dist/validation/join-substitution.d.ts +186 -0
  327. package/dist/validation/join-substitution.d.ts.map +1 -0
  328. package/dist/validation/join-substitution.js +191 -0
  329. package/dist/validation/join-substitution.js.map +1 -0
  330. package/dist/validation/migrations.d.ts +133 -0
  331. package/dist/validation/migrations.d.ts.map +1 -0
  332. package/dist/validation/migrations.js +315 -0
  333. package/dist/validation/migrations.js.map +1 -0
  334. package/dist/validation/nodes.d.ts +32 -0
  335. package/dist/validation/nodes.d.ts.map +1 -0
  336. package/dist/validation/nodes.js +45 -0
  337. package/dist/validation/nodes.js.map +1 -0
  338. package/dist/validation/rollback.d.ts +124 -0
  339. package/dist/validation/rollback.d.ts.map +1 -0
  340. package/dist/validation/rollback.js +302 -0
  341. package/dist/validation/rollback.js.map +1 -0
  342. package/dist/validation/route-drift.d.ts +108 -0
  343. package/dist/validation/route-drift.d.ts.map +1 -0
  344. package/dist/validation/route-drift.js +103 -0
  345. package/dist/validation/route-drift.js.map +1 -0
  346. package/dist/validation/sources.d.ts +153 -0
  347. package/dist/validation/sources.d.ts.map +1 -0
  348. package/dist/validation/sources.js +409 -0
  349. package/dist/validation/sources.js.map +1 -0
  350. package/dist/worker/index.d.ts +5 -0
  351. package/dist/worker/index.d.ts.map +1 -0
  352. package/dist/worker/index.js +3 -0
  353. package/dist/worker/index.js.map +1 -0
  354. package/dist/worker/pool.d.ts +73 -0
  355. package/dist/worker/pool.d.ts.map +1 -0
  356. package/dist/worker/pool.js +203 -0
  357. package/dist/worker/pool.js.map +1 -0
  358. package/dist/worker/protocol.d.ts +91 -0
  359. package/dist/worker/protocol.d.ts.map +1 -0
  360. package/dist/worker/protocol.js +19 -0
  361. package/dist/worker/protocol.js.map +1 -0
  362. package/dist/worker/traversal.worker.d.ts +25 -0
  363. package/dist/worker/traversal.worker.d.ts.map +1 -0
  364. package/dist/worker/traversal.worker.js +124 -0
  365. package/dist/worker/traversal.worker.js.map +1 -0
  366. package/package.json +29 -0
@@ -0,0 +1,131 @@
1
+ /**
2
+ * DEC-244, extended: the same row can be closed by two different kinds of
3
+ * evidence at once, and they must never collapse into each other.
4
+ *
5
+ * `applyDeclaredValues` (`declared-value-closure.ts`) answers from `.env*`
6
+ * config alone. `applyConfirmedFacts` (`confirmed-facts.ts`) answers from
7
+ * human testimony alone, and — since `ConfirmedFact.environment` landed —
8
+ * testimony can now be scoped to a *named* environment, not just an unscoped
9
+ * blanket answer. This module is the picture that shows both kinds of
10
+ * evidence side by side, per environment, without ever letting one stand in
11
+ * for the other.
12
+ *
13
+ * ## The real case that forced this shape
14
+ *
15
+ * `sherpa-frontend`'s `import.meta.env.VITE_BACKEND_API_URL` today has, on
16
+ * disk, in this worktree:
17
+ *
18
+ * - `"development"` → `http://localhost:8000`, **declared** — read from
19
+ * `.env.development.local`, class A (DEC-244 Row 1).
20
+ * - `"staging"` → `https://sherpa-backend-staging.up.railway.app`,
21
+ * **asserted** — a human-confirmed `ConfirmedFact` with
22
+ * `environment: "staging"`, class B. `"staging"` never appears in any
23
+ * `.env*` filename here; the *only* reason this module knows it exists at
24
+ * all is that a person named it on the fact.
25
+ * - `"production"` — still entirely unaddressed, by either source, and
26
+ * **still unnameable from anything this module reads.**
27
+ *
28
+ * ## Why `environment` is never inferred, only ever read
29
+ *
30
+ * `ConfirmedFact.environment`'s own doc is explicit: "human-supplied only,
31
+ * never inferred." This module upholds that by construction — the only
32
+ * places an environment name enters this picture are `resolve.ts`'s
33
+ * `knownEnvironments` (from `.env*` **filenames**, DEC-223's own "never
34
+ * guessed, always refused" rule) and `fact.environment` (typed as the human
35
+ * literally set it). Nothing here parses `"staging"` out of a hostname; the
36
+ * hostname's word "staging" and the fact's `environment: "staging"` are
37
+ * correlated in this specific real case only because a *person* read the
38
+ * same signal and typed the same word — this module never makes that
39
+ * connection itself, and would behave identically if the two disagreed.
40
+ *
41
+ * ## Why `"closed"` is reserved for fully-declared rows
42
+ *
43
+ * A row where every named environment resolves — some from config, some from
44
+ * testimony — could be called "closed." It is deliberately not: `state`
45
+ * reaches `"closed"` only when **every** named environment's evidence is
46
+ * `declared` (class A). One environment resting on testimony keeps the whole
47
+ * row at `"partially-closed"`, even if nothing is technically unaddressed —
48
+ * because a caller reading the single word `"closed"` must never have to
49
+ * re-check `environments[].reliability` to find out whether that word is
50
+ * hiding an unaudited assertion. This is the concrete answer to "what each
51
+ * provenance earns, side by side" (DEC-244 Row 1): declared is A, asserted is
52
+ * B, and the top-level state can never quietly promote a B into looking like
53
+ * an A.
54
+ */
55
+ import { askableHandle } from "./refusal-questions.js";
56
+ import { applyConfirmedFacts } from "./confirmed-facts.js";
57
+ import { resolveAgainstDeclared } from "../ledger/resolve.js";
58
+ import { DECLARED_VALUE_RELIABILITY } from "./declared-value-closure.js";
59
+ /** Same bar as `declared-value-closure.ts`, applied to the union of declared + asserted environment names. */
60
+ const MIN_KNOWN_ENVIRONMENTS_FOR_CLOSED = 2;
61
+ function isScoped(fact) {
62
+ return fact.environment !== undefined;
63
+ }
64
+ /**
65
+ * Describe every askable row against both sources of evidence at once.
66
+ *
67
+ * `declared` and `facts` are both pre-loaded by the caller — same
68
+ * read-once-apply-many discipline `resolveAgainstDeclared`/
69
+ * `applyConfirmedFacts` already follow. The fact-matching itself is not
70
+ * re-derived here: `applyConfirmedFacts` is called once and its output
71
+ * reused, so the `(repo, blockedBy)` scoping and the askable filter it
72
+ * already enforces are not re-implemented a second, potentially-diverging
73
+ * way.
74
+ */
75
+ export function describeRowClosures(refs, declared, facts, repo) {
76
+ const factApplication = applyConfirmedFacts(refs, facts, repo);
77
+ const factsByRef = new Map(factApplication.answered.map((m) => [m.ref, m.facts]));
78
+ const resolutionCache = new Map();
79
+ const pictures = [];
80
+ const notAskable = [];
81
+ for (const ref of refs) {
82
+ const blockedBy = askableHandle(ref);
83
+ if (blockedBy === null) {
84
+ notAskable.push(ref);
85
+ continue;
86
+ }
87
+ let resolution = resolutionCache.get(blockedBy);
88
+ if (resolution === undefined) {
89
+ resolution = resolveAgainstDeclared(blockedBy, declared);
90
+ resolutionCache.set(blockedBy, resolution);
91
+ }
92
+ const matchedFacts = factsByRef.get(ref) ?? [];
93
+ const scopedFacts = matchedFacts.filter(isScoped);
94
+ const unscopedAssertions = matchedFacts
95
+ .filter((f) => !isScoped(f))
96
+ .map((f) => ({ value: f.value, confirmedBy: f.confirmedBy, confirmedAt: f.confirmedAt }));
97
+ const environmentNames = new Set(resolution.knownEnvironments);
98
+ for (const f of scopedFacts)
99
+ environmentNames.add(f.environment);
100
+ const environments = [...environmentNames].sort().map((environment) => {
101
+ const declaredEntry = resolution.resolved.find((r) => r.environment === environment);
102
+ // First-write-wins is fine here: two scoped facts naming the same
103
+ // environment is a producer-side data question, not this reader's to
104
+ // adjudicate — surfacing one rather than silently averaging or
105
+ // discarding is the honest minimum.
106
+ const assertedEntry = scopedFacts.find((f) => f.environment === environment);
107
+ const reliability = declaredEntry !== undefined ? DECLARED_VALUE_RELIABILITY : assertedEntry !== undefined ? "B" : null;
108
+ return {
109
+ environment,
110
+ declaredValue: declaredEntry?.value ?? null,
111
+ declaredFile: declaredEntry?.file ?? null,
112
+ declaredLine: declaredEntry?.line ?? null,
113
+ assertedValue: assertedEntry?.value ?? null,
114
+ assertedBy: assertedEntry?.confirmedBy ?? null,
115
+ assertedAt: assertedEntry?.confirmedAt ?? null,
116
+ reliability,
117
+ };
118
+ });
119
+ const stillUnaddressed = environments.filter((e) => e.reliability === null).map((e) => e.environment);
120
+ const allDeclared = environments.length > 0 && environments.every((e) => e.reliability === "A");
121
+ const anyAddressed = environments.some((e) => e.reliability !== null) || unscopedAssertions.length > 0;
122
+ const state = environments.length >= MIN_KNOWN_ENVIRONMENTS_FOR_CLOSED && allDeclared
123
+ ? "closed"
124
+ : anyAddressed
125
+ ? "partially-closed"
126
+ : "open";
127
+ pictures.push({ ref, blockedBy, environments, unscopedAssertions, stillUnaddressed, state });
128
+ }
129
+ return { pictures, notAskable };
130
+ }
131
+ //# sourceMappingURL=row-closure-picture.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"row-closure-picture.js","sourceRoot":"","sources":["../../src/query/row-closure-picture.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,76 @@
1
+ /**
2
+ * The deterministic "have we seen this failure before" matcher — DEC-274.
3
+ *
4
+ * DEC-274 declined to build embedding/pgvector similarity search until a
5
+ * measurement showed what the *existing* graph machinery already answers.
6
+ * `rootCauseSearch` (queries.ts) is half of that existing machinery: it walks
7
+ * `INCIDENT_CORRELATED`/`FIXED_BY` edges from a node **already in the graph**.
8
+ * It cannot help with a brand-new failure that has no node yet — a stack
9
+ * trace or a set of touched files observed just now, before anything about
10
+ * this run has been written to the store.
11
+ *
12
+ * This module is the other half: given a new failure described only as
13
+ * "these files were touched" and/or "this is the error text", rank the
14
+ * `INCIDENT` nodes already in the graph by how much they resemble it, using
15
+ * two signals computed from data the graph already has — no embeddings, no
16
+ * new dependency, no model call:
17
+ *
18
+ * 1. **File-overlap Jaccard** — the new failure's touched-file set against
19
+ * each `INCIDENT`'s `INCIDENT_CORRELATED` file set (§11.6's own
20
+ * correlation edge, read in bulk instead of from one seed node).
21
+ * 2. **Token-set Jaccard on the error text** — the new failure's message
22
+ * against each `INCIDENT` node's `name` (today, always a commit subject
23
+ * line — real signal, but thin; see the git source's own module doc).
24
+ *
25
+ * Both are O(1) string/set operations, not a search index, so this scans
26
+ * every `INCIDENT` node per call. That is deliberate for now: the corpus
27
+ * measured in DEC-274 is a handful of incidents, and a linear scan over a
28
+ * few hundred nodes is not where this decision's cost lives. Revisit if the
29
+ * `INCIDENT` count ever reaches a size where that stops being true — it is
30
+ * not a reason to reach for embeddings, just for an index over this same
31
+ * data.
32
+ */
33
+ import type { IRNode } from "@descryy/ir";
34
+ import type { AdjacencyProvider, QueryResult } from "./provider.ts";
35
+ /**
36
+ * Jaccard similarity of the two strings' token sets: `|intersection| / |union|`.
37
+ *
38
+ * Exported so the measurement script and the tests can assert on it directly
39
+ * rather than only through the combined ranking, per the "caller must see
40
+ * why" requirement below.
41
+ */
42
+ export declare function tokenSetSimilarity(a: string, b: string): number;
43
+ /** Jaccard similarity of two file-path sets. Exported for the same reason as above. */
44
+ export declare function fileOverlapSimilarity(a: readonly string[], b: readonly string[]): number;
45
+ export interface SimilarFailureQuery {
46
+ /** Repo-relative paths touched by the new failure, if known. */
47
+ readonly touchedFiles?: readonly string[];
48
+ /** The new failure's error/exception text, if known. */
49
+ readonly errorMessage?: string;
50
+ }
51
+ export type SimilarIncidentSignalKind = "file-overlap" | "message-similarity";
52
+ export interface SimilarIncidentSignal {
53
+ readonly kind: SimilarIncidentSignalKind;
54
+ /** Jaccard similarity, 0..1. */
55
+ readonly score: number;
56
+ }
57
+ export interface SimilarIncidentMatch {
58
+ readonly incident: IRNode;
59
+ /** The FIX_PATTERN this incident resolved to, if the graph has one via FIXED_BY. */
60
+ readonly fix: IRNode | null;
61
+ /** Every signal that fired (score > 0) for this candidate — the "why". */
62
+ readonly signals: readonly SimilarIncidentSignal[];
63
+ /** Weighted combination of the fired signals. See `combine` below for the weights. */
64
+ readonly combinedScore: number;
65
+ }
66
+ export interface SimilarIncidentOptions {
67
+ /** Drop candidates whose combined score falls below this. Default: >0 (any signal fired). */
68
+ readonly minScore?: number;
69
+ readonly limit?: number;
70
+ }
71
+ /**
72
+ * Rank existing `INCIDENT` nodes by resemblance to a new, not-yet-recorded
73
+ * failure — graph identity only, explicitly not embeddings (DEC-274).
74
+ */
75
+ export declare function similarIncidents(provider: AdjacencyProvider, query: SimilarFailureQuery, options?: SimilarIncidentOptions): QueryResult<SimilarIncidentMatch[]>;
76
+ //# sourceMappingURL=similar-incidents.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"similar-incidents.d.ts","sourceRoot":"","sources":["../../src/query/similar-incidents.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAmB,MAAM,aAAa,CAAC;AAE3D,OAAO,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAiBpE;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAQ/D;AAED,uFAAuF;AACvF,wBAAgB,qBAAqB,CACnC,CAAC,EAAE,SAAS,MAAM,EAAE,EACpB,CAAC,EAAE,SAAS,MAAM,EAAE,GACnB,MAAM,CAQR;AAMD,MAAM,WAAW,mBAAmB;IAClC,gEAAgE;IAChE,QAAQ,CAAC,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1C,wDAAwD;IACxD,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,MAAM,yBAAyB,GAAG,cAAc,GAAG,oBAAoB,CAAC;AAE9E,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,IAAI,EAAE,yBAAyB,CAAC;IACzC,gCAAgC;IAChC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,oFAAoF;IACpF,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,0EAA0E;IAC1E,QAAQ,CAAC,OAAO,EAAE,SAAS,qBAAqB,EAAE,CAAC;IACnD,sFAAsF;IACtF,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,sBAAsB;IACrC,6FAA6F;IAC7F,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AA+BD;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,iBAAiB,EAC3B,KAAK,EAAE,mBAAmB,EAC1B,OAAO,GAAE,sBAA2B,GACnC,WAAW,CAAC,oBAAoB,EAAE,CAAC,CAiErC"}
@@ -0,0 +1,169 @@
1
+ /**
2
+ * The deterministic "have we seen this failure before" matcher — DEC-274.
3
+ *
4
+ * DEC-274 declined to build embedding/pgvector similarity search until a
5
+ * measurement showed what the *existing* graph machinery already answers.
6
+ * `rootCauseSearch` (queries.ts) is half of that existing machinery: it walks
7
+ * `INCIDENT_CORRELATED`/`FIXED_BY` edges from a node **already in the graph**.
8
+ * It cannot help with a brand-new failure that has no node yet — a stack
9
+ * trace or a set of touched files observed just now, before anything about
10
+ * this run has been written to the store.
11
+ *
12
+ * This module is the other half: given a new failure described only as
13
+ * "these files were touched" and/or "this is the error text", rank the
14
+ * `INCIDENT` nodes already in the graph by how much they resemble it, using
15
+ * two signals computed from data the graph already has — no embeddings, no
16
+ * new dependency, no model call:
17
+ *
18
+ * 1. **File-overlap Jaccard** — the new failure's touched-file set against
19
+ * each `INCIDENT`'s `INCIDENT_CORRELATED` file set (§11.6's own
20
+ * correlation edge, read in bulk instead of from one seed node).
21
+ * 2. **Token-set Jaccard on the error text** — the new failure's message
22
+ * against each `INCIDENT` node's `name` (today, always a commit subject
23
+ * line — real signal, but thin; see the git source's own module doc).
24
+ *
25
+ * Both are O(1) string/set operations, not a search index, so this scans
26
+ * every `INCIDENT` node per call. That is deliberate for now: the corpus
27
+ * measured in DEC-274 is a handful of incidents, and a linear scan over a
28
+ * few hundred nodes is not where this decision's cost lives. Revisit if the
29
+ * `INCIDENT` count ever reaches a size where that stops being true — it is
30
+ * not a reason to reach for embeddings, just for an index over this same
31
+ * data.
32
+ */
33
+ // ---------------------------------------------------------------------------
34
+ // Token-set Jaccard — the deterministic stand-in for "fuzzy" text matching.
35
+ // ---------------------------------------------------------------------------
36
+ /**
37
+ * Lowercased alphanumeric tokens. No stemming, no stopword list — either
38
+ * would be a modelling decision this function has no business making, and
39
+ * DEC-274 asks for "a real string-similarity measure", not a bespoke NLP
40
+ * pipeline standing in for the embeddings this decision is deferring.
41
+ */
42
+ function tokenize(text) {
43
+ const matches = text.toLowerCase().match(/[a-z0-9]+/g);
44
+ return new Set(matches ?? []);
45
+ }
46
+ /**
47
+ * Jaccard similarity of the two strings' token sets: `|intersection| / |union|`.
48
+ *
49
+ * Exported so the measurement script and the tests can assert on it directly
50
+ * rather than only through the combined ranking, per the "caller must see
51
+ * why" requirement below.
52
+ */
53
+ export function tokenSetSimilarity(a, b) {
54
+ const ta = tokenize(a);
55
+ const tb = tokenize(b);
56
+ if (ta.size === 0 || tb.size === 0)
57
+ return 0;
58
+ let intersection = 0;
59
+ for (const token of ta)
60
+ if (tb.has(token))
61
+ intersection += 1;
62
+ const union = ta.size + tb.size - intersection;
63
+ return union === 0 ? 0 : intersection / union;
64
+ }
65
+ /** Jaccard similarity of two file-path sets. Exported for the same reason as above. */
66
+ export function fileOverlapSimilarity(a, b) {
67
+ const sa = new Set(a);
68
+ const sb = new Set(b);
69
+ if (sa.size === 0 || sb.size === 0)
70
+ return 0;
71
+ let intersection = 0;
72
+ for (const path of sa)
73
+ if (sb.has(path))
74
+ intersection += 1;
75
+ const union = sa.size + sb.size - intersection;
76
+ return union === 0 ? 0 : intersection / union;
77
+ }
78
+ /**
79
+ * File overlap is weighted above message similarity: which files broke is a
80
+ * fact about the code, while a commit subject line is an incidental label a
81
+ * human happened to type. Both are real signal; neither is authoritative
82
+ * alone, which is exactly why DEC-274 asks for both rather than one.
83
+ */
84
+ const FILE_OVERLAP_WEIGHT = 0.6;
85
+ const MESSAGE_SIMILARITY_WEIGHT = 0.4;
86
+ /**
87
+ * Weighted average over the signals the *query* attempted, not just the ones
88
+ * that scored above zero. Normalising over only the non-zero scores would let
89
+ * a candidate matching on one signal alone outrank a candidate matching on
90
+ * both signals whenever the second signal's score is imperfect — a single
91
+ * exact file match would beat a near-exact file match paired with a partial
92
+ * message match, which inverts the whole point of combining two signals:
93
+ * corroborating evidence should rank *above* single-signal evidence, never
94
+ * below it. Zero-scoring an attempted-but-absent signal keeps that true.
95
+ */
96
+ function combine(attempted) {
97
+ if (attempted.length === 0)
98
+ return 0;
99
+ const weightOf = (kind) => kind === "file-overlap" ? FILE_OVERLAP_WEIGHT : MESSAGE_SIMILARITY_WEIGHT;
100
+ const totalWeight = attempted.reduce((sum, s) => sum + weightOf(s.kind), 0);
101
+ if (totalWeight === 0)
102
+ return 0;
103
+ const weighted = attempted.reduce((sum, s) => sum + weightOf(s.kind) * s.score, 0);
104
+ return weighted / totalWeight;
105
+ }
106
+ /**
107
+ * Rank existing `INCIDENT` nodes by resemblance to a new, not-yet-recorded
108
+ * failure — graph identity only, explicitly not embeddings (DEC-274).
109
+ */
110
+ export function similarIncidents(provider, query, options = {}) {
111
+ const minScore = options.minScore ?? 0;
112
+ const { nodes: incidents, truncated } = provider.nodesOfType("INCIDENT");
113
+ const queryFiles = query.touchedFiles ?? [];
114
+ const queryMessage = query.errorMessage ?? "";
115
+ const matches = [];
116
+ let floor = 4;
117
+ for (const incident of incidents) {
118
+ // Every signal the query attempted, including zero-scoring ones — the
119
+ // denominator `combine` needs. `signals` (below) keeps only the ones that
120
+ // actually fired, since that is the "why" a caller should see.
121
+ const attempted = [];
122
+ if (queryFiles.length > 0) {
123
+ const correlated = provider.outgoing(incident.id, { types: ["INCIDENT_CORRELATED"] });
124
+ const incidentFiles = [];
125
+ for (const edge of correlated) {
126
+ const node = provider.node(edge.to);
127
+ if (node?.file != null)
128
+ incidentFiles.push(node.file);
129
+ if (edge.resolution < floor)
130
+ floor = edge.resolution;
131
+ }
132
+ attempted.push({ kind: "file-overlap", score: fileOverlapSimilarity(queryFiles, incidentFiles) });
133
+ }
134
+ if (queryMessage.length > 0) {
135
+ attempted.push({ kind: "message-similarity", score: tokenSetSimilarity(queryMessage, incident.name) });
136
+ }
137
+ const signals = attempted.filter((s) => s.score > 0);
138
+ if (signals.length === 0)
139
+ continue;
140
+ const combinedScore = combine(attempted);
141
+ if (combinedScore < minScore || (minScore === 0 && combinedScore === 0))
142
+ continue;
143
+ let fix = null;
144
+ const fixedBy = provider.outgoing(incident.id, { types: ["FIXED_BY"] });
145
+ if (fixedBy.length > 0) {
146
+ fix = provider.node(fixedBy[0].to) ?? null;
147
+ if (fixedBy[0].resolution < floor)
148
+ floor = fixedBy[0].resolution;
149
+ }
150
+ matches.push({ incident, fix, signals, combinedScore });
151
+ }
152
+ matches.sort((a, b) => b.combinedScore - a.combinedScore || a.incident.id.localeCompare(b.incident.id));
153
+ const ranked = options.limit === undefined ? matches : matches.slice(0, Math.max(0, options.limit));
154
+ const notes = [
155
+ "Graph-structural + fuzzy-text matching only (DEC-274). No embedding similarity was run — " +
156
+ "a past incident with neither an overlapping file nor a similar commit subject will not " +
157
+ "appear here even if it was, in substance, the same failure.",
158
+ ];
159
+ if (queryFiles.length === 0 && queryMessage.length === 0) {
160
+ notes.push("Neither touchedFiles nor errorMessage was given, so no candidate could score above 0.");
161
+ }
162
+ return {
163
+ data: ranked,
164
+ stamp: { ...provider.baseStamp(), resolutionFloor: matches.length === 0 ? 0 : floor },
165
+ truncated: truncated || (options.limit !== undefined && matches.length > options.limit),
166
+ notes,
167
+ };
168
+ }
169
+ //# sourceMappingURL=similar-incidents.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"similar-incidents.js","sourceRoot":"","sources":["../../src/query/similar-incidents.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAMH,8EAA8E;AAC9E,4EAA4E;AAC5E,8EAA8E;AAE9E;;;;;GAKG;AACH,SAAS,QAAQ,CAAC,IAAY;IAC5B,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;IACvD,OAAO,IAAI,GAAG,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;AAChC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAAC,CAAS,EAAE,CAAS;IACrD,MAAM,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IACvB,MAAM,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IACvB,IAAI,EAAE,CAAC,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,IAAI,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IAC7C,IAAI,YAAY,GAAG,CAAC,CAAC;IACrB,KAAK,MAAM,KAAK,IAAI,EAAE;QAAE,IAAI,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC;YAAE,YAAY,IAAI,CAAC,CAAC;IAC7D,MAAM,KAAK,GAAG,EAAE,CAAC,IAAI,GAAG,EAAE,CAAC,IAAI,GAAG,YAAY,CAAC;IAC/C,OAAO,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,GAAG,KAAK,CAAC;AAChD,CAAC;AAED,uFAAuF;AACvF,MAAM,UAAU,qBAAqB,CACnC,CAAoB,EACpB,CAAoB;IAEpB,MAAM,EAAE,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC;IACtB,MAAM,EAAE,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC;IACtB,IAAI,EAAE,CAAC,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,IAAI,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IAC7C,IAAI,YAAY,GAAG,CAAC,CAAC;IACrB,KAAK,MAAM,IAAI,IAAI,EAAE;QAAE,IAAI,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,YAAY,IAAI,CAAC,CAAC;IAC3D,MAAM,KAAK,GAAG,EAAE,CAAC,IAAI,GAAG,EAAE,CAAC,IAAI,GAAG,YAAY,CAAC;IAC/C,OAAO,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,GAAG,KAAK,CAAC;AAChD,CAAC;AAqCD;;;;;GAKG;AACH,MAAM,mBAAmB,GAAG,GAAG,CAAC;AAChC,MAAM,yBAAyB,GAAG,GAAG,CAAC;AAEtC;;;;;;;;;GASG;AACH,SAAS,OAAO,CAAC,SAA2C;IAC1D,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IACrC,MAAM,QAAQ,GAAG,CAAC,IAA+B,EAAU,EAAE,CAC3D,IAAI,KAAK,cAAc,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,yBAAyB,CAAC;IAC5E,MAAM,WAAW,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;IAC5E,IAAI,WAAW,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IAChC,MAAM,QAAQ,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IACnF,OAAO,QAAQ,GAAG,WAAW,CAAC;AAChC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAC9B,QAA2B,EAC3B,KAA0B,EAC1B,UAAkC,EAAE;IAEpC,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,CAAC,CAAC;IACvC,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,GAAG,QAAQ,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;IAEzE,MAAM,UAAU,GAAG,KAAK,CAAC,YAAY,IAAI,EAAE,CAAC;IAC5C,MAAM,YAAY,GAAG,KAAK,CAAC,YAAY,IAAI,EAAE,CAAC;IAE9C,MAAM,OAAO,GAA2B,EAAE,CAAC;IAC3C,IAAI,KAAK,GAAoB,CAAC,CAAC;IAE/B,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;QACjC,sEAAsE;QACtE,0EAA0E;QAC1E,+DAA+D;QAC/D,MAAM,SAAS,GAA4B,EAAE,CAAC;QAE9C,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC1B,MAAM,UAAU,GAAG,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,qBAAqB,CAAC,EAAE,CAAC,CAAC;YACtF,MAAM,aAAa,GAAa,EAAE,CAAC;YACnC,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;gBAC9B,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBACpC,IAAI,IAAI,EAAE,IAAI,IAAI,IAAI;oBAAE,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACtD,IAAI,IAAI,CAAC,UAAU,GAAG,KAAK;oBAAE,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC;YACvD,CAAC;YACD,SAAS,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,qBAAqB,CAAC,UAAU,EAAE,aAAa,CAAC,EAAE,CAAC,CAAC;QACpG,CAAC;QAED,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5B,SAAS,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,oBAAoB,EAAE,KAAK,EAAE,kBAAkB,CAAC,YAAY,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACzG,CAAC;QAED,MAAM,OAAO,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;QACrD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,SAAS;QACnC,MAAM,aAAa,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;QACzC,IAAI,aAAa,GAAG,QAAQ,IAAI,CAAC,QAAQ,KAAK,CAAC,IAAI,aAAa,KAAK,CAAC,CAAC;YAAE,SAAS;QAElF,IAAI,GAAG,GAAkB,IAAI,CAAC;QAC9B,MAAM,OAAO,GAAG,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;QACxE,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,GAAG,GAAG,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAE,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC;YAC5C,IAAI,OAAO,CAAC,CAAC,CAAE,CAAC,UAAU,GAAG,KAAK;gBAAE,KAAK,GAAG,OAAO,CAAC,CAAC,CAAE,CAAC,UAAU,CAAC;QACrE,CAAC;QAED,OAAO,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,GAAG,EAAE,OAAO,EAAE,aAAa,EAAE,CAAC,CAAC;IAC1D,CAAC;IAED,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,GAAG,CAAC,CAAC,aAAa,IAAI,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC;IAExG,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;IAEpG,MAAM,KAAK,GAAa;QACtB,2FAA2F;YACzF,yFAAyF;YACzF,6DAA6D;KAChE,CAAC;IACF,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzD,KAAK,CAAC,IAAI,CAAC,uFAAuF,CAAC,CAAC;IACtG,CAAC;IAED,OAAO;QACL,IAAI,EAAE,MAAM;QACZ,KAAK,EAAE,EAAE,GAAG,QAAQ,CAAC,SAAS,EAAE,EAAE,eAAe,EAAE,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE;QACrF,SAAS,EAAE,SAAS,IAAI,CAAC,OAAO,CAAC,KAAK,KAAK,SAAS,IAAI,OAAO,CAAC,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC;QACvF,KAAK;KACN,CAAC;AACJ,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * The store-backed `AdjacencyProvider`.
3
+ *
4
+ * One implementation of the interface, not the interface's reason for existing.
5
+ * Everything above it is written against `AdjacencyProvider`, so swapping this
6
+ * for a Postgres or worker-hosted provider changes this file and nothing else.
7
+ */
8
+ import { type AdjacencyProvider } from "./provider.ts";
9
+ import type { SqlDriver } from "../store/driver/driver.ts";
10
+ export declare function createStoreProvider(driver: SqlDriver): AdjacencyProvider;
11
+ /** How many distinct commits the stored graph spans. One is healthy; more is not. */
12
+ export declare function commitSpread(driver: SqlDriver): number;
13
+ //# sourceMappingURL=sqlite.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sqlite.d.ts","sourceRoot":"","sources":["../../src/query/sqlite.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAGL,KAAK,iBAAiB,EAEvB,MAAM,eAAe,CAAC;AAGvB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAQ3D,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,GAAG,iBAAiB,CA4BxE;AAED,qFAAqF;AACrF,wBAAgB,YAAY,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM,CAMtD"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * The store-backed `AdjacencyProvider`.
3
+ *
4
+ * One implementation of the interface, not the interface's reason for existing.
5
+ * Everything above it is written against `AdjacencyProvider`, so swapping this
6
+ * for a Postgres or worker-hosted provider changes this file and nothing else.
7
+ */
8
+ import { DEFAULT_NODE_SET_LIMIT, } from "./provider.js";
9
+ import { getNode, incoming, nodesOfType, outgoing, unresolvedRefs } from "../store/reader.js";
10
+ import { IR_SCHEMA_VERSION } from "../store/schema.js";
11
+ export function createStoreProvider(driver) {
12
+ return {
13
+ node: (id) => getNode(driver, id),
14
+ outgoing: (id, options) => withOptions(outgoing(driver, id, options), options),
15
+ incoming: (id, options) => withOptions(incoming(driver, id, options), options),
16
+ nodesOfType: (type, limit = DEFAULT_NODE_SET_LIMIT) => nodesOfType(driver, type, limit),
17
+ unresolvedRefs: (options) => unresolvedRefs(driver, options ?? {}),
18
+ baseStamp() {
19
+ // The most recent run's commit, plus how many distinct commits are in the
20
+ // graph at all. More than one is a real staleness signal — it means part
21
+ // of the graph describes code that is no longer what the other part
22
+ // describes — and it is surfaced as a note rather than averaged away.
23
+ const row = driver
24
+ .prepare(`SELECT
25
+ (SELECT commit_sha FROM adapter_runs ORDER BY written_at DESC, id ASC LIMIT 1) AS commit_sha,
26
+ (SELECT MAX(written_at) FROM adapter_runs) AS built_at,
27
+ (SELECT COUNT(DISTINCT commit_sha) FROM adapter_runs) AS commits`)
28
+ .get();
29
+ return {
30
+ commitSha: row?.commit_sha ?? null,
31
+ graphBuiltAt: row?.built_at ?? null,
32
+ irSchemaVersion: IR_SCHEMA_VERSION,
33
+ };
34
+ },
35
+ };
36
+ }
37
+ /** How many distinct commits the stored graph spans. One is healthy; more is not. */
38
+ export function commitSpread(driver) {
39
+ return (driver
40
+ .prepare("SELECT COUNT(DISTINCT commit_sha) AS n FROM adapter_runs")
41
+ .get()?.n ?? 0);
42
+ }
43
+ /**
44
+ * The reader already filters by type and applies a limit in SQL. The confidence
45
+ * floor is applied here rather than pushed down, so that a provider swap cannot
46
+ * silently change which edges a traversal sees.
47
+ */
48
+ function withOptions(edges, options = {}) {
49
+ if (options.minConfidence === undefined)
50
+ return [...edges];
51
+ const floor = options.minConfidence;
52
+ return edges.filter((e) => e.confidence >= floor);
53
+ }
54
+ //# sourceMappingURL=sqlite.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sqlite.js","sourceRoot":"","sources":["../../src/query/sqlite.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACL,sBAAsB,GAIvB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAC9F,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AASvD,MAAM,UAAU,mBAAmB,CAAC,MAAiB;IACnD,OAAO;QACL,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;QACjC,QAAQ,EAAE,CAAC,EAAE,EAAE,OAA0B,EAAE,EAAE,CAAC,WAAW,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC;QACjG,QAAQ,EAAE,CAAC,EAAE,EAAE,OAA0B,EAAE,EAAE,CAAC,WAAW,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC;QACjG,WAAW,EAAE,CAAC,IAAI,EAAE,KAAK,GAAG,sBAAsB,EAAE,EAAE,CAAC,WAAW,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC;QACvF,cAAc,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,cAAc,CAAC,MAAM,EAAE,OAAO,IAAI,EAAE,CAAC;QAElE,SAAS;YACP,0EAA0E;YAC1E,yEAAyE;YACzE,oEAAoE;YACpE,sEAAsE;YACtE,MAAM,GAAG,GAAG,MAAM;iBACf,OAAO,CACN;;;8EAGoE,CACrE;iBACA,GAAG,EAAE,CAAC;YACT,OAAO;gBACL,SAAS,EAAE,GAAG,EAAE,UAAU,IAAI,IAAI;gBAClC,YAAY,EAAE,GAAG,EAAE,QAAQ,IAAI,IAAI;gBACnC,eAAe,EAAE,iBAAiB;aACnC,CAAC;QACJ,CAAC;KACF,CAAC;AACJ,CAAC;AAED,qFAAqF;AACrF,MAAM,UAAU,YAAY,CAAC,MAAiB;IAC5C,OAAO,CACL,MAAM;SACH,OAAO,CAAgB,0DAA0D,CAAC;SAClF,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,CACjB,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,SAAS,WAAW,CAClB,KAAmB,EACnB,UAA4B,EAAE;IAE9B,IAAI,OAAO,CAAC,aAAa,KAAK,SAAS;QAAE,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC;IAC3D,MAAM,KAAK,GAAG,OAAO,CAAC,aAAa,CAAC;IACpC,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,IAAI,KAAK,CAAC,CAAC;AACpD,CAAC"}
@@ -0,0 +1,110 @@
1
+ /**
2
+ * Traversal primitives — blueprint 1.1's `bfs`, `weightedBfs` and `findPath`.
3
+ *
4
+ * All written against `AdjacencyProvider`, never against the store. §11.8 chose
5
+ * application-code traversal over recursive SQL so that decay scoring, budgets
6
+ * and per-edge weights behave identically on SQLite and Postgres; that only
7
+ * holds while the traversal cannot tell which it is talking to.
8
+ *
9
+ * ## The termination trap, guarded here rather than at Step 12
10
+ *
11
+ * §12.4 scores a hop as
12
+ *
13
+ * new = parent × edgeWeight × coupling × incident × confidence
14
+ *
15
+ * and the coupling and incident factors *boost* — they can exceed 1.0. Three
16
+ * things break the moment the product can reach 1.0:
17
+ *
18
+ * - score stops decreasing monotonically, so best-first is no longer optimal;
19
+ * - a node can be reached later by a better path than the one that first found
20
+ * it, so a plain visited-set silently keeps the worse score;
21
+ * - on a cycle where the product is ≥ 1, traversal **does not terminate**.
22
+ *
23
+ * Two fixes, both here: `weightedBfs` keeps a best-score map and re-pushes on
24
+ * improvement (relaxation), and any hop whose combined factor reaches 1.0 is
25
+ * rejected with an error naming the edge. Step 12 supplies the weights; this is
26
+ * the layer that refuses to run with weights that cannot terminate.
27
+ */
28
+ import type { EdgeType, IREdge, ResolutionLevel } from "@descryy/ir";
29
+ import type { AdjacencyProvider } from "./provider.ts";
30
+ export type Direction = "out" | "in" | "both";
31
+ /**
32
+ * `USES_API`/`SERVES_API` edges, the two halves DEC-115 joins at one
33
+ * `API_ENDPOINT` node — a caller reaches it from one side, a route serves it
34
+ * from the other, and either side can exist without the other (golden
35
+ * pattern 08's own note). Named once so `crossApiEndpoint` and its tests read
36
+ * the same list rather than two copies drifting.
37
+ */
38
+ export declare const API_JOIN_EDGE_TYPES: readonly EdgeType[];
39
+ export interface TraversalOptions {
40
+ readonly types?: readonly EdgeType[];
41
+ readonly direction?: Direction;
42
+ readonly maxDepth?: number;
43
+ /** Node budget — DEC-007's 200 / 1,000 / 5,000. Truncation is always reported. */
44
+ readonly budget?: number;
45
+ readonly minConfidence?: number;
46
+ /** Fan-out cap per hop. Guards against hub nodes with in-degree in the thousands. */
47
+ readonly perNodeLimit?: number;
48
+ /**
49
+ * Opt-in, default off. At an `API_ENDPOINT` node specifically, also follow
50
+ * `USES_API`/`SERVES_API` edges in the direction the walk is not already
51
+ * using — DEC-138's measured gap: a walk reaching the shared endpoint from
52
+ * one side (say, a frontend caller's `USES_API` edge, direction `out`)
53
+ * cannot see the route that serves it, because `SERVES_API` is stored
54
+ * route -> endpoint and a uniform `out` walk never looks incoming at that
55
+ * one node. Off by default because it is a real, deliberate exception to
56
+ * "the walk means one direction throughout" — every other node keeps that
57
+ * property; only the join node DEC-115 designed to be crossed does not.
58
+ */
59
+ readonly crossApiEndpoint?: boolean;
60
+ }
61
+ export interface Reached {
62
+ readonly id: string;
63
+ readonly depth: number;
64
+ /** 1.0 at the seed, decaying outward. Always 1.0 for unweighted traversal. */
65
+ readonly score: number;
66
+ /** The edge that produced the best-known path to this node. Null at a seed. */
67
+ readonly via: IREdge | null;
68
+ }
69
+ export interface TraversalOutcome {
70
+ readonly reached: readonly Reached[];
71
+ readonly truncated: boolean;
72
+ /** Lowest resolution on any edge the answer traversed. Caps the reliability class. */
73
+ readonly resolutionFloor: ResolutionLevel;
74
+ }
75
+ /**
76
+ * Breadth-first reachability. Unweighted: every reached node scores 1.0.
77
+ *
78
+ * Terminates on a cyclic graph by construction — a plain visited-set is correct
79
+ * here precisely because there is no score to improve on a second visit.
80
+ */
81
+ export declare function bfs(provider: AdjacencyProvider, seeds: readonly string[], options?: TraversalOptions): TraversalOutcome;
82
+ export interface WeightedOptions extends TraversalOptions {
83
+ /**
84
+ * The per-hop decay factor for an edge. Must be strictly less than 1.0 —
85
+ * see the note at the top of this file. Defaults to the edge's own confidence,
86
+ * which §12.4 makes one term of the real formula.
87
+ */
88
+ readonly weightFor?: (edge: IREdge) => number;
89
+ /** Stop expanding below this score. The main reason traversal ends before the budget. */
90
+ readonly minScore?: number;
91
+ }
92
+ /**
93
+ * Best-first traversal with score decay and relaxation.
94
+ *
95
+ * "Relaxation" is not an optimisation here, it is what makes the result correct:
96
+ * with boosting factors in play a node can be reached later by a better path,
97
+ * and a visited-set that refuses to revisit would keep the worse score
98
+ * permanently. The best-score map plus re-push on improvement is the fix, and
99
+ * it costs nothing when scores do decrease monotonically.
100
+ */
101
+ export declare function weightedBfs(provider: AdjacencyProvider, seeds: readonly string[], options?: WeightedOptions): TraversalOutcome;
102
+ /**
103
+ * Shortest path by hop count, as a list of edges. Empty when unreachable.
104
+ *
105
+ * Hop count rather than score: "how is this connected" and "how much impact
106
+ * propagates" are different questions, and answering the first with the second's
107
+ * machinery gives a path that is heavier but shorter-looking.
108
+ */
109
+ export declare function findPath(provider: AdjacencyProvider, from: string, to: string, options?: TraversalOptions): readonly IREdge[];
110
+ //# sourceMappingURL=traverse.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"traverse.d.ts","sourceRoot":"","sources":["../../src/query/traverse.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAErE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAEvD,MAAM,MAAM,SAAS,GAAG,KAAK,GAAG,IAAI,GAAG,MAAM,CAAC;AAE9C;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,EAAE,SAAS,QAAQ,EAA+B,CAAC;AAEnF,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,QAAQ,EAAE,CAAC;IACrC,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,CAAC;IAC/B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,kFAAkF;IAClF,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,qFAAqF;IACrF,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,gBAAgB,CAAC,EAAE,OAAO,CAAC;CACrC;AAED,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,8EAA8E;IAC9E,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,+EAA+E;IAC/E,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,OAAO,EAAE,SAAS,OAAO,EAAE,CAAC;IACrC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,sFAAsF;IACtF,QAAQ,CAAC,eAAe,EAAE,eAAe,CAAC;CAC3C;AA2CD;;;;;GAKG;AACH,wBAAgB,GAAG,CACjB,QAAQ,EAAE,iBAAiB,EAC3B,KAAK,EAAE,SAAS,MAAM,EAAE,EACxB,OAAO,GAAE,gBAAqB,GAC7B,gBAAgB,CAkClB;AAED,MAAM,WAAW,eAAgB,SAAQ,gBAAgB;IACvD;;;;OAIG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IAC9C,yFAAyF;IACzF,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CACzB,QAAQ,EAAE,iBAAiB,EAC3B,KAAK,EAAE,SAAS,MAAM,EAAE,EACxB,OAAO,GAAE,eAAoB,GAC5B,gBAAgB,CAsDlB;AAED;;;;;;GAMG;AACH,wBAAgB,QAAQ,CACtB,QAAQ,EAAE,iBAAiB,EAC3B,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,EACV,OAAO,GAAE,gBAAqB,GAC7B,SAAS,MAAM,EAAE,CA8BnB"}
Binary file
@@ -0,0 +1 @@
1
+ {"version":3,"file":"traverse.js","sourceRoot":"","sources":["../../src/query/traverse.ts"],"names":[],"mappings":"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"}