@descryy/core 0.4.0 → 0.5.1

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 (361) hide show
  1. package/dist/budget/reply.d.ts +11 -46
  2. package/dist/budget/reply.d.ts.map +1 -1
  3. package/dist/budget/reply.js +10 -39
  4. package/dist/budget/reply.js.map +1 -1
  5. package/dist/budget/size.d.ts +2 -21
  6. package/dist/budget/size.d.ts.map +1 -1
  7. package/dist/budget/size.js +3 -24
  8. package/dist/budget/size.js.map +1 -1
  9. package/dist/capabilities/preconditions.d.ts +7 -68
  10. package/dist/capabilities/preconditions.d.ts.map +1 -1
  11. package/dist/capabilities/preconditions.js +6 -57
  12. package/dist/capabilities/preconditions.js.map +1 -1
  13. package/dist/contracts/engine.d.ts +23 -11
  14. package/dist/contracts/engine.d.ts.map +1 -1
  15. package/dist/contracts/engine.js +23 -11
  16. package/dist/contracts/engine.js.map +1 -1
  17. package/dist/contracts/orphans.d.ts +18 -122
  18. package/dist/contracts/orphans.d.ts.map +1 -1
  19. package/dist/contracts/orphans.js +36 -134
  20. package/dist/contracts/orphans.js.map +1 -1
  21. package/dist/contracts/paths.d.ts +4 -114
  22. package/dist/contracts/paths.d.ts.map +1 -1
  23. package/dist/contracts/paths.js +7 -140
  24. package/dist/contracts/paths.js.map +1 -1
  25. package/dist/contracts/shapes.d.ts +13 -66
  26. package/dist/contracts/shapes.d.ts.map +1 -1
  27. package/dist/contracts/shapes.js +20 -91
  28. package/dist/contracts/shapes.js.map +1 -1
  29. package/dist/governance/budget.d.ts +12 -48
  30. package/dist/governance/budget.d.ts.map +1 -1
  31. package/dist/governance/budget.js +12 -48
  32. package/dist/governance/budget.js.map +1 -1
  33. package/dist/governance/candidate-boundary.d.ts +4 -32
  34. package/dist/governance/candidate-boundary.d.ts.map +1 -1
  35. package/dist/governance/candidate-boundary.js +4 -32
  36. package/dist/governance/candidate-boundary.js.map +1 -1
  37. package/dist/governance/escalation.d.ts +7 -45
  38. package/dist/governance/escalation.d.ts.map +1 -1
  39. package/dist/governance/escalation.js +7 -45
  40. package/dist/governance/escalation.js.map +1 -1
  41. package/dist/governance/fact-boundary.d.ts +7 -49
  42. package/dist/governance/fact-boundary.d.ts.map +1 -1
  43. package/dist/governance/fact-boundary.js +5 -43
  44. package/dist/governance/fact-boundary.js.map +1 -1
  45. package/dist/governance/finding-funnel.d.ts +11 -72
  46. package/dist/governance/finding-funnel.d.ts.map +1 -1
  47. package/dist/governance/finding-funnel.js +9 -68
  48. package/dist/governance/finding-funnel.js.map +1 -1
  49. package/dist/graph/build.d.ts +9 -90
  50. package/dist/graph/build.d.ts.map +1 -1
  51. package/dist/graph/build.js +15 -62
  52. package/dist/graph/build.js.map +1 -1
  53. package/dist/graph/cross-language.d.ts +4 -43
  54. package/dist/graph/cross-language.d.ts.map +1 -1
  55. package/dist/graph/cross-language.js +9 -77
  56. package/dist/graph/cross-language.js.map +1 -1
  57. package/dist/graph/merge.d.ts +8 -88
  58. package/dist/graph/merge.d.ts.map +1 -1
  59. package/dist/graph/merge.js +9 -93
  60. package/dist/graph/merge.js.map +1 -1
  61. package/dist/graph/observed-tests.d.ts +7 -68
  62. package/dist/graph/observed-tests.d.ts.map +1 -1
  63. package/dist/graph/observed-tests.js +5 -60
  64. package/dist/graph/observed-tests.js.map +1 -1
  65. package/dist/graph/persist.d.ts +2 -25
  66. package/dist/graph/persist.d.ts.map +1 -1
  67. package/dist/graph/persist.js +2 -25
  68. package/dist/graph/persist.js.map +1 -1
  69. package/dist/graph/runtime-confirmation.d.ts +14 -91
  70. package/dist/graph/runtime-confirmation.d.ts.map +1 -1
  71. package/dist/graph/runtime-confirmation.js +19 -103
  72. package/dist/graph/runtime-confirmation.js.map +1 -1
  73. package/dist/ledger/mint.d.ts +9 -43
  74. package/dist/ledger/mint.d.ts.map +1 -1
  75. package/dist/ledger/mint.js +15 -65
  76. package/dist/ledger/mint.js.map +1 -1
  77. package/dist/ledger/resolve.d.ts +13 -81
  78. package/dist/ledger/resolve.d.ts.map +1 -1
  79. package/dist/ledger/resolve.js +13 -76
  80. package/dist/ledger/resolve.js.map +1 -1
  81. package/dist/multipr/fingerprint.d.ts +5 -46
  82. package/dist/multipr/fingerprint.d.ts.map +1 -1
  83. package/dist/multipr/fingerprint.js +22 -74
  84. package/dist/multipr/fingerprint.js.map +1 -1
  85. package/dist/multipr/hidden-dependency.d.ts +13 -73
  86. package/dist/multipr/hidden-dependency.d.ts.map +1 -1
  87. package/dist/multipr/hidden-dependency.js +12 -63
  88. package/dist/multipr/hidden-dependency.js.map +1 -1
  89. package/dist/multipr/mechanical.d.ts +25 -160
  90. package/dist/multipr/mechanical.d.ts.map +1 -1
  91. package/dist/multipr/mechanical.js +21 -137
  92. package/dist/multipr/mechanical.js.map +1 -1
  93. package/dist/multipr/migration-heads.d.ts +18 -105
  94. package/dist/multipr/migration-heads.d.ts.map +1 -1
  95. package/dist/multipr/migration-heads.js +15 -84
  96. package/dist/multipr/migration-heads.js.map +1 -1
  97. package/dist/multipr/overlap.d.ts +16 -94
  98. package/dist/multipr/overlap.d.ts.map +1 -1
  99. package/dist/multipr/overlap.js +25 -105
  100. package/dist/multipr/overlap.js.map +1 -1
  101. package/dist/multipr/scope-store.d.ts +15 -80
  102. package/dist/multipr/scope-store.d.ts.map +1 -1
  103. package/dist/multipr/scope-store.js +17 -87
  104. package/dist/multipr/scope-store.js.map +1 -1
  105. package/dist/multipr/superseded.d.ts +10 -95
  106. package/dist/multipr/superseded.d.ts.map +1 -1
  107. package/dist/multipr/superseded.js +7 -60
  108. package/dist/multipr/superseded.js.map +1 -1
  109. package/dist/query/confirmed-facts.d.ts +12 -58
  110. package/dist/query/confirmed-facts.d.ts.map +1 -1
  111. package/dist/query/confirmed-facts.js +8 -47
  112. package/dist/query/confirmed-facts.js.map +1 -1
  113. package/dist/query/declared-value-closure.d.ts +13 -104
  114. package/dist/query/declared-value-closure.d.ts.map +1 -1
  115. package/dist/query/declared-value-closure.js +15 -104
  116. package/dist/query/declared-value-closure.js.map +1 -1
  117. package/dist/query/memory.d.ts +4 -16
  118. package/dist/query/memory.d.ts.map +1 -1
  119. package/dist/query/memory.js +9 -22
  120. package/dist/query/memory.js.map +1 -1
  121. package/dist/query/prominence.d.ts +6 -55
  122. package/dist/query/prominence.d.ts.map +1 -1
  123. package/dist/query/prominence.js +6 -55
  124. package/dist/query/prominence.js.map +1 -1
  125. package/dist/query/provider.d.ts +27 -93
  126. package/dist/query/provider.d.ts.map +1 -1
  127. package/dist/query/provider.js +8 -29
  128. package/dist/query/provider.js.map +1 -1
  129. package/dist/query/queries.d.ts +15 -65
  130. package/dist/query/queries.d.ts.map +1 -1
  131. package/dist/query/queries.js +30 -104
  132. package/dist/query/queries.js.map +1 -1
  133. package/dist/query/refusal-fetch.d.ts +8 -85
  134. package/dist/query/refusal-fetch.d.ts.map +1 -1
  135. package/dist/query/refusal-fetch.js +11 -93
  136. package/dist/query/refusal-fetch.js.map +1 -1
  137. package/dist/query/refusal-questions.d.ts +17 -92
  138. package/dist/query/refusal-questions.d.ts.map +1 -1
  139. package/dist/query/refusal-questions.js +14 -78
  140. package/dist/query/refusal-questions.js.map +1 -1
  141. package/dist/query/resolution-floor.d.ts +3 -23
  142. package/dist/query/resolution-floor.d.ts.map +1 -1
  143. package/dist/query/resolution-floor.js +3 -23
  144. package/dist/query/resolution-floor.js.map +1 -1
  145. package/dist/query/root-cause-score.d.ts +11 -161
  146. package/dist/query/root-cause-score.d.ts.map +1 -1
  147. package/dist/query/root-cause-score.js +6 -137
  148. package/dist/query/root-cause-score.js.map +1 -1
  149. package/dist/query/row-closure-picture.d.ts +5 -67
  150. package/dist/query/row-closure-picture.d.ts.map +1 -1
  151. package/dist/query/row-closure-picture.js +6 -67
  152. package/dist/query/row-closure-picture.js.map +1 -1
  153. package/dist/query/similar-incidents.d.ts +6 -41
  154. package/dist/query/similar-incidents.d.ts.map +1 -1
  155. package/dist/query/similar-incidents.js +15 -69
  156. package/dist/query/similar-incidents.js.map +1 -1
  157. package/dist/query/sqlite.d.ts +3 -7
  158. package/dist/query/sqlite.d.ts.map +1 -1
  159. package/dist/query/sqlite.js +9 -19
  160. package/dist/query/sqlite.js.map +1 -1
  161. package/dist/query/test-coverage.d.ts +5 -45
  162. package/dist/query/test-coverage.d.ts.map +1 -1
  163. package/dist/query/test-coverage.js +10 -53
  164. package/dist/query/test-coverage.js.map +1 -1
  165. package/dist/query/traverse.d.ts +22 -126
  166. package/dist/query/traverse.d.ts.map +1 -1
  167. package/dist/query/traverse.js +25 -126
  168. package/dist/query/traverse.js.map +1 -1
  169. package/dist/query/unresolved.d.ts +19 -164
  170. package/dist/query/unresolved.d.ts.map +1 -1
  171. package/dist/query/unresolved.js +11 -138
  172. package/dist/query/unresolved.js.map +1 -1
  173. package/dist/query/verification-status.d.ts +12 -109
  174. package/dist/query/verification-status.d.ts.map +1 -1
  175. package/dist/query/verification-status.js +9 -99
  176. package/dist/query/verification-status.js.map +1 -1
  177. package/dist/recording/migrate.d.ts +4 -10
  178. package/dist/recording/migrate.d.ts.map +1 -1
  179. package/dist/recording/migrate.js +4 -10
  180. package/dist/recording/migrate.js.map +1 -1
  181. package/dist/recording/reader.d.ts +2 -7
  182. package/dist/recording/reader.d.ts.map +1 -1
  183. package/dist/recording/reader.js +2 -7
  184. package/dist/recording/reader.js.map +1 -1
  185. package/dist/recording/redact.d.ts +6 -57
  186. package/dist/recording/redact.d.ts.map +1 -1
  187. package/dist/recording/redact.js +8 -64
  188. package/dist/recording/redact.js.map +1 -1
  189. package/dist/recording/schema.d.ts +3 -38
  190. package/dist/recording/schema.d.ts.map +1 -1
  191. package/dist/recording/schema.js +3 -38
  192. package/dist/recording/schema.js.map +1 -1
  193. package/dist/recording/writer.d.ts +11 -74
  194. package/dist/recording/writer.d.ts.map +1 -1
  195. package/dist/recording/writer.js +3 -43
  196. package/dist/recording/writer.js.map +1 -1
  197. package/dist/scoping/fanout.d.ts +6 -68
  198. package/dist/scoping/fanout.d.ts.map +1 -1
  199. package/dist/scoping/fanout.js +6 -68
  200. package/dist/scoping/fanout.js.map +1 -1
  201. package/dist/scoping/score.d.ts +20 -70
  202. package/dist/scoping/score.d.ts.map +1 -1
  203. package/dist/scoping/score.js +20 -70
  204. package/dist/scoping/score.js.map +1 -1
  205. package/dist/scoping/tiers.d.ts +4 -16
  206. package/dist/scoping/tiers.d.ts.map +1 -1
  207. package/dist/scoping/tiers.js +4 -16
  208. package/dist/scoping/tiers.js.map +1 -1
  209. package/dist/scoping/traverse.d.ts +3 -25
  210. package/dist/scoping/traverse.d.ts.map +1 -1
  211. package/dist/scoping/traverse.js +14 -49
  212. package/dist/scoping/traverse.js.map +1 -1
  213. package/dist/scoping/weights.d.ts +10 -74
  214. package/dist/scoping/weights.d.ts.map +1 -1
  215. package/dist/scoping/weights.js +14 -86
  216. package/dist/scoping/weights.js.map +1 -1
  217. package/dist/sources/confirmed/incidents.d.ts +5 -35
  218. package/dist/sources/confirmed/incidents.d.ts.map +1 -1
  219. package/dist/sources/confirmed/incidents.js +14 -48
  220. package/dist/sources/confirmed/incidents.js.map +1 -1
  221. package/dist/sources/git/diff.d.ts +93 -63
  222. package/dist/sources/git/diff.d.ts.map +1 -1
  223. package/dist/sources/git/diff.js +200 -81
  224. package/dist/sources/git/diff.js.map +1 -1
  225. package/dist/sources/git/env.d.ts +7 -0
  226. package/dist/sources/git/env.d.ts.map +1 -1
  227. package/dist/sources/git/env.js +10 -11
  228. package/dist/sources/git/env.js.map +1 -1
  229. package/dist/sources/git/history.d.ts +64 -84
  230. package/dist/sources/git/history.d.ts.map +1 -1
  231. package/dist/sources/git/history.js +141 -112
  232. package/dist/sources/git/history.js.map +1 -1
  233. package/dist/sources/git/incidents.d.ts +13 -75
  234. package/dist/sources/git/incidents.d.ts.map +1 -1
  235. package/dist/sources/git/incidents.js +21 -91
  236. package/dist/sources/git/incidents.js.map +1 -1
  237. package/dist/sources/git/index.d.ts +5 -3
  238. package/dist/sources/git/index.d.ts.map +1 -1
  239. package/dist/sources/git/index.js +3 -2
  240. package/dist/sources/git/index.js.map +1 -1
  241. package/dist/sources/git/source.d.ts +9 -79
  242. package/dist/sources/git/source.d.ts.map +1 -1
  243. package/dist/sources/git/source.js +33 -133
  244. package/dist/sources/git/source.js.map +1 -1
  245. package/dist/sources/migrations/across-change.d.ts +94 -0
  246. package/dist/sources/migrations/across-change.d.ts.map +1 -0
  247. package/dist/sources/migrations/across-change.js +278 -0
  248. package/dist/sources/migrations/across-change.js.map +1 -0
  249. package/dist/sources/migrations/dialects.d.ts +20 -36
  250. package/dist/sources/migrations/dialects.d.ts.map +1 -1
  251. package/dist/sources/migrations/dialects.js +11 -36
  252. package/dist/sources/migrations/dialects.js.map +1 -1
  253. package/dist/sources/migrations/index.d.ts +3 -1
  254. package/dist/sources/migrations/index.d.ts.map +1 -1
  255. package/dist/sources/migrations/index.js +2 -1
  256. package/dist/sources/migrations/index.js.map +1 -1
  257. package/dist/sources/migrations/read.d.ts +14 -79
  258. package/dist/sources/migrations/read.d.ts.map +1 -1
  259. package/dist/sources/migrations/read.js +14 -89
  260. package/dist/sources/migrations/read.js.map +1 -1
  261. package/dist/sources/workspace/workspace.d.ts +6 -42
  262. package/dist/sources/workspace/workspace.d.ts.map +1 -1
  263. package/dist/sources/workspace/workspace.js +10 -53
  264. package/dist/sources/workspace/workspace.js.map +1 -1
  265. package/dist/store/driver/driver.d.ts +9 -38
  266. package/dist/store/driver/driver.d.ts.map +1 -1
  267. package/dist/store/driver/driver.js +4 -22
  268. package/dist/store/driver/driver.js.map +1 -1
  269. package/dist/store/driver/node-sqlite.d.ts +3 -12
  270. package/dist/store/driver/node-sqlite.d.ts.map +1 -1
  271. package/dist/store/driver/node-sqlite.js +4 -18
  272. package/dist/store/driver/node-sqlite.js.map +1 -1
  273. package/dist/store/index.d.ts +2 -7
  274. package/dist/store/index.d.ts.map +1 -1
  275. package/dist/store/index.js +4 -10
  276. package/dist/store/index.js.map +1 -1
  277. package/dist/store/migrate.d.ts +14 -50
  278. package/dist/store/migrate.d.ts.map +1 -1
  279. package/dist/store/migrate.js +15 -52
  280. package/dist/store/migrate.js.map +1 -1
  281. package/dist/store/reader.d.ts +19 -84
  282. package/dist/store/reader.d.ts.map +1 -1
  283. package/dist/store/reader.js +25 -92
  284. package/dist/store/reader.js.map +1 -1
  285. package/dist/store/schema.d.ts +14 -76
  286. package/dist/store/schema.d.ts.map +1 -1
  287. package/dist/store/schema.js +14 -76
  288. package/dist/store/schema.js.map +1 -1
  289. package/dist/store/writer.d.ts +14 -88
  290. package/dist/store/writer.d.ts.map +1 -1
  291. package/dist/store/writer.js +29 -123
  292. package/dist/store/writer.js.map +1 -1
  293. package/dist/tiers/certify.d.ts +46 -281
  294. package/dist/tiers/certify.d.ts.map +1 -1
  295. package/dist/tiers/certify.js +46 -226
  296. package/dist/tiers/certify.js.map +1 -1
  297. package/dist/tiers/ladder.d.ts +7 -51
  298. package/dist/tiers/ladder.d.ts.map +1 -1
  299. package/dist/tiers/ladder.js +13 -89
  300. package/dist/tiers/ladder.js.map +1 -1
  301. package/dist/validation/attributes.d.ts +6 -55
  302. package/dist/validation/attributes.d.ts.map +1 -1
  303. package/dist/validation/attributes.js +6 -55
  304. package/dist/validation/attributes.js.map +1 -1
  305. package/dist/validation/config-graph.d.ts +7 -56
  306. package/dist/validation/config-graph.d.ts.map +1 -1
  307. package/dist/validation/config-graph.js +15 -61
  308. package/dist/validation/config-graph.js.map +1 -1
  309. package/dist/validation/env.d.ts +47 -8
  310. package/dist/validation/env.d.ts.map +1 -1
  311. package/dist/validation/env.js +119 -31
  312. package/dist/validation/env.js.map +1 -1
  313. package/dist/validation/index.d.ts +2 -0
  314. package/dist/validation/index.d.ts.map +1 -1
  315. package/dist/validation/index.js +1 -0
  316. package/dist/validation/index.js.map +1 -1
  317. package/dist/validation/join-substitution.d.ts +22 -120
  318. package/dist/validation/join-substitution.d.ts.map +1 -1
  319. package/dist/validation/join-substitution.js +13 -90
  320. package/dist/validation/join-substitution.js.map +1 -1
  321. package/dist/validation/migration-integrity.d.ts +11 -72
  322. package/dist/validation/migration-integrity.d.ts.map +1 -1
  323. package/dist/validation/migration-integrity.js +16 -79
  324. package/dist/validation/migration-integrity.js.map +1 -1
  325. package/dist/validation/migrations.d.ts +22 -101
  326. package/dist/validation/migrations.d.ts.map +1 -1
  327. package/dist/validation/migrations.js +19 -83
  328. package/dist/validation/migrations.js.map +1 -1
  329. package/dist/validation/nodes.d.ts +3 -1
  330. package/dist/validation/nodes.d.ts.map +1 -1
  331. package/dist/validation/nodes.js +3 -1
  332. package/dist/validation/nodes.js.map +1 -1
  333. package/dist/validation/orm-registration.d.ts +106 -0
  334. package/dist/validation/orm-registration.d.ts.map +1 -0
  335. package/dist/validation/orm-registration.js +191 -0
  336. package/dist/validation/orm-registration.js.map +1 -0
  337. package/dist/validation/rollback.d.ts +10 -73
  338. package/dist/validation/rollback.d.ts.map +1 -1
  339. package/dist/validation/rollback.js +15 -82
  340. package/dist/validation/rollback.js.map +1 -1
  341. package/dist/validation/route-drift.d.ts +9 -62
  342. package/dist/validation/route-drift.d.ts.map +1 -1
  343. package/dist/validation/route-drift.js +7 -52
  344. package/dist/validation/route-drift.js.map +1 -1
  345. package/dist/validation/sources.d.ts +16 -94
  346. package/dist/validation/sources.d.ts.map +1 -1
  347. package/dist/validation/sources.js +51 -147
  348. package/dist/validation/sources.js.map +1 -1
  349. package/dist/worker/pool.d.ts +6 -45
  350. package/dist/worker/pool.d.ts.map +1 -1
  351. package/dist/worker/pool.js +5 -42
  352. package/dist/worker/pool.js.map +1 -1
  353. package/dist/worker/protocol.d.ts +7 -20
  354. package/dist/worker/protocol.d.ts.map +1 -1
  355. package/dist/worker/protocol.js +3 -10
  356. package/dist/worker/protocol.js.map +1 -1
  357. package/dist/worker/traversal.worker.d.ts +2 -21
  358. package/dist/worker/traversal.worker.d.ts.map +1 -1
  359. package/dist/worker/traversal.worker.js +4 -23
  360. package/dist/worker/traversal.worker.js.map +1 -1
  361. package/package.json +11 -2
