@descryy/core 0.3.0 → 0.5.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 (362) 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 +26 -12
  14. package/dist/contracts/engine.d.ts.map +1 -1
  15. package/dist/contracts/engine.js +28 -11
  16. package/dist/contracts/engine.js.map +1 -1
  17. package/dist/contracts/index.d.ts +1 -1
  18. package/dist/contracts/index.d.ts.map +1 -1
  19. package/dist/contracts/index.js.map +1 -1
  20. package/dist/contracts/orphans.d.ts +28 -77
  21. package/dist/contracts/orphans.d.ts.map +1 -1
  22. package/dist/contracts/orphans.js +124 -94
  23. package/dist/contracts/orphans.js.map +1 -1
  24. package/dist/contracts/paths.d.ts +4 -114
  25. package/dist/contracts/paths.d.ts.map +1 -1
  26. package/dist/contracts/paths.js +7 -140
  27. package/dist/contracts/paths.js.map +1 -1
  28. package/dist/contracts/shapes.d.ts +13 -66
  29. package/dist/contracts/shapes.d.ts.map +1 -1
  30. package/dist/contracts/shapes.js +20 -91
  31. package/dist/contracts/shapes.js.map +1 -1
  32. package/dist/governance/budget.d.ts +12 -48
  33. package/dist/governance/budget.d.ts.map +1 -1
  34. package/dist/governance/budget.js +12 -48
  35. package/dist/governance/budget.js.map +1 -1
  36. package/dist/governance/candidate-boundary.d.ts +4 -32
  37. package/dist/governance/candidate-boundary.d.ts.map +1 -1
  38. package/dist/governance/candidate-boundary.js +4 -32
  39. package/dist/governance/candidate-boundary.js.map +1 -1
  40. package/dist/governance/escalation.d.ts +7 -45
  41. package/dist/governance/escalation.d.ts.map +1 -1
  42. package/dist/governance/escalation.js +7 -45
  43. package/dist/governance/escalation.js.map +1 -1
  44. package/dist/governance/fact-boundary.d.ts +7 -49
  45. package/dist/governance/fact-boundary.d.ts.map +1 -1
  46. package/dist/governance/fact-boundary.js +5 -43
  47. package/dist/governance/fact-boundary.js.map +1 -1
  48. package/dist/governance/finding-funnel.d.ts +11 -72
  49. package/dist/governance/finding-funnel.d.ts.map +1 -1
  50. package/dist/governance/finding-funnel.js +9 -68
  51. package/dist/governance/finding-funnel.js.map +1 -1
  52. package/dist/graph/build.d.ts +13 -75
  53. package/dist/graph/build.d.ts.map +1 -1
  54. package/dist/graph/build.js +0 -0
  55. package/dist/graph/build.js.map +1 -1
  56. package/dist/graph/cross-language.d.ts +4 -43
  57. package/dist/graph/cross-language.d.ts.map +1 -1
  58. package/dist/graph/cross-language.js +9 -77
  59. package/dist/graph/cross-language.js.map +1 -1
  60. package/dist/graph/index.d.ts +1 -1
  61. package/dist/graph/index.d.ts.map +1 -1
  62. package/dist/graph/merge.d.ts +8 -76
  63. package/dist/graph/merge.d.ts.map +1 -1
  64. package/dist/graph/merge.js +27 -77
  65. package/dist/graph/merge.js.map +1 -1
  66. package/dist/graph/observed-tests.d.ts +7 -68
  67. package/dist/graph/observed-tests.d.ts.map +1 -1
  68. package/dist/graph/observed-tests.js +5 -60
  69. package/dist/graph/observed-tests.js.map +1 -1
  70. package/dist/graph/persist.d.ts +2 -25
  71. package/dist/graph/persist.d.ts.map +1 -1
  72. package/dist/graph/persist.js +2 -25
  73. package/dist/graph/persist.js.map +1 -1
  74. package/dist/graph/runtime-confirmation.d.ts +14 -91
  75. package/dist/graph/runtime-confirmation.d.ts.map +1 -1
  76. package/dist/graph/runtime-confirmation.js +19 -103
  77. package/dist/graph/runtime-confirmation.js.map +1 -1
  78. package/dist/ledger/mint.d.ts +9 -43
  79. package/dist/ledger/mint.d.ts.map +1 -1
  80. package/dist/ledger/mint.js +15 -65
  81. package/dist/ledger/mint.js.map +1 -1
  82. package/dist/ledger/resolve.d.ts +13 -81
  83. package/dist/ledger/resolve.d.ts.map +1 -1
  84. package/dist/ledger/resolve.js +13 -76
  85. package/dist/ledger/resolve.js.map +1 -1
  86. package/dist/multipr/fingerprint.d.ts +5 -46
  87. package/dist/multipr/fingerprint.d.ts.map +1 -1
  88. package/dist/multipr/fingerprint.js +22 -74
  89. package/dist/multipr/fingerprint.js.map +1 -1
  90. package/dist/multipr/hidden-dependency.d.ts +13 -73
  91. package/dist/multipr/hidden-dependency.d.ts.map +1 -1
  92. package/dist/multipr/hidden-dependency.js +12 -63
  93. package/dist/multipr/hidden-dependency.js.map +1 -1
  94. package/dist/multipr/mechanical.d.ts +25 -160
  95. package/dist/multipr/mechanical.d.ts.map +1 -1
  96. package/dist/multipr/mechanical.js +21 -137
  97. package/dist/multipr/mechanical.js.map +1 -1
  98. package/dist/multipr/migration-heads.d.ts +18 -105
  99. package/dist/multipr/migration-heads.d.ts.map +1 -1
  100. package/dist/multipr/migration-heads.js +15 -84
  101. package/dist/multipr/migration-heads.js.map +1 -1
  102. package/dist/multipr/overlap.d.ts +16 -94
  103. package/dist/multipr/overlap.d.ts.map +1 -1
  104. package/dist/multipr/overlap.js +25 -105
  105. package/dist/multipr/overlap.js.map +1 -1
  106. package/dist/multipr/scope-store.d.ts +15 -80
  107. package/dist/multipr/scope-store.d.ts.map +1 -1
  108. package/dist/multipr/scope-store.js +17 -87
  109. package/dist/multipr/scope-store.js.map +1 -1
  110. package/dist/multipr/superseded.d.ts +10 -95
  111. package/dist/multipr/superseded.d.ts.map +1 -1
  112. package/dist/multipr/superseded.js +7 -60
  113. package/dist/multipr/superseded.js.map +1 -1
  114. package/dist/query/confirmed-facts.d.ts +12 -58
  115. package/dist/query/confirmed-facts.d.ts.map +1 -1
  116. package/dist/query/confirmed-facts.js +8 -47
  117. package/dist/query/confirmed-facts.js.map +1 -1
  118. package/dist/query/declared-value-closure.d.ts +13 -104
  119. package/dist/query/declared-value-closure.d.ts.map +1 -1
  120. package/dist/query/declared-value-closure.js +15 -104
  121. package/dist/query/declared-value-closure.js.map +1 -1
  122. package/dist/query/memory.d.ts +5 -9
  123. package/dist/query/memory.d.ts.map +1 -1
  124. package/dist/query/memory.js +31 -15
  125. package/dist/query/memory.js.map +1 -1
  126. package/dist/query/prominence.d.ts +6 -55
  127. package/dist/query/prominence.d.ts.map +1 -1
  128. package/dist/query/prominence.js +6 -55
  129. package/dist/query/prominence.js.map +1 -1
  130. package/dist/query/provider.d.ts +28 -81
  131. package/dist/query/provider.d.ts.map +1 -1
  132. package/dist/query/provider.js +8 -29
  133. package/dist/query/provider.js.map +1 -1
  134. package/dist/query/queries.d.ts +15 -65
  135. package/dist/query/queries.d.ts.map +1 -1
  136. package/dist/query/queries.js +43 -100
  137. package/dist/query/queries.js.map +1 -1
  138. package/dist/query/refusal-fetch.d.ts +8 -85
  139. package/dist/query/refusal-fetch.d.ts.map +1 -1
  140. package/dist/query/refusal-fetch.js +11 -93
  141. package/dist/query/refusal-fetch.js.map +1 -1
  142. package/dist/query/refusal-questions.d.ts +17 -92
  143. package/dist/query/refusal-questions.d.ts.map +1 -1
  144. package/dist/query/refusal-questions.js +14 -78
  145. package/dist/query/refusal-questions.js.map +1 -1
  146. package/dist/query/resolution-floor.d.ts +3 -23
  147. package/dist/query/resolution-floor.d.ts.map +1 -1
  148. package/dist/query/resolution-floor.js +3 -23
  149. package/dist/query/resolution-floor.js.map +1 -1
  150. package/dist/query/root-cause-score.d.ts +11 -161
  151. package/dist/query/root-cause-score.d.ts.map +1 -1
  152. package/dist/query/root-cause-score.js +6 -137
  153. package/dist/query/root-cause-score.js.map +1 -1
  154. package/dist/query/row-closure-picture.d.ts +5 -67
  155. package/dist/query/row-closure-picture.d.ts.map +1 -1
  156. package/dist/query/row-closure-picture.js +6 -67
  157. package/dist/query/row-closure-picture.js.map +1 -1
  158. package/dist/query/similar-incidents.d.ts +6 -41
  159. package/dist/query/similar-incidents.d.ts.map +1 -1
  160. package/dist/query/similar-incidents.js +15 -69
  161. package/dist/query/similar-incidents.js.map +1 -1
  162. package/dist/query/sqlite.d.ts +3 -7
  163. package/dist/query/sqlite.d.ts.map +1 -1
  164. package/dist/query/sqlite.js +13 -16
  165. package/dist/query/sqlite.js.map +1 -1
  166. package/dist/query/test-coverage.d.ts +5 -45
  167. package/dist/query/test-coverage.d.ts.map +1 -1
  168. package/dist/query/test-coverage.js +10 -53
  169. package/dist/query/test-coverage.js.map +1 -1
  170. package/dist/query/traverse.d.ts +22 -126
  171. package/dist/query/traverse.d.ts.map +1 -1
  172. package/dist/query/traverse.js +0 -0
  173. package/dist/query/traverse.js.map +1 -1
  174. package/dist/query/unresolved.d.ts +19 -164
  175. package/dist/query/unresolved.d.ts.map +1 -1
  176. package/dist/query/unresolved.js +11 -138
  177. package/dist/query/unresolved.js.map +1 -1
  178. package/dist/query/verification-status.d.ts +12 -109
  179. package/dist/query/verification-status.d.ts.map +1 -1
  180. package/dist/query/verification-status.js +9 -99
  181. package/dist/query/verification-status.js.map +1 -1
  182. package/dist/recording/migrate.d.ts +4 -10
  183. package/dist/recording/migrate.d.ts.map +1 -1
  184. package/dist/recording/migrate.js +4 -10
  185. package/dist/recording/migrate.js.map +1 -1
  186. package/dist/recording/reader.d.ts +2 -7
  187. package/dist/recording/reader.d.ts.map +1 -1
  188. package/dist/recording/reader.js +2 -7
  189. package/dist/recording/reader.js.map +1 -1
  190. package/dist/recording/redact.d.ts +6 -57
  191. package/dist/recording/redact.d.ts.map +1 -1
  192. package/dist/recording/redact.js +8 -64
  193. package/dist/recording/redact.js.map +1 -1
  194. package/dist/recording/schema.d.ts +3 -38
  195. package/dist/recording/schema.d.ts.map +1 -1
  196. package/dist/recording/schema.js +3 -38
  197. package/dist/recording/schema.js.map +1 -1
  198. package/dist/recording/writer.d.ts +11 -74
  199. package/dist/recording/writer.d.ts.map +1 -1
  200. package/dist/recording/writer.js +3 -43
  201. package/dist/recording/writer.js.map +1 -1
  202. package/dist/scoping/fanout.d.ts +6 -68
  203. package/dist/scoping/fanout.d.ts.map +1 -1
  204. package/dist/scoping/fanout.js +6 -68
  205. package/dist/scoping/fanout.js.map +1 -1
  206. package/dist/scoping/score.d.ts +20 -70
  207. package/dist/scoping/score.d.ts.map +1 -1
  208. package/dist/scoping/score.js +20 -70
  209. package/dist/scoping/score.js.map +1 -1
  210. package/dist/scoping/tiers.d.ts +4 -16
  211. package/dist/scoping/tiers.d.ts.map +1 -1
  212. package/dist/scoping/tiers.js +4 -16
  213. package/dist/scoping/tiers.js.map +1 -1
  214. package/dist/scoping/traverse.d.ts +3 -25
  215. package/dist/scoping/traverse.d.ts.map +1 -1
  216. package/dist/scoping/traverse.js +14 -49
  217. package/dist/scoping/traverse.js.map +1 -1
  218. package/dist/scoping/weights.d.ts +10 -74
  219. package/dist/scoping/weights.d.ts.map +1 -1
  220. package/dist/scoping/weights.js +14 -86
  221. package/dist/scoping/weights.js.map +1 -1
  222. package/dist/sources/confirmed/incidents.d.ts +5 -35
  223. package/dist/sources/confirmed/incidents.d.ts.map +1 -1
  224. package/dist/sources/confirmed/incidents.js +14 -48
  225. package/dist/sources/confirmed/incidents.js.map +1 -1
  226. package/dist/sources/git/diff.d.ts +71 -65
  227. package/dist/sources/git/diff.d.ts.map +1 -1
  228. package/dist/sources/git/diff.js +136 -83
  229. package/dist/sources/git/diff.js.map +1 -1
  230. package/dist/sources/git/env.d.ts +7 -0
  231. package/dist/sources/git/env.d.ts.map +1 -1
  232. package/dist/sources/git/env.js +10 -11
  233. package/dist/sources/git/env.js.map +1 -1
  234. package/dist/sources/git/history.d.ts +64 -84
  235. package/dist/sources/git/history.d.ts.map +1 -1
  236. package/dist/sources/git/history.js +141 -112
  237. package/dist/sources/git/history.js.map +1 -1
  238. package/dist/sources/git/incidents.d.ts +13 -75
  239. package/dist/sources/git/incidents.d.ts.map +1 -1
  240. package/dist/sources/git/incidents.js +21 -91
  241. package/dist/sources/git/incidents.js.map +1 -1
  242. package/dist/sources/git/index.d.ts +5 -3
  243. package/dist/sources/git/index.d.ts.map +1 -1
  244. package/dist/sources/git/index.js +3 -2
  245. package/dist/sources/git/index.js.map +1 -1
  246. package/dist/sources/git/source.d.ts +9 -79
  247. package/dist/sources/git/source.d.ts.map +1 -1
  248. package/dist/sources/git/source.js +0 -0
  249. package/dist/sources/git/source.js.map +1 -1
  250. package/dist/sources/migrations/across-change.d.ts +94 -0
  251. package/dist/sources/migrations/across-change.d.ts.map +1 -0
  252. package/dist/sources/migrations/across-change.js +278 -0
  253. package/dist/sources/migrations/across-change.js.map +1 -0
  254. package/dist/sources/migrations/dialects.d.ts +20 -36
  255. package/dist/sources/migrations/dialects.d.ts.map +1 -1
  256. package/dist/sources/migrations/dialects.js +11 -36
  257. package/dist/sources/migrations/dialects.js.map +1 -1
  258. package/dist/sources/migrations/index.d.ts +3 -1
  259. package/dist/sources/migrations/index.d.ts.map +1 -1
  260. package/dist/sources/migrations/index.js +2 -1
  261. package/dist/sources/migrations/index.js.map +1 -1
  262. package/dist/sources/migrations/read.d.ts +14 -79
  263. package/dist/sources/migrations/read.d.ts.map +1 -1
  264. package/dist/sources/migrations/read.js +14 -89
  265. package/dist/sources/migrations/read.js.map +1 -1
  266. package/dist/sources/workspace/workspace.d.ts +6 -42
  267. package/dist/sources/workspace/workspace.d.ts.map +1 -1
  268. package/dist/sources/workspace/workspace.js +10 -53
  269. package/dist/sources/workspace/workspace.js.map +1 -1
  270. package/dist/store/driver/driver.d.ts +9 -38
  271. package/dist/store/driver/driver.d.ts.map +1 -1
  272. package/dist/store/driver/driver.js +4 -22
  273. package/dist/store/driver/driver.js.map +1 -1
  274. package/dist/store/driver/node-sqlite.d.ts +3 -12
  275. package/dist/store/driver/node-sqlite.d.ts.map +1 -1
  276. package/dist/store/driver/node-sqlite.js +4 -18
  277. package/dist/store/driver/node-sqlite.js.map +1 -1
  278. package/dist/store/index.d.ts +2 -7
  279. package/dist/store/index.d.ts.map +1 -1
  280. package/dist/store/index.js +4 -10
  281. package/dist/store/index.js.map +1 -1
  282. package/dist/store/migrate.d.ts +14 -50
  283. package/dist/store/migrate.d.ts.map +1 -1
  284. package/dist/store/migrate.js +15 -52
  285. package/dist/store/migrate.js.map +1 -1
  286. package/dist/store/reader.d.ts +19 -84
  287. package/dist/store/reader.d.ts.map +1 -1
  288. package/dist/store/reader.js +25 -92
  289. package/dist/store/reader.js.map +1 -1
  290. package/dist/store/schema.d.ts +14 -76
  291. package/dist/store/schema.d.ts.map +1 -1
  292. package/dist/store/schema.js +14 -76
  293. package/dist/store/schema.js.map +1 -1
  294. package/dist/store/writer.d.ts +14 -88
  295. package/dist/store/writer.d.ts.map +1 -1
  296. package/dist/store/writer.js +29 -123
  297. package/dist/store/writer.js.map +1 -1
  298. package/dist/tiers/certify.d.ts +46 -281
  299. package/dist/tiers/certify.d.ts.map +1 -1
  300. package/dist/tiers/certify.js +46 -226
  301. package/dist/tiers/certify.js.map +1 -1
  302. package/dist/tiers/ladder.d.ts +7 -51
  303. package/dist/tiers/ladder.d.ts.map +1 -1
  304. package/dist/tiers/ladder.js +13 -89
  305. package/dist/tiers/ladder.js.map +1 -1
  306. package/dist/validation/attributes.d.ts +47 -0
  307. package/dist/validation/attributes.d.ts.map +1 -0
  308. package/dist/validation/attributes.js +130 -0
  309. package/dist/validation/attributes.js.map +1 -0
  310. package/dist/validation/config-graph.d.ts +7 -56
  311. package/dist/validation/config-graph.d.ts.map +1 -1
  312. package/dist/validation/config-graph.js +15 -61
  313. package/dist/validation/config-graph.js.map +1 -1
  314. package/dist/validation/env.d.ts +53 -2
  315. package/dist/validation/env.d.ts.map +1 -1
  316. package/dist/validation/env.js +99 -4
  317. package/dist/validation/env.js.map +1 -1
  318. package/dist/validation/index.d.ts +5 -1
  319. package/dist/validation/index.d.ts.map +1 -1
  320. package/dist/validation/index.js +3 -1
  321. package/dist/validation/index.js.map +1 -1
  322. package/dist/validation/join-substitution.d.ts +22 -120
  323. package/dist/validation/join-substitution.d.ts.map +1 -1
  324. package/dist/validation/join-substitution.js +13 -90
  325. package/dist/validation/join-substitution.js.map +1 -1
  326. package/dist/validation/migration-integrity.d.ts +72 -0
  327. package/dist/validation/migration-integrity.d.ts.map +1 -0
  328. package/dist/validation/migration-integrity.js +238 -0
  329. package/dist/validation/migration-integrity.js.map +1 -0
  330. package/dist/validation/migrations.d.ts +23 -88
  331. package/dist/validation/migrations.d.ts.map +1 -1
  332. package/dist/validation/migrations.js +20 -79
  333. package/dist/validation/migrations.js.map +1 -1
  334. package/dist/validation/nodes.d.ts +3 -1
  335. package/dist/validation/nodes.d.ts.map +1 -1
  336. package/dist/validation/nodes.js +3 -1
  337. package/dist/validation/nodes.js.map +1 -1
  338. package/dist/validation/rollback.d.ts +10 -73
  339. package/dist/validation/rollback.d.ts.map +1 -1
  340. package/dist/validation/rollback.js +23 -81
  341. package/dist/validation/rollback.js.map +1 -1
  342. package/dist/validation/route-drift.d.ts +9 -62
  343. package/dist/validation/route-drift.d.ts.map +1 -1
  344. package/dist/validation/route-drift.js +7 -52
  345. package/dist/validation/route-drift.js.map +1 -1
  346. package/dist/validation/sources.d.ts +16 -94
  347. package/dist/validation/sources.d.ts.map +1 -1
  348. package/dist/validation/sources.js +51 -147
  349. package/dist/validation/sources.js.map +1 -1
  350. package/dist/worker/pool.d.ts +6 -45
  351. package/dist/worker/pool.d.ts.map +1 -1
  352. package/dist/worker/pool.js +5 -42
  353. package/dist/worker/pool.js.map +1 -1
  354. package/dist/worker/protocol.d.ts +7 -20
  355. package/dist/worker/protocol.d.ts.map +1 -1
  356. package/dist/worker/protocol.js +3 -10
  357. package/dist/worker/protocol.js.map +1 -1
  358. package/dist/worker/traversal.worker.d.ts +2 -21
  359. package/dist/worker/traversal.worker.d.ts.map +1 -1
  360. package/dist/worker/traversal.worker.js +4 -23
  361. package/dist/worker/traversal.worker.js.map +1 -1
  362. package/package.json +11 -2
