@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
@@ -0,0 +1,278 @@
1
+ /**
2
+ * §14.6 for one change against a base branch — the shape `cross_pr` actually has.
3
+ *
4
+ * ## Why the base branch is the second member of the set
5
+ *
6
+ * `migration-heads.ts` computes heads across a *set of changes*, and `cross_pr`
7
+ * has one. That is not a mismatch, it is a missing member: the set the
8
+ * migration runner will see after this merge is **base's migrations plus this
9
+ * change's**, and heads over that union is exactly the computation the runner
10
+ * performs when it refuses with *"multiple head revisions are present"*.
11
+ *
12
+ * So base is read as a change with its own id. Nothing about the check changes;
13
+ * it is given the set it was always meant to have.
14
+ *
15
+ * ## The one wrong sentence this must not say
16
+ *
17
+ * A base branch that already forks produces two heads whatever the change does.
18
+ * Reporting that as *this* change's conflict is a wrong sentence about the wrong
19
+ * person, and it would fire on every change to such a repository until someone
20
+ * fixed a fork they did not create.
21
+ *
22
+ * So base is measured **alone** first. Its head count is a fact about base:
23
+ *
24
+ * | base alone | what this reports |
25
+ * | --- | --- |
26
+ * | one head | the union is computed and `baseHead` is supplied, so stale-history is checked too |
27
+ * | more than one | a disclosure naming base's fork, and no conflict attributed to the change |
28
+ * | none — no migrations at all | the change's own migrations, with nothing to fork from |
29
+ *
30
+ * ## Reading base without checking it out
31
+ *
32
+ * `git ls-tree` names base's files and `git show base:<path>` reads one. Neither
33
+ * touches the working tree, so this is safe to run mid-edit — which is the only
34
+ * time anyone runs a pre-merge check.
35
+ *
36
+ * The tree is narrowed by {@link looksLikeMigration} before anything is read. A
37
+ * base branch is thousands of paths and its migrations are dozens; reading all
38
+ * of them to discover that would be the check's whole cost paid for nothing.
39
+ *
40
+ * ## Everything here is R0 and the ceiling follows
41
+ *
42
+ * A regex over source text, per `read.ts`. The class column is a ceiling rather
43
+ * than a floor, so a conflict computed from these records caps at C however
44
+ * certain the arithmetic above it. Reaching A needs the framework's own
45
+ * migration history, which needs the tool installed and run, and nothing here
46
+ * installs or runs anything.
47
+ */
48
+ import { execFile } from "node:child_process";
49
+ import { promisify } from "node:util";
50
+ import { cleanGitEnv } from "../git/env.js";
51
+ import { findMigrationHeadConflicts } from "../../multipr/migration-heads.js";
52
+ import { readMigrations, looksLikeMigration } from "./read.js";
53
+ import { DIALECTS } from "./dialects.js";
54
+ const execFileAsync = promisify(execFile);
55
+ /**
56
+ * Cap on migration files read from either side.
57
+ *
58
+ * A repository with more migrations than this exists, and reading all of them
59
+ * is a subprocess each. Truncation is disclosed and the report is marked
60
+ * incomplete rather than being presented as a full head computation.
61
+ */
62
+ const MAX_FILES = 400;
63
+ /**
64
+ * How many misplaced-looking files in one directory stop being mistakes.
65
+ *
66
+ * A project can configure a second version location this producer's globs do
67
+ * not recognise, and one file at a time that is indistinguishable from a stray.
68
+ * In bulk it is not: a stray sits alone, a configured directory holds a pile.
69
+ * So the rule is about the directory rather than the file, and a directory at
70
+ * or above this count is disclosed rather than reported.
71
+ *
72
+ * Three is a starting value, not a measurement.
73
+ */
74
+ const SECOND_LOCATION_CLUSTER = 3;
75
+ async function git(cwd, args) {
76
+ const { stdout } = await execFileAsync("git", args, {
77
+ cwd,
78
+ encoding: "utf8",
79
+ env: cleanGitEnv(),
80
+ maxBuffer: 64 * 1024 * 1024,
81
+ });
82
+ return stdout;
83
+ }
84
+ /**
85
+ * Migrations that parse but sit where nothing will run them.
86
+ *
87
+ * One `git grep` per probing dialect rather than a walk: the whole tree is
88
+ * searched in one indexed subprocess, and only the files it names are read.
89
+ * Reading every source file to find out it is not a migration is the cost this
90
+ * check would otherwise pay on every run.
91
+ *
92
+ * Guarded twice, because the failure to avoid is telling a project its own
93
+ * layout is wrong:
94
+ *
95
+ * 1. **The dialect must already be in use** somewhere this producer
96
+ * recognises. With no recognised migrations there is nothing to be outside
97
+ * of, and a project keeping them somewhere unknown is not a project with a
98
+ * misplaced file.
99
+ * 2. **A directory holding several is a location, not a pile of mistakes** —
100
+ * see {@link SECOND_LOCATION_CLUSTER}. Disclosed rather than reported.
101
+ */
102
+ async function findMisplaced(cwd, rev, recognised, read, notes) {
103
+ const out = [];
104
+ for (const dialect of DIALECTS) {
105
+ if (dialect.probe === undefined)
106
+ continue;
107
+ // Guard 1: this dialect has to be in use here already.
108
+ if (!recognised.some((path) => looksLikeMigration(path)))
109
+ continue;
110
+ let hits;
111
+ try {
112
+ const stdout = await git(cwd, ["grep", "-l", "-E", dialect.probe, rev]);
113
+ hits = stdout
114
+ .split("\n")
115
+ .map((line) => line.trim())
116
+ .filter((line) => line !== "")
117
+ // `git grep <rev>` prefixes every path with `<rev>:`.
118
+ .map((line) => (line.startsWith(`${rev}:`) ? line.slice(rev.length + 1) : line))
119
+ .filter((path) => !looksLikeMigration(path));
120
+ }
121
+ catch {
122
+ // git grep exits non-zero when nothing matches. No hits is the answer.
123
+ continue;
124
+ }
125
+ if (hits.length === 0)
126
+ continue;
127
+ // Guard 2: group by directory before deciding anything.
128
+ const byDirectory = new Map();
129
+ for (const path of hits) {
130
+ const dir = path.includes("/") ? path.slice(0, path.lastIndexOf("/")) : ".";
131
+ const bucket = byDirectory.get(dir);
132
+ if (bucket === undefined)
133
+ byDirectory.set(dir, [path]);
134
+ else
135
+ bucket.push(path);
136
+ }
137
+ for (const [dir, paths] of [...byDirectory].sort(([a], [b]) => a.localeCompare(b))) {
138
+ if (paths.length >= SECOND_LOCATION_CLUSTER) {
139
+ notes.push(`${paths.length} files in ${dir} parse as ${dialect.displayName} migrations and are ` +
140
+ "not in a location this producer recognises. That many together reads as a second " +
141
+ "configured version location rather than as that many mistakes, so they are " +
142
+ "disclosed here and not reported as findings — and they are not in the head " +
143
+ "computation either.");
144
+ continue;
145
+ }
146
+ for (const path of paths) {
147
+ const text = await read(path);
148
+ if (text === null)
149
+ continue;
150
+ // Confirmed with the real reader, never from the grep hit alone: the
151
+ // probe finds a candidate and the parser decides whether it is one.
152
+ //
153
+ // The reader selects a dialect by path and this path is, by definition,
154
+ // one no dialect claims — so it is offered a synthetic path under a
155
+ // recognised directory. The content is the file's own and unmodified;
156
+ // only the question changes, from "is there a migration here?" to
157
+ // "would this parse as one if it were where it belongs?". The real path
158
+ // is what the finding reports.
159
+ const name = path.slice(path.lastIndexOf("/") + 1);
160
+ const report = readMigrations(rev, [`versions/${name}`], { read: () => text });
161
+ const record = report.records[0];
162
+ if (record === undefined)
163
+ continue;
164
+ out.push({ file: path, revision: record.revision, dialect: dialect.id });
165
+ }
166
+ }
167
+ }
168
+ return out;
169
+ }
170
+ /** Every migration-shaped path in one revision's tree. */
171
+ async function migrationPathsIn(cwd, rev) {
172
+ const stdout = await git(cwd, ["ls-tree", "-r", "--name-only", rev]);
173
+ return stdout
174
+ .split("\n")
175
+ .map((line) => line.trim())
176
+ .filter((line) => line !== "" && looksLikeMigration(line));
177
+ }
178
+ /** Heads of a record set: revisions nothing else in the set descends from. */
179
+ function headsOf(report) {
180
+ const claimed = new Set();
181
+ for (const record of report.records) {
182
+ if (record.parents === "unknown")
183
+ continue;
184
+ for (const parent of record.parents)
185
+ claimed.add(parent);
186
+ }
187
+ return report.records.map((r) => r.revision).filter((revision) => !claimed.has(revision));
188
+ }
189
+ /**
190
+ * Read both sides of a merge and compute the heads it would leave.
191
+ *
192
+ * @param base the branch this change would merge into
193
+ * @param head the tip being reviewed
194
+ */
195
+ export async function readMigrationsAcrossChange(cwd, base, head, options = {}) {
196
+ const maxFiles = options.maxFiles ?? MAX_FILES;
197
+ const notes = [];
198
+ const changed = options.changedFiles ??
199
+ (await git(cwd, ["diff", "--name-only", "-M", `${base}...${head}`]))
200
+ .split("\n")
201
+ .map((l) => l.trim())
202
+ .filter((l) => l !== "");
203
+ const changedMigrations = changed.filter(looksLikeMigration);
204
+ // Base's own migrations, minus anything this change also touches: a file on
205
+ // both sides is the change's, and counting it twice would mint two records
206
+ // for one revision and report a duplicate identifier that does not exist.
207
+ const touched = new Set(changedMigrations);
208
+ const basePaths = (await migrationPathsIn(cwd, base)).filter((p) => !touched.has(p));
209
+ const cap = (paths, side) => {
210
+ if (paths.length <= maxFiles)
211
+ return paths;
212
+ notes.push(`${paths.length} migration file(s) are on ${side} and only ${maxFiles} were read. The head ` +
213
+ "computation below covers a prefix of them rather than all of them, so it is not a " +
214
+ "complete answer — an unread migration may be exactly the merge that resolves a fork.");
215
+ return paths.slice(0, maxFiles);
216
+ };
217
+ const contents = async (rev, paths) => {
218
+ const out = new Map();
219
+ for (const path of paths) {
220
+ try {
221
+ out.set(path, await git(cwd, ["show", `${rev}:${path}`]));
222
+ }
223
+ catch {
224
+ // Left absent. `readMigrations` records the failure as a refusal row.
225
+ }
226
+ }
227
+ return out;
228
+ };
229
+ const baseRead = cap(basePaths, `\`${base}\``);
230
+ const changePaths = cap(changedMigrations, "this change");
231
+ const baseText = await contents(base, baseRead);
232
+ const changeText = await contents(head, changePaths);
233
+ const reader = (map) => (path) => {
234
+ const text = map.get(path);
235
+ if (text === undefined)
236
+ throw new Error("not present in that revision");
237
+ return text;
238
+ };
239
+ const baseReport = readMigrations(base, baseRead, { read: reader(baseText) });
240
+ const changeReport = readMigrations(head, changePaths, { read: reader(changeText) });
241
+ // Base measured alone, so a fork it already has is never attributed here.
242
+ const baseHeads = headsOf(baseReport);
243
+ let baseHead = null;
244
+ if (baseHeads.length === 1)
245
+ baseHead = baseHeads[0];
246
+ else if (baseHeads.length > 1) {
247
+ notes.push(`The base branch already has ${baseHeads.length} migration heads before this change: ` +
248
+ `${baseHeads.join(", ")}. That fork is not this change's, so no conflict is attributed ` +
249
+ "to it here and the merged head count is not reported as a finding.");
250
+ }
251
+ const union = [...baseReport.records, ...changeReport.records];
252
+ const report = baseHeads.length > 1
253
+ ? // Base is already forked. Compute the change's own migrations against
254
+ // each other so a fork *within* the change is still caught, and leave
255
+ // base out of the head count entirely.
256
+ findMigrationHeadConflicts(changeReport.records)
257
+ : findMigrationHeadConflicts(union, ...(baseHead === null ? [] : [{ baseHead }]));
258
+ // Searched on `head`, because that is the tree about to be merged. A file
259
+ // misplaced on base and left alone by this change is still misplaced, and the
260
+ // developer pushing is the one who can see it.
261
+ const misplaced = await findMisplaced(cwd, head, [...basePaths, ...changedMigrations], async (path) => {
262
+ try {
263
+ return await git(cwd, ["show", `${head}:${path}`]);
264
+ }
265
+ catch {
266
+ return null;
267
+ }
268
+ }, notes);
269
+ return {
270
+ base: baseReport,
271
+ change: changeReport,
272
+ baseHead,
273
+ report,
274
+ misplaced,
275
+ notes: [...notes, ...report.notes],
276
+ };
277
+ }
278
+ //# sourceMappingURL=across-change.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"across-change.js","sourceRoot":"","sources":["../../../src/sources/migrations/across-change.ts"],"names":[],"mappings":"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"}
@@ -1,33 +1,8 @@
1
- /**
2
- * The dialect table — the only place in `descry-core` that describes a migration
3
- * file format, and it does so **without naming a single tool**.
4
- *
5
- * That is not a dodge around the boundary lint; it is the design the lint is a
6
- * proxy for. Rule 1 forbids a language or framework name above the Canonical IR.
7
- * A migration-file reader is a producer and sits below it — exactly like
8
- * `sources/git` and like an adapter — so naming a tool here would be defensible.
9
- * It turned out not to be necessary: every distinction §14.6 needs is a
10
- * distinction about **shape**, and a table written in shapes is one an unfamiliar
11
- * reader can check against a file without knowing which ecosystem it came from.
12
- *
13
- * The consequence worth having is that `read.ts` knows nothing but this table, so
14
- * **adding a dialect is a data change and never a code change**.
15
- *
16
- * `parentsKind` names a shape:
17
- *
18
- * | kind | the captured expression is |
19
- * | --- | --- |
20
- * | `single-or-none` | one quoted id, a null literal, or a tuple for a merge |
21
- * | `id-list` | a bracketed list of quoted ids |
22
- * | `pair-list` | a bracketed list of two-element tuples, joined with `/` |
23
- *
24
- * Every dialect here is **R0** — a regex over source text. DEC-058 and §15.3: a
25
- * record carries the resolution of its own evidence, so a head conflict computed
26
- * from these caps at class C however certain the arithmetic on top of it. Class A
27
- * needs the framework's own migration history, which is DEC-115's promotion path
28
- * and needs the tool installed and run. **Nothing here installs or runs
29
- * anything.**
30
- */
1
+ /** Migration dialect table — no tool named (rule 1: this producer sits
2
+ * below the IR, but every distinction §14.6 needs is about shape, so a
3
+ * tool name was never necessary). Adding a dialect is a data change, not
4
+ * code. All R0 (regex over text) — DEC-058/§15.3 caps a resulting
5
+ * conflict at class C; class A needs the tool's own history (DEC-115). */
31
6
  export type ParentsKind = "single-or-none" | "id-list" | "pair-list";