@@ -1,84 +1,20 @@
1
- /**
2
- * Recording a run and its calls — `ai-tool-contract.md` §6, rule 5 (§41.15).
3
- *
4
- * ## Ordering is a counter, not a clock
5
- *
6
- * Two calls can land in the same millisecond, so `recorded_at` cannot be the
7
- * ordering key. `recorded_runs.next_seq` is incremented atomically with every
8
- * insert into `recorded_calls`, in the same transaction, so "what order did
9
- * these happen in" is answerable from the primary key alone — the property
10
- * §12's replay requirement depends on ("same inputs + same recorded responses
11
- * = the same finding, byte for byte" only holds if a replayer can tell what
12
- * order to feed them back in).
13
- *
14
- * ## `recordCall` cannot change the tool's own return
15
- *
16
- * A caller is expected to call the real tool, get its result, and *then* call
17
- * `recordCall` — recording is telemetry about a call that has already
18
- * happened, never a gate on it. So `recordCall` never throws: every failure
19
- * inside it — no such run, a driver error, `arguments`/`result` containing
20
- * something `canonicalJson` refuses (a `bigint`, a top-level `undefined`) — is
21
- * caught here and reported back as `{ recorded: false, error }`. A caller that
22
- * ignores the return value still gets its tool result untouched. This is
23
- * `CLAUDE.md`'s honest-degradation rule applied to the recorder itself: a
24
- * failed recording is disclosed in the return value, never silent, and never
25
- * fatal to the call it was recording.
26
- *
27
- * ## Redaction is a documented seam
28
- *
29
- * Contract §6 puts redaction at the tool boundary, before the model call.
30
- * `RecordCallOptions.redact`, when supplied, runs on the call *before* it is
31
- * serialised, so nothing unredacted ever reaches `canonicalJson` once a
32
- * redactor is passed in. `./redact.ts`'s `createRecordingRedactor` is a real
33
- * implementation of that seam, ported from the model-client redaction seam in
34
- * descry-desktop — see its module header. It is still opt-in rather than
35
- * automatic here: this module has no way to know a deployment's actual
36
- * secret values on its own, only the caller does, so a caller must construct
37
- * the redactor and pass it. **No caller in this repo does that yet** — the
38
- * MCP server's tool dispatch and `descry-runtime`'s do not call `recordCall`
39
- * at all today (that wiring is separate, P3-boundary work) — so every row
40
- * this module writes today is still exactly what the tool call carried. See
41
- * `schema.ts`'s module header before treating a recording database file as
42
- * safe to hand around.
43
- */
1
+ /** Records a run and its calls (`ai-tool-contract.md` §6 rule 5, §41.15). Ordering is
2
+ * `recorded_runs.next_seq`, not `recorded_at` — a clock can tie, and §12's replay guarantee
3
+ * needs a total order. `recordCall` never throws: failure returns `{recorded:false,error}`. */
44
4
  import { type ToolClass } from "@descryy/ir";