@@ -1,64 +1,19 @@
1
1
  /**
2
- * §14.2 — persisting a change's scoped subgraph, and the one field that makes
3
- * two of them comparable.
4
- *
5
- * ## Why this is stored at all, when everything else derived is thrown away
6
- *
7
- * A scope looks derived. It is not, and the reason is easy to get backwards:
8
- * everything on the derived side regenerates because *the source still produces
9
- * it*. A PR scope was computed against a graph **at one commit**, and that graph
10
- * moves. Recomputing it later does not restore it — it answers a different
11
- * question and returns a plausible answer to it. Dropping it does not lose time,
12
- * it loses the comparison basis.
13
- *
14
- * That is why `pr_scopes` sits in `EARNED_TABLES` beside observed edges and
15
- * human corrections, and it is the weaker-looking member of that set in one
16
- * respect and the more dangerous in another: an R4 observation cannot be
17
- * recomputed at any price, whereas a PR scope can be recomputed **wrongly**.
18
- *
19
- * ## `graphCommitSha` is the whole design
20
- *
21
- * Two scopes are comparable only when they were computed against the same
22
- * graph. The schema puts that commit in the primary key so the same PR at two
23
- * graph states is two rows rather than one silently overwriting the other, and
24
- * indexes `(repo, graph_commit_sha)` because overlap scoring's only real query
25
- * is *every scope computed against one graph*.
26
- *
27
- * **It is a different commit from the PR's own head**, and this module renamed a
28
- * field to say so. `overlap.ts` originally carried one `baseSha` described as
29
- * "the base commit it was computed against", which is ambiguous between the two
30
- * and would have let a comparison key on the wrong one. The store's column
31
- * comment is what caught it.
32
- *
33
- * ## An incomparable pair and a non-conflicting pair look identical
34
- *
35
- * Both produce an empty overlap. The schema comment warns that a reader
36
- * ignoring `graph_commit_sha` "will happily overlap a scope from last week with
37
- * one from today and report a number" — so the refusal lives in `findOverlaps`
38
- * rather than here, where it also protects the caller who never touches a store.
2
+ * §14.2 — persisting a change's scoped subgraph. Looks derived but isn't: computed against a graph at one commit, and that graph moves — recomputing later answers a different question, so pr_scopes sits in EARNED_TABLES (worse than an R4 observation: it can be recomputed wrongly, not just never).
3
+ * graphCommitSha (distinct from the PR's head — a prior `baseSha` name was ambiguous) is in the primary key so two graph states are two rows, not an overwrite. An incomparable pair and a non-conflicting pair both produce empty overlap, so that refusal lives in findOverlaps, not here.
39
4
  */