32
7
  export interface Dialect {
33
8
  readonly id: string;
@@ -41,6 +16,19 @@ export interface Dialect {
41
16
  readonly parentsKind: ParentsKind;
42
17
  /** A second, additive predecessor channel where the format has one. */
43
18
  readonly alsoParents?: string;
19
+ /**
20
+ * A POSIX ERE `git grep` can run to find candidate files **by content**,
21
+ * anywhere in a tree, for the misplaced-migration check.
22
+ *
23
+ * Separate from `parents` rather than derived from it: that pattern is
24
+ * JavaScript-flavoured and this one is handed to another program. Optional
25
+ * on purpose — a dialect whose marker is not distinctive enough to survive a
26
+ * whole-repository grep declares none, and is simply not searched for. The
27
+ * dependency-list dialect is the case: `dependencies = [` appears in
28
+ * packaging metadata across most of the ecosystem, so grepping for it would
29
+ * return a repository's build files and call them migrations.
30
+ */
31
+ readonly probe?: string;
44
32
  readonly why: string;
45
33
  }
46
34
  export interface RefusedFamily {
@@ -49,11 +37,7 @@ export interface RefusedFamily {
49
37
  readonly why: string;
50
38
  }
51
39
  export declare const DIALECTS: readonly Dialect[];
52
- /**
53
- * Families this producer declines, by design rather than by failure.
54
- *
55
- * The refusal is the interesting half of this table, so it is data too — a
56
- * refused file produces a row carrying this sentence, not a silence.
57
- */
40
+ /** Families this producer declines, by design not failure — the refusal
41
+ * is data too: a refused file gets this sentence, not silence. */
58
42
  export declare const REFUSED: readonly RefusedFamily[];
59
43
  //# sourceMappingURL=dialects.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"dialects.d.ts","sourceRoot":"","sources":["../../../src/sources/migrations/dialects.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,MAAM,MAAM,WAAW,GAAG,gBAAgB,GAAG,SAAS,GAAG,WAAW,CAAC;AAErE,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,iCAAiC;IACjC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,4EAA4E;IAC5E,QAAQ,CAAC,oBAAoB,CAAC,EAAE,MAAM,CAAC;IACvC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC;IAClC,uEAAuE;IACvE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB;AAED,eAAO,MAAM,QAAQ,EAAE,SAAS,OAAO,EAyBtC,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,OAAO,EAAE,SAAS,aAAa,EAuB3C,CAAC"}
1
+ {"version":3,"file":"dialects.d.ts","sourceRoot":"","sources":["../../../src/sources/migrations/dialects.ts"],"names":[],"mappings":"AAAA;;;;2EAI2E;AAE3E,MAAM,MAAM,WAAW,GAAG,gBAAgB,GAAG,SAAS,GAAG,WAAW,CAAC;AAErE,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,iCAAiC;IACjC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,4EAA4E;IAC5E,QAAQ,CAAC,oBAAoB,CAAC,EAAE,MAAM,CAAC;IACvC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC;IAClC,uEAAuE;IACvE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB;AAED,eAAO,MAAM,QAAQ,EAAE,SAAS,OAAO,EA6BtC,CAAC;AAEF;mEACmE;AACnE,eAAO,MAAM,OAAO,EAAE,SAAS,aAAa,EAuB3C,CAAC"}
@@ -1,33 +1,8 @@
1
- /**
2
- * The dialect table — the only place in `descry-core` that describes a migration
3
- * file format, and it does so **without naming a single tool**.
4
- *
5
- * That is not a dodge around the boundary lint; it is the design the lint is a
6
- * proxy for. Rule 1 forbids a language or framework name above the Canonical IR.
7
- * A migration-file reader is a producer and sits below it — exactly like
8
- * `sources/git` and like an adapter — so naming a tool here would be defensible.
9
- * It turned out not to be necessary: every distinction §14.6 needs is a
10
- * distinction about **shape**, and a table written in shapes is one an unfamiliar
11
- * reader can check against a file without knowing which ecosystem it came from.
12
- *
13
- * The consequence worth having is that `read.ts` knows nothing but this table, so
14
- * **adding a dialect is a data change and never a code change**.
15
- *
16
- * `parentsKind` names a shape:
17
- *
18
- * | kind | the captured expression is |
19
- * | --- | --- |
20
- * | `single-or-none` | one quoted id, a null literal, or a tuple for a merge |
21
- * | `id-list` | a bracketed list of quoted ids |
22
- * | `pair-list` | a bracketed list of two-element tuples, joined with `/` |
23
- *
24
- * Every dialect here is **R0** — a regex over source text. DEC-058 and §15.3: a
25
- * record carries the resolution of its own evidence, so a head conflict computed
26
- * from these caps at class C however certain the arithmetic on top of it. Class A
27
- * needs the framework's own migration history, which is DEC-115's promotion path
28
- * and needs the tool installed and run. **Nothing here installs or runs
29
- * anything.**
30
- */
1
+ /** Migration dialect table — no tool named (rule 1: this producer sits
2
+ * below the IR, but every distinction §14.6 needs is about shape, so a
3
+ * tool name was never necessary). Adding a dialect is a data change, not
4
+ * code. All R0 (regex over text) — DEC-058/§15.3 caps a resulting
5
+ * conflict at class C; class A needs the tool's own history (DEC-115). */
31
6
  export const DIALECTS = [
32
7
  {
33
8
  id: "revision-chain",
@@ -37,6 +12,10 @@ export const DIALECTS = [
37
12
  parents: "^\\s*down_revision(?:\\s*:\\s*[^=]+)?\\s*=\\s*(.+)$",
38
13
  parentsKind: "single-or-none",
39
14
  alsoParents: "^\\s*depends_on(?:\\s*:\\s*[^=]+)?\\s*=\\s*(.+)$",
15
+ // Distinctive enough for a whole-repository search: a module-level
16
+ // `down_revision` binding exists to name a migration's parent and has no
17
+ // second meaning.
18
+ probe: "^[[:space:]]*down_revision[[:space:]]*[:=]",
40
19
  why: "Each revision names exactly one predecessor, or a null literal for the root; a merge " +
41
20
  "revision names a tuple. A declared DAG, and the tool itself refuses to run with more " +
42
21
  "than one head — which is the failure §14.6 predicts.",
@@ -52,12 +31,8 @@ export const DIALECTS = [
52
31
  "and the tool detects conflicting leaves by name.",
53
32
  },
54
33
  ];
55
- /**
56
- * Families this producer declines, by design rather than by failure.
57
- *
58
- * The refusal is the interesting half of this table, so it is data too — a
59
- * refused file produces a row carrying this sentence, not a silence.
60
- */
34
+ /** Families this producer declines, by design not failure — the refusal
35
+ * is data too: a refused file gets this sentence, not silence. */
61
36
  export const REFUSED = [
62
37
  {
63
38
  id: "timestamp-ordered-directory",
@@ -1 +1 @@
1
- {"version":3,"file":"dialects.js","sourceRoot":"","sources":["../../../src/sources/migrations/dialects.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAyBH,MAAM,CAAC,MAAM,QAAQ,GAAuB;IAC1C;QACE,EAAE,EAAE,gBAAgB;QACpB,WAAW,EAAE,8BAA8B;QAC3C,KAAK,EAAE,CAAC,kBAAkB,EAAE,6BAA6B,CAAC;QAC1D,QAAQ,EAAE,4DAA4D;QACtE,OAAO,EAAE,qDAAqD;QAC9D,WAAW,EAAE,gBAAgB;QAC7B,WAAW,EAAE,kDAAkD;QAC/D,GAAG,EACD,uFAAuF;YACvF,uFAAuF;YACvF,sDAAsD;KACzD;IACD;QACE,EAAE,EAAE,iBAAiB;QACrB,WAAW,EAAE,iBAAiB;QAC9B,KAAK,EAAE,CAAC,oBAAoB,CAAC;QAC7B,oBAAoB,EAAE,sBAAsB;QAC5C,OAAO,EAAE,yCAAyC;QAClD,WAAW,EAAE,WAAW;QACxB,GAAG,EACD,yFAAyF;YACzF,kDAAkD;KACrD;CACF,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,OAAO,GAA6B;IAC/C;QACE,EAAE,EAAE,6BAA6B;QACjC,KAAK,EAAE,CAAC,8BAA8B,EAAE,oBAAoB,CAAC;QAC7D,GAAG,EACD,sFAAsF;YACtF,wFAAwF;YACxF,mFAAmF;YACnF,oFAAoF;YACpF,wFAAwF;YACxF,yFAAyF;YACzF,qFAAqF;YACrF,gEAAgE;YAChE,yFAAyF;YACzF,mFAAmF;YACnF,0FAA0F;YAC1F,sFAAsF;YACtF,wFAAwF;YACxF,wFAAwF;YACxF,sFAAsF;YACtF,qFAAqF;YACrF,uEAAuE;KAC1E;CACF,CAAC"}
1
+ {"version":3,"file":"dialects.js","sourceRoot":"","sources":["../../../src/sources/migrations/dialects.ts"],"names":[],"mappings":"AAAA;;;;2EAI2E;AAsC3E,MAAM,CAAC,MAAM,QAAQ,GAAuB;IAC1C;QACE,EAAE,EAAE,gBAAgB;QACpB,WAAW,EAAE,8BAA8B;QAC3C,KAAK,EAAE,CAAC,kBAAkB,EAAE,6BAA6B,CAAC;QAC1D,QAAQ,EAAE,4DAA4D;QACtE,OAAO,EAAE,qDAAqD;QAC9D,WAAW,EAAE,gBAAgB;QAC7B,WAAW,EAAE,kDAAkD;QAC/D,mEAAmE;QACnE,yEAAyE;QACzE,kBAAkB;QAClB,KAAK,EAAE,4CAA4C;QACnD,GAAG,EACD,uFAAuF;YACvF,uFAAuF;YACvF,sDAAsD;KACzD;IACD;QACE,EAAE,EAAE,iBAAiB;QACrB,WAAW,EAAE,iBAAiB;QAC9B,KAAK,EAAE,CAAC,oBAAoB,CAAC;QAC7B,oBAAoB,EAAE,sBAAsB;QAC5C,OAAO,EAAE,yCAAyC;QAClD,WAAW,EAAE,WAAW;QACxB,GAAG,EACD,yFAAyF;YACzF,kDAAkD;KACrD;CACF,CAAC;AAEF;mEACmE;AACnE,MAAM,CAAC,MAAM,OAAO,GAA6B;IAC/C;QACE,EAAE,EAAE,6BAA6B;QACjC,KAAK,EAAE,CAAC,8BAA8B,EAAE,oBAAoB,CAAC;QAC7D,GAAG,EACD,sFAAsF;YACtF,wFAAwF;YACxF,mFAAmF;YACnF,oFAAoF;YACpF,wFAAwF;YACxF,yFAAyF;YACzF,qFAAqF;YACrF,gEAAgE;YAChE,yFAAyF;YACzF,mFAAmF;YACnF,0FAA0F;YAC1F,sFAAsF;YACtF,wFAAwF;YACxF,wFAAwF;YACxF,sFAAsF;YACtF,qFAAqF;YACrF,uEAAuE;KAC1E;CACF,CAAC"}
@@ -1,3 +1,5 @@
1
- export { readMigrations, DIALECTS, REFUSED } from "./read.ts";
1
+ export { readMigrations, looksLikeMigration, DIALECTS, REFUSED } from "./read.ts";
2
+ export { readMigrationsAcrossChange } from "./across-change.ts";
3
+ export type { MigrationsAcrossChange, AcrossChangeOptions } from "./across-change.ts";
2
4
  export type { Dialect, RefusedFamily, MigrationRefusal, MigrationReadReport, ParentsKind, ReadOptions, } from "./read.ts";
3
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/sources/migrations/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC9D,YAAY,EACV,OAAO,EACP,aAAa,EACb,gBAAgB,EAChB,mBAAmB,EACnB,WAAW,EACX,WAAW,GACZ,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/sources/migrations/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAClF,OAAO,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC;AAChE,YAAY,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACtF,YAAY,EACV,OAAO,EACP,aAAa,EACb,gBAAgB,EAChB,mBAAmB,EACnB,WAAW,EACX,WAAW,GACZ,MAAM,WAAW,CAAC"}
@@ -1,2 +1,3 @@
1
- export { readMigrations, DIALECTS, REFUSED } from "./read.js";
1
+ export { readMigrations, looksLikeMigration, DIALECTS, REFUSED } from "./read.js";
2
+ export { readMigrationsAcrossChange } from "./across-change.js";
2
3
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/sources/migrations/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/sources/migrations/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAClF,OAAO,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC"}
@@ -1,70 +1,7 @@
1
1
  /**
2
- * The producer `migration-heads.ts` has been waiting for.
3
- *
4
- * §14.6's check is built, exposed through the MCP tool, and **nothing fed it**.
5
- * It has been recommended four times and declined once. This is the feed.
6
- *
7
- * ## What it will and will not read
8
- *
9
- * `migration-heads.ts` says the input is *"a revision, its declared parents and
10
- * where it came from — the shape every migration tool has, whatever it calls the
11
- * fields"*, and it says the reading is producer work. It is right about the
12
- * shape and it is wrong that every tool has it.
13
- *
14
- * **Two of the four common families declare a DAG and two do not**, and the
15
- * difference is not cosmetic — it decides whether §14.6's finding exists at all:
16
- *
17
- * | family | declares | head conflict is |
18
- * | --- | --- | --- |
19
- * | revision/down_revision chain | one parent per revision, tuples for merges | a real failure the tool itself raises |
20
- * | dependency list | `(app, name)` pairs per migration | a real failure the tool itself detects |
21
- * | **timestamp-ordered directory** | **nothing** | **not a thing that can happen** |
22
- *
23
- * The last row covers both of the two frameworks this row named as *"the obvious
24
- * first two"*. They track applied migrations as a **set** in a table, run
25
- * whatever is pending in filename order, and have no multiple-head error to
26
- * predict. Two changes each adding a migration is the normal case and it
27
- * succeeds.
28
- *
29
- * Synthesising `parents = [the previous file by timestamp]` would manufacture
30
- * exactly the DAG this check consumes — and would then report a conflict for
31
- * *every* pair of changes that each add a migration, since both would carry the
32
- * same synthesised parent. A maybe-list built from an invented format, published
33
- * beside real Class A structural facts and indistinguishable from them in the
34
- * output.
35
- *
36
- * So those files are **refused with a reason**, and the refusal is a row.
37
- *
38
- * ## Measured rather than assumed, and the asymmetry is stated
39
- *
40
- * 604 migrations across three real applications using the timestamp-ordered
41
- * pattern: **0 declare a revision id or a parent.** The twelve files that matched
42
- * `/parent/` matched a `parent_id` column and one comment.
43
- *
44
- * The other timestamp-ordered ecosystem is refused on **documented behaviour**,
45
- * because no corpus using it was available here. That is a weaker basis than the
46
- * measured one and is labelled as such rather than folded in beside it.
47
- *
48
- * ## Everything this produces is R0, and the ceiling follows
49
- *
50
- * A regex over source text. §15.2 lists migration head conflict as Class A and
51
- * §15.3 already settles the disagreement: **the Class column is a ceiling, not a
52
- * floor.** Per DEC-058 the record carries the resolution of its own evidence, so
53
- * a conflict computed from these records caps at C however certain the
54
- * arithmetic above it. Class A needs the framework's own migration history —
55
- * DEC-115's promotion path — which needs the tool installed and run.
56
- *
57
- * **Nothing here installs or runs anything**, by policy: cloned third-party
58
- * source is arbitrary code and installing it executes it. The cost of that policy
59
- * is this ceiling, and it is disclosed rather than hidden.
60
- *
61
- * ## `"unknown"` is not `[]`, enforced here rather than downstream
62
- *
63
- * A migration whose parent line could not be read gets `"unknown"`. An initial
64
- * migration gets `[]`. `migration-heads.ts` makes the distinction unrepresentable
65
- * in its type for a reason — an unread migration might be exactly the merge that
66
- * resolves the fork being reported — and a producer that returns `[]` on a failed
67
- * match would defeat that from below.
2
+ * Feeds §14.6's migration head conflict check. Regex over source (R0) caps a conflict at C (DEC-058) —
3
+ * Class A needs the framework's own tool run (DEC-115), which this never does, by policy. Timestamp-ordered
4
+ * directories declare no DAG (604 migrations measured, 0 declare a parent) — refused with a reason, never a synthesised fake parent.
68
5
  */
69
6
  import type { ResolutionLevel } from "@descryy/ir";
70
7
  import type { MigrationRecord } from "../../multipr/migration-heads.ts";
@@ -82,13 +19,7 @@ export interface MigrationRefusal {
82
19
  export interface MigrationReadReport {
83
20
  readonly records: readonly MigrationRecord[];
84
21
  readonly refusals: readonly MigrationRefusal[];
85
- /**
86
- * False when no file matched any dialect at all.
87
- *
88
- * An empty `records` with `analysed: false` means no migration format was
89
- * recognised, not that the change adds no migrations — the same distinction
90
- * `hidden-dependency.ts` draws for co-change history, for the same reason.
91
- */
22
+ /** False when no file matched any dialect — not the same as "adds no migrations" (same distinction as `hidden-dependency.ts`). */
92
23
  readonly analysed: boolean;
93
24
  readonly checked: {
94
25
  readonly files: number;
@@ -98,16 +29,20 @@ export interface MigrationReadReport {
98
29
  readonly parentsUnknown: number;
99
30
  };
100
31
  }
32
+ /**
33
+ * Does any dialect or refused family claim this path?
34
+ *
35
+ * Exported so a caller enumerating a whole tree can narrow it before reading
36
+ * anything. A base branch's full file list is thousands of paths and its
37
+ * migrations are dozens; reading all of them to discover that would be the
38
+ * check's cost paid on every run for nothing.
39
+ */
40
+ export declare const looksLikeMigration: (path: string) => boolean;
101
41
  export interface ReadOptions {
102
42
  /** Reads the file. Injectable so the whole producer is testable with no disk. */
103
43
  readonly read?: (path: string) => string;
104
44
  readonly resolution?: ResolutionLevel;
105
45
  }
106
- /**
107
- * Read every migration a change adds.
108
- *
109
- * @param prId whatever identifies the change — passed straight through
110
- * @param files paths the change added, relative to the repository root
111
- */
46
+ /** Read every migration a change adds. `files` are paths relative to the repository root. */
112
47
  export declare function readMigrations(prId: string, files: readonly string[], options?: ReadOptions): MigrationReadReport;
113
48
  //# sourceMappingURL=read.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"read.d.ts","sourceRoot":"","sources":["../../../src/sources/migrations/read.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmEG;AAKH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACxE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEzE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;AAC7B,YAAY,EAAE,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,CAAC;AAEpD,qFAAqF;AACrF,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,2FAA2F;IAC3F,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,OAAO,EAAE,SAAS,eAAe,EAAE,CAAC;IAC7C,QAAQ,CAAC,QAAQ,EAAE,SAAS,gBAAgB,EAAE,CAAC;IAC/C;;;;;;OAMG;IACH,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE;QAChB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;QAChC,QAAQ,CAAC,oBAAoB,EAAE,MAAM,CAAC;QACtC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;QAC9B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;KACjC,CAAC;CACH;AAsGD,MAAM,WAAW,WAAW;IAC1B,iFAAiF;IACjF,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IACzC,QAAQ,CAAC,UAAU,CAAC,EAAE,eAAe,CAAC;CACvC;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,SAAS,MAAM,EAAE,EACxB,OAAO,GAAE,WAAgB,GACxB,mBAAmB,CAoGrB"}
1
+ {"version":3,"file":"read.d.ts","sourceRoot":"","sources":["../../../src/sources/migrations/read.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACxE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEzE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;AAC7B,YAAY,EAAE,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,CAAC;AAEpD,qFAAqF;AACrF,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,2FAA2F;IAC3F,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,OAAO,EAAE,SAAS,eAAe,EAAE,CAAC;IAC7C,QAAQ,CAAC,QAAQ,EAAE,SAAS,gBAAgB,EAAE,CAAC;IAC/C,kIAAkI;IAClI,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE;QAChB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;QAChC,QAAQ,CAAC,oBAAoB,EAAE,MAAM,CAAC;QACtC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;QAC9B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;KACjC,CAAC;CACH;AA4BD;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB,GAAI,MAAM,MAAM,KAAG,OAEF,CAAC;AA2DjD,MAAM,WAAW,WAAW;IAC1B,iFAAiF;IACjF,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IACzC,QAAQ,CAAC,UAAU,CAAC,EAAE,eAAe,CAAC;CACvC;AAED,6FAA6F;AAC7F,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,SAAS,MAAM,EAAE,EACxB,OAAO,GAAE,WAAgB,GACxB,mBAAmB,CAoGrB"}