45
5
  import type { SqlDriver } from "../store/driver/driver.ts";
46
- /**
47
- * The graph stamp, captured once per run. `null` where the graph was not
48
- * consulted — never omitted, for the same reason the wire envelope's
49
- * `graph.resolutionFloor` is never absent (contract §3): a missing field and a
50
- * null field read identically to a careless caller, and only one of them is
51
- * honest about what this run actually saw.
52
- */
6
+ /** Graph stamp, captured once per run. `null` (never omitted) where the graph wasn't consulted
7
+ * — same as contract §3's `graph.resolutionFloor`: a missing field and a null field read
8
+ * identically to a careless caller, and only one is honest. */
53
9
  export interface RunStamp {
54
10
  readonly commitSha: string | null;
55
11
  readonly builtAt: string | null;
56
12
  readonly irSchemaVersion: number | null;
57
13
  }
58
14
  export interface StartRunOptions {
59
- /**
60
- * §12: present and nullable, **and null on every row this store will ever
61
- * hold.** That is a settled fact now, not a pending wiring job.
62
- *
63
- * This comment used to say a caller in `descry-desktop/packages/pipeline`
64
- * would eventually pass a value here. It will not, and the reason is
65
- * structural rather than a matter of scheduling: this is the **tool-call**
66
- * recording store, and `descry-desktop` never calls into it — measured, a
67
- * grep for `startRun(`, `recordCall(` and `readRun(` across every `src`
68
- * directory in that repository returns no reference to this module. It
69
- * records model calls in its own `model_recording_attempts` table
70
- * (`packages/session/src/model-recording/`), which carries its own
71
- * `prompt_version` column, **per attempt** — because one run of that
72
- * pipeline renders eight distinct prompts, and one column once per run
73
- * cannot carry eight values without inventing a summary of seven of them.
74
- *
75
- * The column stays. A store that records tool calls has an honest place to
76
- * name the prompt a run was issued under, if this repository ever grows a
77
- * caller that knows one. What it does not have is a caller today, and
78
- * saying "until that wiring lands" implied one was on its way.
79
- *
80
- * Corrected by PF-1 of `documents/plans/prompt-fingerprinting.md`.
81
- */
15
+ /** §12: present and nullable, and null on every row this store will hold — settled, not pending.
16
+ * descry-desktop never calls this tool-recording store; it tracks prompt_version per-attempt in
17
+ * its own model_recording_attempts table (one run renders multiple prompts). Corrected by PF-1. */
82
18
  readonly promptVersion?: string | null;
83
19
  /** §12: present and nullable. No model layer exists yet, so always null today. */
84
20
  readonly modelId?: string | null;
@@ -105,7 +41,8 @@ export interface ToolCallRecord {
105
41
  }
106
42
  export interface RecordCallOptions {
107
43
  readonly now?: () => number;
108
- /** The redaction seam — see this file's module header. */
44
+ /** Opt-in redaction, run before serialising (§6: redaction at the tool boundary). No caller in
45
+ * this repo passes one yet — every row currently written is exactly what the tool call carried. */
109
46
  readonly redact?: (call: ToolCallRecord) => ToolCallRecord;
110
47
  }
111
48
  export type RecordCallResult = {
@@ -1 +1 @@
1
- {"version":3,"file":"writer.d.ts","sourceRoot":"","sources":["../../src/recording/writer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AAGH,OAAO,EAAiB,KAAK,SAAS,EAAE,MAAM,aAAa,CAAC;AAE5D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAE3D;;;;;;GAMG;AACH,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,QAAQ,CAAC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;CACzC;AAED,MAAM,WAAW,eAAe;IAC9B;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvC,kFAAkF;IAClF,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,+EAA+E;IAC/E,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IAC5B,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,MAAM,CAAC;CAC5B;AAED,wBAAgB,QAAQ,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,GAAE,eAAoB,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAsB7G;AAED,qFAAqF;AACrF,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC;IAC1B,6CAA6C;IAC7C,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,gFAAgF;IAChF,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,wFAAwF;IACxF,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IAC5B,0DAA0D;IAC1D,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,cAAc,KAAK,cAAc,CAAC;CAC5D;AAED,MAAM,MAAM,gBAAgB,GACxB;IAAE,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GACjD;IAAE,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAAC;AAE1D,qEAAqE;AACrE,wBAAgB,UAAU,CACxB,MAAM,EAAE,SAAS,EACjB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,cAAc,EACpB,OAAO,GAAE,iBAAsB,GAC9B,gBAAgB,CAsClB"}
1
+ {"version":3,"file":"writer.d.ts","sourceRoot":"","sources":["../../src/recording/writer.ts"],"names":[],"mappings":"AAAA;;gGAEgG;AAGhG,OAAO,EAAiB,KAAK,SAAS,EAAE,MAAM,aAAa,CAAC;AAE5D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAE3D;;gEAEgE;AAChE,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,QAAQ,CAAC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;CACzC;AAED,MAAM,WAAW,eAAe;IAC9B;;wGAEoG;IACpG,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvC,kFAAkF;IAClF,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,+EAA+E;IAC/E,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IAC5B,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,MAAM,CAAC;CAC5B;AAED,wBAAgB,QAAQ,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,GAAE,eAAoB,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAsB7G;AAED,qFAAqF;AACrF,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC;IAC1B,6CAA6C;IAC7C,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,gFAAgF;IAChF,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,wFAAwF;IACxF,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IAC5B;wGACoG;IACpG,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,cAAc,KAAK,cAAc,CAAC;CAC5D;AAED,MAAM,MAAM,gBAAgB,GACxB;IAAE,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GACjD;IAAE,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAAC;AAE1D,qEAAqE;AACrE,wBAAgB,UAAU,CACxB,MAAM,EAAE,SAAS,EACjB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,cAAc,EACpB,OAAO,GAAE,iBAAsB,GAC9B,gBAAgB,CAsClB"}
@@ -1,46 +1,6 @@
1
- /**
2
- * Recording a run and its calls — `ai-tool-contract.md` §6, rule 5 (§41.15).
3
- *
4
- * ## Ordering is a counter, not a clock
5
- *
6
- * Two calls can land in the same millisecond, so `recorded_at` cannot be the
7
- * ordering key. `recorded_runs.next_seq` is incremented atomically with every
8
- * insert into `recorded_calls`, in the same transaction, so "what order did
9
- * these happen in" is answerable from the primary key alone — the property
10
- * §12's replay requirement depends on ("same inputs + same recorded responses
11
- * = the same finding, byte for byte" only holds if a replayer can tell what
12
- * order to feed them back in).
13
- *
14
- * ## `recordCall` cannot change the tool's own return
15
- *
16
- * A caller is expected to call the real tool, get its result, and *then* call
17
- * `recordCall` — recording is telemetry about a call that has already
18
- * happened, never a gate on it. So `recordCall` never throws: every failure
19
- * inside it — no such run, a driver error, `arguments`/`result` containing
20
- * something `canonicalJson` refuses (a `bigint`, a top-level `undefined`) — is
21
- * caught here and reported back as `{ recorded: false, error }`. A caller that
22
- * ignores the return value still gets its tool result untouched. This is
23
- * `CLAUDE.md`'s honest-degradation rule applied to the recorder itself: a
24
- * failed recording is disclosed in the return value, never silent, and never
25
- * fatal to the call it was recording.
26
- *
27
- * ## Redaction is a documented seam
28
- *
29
- * Contract §6 puts redaction at the tool boundary, before the model call.
30
- * `RecordCallOptions.redact`, when supplied, runs on the call *before* it is
31
- * serialised, so nothing unredacted ever reaches `canonicalJson` once a
32
- * redactor is passed in. `./redact.ts`'s `createRecordingRedactor` is a real
33
- * implementation of that seam, ported from the model-client redaction seam in
34
- * descry-desktop — see its module header. It is still opt-in rather than
35
- * automatic here: this module has no way to know a deployment's actual
36
- * secret values on its own, only the caller does, so a caller must construct
37
- * the redactor and pass it. **No caller in this repo does that yet** — the
38
- * MCP server's tool dispatch and `descry-runtime`'s do not call `recordCall`
39
- * at all today (that wiring is separate, P3-boundary work) — so every row
40
- * this module writes today is still exactly what the tool call carried. See
41
- * `schema.ts`'s module header before treating a recording database file as
42
- * safe to hand around.
43
- */
1
+ /** Records a run and its calls (`ai-tool-contract.md` §6 rule 5, §41.15). Ordering is
2
+ * `recorded_runs.next_seq`, not `recorded_at` — a clock can tie, and §12's replay guarantee
3
+ * needs a total order. `recordCall` never throws: failure returns `{recorded:false,error}`. */
44
4
  import { randomUUID } from "node:crypto";
45
5
  import { canonicalJson } from "@descryy/ir";
46
6
  export function startRun(driver, stamp, options = {}) {
@@ -1 +1 @@
1
- {"version":3,"file":"writer.js","sourceRoot":"","sources":["../../src/recording/writer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,aAAa,EAAkB,MAAM,aAAa,CAAC;AAkD5D,MAAM,UAAU,QAAQ,CAAC,MAAiB,EAAE,KAAe,EAAE,UAA2B,EAAE;IACxF,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC;IACpC,MAAM,MAAM,GAAG,OAAO,CAAC,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,UAAU,EAAE,EAAE,CAAC,CAAC;IAC5D,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC;IAEvB,MAAM;SACH,OAAO,CACN;;uCAEiC,CAClC;SACA,GAAG,CACF,KAAK,EACL,GAAG,EAAE,EACL,KAAK,CAAC,SAAS,EACf,KAAK,CAAC,OAAO,EACb,KAAK,CAAC,eAAe,EACrB,OAAO,CAAC,aAAa,IAAI,IAAI,EAC7B,OAAO,CAAC,OAAO,IAAI,IAAI,CACxB,CAAC;IAEJ,OAAO,EAAE,KAAK,EAAE,CAAC;AACnB,CAAC;AA0BD,qEAAqE;AACrE,MAAM,UAAU,UAAU,CACxB,MAAiB,EACjB,KAAa,EACb,IAAoB,EACpB,UAA6B,EAAE;IAE/B,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC;QAEpC,OAAO,MAAM,CAAC,WAAW,CAAC,GAAG,EAAE;YAC7B,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,CAAuB,iDAAiD,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YAC/G,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;gBACtB,MAAM,IAAI,KAAK,CAAC,4BAA4B,KAAK,mCAAmC,CAAC,CAAC;YACxF,CAAC;YACD,MAAM,GAAG,GAAG,GAAG,CAAC,QAAQ,CAAC;YACzB,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YAE/D,MAAM;iBACH,OAAO,CACN;;iDAEuC,CACxC;iBACA,GAAG,CACF,KAAK,EACL,GAAG,EACH,SAAS,CAAC,IAAI,EACd,SAAS,CAAC,WAAW,EACrB,SAAS,CAAC,KAAK,EACf,aAAa,CAAC,SAAS,CAAC,SAAS,CAAC,EAClC,aAAa,CAAC,SAAS,CAAC,MAAM,CAAC,EAC/B,SAAS,CAAC,UAAU,EACpB,SAAS,CAAC,IAAI,EACd,GAAG,EAAE,CACN,CAAC;YAEJ,MAAM,CAAC,OAAO,CAAC,oDAAoD,CAAC,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,EAAE,KAAK,CAAC,CAAC;YAEzF,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,EAAW,CAAC;QAC1C,CAAC,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;IACpC,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"writer.js","sourceRoot":"","sources":["../../src/recording/writer.ts"],"names":[],"mappings":"AAAA;;gGAEgG;AAEhG,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,aAAa,EAAkB,MAAM,aAAa,CAAC;AA0B5D,MAAM,UAAU,QAAQ,CAAC,MAAiB,EAAE,KAAe,EAAE,UAA2B,EAAE;IACxF,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC;IACpC,MAAM,MAAM,GAAG,OAAO,CAAC,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,UAAU,EAAE,EAAE,CAAC,CAAC;IAC5D,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC;IAEvB,MAAM;SACH,OAAO,CACN;;uCAEiC,CAClC;SACA,GAAG,CACF,KAAK,EACL,GAAG,EAAE,EACL,KAAK,CAAC,SAAS,EACf,KAAK,CAAC,OAAO,EACb,KAAK,CAAC,eAAe,EACrB,OAAO,CAAC,aAAa,IAAI,IAAI,EAC7B,OAAO,CAAC,OAAO,IAAI,IAAI,CACxB,CAAC;IAEJ,OAAO,EAAE,KAAK,EAAE,CAAC;AACnB,CAAC;AA2BD,qEAAqE;AACrE,MAAM,UAAU,UAAU,CACxB,MAAiB,EACjB,KAAa,EACb,IAAoB,EACpB,UAA6B,EAAE;IAE/B,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC;QAEpC,OAAO,MAAM,CAAC,WAAW,CAAC,GAAG,EAAE;YAC7B,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,CAAuB,iDAAiD,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YAC/G,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;gBACtB,MAAM,IAAI,KAAK,CAAC,4BAA4B,KAAK,mCAAmC,CAAC,CAAC;YACxF,CAAC;YACD,MAAM,GAAG,GAAG,GAAG,CAAC,QAAQ,CAAC;YACzB,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YAE/D,MAAM;iBACH,OAAO,CACN;;iDAEuC,CACxC;iBACA,GAAG,CACF,KAAK,EACL,GAAG,EACH,SAAS,CAAC,IAAI,EACd,SAAS,CAAC,WAAW,EACrB,SAAS,CAAC,KAAK,EACf,aAAa,CAAC,SAAS,CAAC,SAAS,CAAC,EAClC,aAAa,CAAC,SAAS,CAAC,MAAM,CAAC,EAC/B,SAAS,CAAC,UAAU,EACpB,SAAS,CAAC,IAAI,EACd,GAAG,EAAE,CACN,CAAC;YAEJ,MAAM,CAAC,OAAO,CAAC,oDAAoD,CAAC,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,EAAE,KAAK,CAAC,CAAC;YAEzF,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,EAAW,CAAC;QAC1C,CAAC,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;IACpC,CAAC;AACH,CAAC"}
@@ -1,59 +1,6 @@
1
1
  /**
2
- * Fan-out attenuation — DEC-067.
3
- *
4
- * ## The problem this solves, and the one it must not create
5
- *
6
- * A handful of declarations are depended on by everything: on one measured
7
- * repository `Stage` has 186 dependents and `DocumentType` 165. Those
8
- * dependencies are **real**, and the graph represents them at full weight. The
9
- * damage is not in the edge, it is in what traversal does when it *passes
10
- * through* such a node — one function's reference to an enum drags 164
11
- * unrelated consumers into a blast radius they have nothing to do with.
12
- *
13
- * So the attenuation attaches to **expansion out of a hub**, never to the edge.
14
- * Weighting the edge would penalise both directions, and only one of them is
15
- * wrong:
16
- *
17
- * - **change `DocumentType`** — all 165 dependents genuinely break. Damping that
18
- * makes Descry *understate* real impact, which is the opposite of the failure
19
- * being fixed.
20
- * - **change a function that references `DocumentType`** — the other 164
21
- * consumers are unaffected, and pulling them in is noise.
22
- *
23
- * **The seed exemption is what separates those two cases**, and without it this
24
- * module contradicts its own reason for existing. Seeds enter traversal at depth
25
- * 0; attenuation applies only from depth 1 onward. A hub that was *changed* is
26
- * never attenuated; a hub that was *reached* always is.
27
- *
28
- * ## Fan-out is not stored anywhere
29
- *
30
- * It is derived at traversal time from the adjacency already fetched, and is
31
- * never written to a node, never part of identity, never hashed, never in a
32
- * qualified symbol path, and never persisted (DEC-017's derived/earned split
33
- * puts it firmly on the derived side — in fact it is not even that, it is not
34
- * stored at all).
35
- *
36
- * ## Why the candidate count and not a separate in-degree query
37
- *
38
- * Traversal has already enumerated exactly the edges it would follow out of the
39
- * current node. That count **is** the operational fan-out — the number of ways
40
- * this node can explode — and it needs no second query, no index and no
41
- * post-build pass. Defining fan-out as "edges expansion would follow" rather
42
- * than as abstract in-degree also makes it the quantity that actually causes the
43
- * dilution, rather than a proxy for it.
44
- *
45
- * One consequence has to be stated: `perNodeLimit` caps that enumeration, so a
46
- * limit at or below the top boundary would understate a hub's fan-out and
47
- * under-attenuate it. `validateScopingConfig` refuses that combination rather
48
- * than silently mis-bucketing.
49
- *
50
- * ## Calibration
51
- *
52
- * Every number here is **provisional** (DEC-067). They are starting values from
53
- * a single repository, chosen so that all four buckets are occupied — measured
54
- * at 8.5% / 22.0% / 28.5% / 41.0% of `USES_TYPE` edges — which is the minimum
55
- * property that makes the table worth having. They are to be tuned from real
56
- * traversal data, like every other weight in §12.
2
+ * Fan-out attenuation (DEC-067). A hub (e.g. `DocumentType`, 165 dependents) drags unrelated consumers into a blast radius when merely *passed through* — so attenuation hits expansion out of a hub, never the edge itself: a changed hub still shows full impact (seed exemption, depth 0), a reached one is always damped.
3
+ * Derived at traversal time from adjacency already fetched — never stored, never part of identity (DEC-017). Table is provisional, measured at 8.5/22.0/28.5/41.0% of `USES_TYPE` edges on one repository; tune from real data like every §12 weight.
57
4
  */
58
5
  /** One band of the attenuation table. `upTo` is inclusive. */
59
6
  export interface FanOutBucket {
@@ -64,22 +11,13 @@ export interface FanOutBucket {
64
11
  /** Human label, for explaining a score rather than for logic. */
65
12
  readonly label: string;
66
13
  }
67
- /**
68
- * DEC-067's provisional table.
69
- *
70
- * `1.0` for the first band matters: an ordinary node must be completely
71
- * unaffected, so that introducing this feature cannot move any score in a graph
72
- * without hubs.
73
- */
14
+ /** DEC-067's provisional table. `1.0` for the first band matters — an ordinary
15
+ * node must be unaffected in a graph without hubs. */
74
16
  export declare const DEFAULT_FANOUT_BUCKETS: readonly FanOutBucket[];
75
17
  /** The bucket a fan-out falls in. Never undefined — the last bucket is open. */
76
18
  export declare function bucketFor(fanOut: number, buckets?: readonly FanOutBucket[]): FanOutBucket;
77
- /**
78
- * The multiplier for expansion out of a node.
79
- *
80
- * `depth === 0` is the seed exemption and is checked here rather than at the
81
- * call site, so the rule lives in one place and cannot be half-applied.
82
- */
19
+ /** Multiplier for expansion out of a node. `depth === 0` seed exemption checked
20
+ * here, not at the call site, so it can't be half-applied. */
83
21
  export declare function attenuationFor(fanOut: number, depth: number, buckets?: readonly FanOutBucket[]): number;
84
22
  /** The largest multiplier any bucket can apply — what termination must clear. */
85
23
  export declare function maxAttenuation(buckets: readonly FanOutBucket[]): number;
@@ -1 +1 @@
1
- {"version":3,"file":"fanout.d.ts","sourceRoot":"","sources":["../../src/scoping/fanout.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwDG;AAEH,8DAA8D;AAC9D,MAAM,WAAW,YAAY;IAC3B,sEAAsE;IACtE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,kEAAkE;IAClE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,iEAAiE;IACjE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,EAAE,SAAS,YAAY,EAKzD,CAAC;AAEF,gFAAgF;AAChF,wBAAgB,SAAS,CACvB,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,SAAS,YAAY,EAA2B,GACxD,YAAY,CAMd;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,SAAS,YAAY,EAA2B,GACxD,MAAM,CAGR;AAED,iFAAiF;AACjF,wBAAgB,cAAc,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,GAAG,MAAM,CAEvE"}
1
+ {"version":3,"file":"fanout.d.ts","sourceRoot":"","sources":["../../src/scoping/fanout.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,8DAA8D;AAC9D,MAAM,WAAW,YAAY;IAC3B,sEAAsE;IACtE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,kEAAkE;IAClE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,iEAAiE;IACjE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED;uDACuD;AACvD,eAAO,MAAM,sBAAsB,EAAE,SAAS,YAAY,EAKzD,CAAC;AAEF,gFAAgF;AAChF,wBAAgB,SAAS,CACvB,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,SAAS,YAAY,EAA2B,GACxD,YAAY,CAMd;AAED;+DAC+D;AAC/D,wBAAgB,cAAc,CAC5B,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,SAAS,YAAY,EAA2B,GACxD,MAAM,CAGR;AAED,iFAAiF;AACjF,wBAAgB,cAAc,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,GAAG,MAAM,CAEvE"}
@@ -1,67 +1,9 @@
1
1
  /**
2
- * Fan-out attenuation — DEC-067.
3
- *
4
- * ## The problem this solves, and the one it must not create
5
- *
6
- * A handful of declarations are depended on by everything: on one measured
7
- * repository `Stage` has 186 dependents and `DocumentType` 165. Those
8
- * dependencies are **real**, and the graph represents them at full weight. The
9
- * damage is not in the edge, it is in what traversal does when it *passes
10
- * through* such a node — one function's reference to an enum drags 164
11
- * unrelated consumers into a blast radius they have nothing to do with.
12
- *
13
- * So the attenuation attaches to **expansion out of a hub**, never to the edge.
14
- * Weighting the edge would penalise both directions, and only one of them is
15
- * wrong:
16
- *
17
- * - **change `DocumentType`** — all 165 dependents genuinely break. Damping that
18
- * makes Descry *understate* real impact, which is the opposite of the failure
19
- * being fixed.
20
- * - **change a function that references `DocumentType`** — the other 164
21
- * consumers are unaffected, and pulling them in is noise.
22
- *
23
- * **The seed exemption is what separates those two cases**, and without it this
24
- * module contradicts its own reason for existing. Seeds enter traversal at depth
25
- * 0; attenuation applies only from depth 1 onward. A hub that was *changed* is
26
- * never attenuated; a hub that was *reached* always is.
27
- *
28
- * ## Fan-out is not stored anywhere
29
- *
30
- * It is derived at traversal time from the adjacency already fetched, and is
31
- * never written to a node, never part of identity, never hashed, never in a
32
- * qualified symbol path, and never persisted (DEC-017's derived/earned split
33
- * puts it firmly on the derived side — in fact it is not even that, it is not
34
- * stored at all).
35
- *
36
- * ## Why the candidate count and not a separate in-degree query
37
- *
38
- * Traversal has already enumerated exactly the edges it would follow out of the
39
- * current node. That count **is** the operational fan-out — the number of ways
40
- * this node can explode — and it needs no second query, no index and no
41
- * post-build pass. Defining fan-out as "edges expansion would follow" rather
42
- * than as abstract in-degree also makes it the quantity that actually causes the
43
- * dilution, rather than a proxy for it.
44
- *
45
- * One consequence has to be stated: `perNodeLimit` caps that enumeration, so a
46
- * limit at or below the top boundary would understate a hub's fan-out and
47
- * under-attenuate it. `validateScopingConfig` refuses that combination rather
48
- * than silently mis-bucketing.
49
- *
50
- * ## Calibration
51
- *
52
- * Every number here is **provisional** (DEC-067). They are starting values from
53
- * a single repository, chosen so that all four buckets are occupied — measured
54
- * at 8.5% / 22.0% / 28.5% / 41.0% of `USES_TYPE` edges — which is the minimum
55
- * property that makes the table worth having. They are to be tuned from real
56
- * traversal data, like every other weight in §12.
57
- */
58
- /**
59
- * DEC-067's provisional table.
60
- *
61
- * `1.0` for the first band matters: an ordinary node must be completely
62
- * unaffected, so that introducing this feature cannot move any score in a graph
63
- * without hubs.
2
+ * Fan-out attenuation (DEC-067). A hub (e.g. `DocumentType`, 165 dependents) drags unrelated consumers into a blast radius when merely *passed through* — so attenuation hits expansion out of a hub, never the edge itself: a changed hub still shows full impact (seed exemption, depth 0), a reached one is always damped.
3
+ * Derived at traversal time from adjacency already fetched — never stored, never part of identity (DEC-017). Table is provisional, measured at 8.5/22.0/28.5/41.0% of `USES_TYPE` edges on one repository; tune from real data like every §12 weight.
64
4
  */
5
+ /** DEC-067's provisional table. `1.0` for the first band matters — an ordinary
6
+ * node must be unaffected in a graph without hubs. */
65
7
  export const DEFAULT_FANOUT_BUCKETS = [
66
8
  { upTo: 5, multiplier: 1.0, label: "local" },
67
9
  { upTo: 20, multiplier: 0.8, label: "shared" },
@@ -77,12 +19,8 @@ export function bucketFor(fanOut, buckets = DEFAULT_FANOUT_BUCKETS) {
77
19
  // Unreachable when the table is validated, since the last `upTo` is Infinity.
78
20
  return buckets[buckets.length - 1];
79
21
  }
80
- /**
81
- * The multiplier for expansion out of a node.
82
- *
83
- * `depth === 0` is the seed exemption and is checked here rather than at the
84
- * call site, so the rule lives in one place and cannot be half-applied.
85
- */
22
+ /** Multiplier for expansion out of a node. `depth === 0` seed exemption checked
23
+ * here, not at the call site, so it can't be half-applied. */
86
24
  export function attenuationFor(fanOut, depth, buckets = DEFAULT_FANOUT_BUCKETS) {
87
25
  if (depth === 0)
88
26
  return 1;
@@ -1 +1 @@
1
- {"version":3,"file":"fanout.js","sourceRoot":"","sources":["../../src/scoping/fanout.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwDG;AAYH;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAA4B;IAC7D,EAAE,IAAI,EAAE,CAAC,EAAE,UAAU,EAAE,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE;IAC5C,EAAE,IAAI,EAAE,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE;IAC9C,EAAE,IAAI,EAAE,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,KAAK,EAAE,cAAc,EAAE;IACpD,EAAE,IAAI,EAAE,MAAM,CAAC,iBAAiB,EAAE,UAAU,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE;CACnE,CAAC;AAEF,gFAAgF;AAChF,MAAM,UAAU,SAAS,CACvB,MAAc,EACd,UAAmC,sBAAsB;IAEzD,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,IAAI,MAAM,IAAI,MAAM,CAAC,IAAI;YAAE,OAAO,MAAM,CAAC;IAC3C,CAAC;IACD,8EAA8E;IAC9E,OAAO,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAE,CAAC;AACtC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAC5B,MAAc,EACd,KAAa,EACb,UAAmC,sBAAsB;IAEzD,IAAI,KAAK,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IAC1B,OAAO,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,UAAU,CAAC;AAC/C,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,cAAc,CAAC,OAAgC;IAC7D,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC;AACtF,CAAC"}
1
+ {"version":3,"file":"fanout.js","sourceRoot":"","sources":["../../src/scoping/fanout.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAYH;uDACuD;AACvD,MAAM,CAAC,MAAM,sBAAsB,GAA4B;IAC7D,EAAE,IAAI,EAAE,CAAC,EAAE,UAAU,EAAE,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE;IAC5C,EAAE,IAAI,EAAE,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE;IAC9C,EAAE,IAAI,EAAE,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,KAAK,EAAE,cAAc,EAAE;IACpD,EAAE,IAAI,EAAE,MAAM,CAAC,iBAAiB,EAAE,UAAU,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE;CACnE,CAAC;AAEF,gFAAgF;AAChF,MAAM,UAAU,SAAS,CACvB,MAAc,EACd,UAAmC,sBAAsB;IAEzD,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,IAAI,MAAM,IAAI,MAAM,CAAC,IAAI;YAAE,OAAO,MAAM,CAAC;IAC3C,CAAC;IACD,8EAA8E;IAC9E,OAAO,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAE,CAAC;AACtC,CAAC;AAED;+DAC+D;AAC/D,MAAM,UAAU,cAAc,CAC5B,MAAc,EACd,KAAa,EACb,UAAmC,sBAAsB;IAEzD,IAAI,KAAK,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IAC1B,OAAO,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,UAAU,CAAC;AAC/C,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,cAAc,CAAC,OAAgC;IAC7D,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC;AACtF,CAAC"}
@@ -1,83 +1,33 @@
1
- /**
2
- * The impact score — §12.4.
3
- *
4
- * NewScore = ParentScore × EdgeWeight × ChangeCouplingFactor
5
- * × IncidentCorrelationFactor × EdgeConfidence
6
- *
7
- * Both history factors **default to 1.0** so a brand-new file, or a repo with no
8
- * logged incidents, is not unfairly under-scored. `EdgeConfidence` defaults to
9
- * the edge's own value, which is 1.0 for a well-resolved adapter — so in a clean
10
- * R3 repository the last three terms vanish and the formula is just weight
11
- * decay. They do their work in a degraded one, which is the point.
12
- *
13
- * **The formula is applied in two parts, not as one product per hop.** Path
14
- * decay uses only `EdgeWeight × EdgeConfidence`, which is strictly below 1 and
15
- * therefore always terminates; the two history factors are applied once to a
16
- * node's final score. See the long note in `weights.ts` for why the literal
17
- * per-hop form cannot hold alongside §12.3 and §12.7, and DEC-037 for the
18
- * decision. The short version: compounding a node's incident history at every
19
- * hop of a path that merely passes through it counts the same evidence
20
- * repeatedly.
21
- */
1
+ /** §12.4 impact score: ParentScore × EdgeWeight × ChangeCouplingFactor ×
2
+ * IncidentCorrelationFactor × EdgeConfidence. History factors default 1.0
3
+ * (new file/no incidents isn't under-scored). Applied in two parts, not
4
+ * per-hop: path decay uses EdgeWeight×EdgeConfidence only (<1, terminates);
5
+ * history factors apply once to a node's final score (DEC-037, §12.3/§12.7). */
22
6
  import type { IREdge } from "@descryy/ir";
23
7
  import type { AdjacencyProvider } from "../query/provider.ts";
24
8
  import type { ScopingConfig } from "./weights.ts";
25
- /**
26
- * Per-node history factors, computed once and cached.
27
- *
28
- * Both are looked up on the node being *entered*, not on the edge: "this file
29
- * has been involved in incidents" and "this file moves with the change" are
30
- * properties of the destination, and computing them per edge would multiply the
31
- * same boost in twice for a node reached two ways.
32
- */
9
+ /** Per-node history factors, computed once and cached — looked up on the
10
+ * node entered, not the edge, or a node reached two ways double-boosts. */
33
11
  export declare class HistoryFactors {
34
12
  #private;
35
13
  constructor(provider: AdjacencyProvider, config: ScopingConfig, seeds: ReadonlySet<string>);
36
- /**
37
- * §12.4's `ChangeCouplingFactor`, from `CHANGES_WITH` edges (§11.7).
38
- *
39
- * Boosts a node that historically moves with something in the diff. Two things
40
- * make this narrower than it first appears, and both are honest limits rather
41
- * than bugs:
42
- *
43
- * - `CHANGES_WITH` is **file-to-file**, so this only fires for `FILE` nodes.
44
- * A `FUNCTION` never has co-change history of its own.
45
- * - The edge is stored in one canonical direction (DEC-036), so both
46
- * directions must be read. This is the one edge type where `outgoing` alone
47
- * is wrong.
48
- */
14
+ /** §12.4's `ChangeCouplingFactor` (`CHANGES_WITH`, §11.7). File-to-file
15
+ * only — a `FUNCTION` has no co-change history. Stored in one canonical
16
+ * direction (DEC-036), so both `outgoing`/`incoming` must be read. */
49
17
  couplingFor(nodeId: string): number;
50
- /**
51
- * §12.4's `IncidentCorrelationFactor`, from `INCIDENT_CORRELATED` edges (§11.6).
52
- *
53
- * Saturating rather than linear: the third incident on a file says much less
54
- * than the first, and an unbounded count would let one pathological file
55
- * dominate every blast radius it appears in.
56
- */
18
+ /** §12.4's `IncidentCorrelationFactor` (`INCIDENT_CORRELATED`, §11.6).
19
+ * Saturating, not linear — an unbounded count would let one pathological
20
+ * file dominate every blast radius. */
57
21
  incidentFor(nodeId: string): number;
58
22
  }
59
- /**
60
- * The per-hop decay: `EdgeWeight × EdgeConfidence`, and nothing else.
61
- *
62
- * Strictly below 1 for any valid configuration, so the path score decreases
63
- * monotonically and traversal terminates on any graph, cyclic or not. That is
64
- * the whole termination argument, and it does not depend on what the history
65
- * factors happen to be — which is what makes it a guarantee rather than a hope.
66
- */
23
+ /** Per-hop decay: `EdgeWeight × EdgeConfidence` only — strictly <1, so path
24
+ * score decreases monotonically and traversal terminates on any graph. */
67
25
  export declare function hopDecay(edge: IREdge, config: ScopingConfig): number;
68
- /**
69
- * A node's final score: its best path decay, adjusted once by its own history.
70
- *
71
- * Capped at `maxScore` because §12.7 tiers on absolute thresholds — a boosted
72
- * score above 1.0 would put a two-hop node above the diff itself.
73
- */
26
+ /** A node's final score: best path decay, adjusted once by its own history.
27
+ * Capped at `maxScore` (§12.7 tiers on absolute thresholds). */
74
28
  export declare function finalScore(pathScore: number, nodeId: string, config: ScopingConfig, history: HistoryFactors): number;
75
- /**
76
- * The largest amount any node's score can be raised by history.
77
- *
78
- * Pruning happens on the *unboosted* path score, so the prune point must be
79
- * lowered by this much — otherwise a node that would clear the threshold once
80
- * boosted is discarded before its boost is ever computed.
81
- */
29
+ /** Largest boost history can add. Pruning runs on the unboosted path score,
30
+ * so the prune point must be lowered by this much or a boostable node is
31
+ * discarded before its boost is computed. */
82
32
  export declare function maxBoost(config: ScopingConfig): number;
83
33
  //# sourceMappingURL=score.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"score.d.ts","sourceRoot":"","sources":["../../src/scoping/score.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAY,MAAM,EAAE,MAAM,aAAa,CAAC;AAEpD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD;;;;;;;GAOG;AACH,qBAAa,cAAc;;gBAOb,QAAQ,EAAE,iBAAiB,EAAE,MAAM,EAAE,aAAa,EAAE,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC;IAM1F;;;;;;;;;;;;OAYG;IACH,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAwBnC;;;;;;OAMG;IACH,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;CAUpC;AAED;;;;;;;GAOG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,GAAG,MAAM,CAEpE;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CACxB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,aAAa,EACrB,OAAO,EAAE,cAAc,GACtB,MAAM,CAGR;AAED;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,CAEtD"}
1
+ {"version":3,"file":"score.d.ts","sourceRoot":"","sources":["../../src/scoping/score.ts"],"names":[],"mappings":"AAAA;;;;iFAIiF;AAEjF,OAAO,KAAK,EAAY,MAAM,EAAE,MAAM,aAAa,CAAC;AAEpD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD;4EAC4E;AAC5E,qBAAa,cAAc;;gBAOb,QAAQ,EAAE,iBAAiB,EAAE,MAAM,EAAE,aAAa,EAAE,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC;IAM1F;;2EAEuE;IACvE,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAwBnC;;4CAEwC;IACxC,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;CAUpC;AAED;2EAC2E;AAC3E,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,GAAG,MAAM,CAEpE;AAED;iEACiE;AACjE,wBAAgB,UAAU,CACxB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,aAAa,EACrB,OAAO,EAAE,cAAc,GACtB,MAAM,CAGR;AAED;;8CAE8C;AAC9C,wBAAgB,QAAQ,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,CAEtD"}
@@ -1,32 +1,10 @@
1
- /**
2
- * The impact score — §12.4.
3
- *
4
- * NewScore = ParentScore × EdgeWeight × ChangeCouplingFactor
5
- * × IncidentCorrelationFactor × EdgeConfidence
6
- *
7
- * Both history factors **default to 1.0** so a brand-new file, or a repo with no
8
- * logged incidents, is not unfairly under-scored. `EdgeConfidence` defaults to
9
- * the edge's own value, which is 1.0 for a well-resolved adapter — so in a clean
10
- * R3 repository the last three terms vanish and the formula is just weight
11
- * decay. They do their work in a degraded one, which is the point.
12
- *
13
- * **The formula is applied in two parts, not as one product per hop.** Path
14
- * decay uses only `EdgeWeight × EdgeConfidence`, which is strictly below 1 and
15
- * therefore always terminates; the two history factors are applied once to a
16
- * node's final score. See the long note in `weights.ts` for why the literal
17
- * per-hop form cannot hold alongside §12.3 and §12.7, and DEC-037 for the
18
- * decision. The short version: compounding a node's incident history at every
19
- * hop of a path that merely passes through it counts the same evidence
20
- * repeatedly.
21
- */
22
- /**
23
- * Per-node history factors, computed once and cached.
24
- *
25
- * Both are looked up on the node being *entered*, not on the edge: "this file
26
- * has been involved in incidents" and "this file moves with the change" are
27
- * properties of the destination, and computing them per edge would multiply the
28
- * same boost in twice for a node reached two ways.
29
- */
1
+ /** §12.4 impact score: ParentScore × EdgeWeight × ChangeCouplingFactor ×
2
+ * IncidentCorrelationFactor × EdgeConfidence. History factors default 1.0
3
+ * (new file/no incidents isn't under-scored). Applied in two parts, not
4
+ * per-hop: path decay uses EdgeWeight×EdgeConfidence only (<1, terminates);
5
+ * history factors apply once to a node's final score (DEC-037, §12.3/§12.7). */
6
+ /** Per-node history factors, computed once and cached — looked up on the
7
+ * node entered, not the edge, or a node reached two ways double-boosts. */
30
8
  export class HistoryFactors {
31
9
  #provider;
32
10
  #config;
@@ -38,19 +16,9 @@ export class HistoryFactors {
38
16
  this.#config = config;
39
17
  this.#seeds = seeds;
40
18
  }
41
- /**
42
- * §12.4's `ChangeCouplingFactor`, from `CHANGES_WITH` edges (§11.7).
43
- *
44
- * Boosts a node that historically moves with something in the diff. Two things
45
- * make this narrower than it first appears, and both are honest limits rather
46
- * than bugs:
47
- *
48
- * - `CHANGES_WITH` is **file-to-file**, so this only fires for `FILE` nodes.
49
- * A `FUNCTION` never has co-change history of its own.
50
- * - The edge is stored in one canonical direction (DEC-036), so both
51
- * directions must be read. This is the one edge type where `outgoing` alone
52
- * is wrong.
53
- */
19
+ /** §12.4's `ChangeCouplingFactor` (`CHANGES_WITH`, §11.7). File-to-file
20
+ * only — a `FUNCTION` has no co-change history. Stored in one canonical
21
+ * direction (DEC-036), so both `outgoing`/`incoming` must be read. */
54
22
  couplingFor(nodeId) {
55
23
  const cached = this.#coupling.get(nodeId);
56
24
  if (cached !== undefined)
@@ -73,13 +41,9 @@ export class HistoryFactors {
73
41
  this.#coupling.set(nodeId, factor);
74
42
  return factor;
75
43
  }
76
- /**
77
- * §12.4's `IncidentCorrelationFactor`, from `INCIDENT_CORRELATED` edges (§11.6).
78
- *
79
- * Saturating rather than linear: the third incident on a file says much less
80
- * than the first, and an unbounded count would let one pathological file
81
- * dominate every blast radius it appears in.
82
- */
44
+ /** §12.4's `IncidentCorrelationFactor` (`INCIDENT_CORRELATED`, §11.6).
45
+ * Saturating, not linear — an unbounded count would let one pathological
46
+ * file dominate every blast radius. */
83
47
  incidentFor(nodeId) {
84
48
  const cached = this.#incident.get(nodeId);
85
49
  if (cached !== undefined)
@@ -91,34 +55,20 @@ export class HistoryFactors {
91
55
  return factor;
92
56
  }
93
57
  }
94
- /**
95
- * The per-hop decay: `EdgeWeight × EdgeConfidence`, and nothing else.
96
- *
97
- * Strictly below 1 for any valid configuration, so the path score decreases
98
- * monotonically and traversal terminates on any graph, cyclic or not. That is
99
- * the whole termination argument, and it does not depend on what the history
100
- * factors happen to be — which is what makes it a guarantee rather than a hope.
101
- */
58
+ /** Per-hop decay: `EdgeWeight × EdgeConfidence` only — strictly <1, so path
59
+ * score decreases monotonically and traversal terminates on any graph. */
102
60
  export function hopDecay(edge, config) {
103
61
  return config.edgeWeights[edge.type] * edge.confidence;
104
62
  }
105
- /**
106
- * A node's final score: its best path decay, adjusted once by its own history.
107
- *
108
- * Capped at `maxScore` because §12.7 tiers on absolute thresholds — a boosted
109
- * score above 1.0 would put a two-hop node above the diff itself.
110
- */
63
+ /** A node's final score: best path decay, adjusted once by its own history.
64
+ * Capped at `maxScore` (§12.7 tiers on absolute thresholds). */
111
65
  export function finalScore(pathScore, nodeId, config, history) {
112
66
  const boosted = pathScore * history.couplingFor(nodeId) * history.incidentFor(nodeId);
113
67
  return Math.min(boosted, config.maxScore);
114
68
  }
115
- /**
116
- * The largest amount any node's score can be raised by history.
117
- *
118
- * Pruning happens on the *unboosted* path score, so the prune point must be
119
- * lowered by this much — otherwise a node that would clear the threshold once
120
- * boosted is discarded before its boost is ever computed.
121
- */
69
+ /** Largest boost history can add. Pruning runs on the unboosted path score,
70
+ * so the prune point must be lowered by this much or a boostable node is
71
+ * discarded before its boost is computed. */
122
72
  export function maxBoost(config) {
123
73
  return config.maxCouplingFactor * config.maxIncidentFactor;
124
74
  }
@@ -1 +1 @@
1
- {"version":3,"file":"score.js","sourceRoot":"","sources":["../../src/scoping/score.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"score.js","sourceRoot":"","sources":["../../src/scoping/score.ts"],"names":[],"mappings":"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"}