@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,218 @@
1
+ /**
2
+ * `RootCauseScore` — architecture §18.3a, the deterministic ranking half.
3
+ *
4
+ * ```
5
+ * RootCauseScore = RuntimeEvidence + GraphDistance + ChangeCoupling + IncidentCorrelation
6
+ * ```
7
+ *
8
+ * §18.3 establishes why ranking exists at all: traversal alone returns a
9
+ * *path*, not a culprit. A five-hop chain has five candidate locations, and
10
+ * presenting all five is diagnostically equivalent to presenting none.
11
+ *
12
+ * ## Reuses three existing queries — does not re-derive them
13
+ *
14
+ * `documents/decisions-inbox/NOTE-4-correlation-graph-integration-prep.md`
15
+ * §1 maps three of the four terms onto queries this package already has,
16
+ * checked line by line against `queries.ts` rather than assumed:
17
+ *
18
+ * | Term | Query | Role here |
19
+ * | --- | --- | --- |
20
+ * | `GraphDistance` | `weightedBfs` (`impactOf`'s own underlying primitive, called directly — see below) | `direction: "out"`, walking `CALLS`/`USES_API`/`SERVES_API` from the failure point toward the deep implementation — §18.3's own worked example, and its own hop×confidence-decayed `score` is used as-is. |
21
+ * | `ChangeCoupling` | `changesWith` | Was this candidate, or a co-change partner of it, in the current diff. |
22
+ * | `IncidentCorrelation` | `rootCauseSearch` | Structural half only — inherits that query's own disclosed gap (no vector store, §8.2) unchanged. |
23
+ * | `RuntimeEvidence` | **none, and none should exist here** | See below. |
24
+ *
25
+ * **`weightedBfs` directly, not `impactOf`** — a deliberate, narrow deviation
26
+ * from "reuses, does not re-derive." `RankedRootCauseCandidate.path` (the
27
+ * real hop-by-hop `GraphPathHop[]` `Finding.graphPath` needs,
28
+ * `documents/decisions-inbox/DEC-D-NEXT-graph-path-hop-reconstruction.md`,
29
+ * `descry-desktop`) is reconstructed by walking `Reached.via`'s parent
30
+ * pointers back to the seed — the exact traversal that produced `depth`/
31
+ * `score`. `impactOf` discards `via` in its own `hydrate()` step before this
32
+ * module ever sees the result, so getting it means calling `weightedBfs`
33
+ * itself. The scoring math is not re-derived — `entry.score`/`entry.depth`
34
+ * are still `weightedBfs`'s own values, used as-is, same as before; only the
35
+ * thin hydrate-plus-note wrapper `impactOf` adds is now inlined here so the
36
+ * `via` chain survives.
37
+ *
38
+ * `RootCauseScore`'s own walk crosses the `SERVES_API` join the same way
39
+ * §18.3's example does: `SERVES_API` is stored route → endpoint
40
+ * (`queries.ts`'s own comment), so a plain `direction: "out"` walk reaches
41
+ * the endpoint from a caller's `USES_API` edge and stops — it never looks
42
+ * incoming at that one node to find the route serving it. `crossApiEndpoint`
43
+ * (DEC-138) is passed through for exactly this reason; without it, this
44
+ * module's own fixture (`InvoicePage → deleteInvoice → DELETE
45
+ * /invoice/:id`) would never reach `InvoiceController`/`InvoiceService` at
46
+ * all, and the architecture's own worked example would not walk. The join
47
+ * crossover means a hop's own `from`/`to` sometimes runs opposite the walk's
48
+ * direction (the route→endpoint edge is walked endpoint→controller) — `path`
49
+ * reports the edge exactly as stored, never flipped to look like a forward
50
+ * chain that was never actually walked that way; see `pathTo`'s own comment.
51
+ *
52
+ * ## `RuntimeEvidence` is a precondition, never a fourth addend — read this before changing anything
53
+ *
54
+ * NOTE-4 §5 settles this and `ai-layer-plan.md` §5 (G3) preserves it: a
55
+ * candidate with maximal `GraphDistance + ChangeCoupling + IncidentCorrelation`
56
+ * and zero `RuntimeEvidence` is a plausible guess ranked well, and it must
57
+ * **never** reach `confirmed` however the other three terms sum — because
58
+ * summing all four together *is* the failure mode where a well-ranked guess
59
+ * reads as an established fact. DEC-276 encodes the same rule one layer up
60
+ * as `E == 0 → unconfirmed`.
61
+ *
62
+ * So this module never computes `structuralScore + runtimeEvidence` — not
63
+ * as an internal step, not as a returned field, nowhere. Two design choices
64
+ * make this a **type constraint**, not just a documented convention (proven
65
+ * by a `@ts-expect-error` test in this module's test file, checked by
66
+ * `tsc`, not merely asserted at runtime):
67
+ *
68
+ * 1. `structuralScore: number` carries only `GraphDistance + ChangeCoupling
69
+ * + IncidentCorrelation`. Nothing runtime-evidence-shaped is a term in
70
+ * it, ever.
71
+ * 2. `namedByEvidence: readonly string[]` — the verbatim evidence
72
+ * descriptions naming this exact candidate, supplied by the caller
73
+ * (`descry-runtime`'s evidence-to-node resolution; NOTE-4 §2 is explicit
74
+ * that no graph query for this term exists or should — it is not a
75
+ * graph fact). A `string[]`, not a `number` or a boolean count:
76
+ * `structuralScore + namedByEvidence` does not typecheck, so a caller
77
+ * cannot casually fold it into the ranking arithmetic by accident. A
78
+ * caller who really wants to misuse it has to write new code to do so —
79
+ * this module supplies no field shaped like the thing G3 forbids
80
+ * summing.
81
+ *
82
+ * §18.3a's own table still calls `RuntimeEvidence` *"the strongest
83
+ * signal"* — a node named directly in a backend log outranks one merely on
84
+ * the path. That is honored **as a sort key, not a score term**:
85
+ * `namedByEvidence`-non-empty candidates sort before every candidate
86
+ * without it, and only within each of those two groups does
87
+ * `structuralScore` decide. Categorical partitioning, never arithmetic
88
+ * combination — the distinction NOTE-4 §5 draws is preserved exactly.
89
+ *
90
+ * `RootCauseScore` the architecture names is therefore not a function this
91
+ * module returns as one number. It ranks; a gate above this layer (G3/G4,
92
+ * `descry-runtime`/the pipeline) decides what `namedByEvidence` and the
93
+ * finding's actual evidence bundle are allowed to promote — this module
94
+ * does not gate and does not categorise.
95
+ *
96
+ * ## The resolution caveat (§18.3)
97
+ *
98
+ * *"At R0/R1 the tracer will lose the trail at the first cross-file call
99
+ * and must say 'trace stopped here' rather than presenting a truncated
100
+ * chain as complete."* When the traversal's own resolution floor is R0/R1,
101
+ * a note says so in those words — in addition to, not instead of,
102
+ * `impactOf`'s own disclosure, which explains *why* (cross-file calls are
103
+ * not reliably resolved at that level).
104
+ *
105
+ * ## Weights are starting values, not measurements
106
+ *
107
+ * `CLAUDE.md`: *"Numbers in the docs are targets or starting values, not
108
+ * measurements."* `DEFAULT_ROOT_CAUSE_WEIGHTS` and `INCIDENT_SATURATION`
109
+ * below are exactly that — picked, not measured, gathered into one named
110
+ * block rather than left as literals in the arithmetic so the next reader
111
+ * can find and tune them without reading the function body.
112
+ */
113
+ import type { EdgeType, GraphPathHop, IRNode, ResolutionLevel } from "@descryy/ir";
114
+ import type { AdjacencyProvider } from "./provider.ts";
115
+ import { type RootCauseMatch } from "./queries.ts";
116
+ /** §18.3's own walk: from the failure point toward the deep implementation. */
117
+ export declare const ROOT_CAUSE_TRACE_EDGE_TYPES: readonly EdgeType[];
118
+ /**
119
+ * The three structural terms' multipliers. **Unmeasured starting values**
120
+ * (`CLAUDE.md`'s own rule) — tune from data, not intuition, once golden
121
+ * investigations (`ai-layer-plan.md` §9 layer 4) exist to tune against.
122
+ */
123
+ export interface RootCauseWeights {
124
+ readonly graphDistance: number;
125
+ readonly changeCoupling: number;
126
+ readonly incidentCorrelation: number;
127
+ }
128
+ export declare const DEFAULT_ROOT_CAUSE_WEIGHTS: RootCauseWeights;
129
+ /**
130
+ * How many correlated incidents saturate `IncidentCorrelation`'s raw 0–1
131
+ * contribution. Unmeasured, same rule as the weights above: a candidate
132
+ * with dozens of correlated incidents should not dominate the ranking
133
+ * arithmetically more than one with a handful, so the raw count is capped
134
+ * before it is weighted.
135
+ */
136
+ export declare const INCIDENT_SATURATION = 3;
137
+ /** Why a candidate's `ChangeCoupling` term is nonzero — a fact worth keeping, not just a number. */
138
+ export type ChangeCouplingEvidence = {
139
+ readonly kind: "direct";
140
+ } | {
141
+ readonly kind: "co-change";
142
+ readonly viaNodeId: string;
143
+ readonly support: number;
144
+ readonly confidence: number;
145
+ };
146
+ export interface RootCauseOptions {
147
+ readonly weights?: RootCauseWeights;
148
+ /** How many ranked candidates to return. Presenting every candidate is diagnostically equivalent to presenting none — §18.3a. */
149
+ readonly topN?: number;
150
+ readonly maxDepth?: number;
151
+ readonly budget?: number;
152
+ /** Node ids the current diff touches directly — `ChangeCoupling`'s "in the current diff" half. */
153
+ readonly changedIds?: ReadonlySet<string>;
154
+ /**
155
+ * Verbatim evidence descriptions, keyed by the exact node id they name
156
+ * directly — supplied by the caller, never computed here. See the module
157
+ * header: this is not a graph fact, and no query for it exists in this
158
+ * package.
159
+ */
160
+ readonly namedByEvidence?: ReadonlyMap<string, readonly string[]>;
161
+ }
162
+ export interface RankedRootCauseCandidate {
163
+ readonly node: IRNode;
164
+ /** Hops from the failure point along the traced walk. 0 at the failure point itself. */
165
+ readonly depth: number;
166
+ /**
167
+ * `GraphDistance + ChangeCoupling + IncidentCorrelation`, weighted.
168
+ * **Never** includes `RuntimeEvidence` — see the module header.
169
+ */
170
+ readonly structuralScore: number;
171
+ readonly changeCoupling: ChangeCouplingEvidence | null;
172
+ readonly correlatedIncidents: readonly RootCauseMatch[];
173
+ /**
174
+ * Verbatim evidence naming this exact candidate. Empty, never omitted,
175
+ * when none. A precondition for promotion elsewhere (NOTE-4 §5, G3,
176
+ * DEC-276) — never a term in `structuralScore`.
177
+ */
178
+ readonly namedByEvidence: readonly string[];
179
+ /** The candidate node's own resolution — a fact stored on it directly, not re-derived. */
180
+ readonly resolution: ResolutionLevel;
181
+ /**
182
+ * `true` when `depth === 0` — this candidate *is* the failure point, and
183
+ * `resolution` above is that single node's own fact, not the minimum over
184
+ * any traced hop. `DEC-NEXT-empty-graph-path-resolution-floor.md` ruled
185
+ * that a zero-hop path caps reliability at the same class as a
186
+ * genuinely-but-badly-resolved one, but the two are not the same claim —
187
+ * this field is what lets a caller (`reliabilityNote()`'s `emptyPath`
188
+ * parameter, `@descryy/ir`) say which one happened, rather than
189
+ * inferring it from `depth === 0` at every call site. Never `true` for a
190
+ * deeper candidate: at least one hop was traced to reach it, however
191
+ * poorly that hop resolved.
192
+ */
193
+ readonly emptyPath: boolean;
194
+ /**
195
+ * The real, walked hop-by-hop chain from the failure point to this
196
+ * candidate — `Finding.graphPath`'s own source. Empty exactly when
197
+ * `emptyPath` is `true`. Reconstructed from `weightedBfs`'s own `via`
198
+ * chain, not a second independent walk — see the module header.
199
+ */
200
+ readonly path: readonly GraphPathHop[];
201
+ }
202
+ export interface RootCauseRanking {
203
+ /** Capped at `topN` (or fewer, if there simply weren't more candidates). */
204
+ readonly ranked: readonly RankedRootCauseCandidate[];
205
+ /** The honest denominator — every candidate the walk reached, before the `topN` cap. */
206
+ readonly candidateCount: number;
207
+ /** True when the walk's own budget stopped it short, or when `topN` dropped candidates. */
208
+ readonly truncated: boolean;
209
+ readonly notes: readonly string[];
210
+ }
211
+ /**
212
+ * Rank the candidates reachable from `failurePoint` by the three structural
213
+ * terms of `RootCauseScore` (architecture §18.3a). See the module header
214
+ * for why `RuntimeEvidence` is deliberately absent from the arithmetic and
215
+ * present only as `namedByEvidence`, a categorical sort key.
216
+ */
217
+ export declare function rankRootCause(provider: AdjacencyProvider, failurePoint: string, options?: RootCauseOptions): RootCauseRanking;
218
+ //# sourceMappingURL=root-cause-score.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"root-cause-score.d.ts","sourceRoot":"","sources":["../../src/query/root-cause-score.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,251 @@
1
+ /**
2
+ * `RootCauseScore` — architecture §18.3a, the deterministic ranking half.
3
+ *
4
+ * ```
5
+ * RootCauseScore = RuntimeEvidence + GraphDistance + ChangeCoupling + IncidentCorrelation
6
+ * ```
7
+ *
8
+ * §18.3 establishes why ranking exists at all: traversal alone returns a
9
+ * *path*, not a culprit. A five-hop chain has five candidate locations, and
10
+ * presenting all five is diagnostically equivalent to presenting none.
11
+ *
12
+ * ## Reuses three existing queries — does not re-derive them
13
+ *
14
+ * `documents/decisions-inbox/NOTE-4-correlation-graph-integration-prep.md`
15
+ * §1 maps three of the four terms onto queries this package already has,
16
+ * checked line by line against `queries.ts` rather than assumed:
17
+ *
18
+ * | Term | Query | Role here |
19
+ * | --- | --- | --- |
20
+ * | `GraphDistance` | `weightedBfs` (`impactOf`'s own underlying primitive, called directly — see below) | `direction: "out"`, walking `CALLS`/`USES_API`/`SERVES_API` from the failure point toward the deep implementation — §18.3's own worked example, and its own hop×confidence-decayed `score` is used as-is. |
21
+ * | `ChangeCoupling` | `changesWith` | Was this candidate, or a co-change partner of it, in the current diff. |
22
+ * | `IncidentCorrelation` | `rootCauseSearch` | Structural half only — inherits that query's own disclosed gap (no vector store, §8.2) unchanged. |
23
+ * | `RuntimeEvidence` | **none, and none should exist here** | See below. |
24
+ *
25
+ * **`weightedBfs` directly, not `impactOf`** — a deliberate, narrow deviation
26
+ * from "reuses, does not re-derive." `RankedRootCauseCandidate.path` (the
27
+ * real hop-by-hop `GraphPathHop[]` `Finding.graphPath` needs,
28
+ * `documents/decisions-inbox/DEC-D-NEXT-graph-path-hop-reconstruction.md`,
29
+ * `descry-desktop`) is reconstructed by walking `Reached.via`'s parent
30
+ * pointers back to the seed — the exact traversal that produced `depth`/
31
+ * `score`. `impactOf` discards `via` in its own `hydrate()` step before this
32
+ * module ever sees the result, so getting it means calling `weightedBfs`
33
+ * itself. The scoring math is not re-derived — `entry.score`/`entry.depth`
34
+ * are still `weightedBfs`'s own values, used as-is, same as before; only the
35
+ * thin hydrate-plus-note wrapper `impactOf` adds is now inlined here so the
36
+ * `via` chain survives.
37
+ *
38
+ * `RootCauseScore`'s own walk crosses the `SERVES_API` join the same way
39
+ * §18.3's example does: `SERVES_API` is stored route → endpoint
40
+ * (`queries.ts`'s own comment), so a plain `direction: "out"` walk reaches
41
+ * the endpoint from a caller's `USES_API` edge and stops — it never looks
42
+ * incoming at that one node to find the route serving it. `crossApiEndpoint`
43
+ * (DEC-138) is passed through for exactly this reason; without it, this
44
+ * module's own fixture (`InvoicePage → deleteInvoice → DELETE
45
+ * /invoice/:id`) would never reach `InvoiceController`/`InvoiceService` at
46
+ * all, and the architecture's own worked example would not walk. The join
47
+ * crossover means a hop's own `from`/`to` sometimes runs opposite the walk's
48
+ * direction (the route→endpoint edge is walked endpoint→controller) — `path`
49
+ * reports the edge exactly as stored, never flipped to look like a forward
50
+ * chain that was never actually walked that way; see `pathTo`'s own comment.
51
+ *
52
+ * ## `RuntimeEvidence` is a precondition, never a fourth addend — read this before changing anything
53
+ *
54
+ * NOTE-4 §5 settles this and `ai-layer-plan.md` §5 (G3) preserves it: a
55
+ * candidate with maximal `GraphDistance + ChangeCoupling + IncidentCorrelation`
56
+ * and zero `RuntimeEvidence` is a plausible guess ranked well, and it must
57
+ * **never** reach `confirmed` however the other three terms sum — because
58
+ * summing all four together *is* the failure mode where a well-ranked guess
59
+ * reads as an established fact. DEC-276 encodes the same rule one layer up
60
+ * as `E == 0 → unconfirmed`.
61
+ *
62
+ * So this module never computes `structuralScore + runtimeEvidence` — not
63
+ * as an internal step, not as a returned field, nowhere. Two design choices
64
+ * make this a **type constraint**, not just a documented convention (proven
65
+ * by a `@ts-expect-error` test in this module's test file, checked by
66
+ * `tsc`, not merely asserted at runtime):
67
+ *
68
+ * 1. `structuralScore: number` carries only `GraphDistance + ChangeCoupling
69
+ * + IncidentCorrelation`. Nothing runtime-evidence-shaped is a term in
70
+ * it, ever.
71
+ * 2. `namedByEvidence: readonly string[]` — the verbatim evidence
72
+ * descriptions naming this exact candidate, supplied by the caller
73
+ * (`descry-runtime`'s evidence-to-node resolution; NOTE-4 §2 is explicit
74
+ * that no graph query for this term exists or should — it is not a
75
+ * graph fact). A `string[]`, not a `number` or a boolean count:
76
+ * `structuralScore + namedByEvidence` does not typecheck, so a caller
77
+ * cannot casually fold it into the ranking arithmetic by accident. A
78
+ * caller who really wants to misuse it has to write new code to do so —
79
+ * this module supplies no field shaped like the thing G3 forbids
80
+ * summing.
81
+ *
82
+ * §18.3a's own table still calls `RuntimeEvidence` *"the strongest
83
+ * signal"* — a node named directly in a backend log outranks one merely on
84
+ * the path. That is honored **as a sort key, not a score term**:
85
+ * `namedByEvidence`-non-empty candidates sort before every candidate
86
+ * without it, and only within each of those two groups does
87
+ * `structuralScore` decide. Categorical partitioning, never arithmetic
88
+ * combination — the distinction NOTE-4 §5 draws is preserved exactly.
89
+ *
90
+ * `RootCauseScore` the architecture names is therefore not a function this
91
+ * module returns as one number. It ranks; a gate above this layer (G3/G4,
92
+ * `descry-runtime`/the pipeline) decides what `namedByEvidence` and the
93
+ * finding's actual evidence bundle are allowed to promote — this module
94
+ * does not gate and does not categorise.
95
+ *
96
+ * ## The resolution caveat (§18.3)
97
+ *
98
+ * *"At R0/R1 the tracer will lose the trail at the first cross-file call
99
+ * and must say 'trace stopped here' rather than presenting a truncated
100
+ * chain as complete."* When the traversal's own resolution floor is R0/R1,
101
+ * a note says so in those words — in addition to, not instead of,
102
+ * `impactOf`'s own disclosure, which explains *why* (cross-file calls are
103
+ * not reliably resolved at that level).
104
+ *
105
+ * ## Weights are starting values, not measurements
106
+ *
107
+ * `CLAUDE.md`: *"Numbers in the docs are targets or starting values, not
108
+ * measurements."* `DEFAULT_ROOT_CAUSE_WEIGHTS` and `INCIDENT_SATURATION`
109
+ * below are exactly that — picked, not measured, gathered into one named
110
+ * block rather than left as literals in the arithmetic so the next reader
111
+ * can find and tune them without reading the function body.
112
+ */
113
+ import { changesWith, rootCauseSearch } from "./queries.js";
114
+ import { weightedBfs } from "./traverse.js";
115
+ /** §18.3's own walk: from the failure point toward the deep implementation. */
116
+ export const ROOT_CAUSE_TRACE_EDGE_TYPES = ["CALLS", "USES_API", "SERVES_API"];
117
+ export const DEFAULT_ROOT_CAUSE_WEIGHTS = {
118
+ graphDistance: 1,
119
+ changeCoupling: 0.6,
120
+ incidentCorrelation: 0.8,
121
+ };
122
+ /**
123
+ * How many correlated incidents saturate `IncidentCorrelation`'s raw 0–1
124
+ * contribution. Unmeasured, same rule as the weights above: a candidate
125
+ * with dozens of correlated incidents should not dominate the ranking
126
+ * arithmetically more than one with a handful, so the raw count is capped
127
+ * before it is weighted.
128
+ */
129
+ export const INCIDENT_SATURATION = 3;
130
+ const DEFAULT_TOP_N = 5;
131
+ function changeCouplingFor(provider, candidateId, changedIds) {
132
+ if (changedIds.has(candidateId))
133
+ return { kind: "direct" };
134
+ let best = null;
135
+ for (const co of changesWith(provider, candidateId).data) {
136
+ if (!changedIds.has(co.node.id))
137
+ continue;
138
+ if (best === null || (best.kind === "co-change" && co.confidence > best.confidence)) {
139
+ best = { kind: "co-change", viaNodeId: co.node.id, support: co.support, confidence: co.confidence };
140
+ }
141
+ }
142
+ return best;
143
+ }
144
+ function rawChangeCoupling(evidence) {
145
+ if (evidence === null)
146
+ return 0;
147
+ return evidence.kind === "direct" ? 1 : evidence.confidence;
148
+ }
149
+ /**
150
+ * Walks `reachedById`'s `via` parent pointers from `targetId` back to the
151
+ * seed (`via === null`), returning the hops in seed-to-target order.
152
+ *
153
+ * The edge stored at each step is reported exactly as `IREdge` has it
154
+ * (`from`/`to` never flipped) — at a `crossApiEndpoint` join the walk can
155
+ * arrive at a node via an edge whose *stored* direction runs the other way
156
+ * (the route→endpoint `SERVES_API` edge, walked endpoint→controller), and
157
+ * `next`/`via` in `neighbours()` already account for that: `entry.id`
158
+ * (the node this hop reached) equals exactly one of `via.from`/`via.to`, and
159
+ * the other end is always the parent — regardless of which direction the
160
+ * walk actually moved. That is the rule this function uses, rather than
161
+ * assuming `via.from` is always the parent.
162
+ */
163
+ function pathTo(reachedById, targetId) {
164
+ const hops = [];
165
+ let currentId = targetId;
166
+ for (;;) {
167
+ const entry = reachedById.get(currentId);
168
+ if (entry === undefined || entry.via === null)
169
+ break;
170
+ const edge = entry.via;
171
+ hops.push({ from: edge.from, to: edge.to, edgeType: edge.type, resolution: edge.resolution });
172
+ currentId = edge.to === currentId ? edge.from : edge.to;
173
+ }
174
+ return hops.reverse();
175
+ }
176
+ /**
177
+ * Rank the candidates reachable from `failurePoint` by the three structural
178
+ * terms of `RootCauseScore` (architecture §18.3a). See the module header
179
+ * for why `RuntimeEvidence` is deliberately absent from the arithmetic and
180
+ * present only as `namedByEvidence`, a categorical sort key.
181
+ */
182
+ export function rankRootCause(provider, failurePoint, options = {}) {
183
+ const weights = options.weights ?? DEFAULT_ROOT_CAUSE_WEIGHTS;
184
+ const topN = Math.max(0, Math.floor(options.topN ?? DEFAULT_TOP_N));
185
+ const changedIds = options.changedIds ?? new Set();
186
+ const namedByEvidence = options.namedByEvidence ?? new Map();
187
+ const outcome = weightedBfs(provider, [failurePoint], {
188
+ direction: "out",
189
+ types: ROOT_CAUSE_TRACE_EDGE_TYPES,
190
+ crossApiEndpoint: true,
191
+ ...(options.maxDepth === undefined ? {} : { maxDepth: options.maxDepth }),
192
+ ...(options.budget === undefined ? {} : { budget: options.budget }),
193
+ });
194
+ const reachedById = new Map(outcome.reached.map((r) => [r.id, r]));
195
+ const candidates = [];
196
+ for (const entry of outcome.reached) {
197
+ const node = provider.node(entry.id);
198
+ if (node === undefined)
199
+ continue; // hydrate: the provider no longer has this node
200
+ const coupling = changeCouplingFor(provider, node.id, changedIds);
201
+ const incidents = rootCauseSearch(provider, node.id).data;
202
+ const incidentCorrelationRaw = Math.min(1, incidents.length / INCIDENT_SATURATION);
203
+ const structuralScore = weights.graphDistance * entry.score + // weightedBfs's own hop x confidence decay — not re-derived
204
+ weights.changeCoupling * rawChangeCoupling(coupling) +
205
+ weights.incidentCorrelation * incidentCorrelationRaw;
206
+ candidates.push({
207
+ node,
208
+ depth: entry.depth,
209
+ structuralScore,
210
+ changeCoupling: coupling,
211
+ correlatedIncidents: incidents,
212
+ namedByEvidence: namedByEvidence.get(node.id) ?? [],
213
+ resolution: node.resolution,
214
+ emptyPath: entry.depth === 0,
215
+ path: pathTo(reachedById, node.id),
216
+ });
217
+ }
218
+ // §18.3a: RuntimeEvidence is "the strongest signal" for which candidate to
219
+ // present first — honored here as a categorical partition (named, then
220
+ // not), never as an arithmetic combination with structuralScore.
221
+ const sorted = [...candidates].sort((a, b) => {
222
+ const evidenceRank = (b.namedByEvidence.length > 0 ? 1 : 0) - (a.namedByEvidence.length > 0 ? 1 : 0);
223
+ if (evidenceRank !== 0)
224
+ return evidenceRank;
225
+ if (b.structuralScore !== a.structuralScore)
226
+ return b.structuralScore - a.structuralScore;
227
+ return a.node.id.localeCompare(b.node.id);
228
+ });
229
+ const notes = [];
230
+ if (outcome.truncated) {
231
+ // Mirrors queries.ts's own `result()` helper — impactOf's equivalent
232
+ // note, inlined here since this module calls weightedBfs directly (see
233
+ // module header).
234
+ notes.push("The node budget was reached, so this answer is partial. Nodes beyond the budget " +
235
+ "were not examined and are not reported as clean.");
236
+ }
237
+ if (outcome.resolutionFloor <= 1) {
238
+ notes.push(`Trace stopped here: edges are resolved no better than R${outcome.resolutionFloor}, and a ` +
239
+ "cross-file call at that level may not appear in the graph at all. Candidates beyond an " +
240
+ "unresolved hop are invisible to this ranking, and their absence must not be read as " +
241
+ '"no root cause beyond this point" (architecture §18.3\'s resolution caveat).');
242
+ }
243
+ const ranked = sorted.slice(0, topN);
244
+ return {
245
+ ranked,
246
+ candidateCount: sorted.length,
247
+ truncated: outcome.truncated || sorted.length > ranked.length,
248
+ notes,
249
+ };
250
+ }
251
+ //# sourceMappingURL=root-cause-score.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"root-cause-score.js","sourceRoot":"","sources":["../../src/query/root-cause-score.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,108 @@
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 type { ConfirmedFact, ReliabilityClass, UnresolvedRef } from "@descryy/ir";
56
+ import type { DeclaredEnvValue } from "../ledger/resolve.ts";
57
+ import { type ClosureState } from "./declared-value-closure.ts";
58
+ /** A human-confirmed value with no `environment` on the fact — deliberately not attributed to any named one. */
59
+ export interface AssertedValue {
60
+ readonly value: string;
61
+ readonly confirmedBy: string;
62
+ readonly confirmedAt: string;
63
+ }
64
+ /**
65
+ * One named environment — named by a `.env*` filename, a scoped
66
+ * `ConfirmedFact`, or both — and everything either source says about it.
67
+ */
68
+ export interface EnvironmentValue {
69
+ readonly environment: string;
70
+ readonly declaredValue: string | null;
71
+ readonly declaredFile: string | null;
72
+ readonly declaredLine: number | null;
73
+ readonly assertedValue: string | null;
74
+ readonly assertedBy: string | null;
75
+ readonly assertedAt: string | null;
76
+ /** `"A"` when `declaredValue` is set, `"B"` when only a scoped assertion addresses it, `null` when neither. */
77
+ readonly reliability: ReliabilityClass | null;
78
+ }
79
+ export interface RowClosurePicture {
80
+ readonly ref: UnresolvedRef;
81
+ readonly blockedBy: string;
82
+ /** Every environment either source names, sorted. Never invented beyond what a filename or a fact states. */
83
+ readonly environments: readonly EnvironmentValue[];
84
+ /** Facts matching this row's `(repo, blockedBy)` with no `environment` — testimony, scope unspecified. */
85
+ readonly unscopedAssertions: readonly AssertedValue[];
86
+ /** `environments` entries with `reliability === null` — named by something, addressed by nothing. */
87
+ readonly stillUnaddressed: readonly string[];
88
+ readonly state: ClosureState | "open";
89
+ }
90
+ export interface RowClosureApplication {
91
+ /** One per askable row, `state` included even when `"open"` — the fuller shape is the point. */
92
+ readonly pictures: readonly RowClosurePicture[];
93
+ /** Rows `askableHandle` refused outright: wrong class, unset, no handle. Untouched by either source. */
94
+ readonly notAskable: readonly UnresolvedRef[];
95
+ }
96
+ /**
97
+ * Describe every askable row against both sources of evidence at once.
98
+ *
99
+ * `declared` and `facts` are both pre-loaded by the caller — same
100
+ * read-once-apply-many discipline `resolveAgainstDeclared`/
101
+ * `applyConfirmedFacts` already follow. The fact-matching itself is not
102
+ * re-derived here: `applyConfirmedFacts` is called once and its output
103
+ * reused, so the `(repo, blockedBy)` scoping and the askable filter it
104
+ * already enforces are not re-implemented a second, potentially-diverging
105
+ * way.
106
+ */
107
+ export declare function describeRowClosures(refs: readonly UnresolvedRef[], declared: readonly DeclaredEnvValue[], facts: readonly ConfirmedFact[], repo: string): RowClosureApplication;
108
+ //# sourceMappingURL=row-closure-picture.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"row-closure-picture.d.ts","sourceRoot":"","sources":["../../src/query/row-closure-picture.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAIlF,OAAO,KAAK,EAAE,gBAAgB,EAA4B,MAAM,sBAAsB,CAAC;AAEvF,OAAO,EAA8B,KAAK,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAK5F,gHAAgH;AAChH,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAED;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,QAAQ,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,+GAA+G;IAC/G,QAAQ,CAAC,WAAW,EAAE,gBAAgB,GAAG,IAAI,CAAC;CAC/C;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,GAAG,EAAE,aAAa,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,6GAA6G;IAC7G,QAAQ,CAAC,YAAY,EAAE,SAAS,gBAAgB,EAAE,CAAC;IACnD,0GAA0G;IAC1G,QAAQ,CAAC,kBAAkB,EAAE,SAAS,aAAa,EAAE,CAAC;IACtD,qGAAqG;IACrG,QAAQ,CAAC,gBAAgB,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7C,QAAQ,CAAC,KAAK,EAAE,YAAY,GAAG,MAAM,CAAC;CACvC;AAED,MAAM,WAAW,qBAAqB;IACpC,gGAAgG;IAChG,QAAQ,CAAC,QAAQ,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAChD,wGAAwG;IACxG,QAAQ,CAAC,UAAU,EAAE,SAAS,aAAa,EAAE,CAAC;CAC/C;AAMD;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,SAAS,aAAa,EAAE,EAC9B,QAAQ,EAAE,SAAS,gBAAgB,EAAE,EACrC,KAAK,EAAE,SAAS,aAAa,EAAE,EAC/B,IAAI,EAAE,MAAM,GACX,qBAAqB,CAoEvB"}