40
5
  import { canonicalJson } from "@descryy/ir";
41
6
  const COLUMNS = "pr_id, repo, head_sha, graph_commit_sha, scope_json, node_count, computed_at";
42
- /**
43
- * Thrown when a stored scope cannot be turned back into one.
44
- *
45
- * A corrupt row is not an empty scope. Returning `[]` here would make a damaged
46
- * store indistinguishable from a PR that touched nothing, which is the
47
- * conflation §14.8 exists to refuse one layer up.
48
- */
7
+ /** Thrown when a stored scope can't be decoded. A corrupt row is not an
8
+ * empty scope — returning [] would conflate the two (§14.8 refuses this). */
49
9
  export class ScopeDecodeError extends Error {
50
10
  name = "ScopeDecodeError";
51
11
  constructor(message, options) {
52
12
  super(message, options);
53
13
  }
54
14
  }
55
- /**
56
- * `canonicalJson` throws on `undefined` rather than dropping the key, which is
57
- * the right call everywhere else in this project and means an optional field
58
- * cannot simply be handed to it. `file` is the only one, and it is genuinely
59
- * absent rather than null — a scope entry for a node the graph has no path for
60
- * is not a scope entry with a null path.
61
- */
15
+ /** canonicalJson throws on undefined rather than dropping the key. `file` is
16
+ * genuinely absent, not null — a no-path node isn't a null-path entry. */
62
17
  function encodeEntry(entry) {
63
18
  const encoded = {
64
19
  nodeId: entry.nodeId,
@@ -95,24 +50,16 @@ function decode(row) {
95
50
  computedAt: row.computed_at,
96
51
  };
97
52
  }
98
- /**
99
- * Row access for `pr_scopes`. Thin on purpose, in the style of `reader.ts`:
100
- * nothing here scores, compares or decides staleness.
101
- */
53
+ /** Row access for pr_scopes. Thin on purpose (style of reader.ts): nothing
54
+ * here scores, compares or decides staleness. */
102
55
  export class ScopeStore {
103
56
  #driver;
104
57
  constructor(driver) {
105
58
  this.#driver = driver;
106
59
  }
107
- /**
108
- * Write a scope, replacing any row for the same `(repo, prId, graphCommitSha)`.
109
- *
110
- * Replacement is safe **only** because the graph commit is in the key:
111
- * recomputing the same PR against the same graph must produce the same scope,
112
- * so the row being replaced is equal to the one replacing it. Recomputing
113
- * against a *different* graph writes a new row and leaves the old comparison
114
- * basis intact, which is the entire reason the column is in the key.
115
- */
60
+ /** Write a scope, replacing any row for (repo, prId, graphCommitSha).
61
+ * Safe only because the graph commit is in the key — a different graph
62
+ * writes a new row and leaves the old comparison basis intact. */
116
63
  save(scope) {
117
64
  const json = canonicalJson(scope.entries.map(encodeEntry));
118
65
  this.#driver
@@ -137,27 +84,16 @@ export class ScopeStore {
137
84
  .get(repo, prId, graphCommitSha);
138
85
  return row === undefined ? undefined : decode(row);
139
86
  }
140
- /**
141
- * **The query overlap scoring is for**: every scope computed against one
142
- * graph, and therefore every scope that can legitimately be compared.
143
- *
144
- * Ordered by `pr_id` so a report is stable across runs — an unordered read
145
- * makes two identical graphs produce two differently-ordered reports and
146
- * turns a diff into noise.
147
- */
87
+ /** The query overlap scoring is for: every scope computed against one
88
+ * graph. Ordered by pr_id so a report is stable across runs. */
148
89
  loadForGraph(repo, graphCommitSha) {
149
90
  return this.#driver
150
91
  .prepare(`SELECT ${COLUMNS} FROM pr_scopes WHERE repo = ? AND graph_commit_sha = ? ORDER BY pr_id`)
151
92
  .all(repo, graphCommitSha)
152
93
  .map(decode);
153
94
  }
154
- /**
155
- * Every graph state a PR has a scope for, newest computation first.
156
- *
157
- * Exposed because "this PR was scoped against three different graphs" is a
158
- * fact a caller may need and cannot reconstruct from `load`, which requires
159
- * knowing the commit in advance.
160
- */
95
+ /** Every graph state a PR has a scope for, newest first — not reconstructable
96
+ * from `load`, which requires knowing the commit in advance. */
161
97
  graphStatesFor(repo, prId) {
162
98
  return this.#driver
163
99
  .prepare(`SELECT graph_commit_sha, computed_at FROM pr_scopes
@@ -165,14 +101,8 @@ export class ScopeStore {
165
101
  .all(repo, prId)
166
102
  .map((r) => ({ graphCommitSha: r.graph_commit_sha, computedAt: r.computed_at }));
167
103
  }
168
- /**
169
- * Forget a PR entirely — every graph state it was scoped against.
170
- *
171
- * The only legitimate deletion: a closed or merged PR is not in flight and
172
- * cannot conflict with anything. Deleting a *single* graph state is not
173
- * offered, because the row is the comparison basis and there is no caller who
174
- * wants exactly one of them gone.
175
- */
104
+ /** Forget a PR entirely — every graph state it was scoped against. The only
105
+ * legitimate deletion: a closed/merged PR can't conflict with anything. */
176
106
  forget(repo, prId) {
177
107
  return this.#driver
178
108
  .prepare("DELETE FROM pr_scopes WHERE repo = ? AND pr_id = ?")
@@ -1 +1 @@
1
- {"version":3,"file":"scope-store.js","sourceRoot":"","sources":["../../src/multipr/scope-store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"scope-store.js","sourceRoot":"","sources":["../../src/multipr/scope-store.ts"],"names":[],"mappings":"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"}
@@ -1,79 +1,18 @@
1
1
  /**
2
- * §14.5 — a change whose work is already in base.
3
- *
4
- * The architecture gives one sentence: *"Compare a PR's resulting code
5
- * (post-diff) against current base. If functionally identical, flag as
6
- * superseded."* Everything below is what that sentence turns into once the
7
- * consequences of being wrong are taken seriously.
8
- *
9
- * ## This is the one check in §14 whose finding destroys work
10
- *
11
- * Every other multi-PR check tells someone to look at something. This one tells
12
- * them to **close a pull request**, and a wrong answer throws away work that
13
- * nobody has a copy of. §14.4's auto-apply path is the documented exception to
14
- * approval-before-code-change and is hedged with a mandatory verify-after; this
15
- * check has no such gate because the action it prompts is a human's.
16
- *
17
- * So the bar is asymmetric on purpose, and it is rule 2 applied to a finding
18
- * rather than to an edge: **a missed supersession costs a redundant review; a
19
- * false one costs the work.** Concretely, `superseded` is claimed only when
20
- * *every* touched node was compared and *every* comparison matched. One node
21
- * whose base state could not be read is enough to withhold the claim — and the
22
- * partial result is still reported, because "9 of 10 already landed" is useful
23
- * to the same reader and is a different sentence.
24
- *
25
- * ## Partial supersession is the common case, not an edge case
26
- *
27
- * The realistic history is that someone landed *most* of this work in another
28
- * change. A binary verdict answers that with `false` and discards the only
29
- * interesting part. So the report is a count and a list either way, and the
30
- * boolean is a summary of it rather than the result itself.
31
- *
32
- * ## Three states, again, and for the same reason
33
- *
34
- * A node whose base fingerprint is absent is not a node that differs. Both
35
- * would make `superseded` false, and only one of them is a statement about the
36
- * code — the other is a statement about the reading. `BaseState` therefore has
37
- * an explicit `"unknown"` rather than letting a missing fingerprint mean
38
- * "different", which is the shape this project has now paid for seven times.
39
- *
40
- * ## What "functionally identical" is allowed to mean here
41
- *
42
- * Whatever the caller's fingerprint says, and no more. This module compares
43
- * opaque strings; it does not normalise whitespace, sort imports or reason
44
- * about equivalence, because every one of those is a judgement about a language
45
- * and would put language knowledge above the IR boundary. A producer that
46
- * fingerprints a normalised AST and one that hashes raw bytes both work here,
47
- * and the report states which was used so a reader is never left to assume the
48
- * stronger one.
2
+ * §14.5: flag a change already landed on base. Asymmetric bar (rule 2) — a missed supersession costs a
3
+ * review, a false one destroys work — so `superseded` is true only when every node compared and matched.
4
+ * `BaseState` distinguishes "unknown" (unread) from "absent" (deleted); compares only opaque fingerprint strings, no normalisation (IR boundary).
49
5
  */
50
6
  import type { ReliabilityClass, ResolutionLevel } from "@descryy/ir";
51
7
  import type { DiffType } from "./overlap.ts";
52
- /**
53
- * One node the change touches, with the two states to compare.
54
- *
55
- * `after` is the node as the change leaves it. `base` is the same node on the
56
- * target branch **now** — not at the change's merge base, which is the whole
57
- * point: the question is whether this work is already there today.
58
- */
8
+ /** One node the change touches. `base` is the target branch **now**, not at merge-base — is the work there today. */
59
9
  export interface SupersededCandidate {
60
10
  readonly nodeId: string;
61
11
  readonly file?: string | undefined;
62
12
  readonly diffType: DiffType;
63
- /**
64
- * Fingerprint of the node as this change leaves it, or `"absent"` when the
65
- * change deletes it.
66
- */
13
+ /** Fingerprint as this change leaves the node, or `"absent"` when it deletes it. */
67
14
  readonly after: string | "absent";
68
- /**
69
- * The same node on base today: a fingerprint, `"absent"` when base does not
70
- * have it, or `"unknown"` when it could not be read.
71
- *
72
- * **`"absent"` and `"unknown"` are different.** A node base genuinely lacks
73
- * matches a deletion; a node whose base state could not be read matches
74
- * nothing, and the difference decides whether a human is told to close a
75
- * change.
76
- */
15
+ /** Base today: fingerprint, `"absent"` (base lacks it), or `"unknown"` (unreadable) — the two are never conflated. */
77
16
  readonly base: string | "absent" | "unknown";
78
17
  readonly resolution: ResolutionLevel;
79
18
  }
@@ -85,12 +24,7 @@ export interface NodeComparison {
85
24
  readonly verdict: NodeVerdict;
86
25
  }
87
26
  export interface SupersededReport {
88
- /**
89
- * True only when every touched node was compared and every one matched.
90
- *
91
- * A single `not-compared` node withholds this, however many matched — the
92
- * finding it feeds tells a human to discard work.
93
- */
27
+ /** True only when every touched node was compared and matched — one `not-compared` node withholds it. */
94
28
  readonly superseded: boolean;
95
29
  readonly comparisons: readonly NodeComparison[];
96
30
  readonly counts: {
@@ -99,35 +33,16 @@ export interface SupersededReport {
99
33
  readonly differs: number;
100
34
  readonly notCompared: number;
101
35
  };
102
- /**
103
- * False when there was nothing to compare.
104
- *
105
- * **Not the same as "not superseded".** A change with no candidates and a
106
- * change whose every node differs both report `superseded: false`.
107
- */
36
+ /** False when nothing was there to compare — not the same as "not superseded" (both report `superseded: false`). */
108
37
  readonly analysed: boolean;
109
38
  readonly reliability: ReliabilityClass;
110
39
  readonly disclosure: string;
111
40
  readonly notes: readonly string[];
112
41
  }
113
42
  export interface SupersededOptions {
114
- /**
115
- * How the caller's fingerprints were produced — "sha256 of raw bytes",
116
- * "hash of normalised AST". Carried into the disclosure verbatim.
117
- *
118
- * Required in substance rather than in type: omitting it produces a
119
- * disclosure that says the basis was not stated, because a reader who assumes
120
- * AST normalisation when the producer hashed bytes will read a `differs` as
121
- * meaningful when it was whitespace.
122
- */
43
+ /** How fingerprints were produced (e.g. "sha256 of raw bytes"), carried into the disclosure verbatim. Omitting it says so. */
123
44
  readonly fingerprintBasis?: string;
124
45
  }
125
- /**
126
- * Whether a change's work is already present on base.
127
- *
128
- * Pure over candidates: no store, no graph, no language. The caller's producer
129
- * decides what a fingerprint means and at what resolution it was obtained; this
130
- * propagates both.
131
- */
46
+ /** Whether a change's work is already present on base. Pure over candidates: no store, no graph, no language. */
132
47
  export declare function findSuperseded(candidates: readonly SupersededCandidate[], options?: SupersededOptions): SupersededReport;
133
48
  //# sourceMappingURL=superseded.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"superseded.d.ts","sourceRoot":"","sources":["../../src/multipr/superseded.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AAGH,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAE7C;;;;;;GAMG;AACH,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B;;;OAGG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,CAAC;IAClC;;;;;;;;OAQG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS,CAAC;IAC7C,QAAQ,CAAC,UAAU,EAAE,eAAe,CAAC;CACtC;AAED,MAAM,MAAM,WAAW,GAAG,iBAAiB,GAAG,SAAS,GAAG,cAAc,CAAC;AAEzE,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC;CAC/B;AAED,MAAM,WAAW,gBAAgB;IAC/B;;;;;OAKG;IACH,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,WAAW,EAAE,SAAS,cAAc,EAAE,CAAC;IAChD,QAAQ,CAAC,MAAM,EAAE;QACf,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;QAC/B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QACzB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;KAC9B,CAAC;IACF;;;;;OAKG;IACH,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,WAAW,EAAE,gBAAgB,CAAC;IACvC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;CACnC;AAED,MAAM,WAAW,iBAAiB;IAChC;;;;;;;;OAQG;IACH,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;CACpC;AAWD;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,UAAU,EAAE,SAAS,mBAAmB,EAAE,EAC1C,OAAO,GAAE,iBAAsB,GAC9B,gBAAgB,CA2ElB"}
1
+ {"version":3,"file":"superseded.d.ts","sourceRoot":"","sources":["../../src/multipr/superseded.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAE7C,qHAAqH;AACrH,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,oFAAoF;IACpF,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,CAAC;IAClC,sHAAsH;IACtH,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS,CAAC;IAC7C,QAAQ,CAAC,UAAU,EAAE,eAAe,CAAC;CACtC;AAED,MAAM,MAAM,WAAW,GAAG,iBAAiB,GAAG,SAAS,GAAG,cAAc,CAAC;AAEzE,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC;CAC/B;AAED,MAAM,WAAW,gBAAgB;IAC/B,yGAAyG;IACzG,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,WAAW,EAAE,SAAS,cAAc,EAAE,CAAC;IAChD,QAAQ,CAAC,MAAM,EAAE;QACf,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;QAC/B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QACzB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;KAC9B,CAAC;IACF,oHAAoH;IACpH,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,WAAW,EAAE,gBAAgB,CAAC;IACvC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;CACnC;AAED,MAAM,WAAW,iBAAiB;IAChC,8HAA8H;IAC9H,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;CACpC;AAUD,iHAAiH;AACjH,wBAAgB,cAAc,CAC5B,UAAU,EAAE,SAAS,mBAAmB,EAAE,EAC1C,OAAO,GAAE,iBAAsB,GAC9B,gBAAgB,CAyElB"}
@@ -1,71 +1,20 @@
1
1
  /**
2
- * §14.5 — a change whose work is already in base.
3
- *
4
- * The architecture gives one sentence: *"Compare a PR's resulting code
5
- * (post-diff) against current base. If functionally identical, flag as
6
- * superseded."* Everything below is what that sentence turns into once the
7
- * consequences of being wrong are taken seriously.
8
- *
9
- * ## This is the one check in §14 whose finding destroys work
10
- *
11
- * Every other multi-PR check tells someone to look at something. This one tells
12
- * them to **close a pull request**, and a wrong answer throws away work that
13
- * nobody has a copy of. §14.4's auto-apply path is the documented exception to
14
- * approval-before-code-change and is hedged with a mandatory verify-after; this
15
- * check has no such gate because the action it prompts is a human's.
16
- *
17
- * So the bar is asymmetric on purpose, and it is rule 2 applied to a finding
18
- * rather than to an edge: **a missed supersession costs a redundant review; a
19
- * false one costs the work.** Concretely, `superseded` is claimed only when
20
- * *every* touched node was compared and *every* comparison matched. One node
21
- * whose base state could not be read is enough to withhold the claim — and the
22
- * partial result is still reported, because "9 of 10 already landed" is useful
23
- * to the same reader and is a different sentence.
24
- *
25
- * ## Partial supersession is the common case, not an edge case
26
- *
27
- * The realistic history is that someone landed *most* of this work in another
28
- * change. A binary verdict answers that with `false` and discards the only
29
- * interesting part. So the report is a count and a list either way, and the
30
- * boolean is a summary of it rather than the result itself.
31
- *
32
- * ## Three states, again, and for the same reason
33
- *
34
- * A node whose base fingerprint is absent is not a node that differs. Both
35
- * would make `superseded` false, and only one of them is a statement about the
36
- * code — the other is a statement about the reading. `BaseState` therefore has
37
- * an explicit `"unknown"` rather than letting a missing fingerprint mean
38
- * "different", which is the shape this project has now paid for seven times.
39
- *
40
- * ## What "functionally identical" is allowed to mean here
41
- *
42
- * Whatever the caller's fingerprint says, and no more. This module compares
43
- * opaque strings; it does not normalise whitespace, sort imports or reason
44
- * about equivalence, because every one of those is a judgement about a language
45
- * and would put language knowledge above the IR boundary. A producer that
46
- * fingerprints a normalised AST and one that hashes raw bytes both work here,
47
- * and the report states which was used so a reader is never left to assume the
48
- * stronger one.
2
+ * §14.5: flag a change already landed on base. Asymmetric bar (rule 2) — a missed supersession costs a
3
+ * review, a false one destroys work — so `superseded` is true only when every node compared and matched.
4
+ * `BaseState` distinguishes "unknown" (unread) from "absent" (deleted); compares only opaque fingerprint strings, no normalisation (IR boundary).
49
5
  */
50
6
  import { reliabilityCap, reliabilityNote } from "@descryy/ir";
51
7
  function compare(c) {
52
8
  if (c.base === "unknown")
53
9
  return "not-compared";
54
- // A deletion is superseded when base has already lost the node. `after` and
55
- // `base` both being "absent" is a match, not two missing values.
10
+ // Both "absent" is a match (deletion already landed), not two missing values.
56
11
  if (c.after === "absent")
57
12
  return c.base === "absent" ? "already-in-base" : "differs";
58
13
  if (c.base === "absent")
59
14
  return "differs";
60
15
  return c.after === c.base ? "already-in-base" : "differs";
61
16
  }
62
- /**
63
- * Whether a change's work is already present on base.
64
- *
65
- * Pure over candidates: no store, no graph, no language. The caller's producer
66
- * decides what a fingerprint means and at what resolution it was obtained; this
67
- * propagates both.
68
- */
17
+ /** Whether a change's work is already present on base. Pure over candidates: no store, no graph, no language. */
69
18
  export function findSuperseded(candidates, options = {}) {
70
19
  const notes = [];
71
20
  const comparisons = candidates.map((c) => ({
@@ -77,10 +26,8 @@ export function findSuperseded(candidates, options = {}) {
77
26
  const alreadyInBase = comparisons.filter((c) => c.verdict === "already-in-base").length;
78
27
  const differs = comparisons.filter((c) => c.verdict === "differs").length;
79
28
  const notCompared = comparisons.filter((c) => c.verdict === "not-compared").length;
80
- // The weakest candidate decides, as everywhere else a claim rests on several
81
- // observations. Whether two fingerprints are equal is a name-level fact — it
82
- // is an identity of strings, not a claim about behaviour — so R2's carve-out
83
- // applies and nothing here reaches beyond what its evidence bought.
29
+ // The weakest candidate decides. Fingerprint equality is a name-level fact
30
+ // (string identity, not behaviour), so R2's carve-out applies.
84
31
  const weakest = candidates.reduce((min, c) => (c.resolution < min ? c.resolution : min), 4);
85
32
  const reliability = reliabilityCap(weakest, true);
86
33
  let disclosure = reliabilityNote(weakest, true);
@@ -1 +1 @@
1
- {"version":3,"file":"superseded.js","sourceRoot":"","sources":["../../src/multipr/superseded.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"superseded.js","sourceRoot":"","sources":["../../src/multipr/superseded.ts"],"names":[],"mappings":"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"}
@@ -1,43 +1,16 @@
1
- /**
2
- * DEC-223's answer half, matching side: which refusal-ledger rows does a
3
- * confirmed fact actually answer?
4
- *
5
- * Deliberately does **not** mint a graph edge. Turning an answered row into a
6
- * real `USES_API`/etc. edge needs a target to join against — an endpoint, a
7
- * route — which this function has no way to resolve and which DEC-223 §6
8
- * named as future work, not this row. What this function owns is narrower
9
- * and load-bearing on its own: **which rows are answered, by what value, and
10
- * that the match never crosses a repo or accessor boundary it should not.**
11
- * A caller minting an edge from `answered` is the one obligated to pass
12
- * `reliabilityCap`'s `humanAsserted: true` — this function does not compute a
13
- * reliability class itself, because it has no resolution level to reason
14
- * from (`UnresolvedRef` carries none — refusals are not edges and were never
15
- * scored). Inventing one here would be exactly the overclaim principle 2
16
- * exists to prevent.
17
- */
1
+ /** DEC-223's matching half: which refusal-ledger rows a confirmed fact answers. Deliberately
2
+ * doesn't mint a graph edge (no target to resolve — DEC-223 §6's future work). A caller minting
3
+ * one must pass `reliabilityCap`'s `humanAsserted: true` itself — refusals carry no resolution level. */
18
4
  import type { ConfirmedFact, UnresolvedRef } from "@descryy/ir";
19
5
  export interface ConfirmedFactMatch {
20
6
  readonly ref: UnresolvedRef;
21
- /**
22
- * True when every fact in `facts` was confirmed in a *different* repository
23
- * and reaches this one only because it was declared `scope: "workspace"`.
24
- *
25
- * Surfaced rather than folded away: "somebody answered this here" and
26
- * "somebody answered this in the frontend and said it holds workspace-wide"
27
- * are different facts about what the developer actually knows, and a caller
28
- * that cannot tell them apart cannot disclose the difference.
29
- */
7
+ /** True when every fact in `facts` was confirmed in a different repo, reaching this one only via
8
+ * `scope: "workspace"`. Surfaced, not folded away — "answered here" and "answered elsewhere,
9
+ * declared workspace-wide" are different facts a caller must be able to disclose. */
30
10
  readonly fromAnotherRepo: boolean;
31
- /**
32
- * Every fact sharing this row's `(repo, blockedBy)`, regardless of
33
- * `environment` — never picks one. A row's own site carries no environment
34
- * of its own (the code runs in whichever environment it is deployed to),
35
- * so this function cannot know which of several environment-scoped facts
36
- * applies; surfacing all of them lets a caller show the split rather than
37
- * silently choosing a value that might be wrong for the environment the
38
- * row actually runs in. Almost always length 1 — DEC-223's own measured
39
- * cases were unscoped, single-fact answers — but never assumed to be.
40
- */
11
+ /** Every fact sharing `(repo, blockedBy)`, regardless of environment — never picks one, since
12
+ * this function can't know which environment-scoped fact applies. Surfacing all lets the caller
13
+ * show the split. Almost always length 1 (DEC-223's measured cases), but never assumed to be. */
41
14
  readonly facts: readonly ConfirmedFact[];
42
15
  }
43
16
  export interface ConfirmedFactApplication {
@@ -46,27 +19,8 @@ export interface ConfirmedFactApplication {
46
19
  /** Every other row: unclassified, a different class than `"value-unknown"`, or no matching fact yet. */
47
20
  readonly stillOpen: readonly UnresolvedRef[];
48
21
  }
49
- /**
50
- * Match ledger rows against confirmed facts, scoped to one repository.
51
- *
52
- * Three things keep a row out of `answered`, all deliberate:
53
- *
54
- * 1. **No `attrs.refusalClass === "value-unknown"`.** Everything else —
55
- * unclassified, `capability-gap`, `out-of-scope`, `varies-per-call` — is
56
- * not askable at all (DEC-242), so no fact could ever answer it; matching
57
- * on `blockedBy` alone without this check would let a stored fact silently
58
- * resolve a `varies-per-call` row that structurally has no single answer.
59
- * 2. **No `attrs.blockedBy`, or it is not a string.** Nothing to key against.
60
- * 3. **No fact in `facts` reaches this repository.** A fact for a different
61
- * `repo` is not consulted merely because its `blockedBy` text matches —
62
- * rule 3's "never an inference about a second case," enforced structurally
63
- * rather than left to caller discipline. The **one** way it crosses is
64
- * `reaches()` below: the person recording it declared
65
- * `scope: "workspace"` under the same workspace id this session is
66
- * configured with. A declaration, not an inference — see
67
- * DEC-NEXT-workspace-scoped-confirmed-facts for why the alternative
68
- * (any fact answers any linked repo) is unsafe: two services can both read
69
- * `DATABASE_URL` and mean different things by it.
70
- */
22
+ /** Matches ledger rows to confirmed facts, scoped to one repo. Excluded from `answered`: not
23
+ * `refusalClass === "value-unknown"` (everything else isn't askable at all, DEC-242); no
24
+ * `blockedBy`; or no fact reaches this repo (rule 3 — crossing needs declared `scope: "workspace"`, never inferred). */
71
25
  export declare function applyConfirmedFacts(refs: readonly UnresolvedRef[], facts: readonly ConfirmedFact[], repo: string, workspace?: string): ConfirmedFactApplication;
72
26
  //# sourceMappingURL=confirmed-facts.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"confirmed-facts.d.ts","sourceRoot":"","sources":["../../src/query/confirmed-facts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEhE,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,GAAG,EAAE,aAAa,CAAC;IAC5B;;;;;;;;OAQG;IACH,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC;IAClC;;;;;;;;;OASG;IACH,QAAQ,CAAC,KAAK,EAAE,SAAS,aAAa,EAAE,CAAC;CAC1C;AAiBD,MAAM,WAAW,wBAAwB;IACvC,8EAA8E;IAC9E,QAAQ,CAAC,QAAQ,EAAE,SAAS,kBAAkB,EAAE,CAAC;IACjD,wGAAwG;IACxG,QAAQ,CAAC,SAAS,EAAE,SAAS,aAAa,EAAE,CAAC;CAC9C;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,SAAS,aAAa,EAAE,EAC9B,KAAK,EAAE,SAAS,aAAa,EAAE,EAC/B,IAAI,EAAE,MAAM,EACZ,SAAS,CAAC,EAAE,MAAM,GACjB,wBAAwB,CA4B1B"}
1
+ {"version":3,"file":"confirmed-facts.d.ts","sourceRoot":"","sources":["../../src/query/confirmed-facts.ts"],"names":[],"mappings":"AAAA;;0GAE0G;AAE1G,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEhE,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,GAAG,EAAE,aAAa,CAAC;IAC5B;;0FAEsF;IACtF,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC;IAClC;;sGAEkG;IAClG,QAAQ,CAAC,KAAK,EAAE,SAAS,aAAa,EAAE,CAAC;CAC1C;AAWD,MAAM,WAAW,wBAAwB;IACvC,8EAA8E;IAC9E,QAAQ,CAAC,QAAQ,EAAE,SAAS,kBAAkB,EAAE,CAAC;IACjD,wGAAwG;IACxG,QAAQ,CAAC,SAAS,EAAE,SAAS,aAAa,EAAE,CAAC;CAC9C;AAED;;yHAEyH;AACzH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,SAAS,aAAa,EAAE,EAC9B,KAAK,EAAE,SAAS,aAAa,EAAE,EAC/B,IAAI,EAAE,MAAM,EACZ,SAAS,CAAC,EAAE,MAAM,GACjB,wBAAwB,CA4B1B"}
@@ -1,28 +1,8 @@
1
- /**
2
- * DEC-223's answer half, matching side: which refusal-ledger rows does a
3
- * confirmed fact actually answer?
4
- *
5
- * Deliberately does **not** mint a graph edge. Turning an answered row into a
6
- * real `USES_API`/etc. edge needs a target to join against — an endpoint, a
7
- * route — which this function has no way to resolve and which DEC-223 §6
8
- * named as future work, not this row. What this function owns is narrower
9
- * and load-bearing on its own: **which rows are answered, by what value, and
10
- * that the match never crosses a repo or accessor boundary it should not.**
11
- * A caller minting an edge from `answered` is the one obligated to pass
12
- * `reliabilityCap`'s `humanAsserted: true` — this function does not compute a
13
- * reliability class itself, because it has no resolution level to reason
14
- * from (`UnresolvedRef` carries none — refusals are not edges and were never
15
- * scored). Inventing one here would be exactly the overclaim principle 2
16
- * exists to prevent.
17
- */
18
- /**
19
- * Does this fact answer rows in `repo`?
20
- *
21
- * Its own repository, always. Any repository in the same workspace **only**
22
- * when it was recorded as `scope: "workspace"` and both sides carry the same
23
- * non-empty workspace id — an unset workspace on either side names no
24
- * boundary, so nothing crosses one.
25
- */
1
+ /** DEC-223's matching half: which refusal-ledger rows a confirmed fact answers. Deliberately
2
+ * doesn't mint a graph edge (no target to resolve — DEC-223 §6's future work). A caller minting
3
+ * one must pass `reliabilityCap`'s `humanAsserted: true` itself — refusals carry no resolution level. */
4
+ /** Does this fact answer rows in `repo`? Its own repo always; another repo only if recorded as
5
+ * `scope: "workspace"` with both sides sharing the same non-empty workspace id. */
26
6
  function reaches(fact, repo, workspace) {
27
7
  if (fact.repo === repo)
28
8
  return true;
@@ -32,28 +12,9 @@ function reaches(fact, repo, workspace) {
32
12
  return false;
33
13
  return fact.workspace === workspace;
34
14
  }
35
- /**
36
- * Match ledger rows against confirmed facts, scoped to one repository.
37
- *
38
- * Three things keep a row out of `answered`, all deliberate:
39
- *
40
- * 1. **No `attrs.refusalClass === "value-unknown"`.** Everything else —
41
- * unclassified, `capability-gap`, `out-of-scope`, `varies-per-call` — is
42
- * not askable at all (DEC-242), so no fact could ever answer it; matching
43
- * on `blockedBy` alone without this check would let a stored fact silently
44
- * resolve a `varies-per-call` row that structurally has no single answer.
45
- * 2. **No `attrs.blockedBy`, or it is not a string.** Nothing to key against.
46
- * 3. **No fact in `facts` reaches this repository.** A fact for a different
47
- * `repo` is not consulted merely because its `blockedBy` text matches —
48
- * rule 3's "never an inference about a second case," enforced structurally
49
- * rather than left to caller discipline. The **one** way it crosses is
50
- * `reaches()` below: the person recording it declared
51
- * `scope: "workspace"` under the same workspace id this session is
52
- * configured with. A declaration, not an inference — see
53
- * DEC-NEXT-workspace-scoped-confirmed-facts for why the alternative
54
- * (any fact answers any linked repo) is unsafe: two services can both read
55
- * `DATABASE_URL` and mean different things by it.
56
- */
15
+ /** Matches ledger rows to confirmed facts, scoped to one repo. Excluded from `answered`: not
16
+ * `refusalClass === "value-unknown"` (everything else isn't askable at all, DEC-242); no
17
+ * `blockedBy`; or no fact reaches this repo (rule 3 — crossing needs declared `scope: "workspace"`, never inferred). */
57
18
  export function applyConfirmedFacts(refs, facts, repo, workspace) {
58
19
  const byBlockedBy = new Map();
59
20
  for (const fact of facts) {
@@ -1 +1 @@
1
- {"version":3,"file":"confirmed-facts.js","sourceRoot":"","sources":["../../src/query/confirmed-facts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AA6BH;;;;;;;GAOG;AACH,SAAS,OAAO,CAAC,IAAmB,EAAE,IAAY,EAAE,SAA6B;IAC/E,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IACpC,IAAI,IAAI,CAAC,KAAK,KAAK,WAAW;QAAE,OAAO,KAAK,CAAC;IAC7C,IAAI,SAAS,KAAK,SAAS,IAAI,SAAS,KAAK,EAAE;QAAE,OAAO,KAAK,CAAC;IAC9D,OAAO,IAAI,CAAC,SAAS,KAAK,SAAS,CAAC;AACtC,CAAC;AASD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,mBAAmB,CACjC,IAA8B,EAC9B,KAA+B,EAC/B,IAAY,EACZ,SAAkB;IAElB,MAAM,WAAW,GAAG,IAAI,GAAG,EAA2B,CAAC;IACvD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,SAAS,CAAC;YAAE,SAAS;QAC9C,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACjD,IAAI,QAAQ,KAAK,SAAS;YAAE,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;;YAC/D,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC3B,CAAC;IAED,MAAM,QAAQ,GAAyB,EAAE,CAAC;IAC1C,MAAM,SAAS,GAAoB,EAAE,CAAC;IAEtC,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,YAAY,GAAG,GAAG,CAAC,KAAK,EAAE,CAAC,cAAc,CAAC,CAAC;QACjD,MAAM,SAAS,GAAG,GAAG,CAAC,KAAK,EAAE,CAAC,WAAW,CAAC,CAAC;QAC3C,IAAI,YAAY,KAAK,eAAe,IAAI,OAAO,SAAS,KAAK,QAAQ,IAAI,SAAS,KAAK,EAAE,EAAE,CAAC;YAC1F,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACpB,SAAS;QACX,CAAC;QACD,MAAM,OAAO,GAAG,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAC3C,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC1B,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACtB,CAAC;aAAM,CAAC;YACN,QAAQ,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,eAAe,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC,CAAC;QACjG,CAAC;IACH,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;AACjC,CAAC"}
1
+ {"version":3,"file":"confirmed-facts.js","sourceRoot":"","sources":["../../src/query/confirmed-facts.ts"],"names":[],"mappings":"AAAA;;0GAE0G;AAgB1G;oFACoF;AACpF,SAAS,OAAO,CAAC,IAAmB,EAAE,IAAY,EAAE,SAA6B;IAC/E,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IACpC,IAAI,IAAI,CAAC,KAAK,KAAK,WAAW;QAAE,OAAO,KAAK,CAAC;IAC7C,IAAI,SAAS,KAAK,SAAS,IAAI,SAAS,KAAK,EAAE;QAAE,OAAO,KAAK,CAAC;IAC9D,OAAO,IAAI,CAAC,SAAS,KAAK,SAAS,CAAC;AACtC,CAAC;AASD;;yHAEyH;AACzH,MAAM,UAAU,mBAAmB,CACjC,IAA8B,EAC9B,KAA+B,EAC/B,IAAY,EACZ,SAAkB;IAElB,MAAM,WAAW,GAAG,IAAI,GAAG,EAA2B,CAAC;IACvD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,SAAS,CAAC;YAAE,SAAS;QAC9C,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACjD,IAAI,QAAQ,KAAK,SAAS;YAAE,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;;YAC/D,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC3B,CAAC;IAED,MAAM,QAAQ,GAAyB,EAAE,CAAC;IAC1C,MAAM,SAAS,GAAoB,EAAE,CAAC;IAEtC,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,YAAY,GAAG,GAAG,CAAC,KAAK,EAAE,CAAC,cAAc,CAAC,CAAC;QACjD,MAAM,SAAS,GAAG,GAAG,CAAC,KAAK,EAAE,CAAC,WAAW,CAAC,CAAC;QAC3C,IAAI,YAAY,KAAK,eAAe,IAAI,OAAO,SAAS,KAAK,QAAQ,IAAI,SAAS,KAAK,EAAE,EAAE,CAAC;YAC1F,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACpB,SAAS;QACX,CAAC;QACD,MAAM,OAAO,GAAG,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAC3C,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC1B,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACtB,CAAC;aAAM,CAAC;YACN,QAAQ,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,eAAe,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC,CAAC;QACjG,CAAC;IACH,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;AACjC,CAAC"}