@descryy/core 0.4.0 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (361) hide show
  1. package/dist/budget/reply.d.ts +11 -46
  2. package/dist/budget/reply.d.ts.map +1 -1
  3. package/dist/budget/reply.js +10 -39
  4. package/dist/budget/reply.js.map +1 -1
  5. package/dist/budget/size.d.ts +2 -21
  6. package/dist/budget/size.d.ts.map +1 -1
  7. package/dist/budget/size.js +3 -24
  8. package/dist/budget/size.js.map +1 -1
  9. package/dist/capabilities/preconditions.d.ts +7 -68
  10. package/dist/capabilities/preconditions.d.ts.map +1 -1
  11. package/dist/capabilities/preconditions.js +6 -57
  12. package/dist/capabilities/preconditions.js.map +1 -1
  13. package/dist/contracts/engine.d.ts +23 -11
  14. package/dist/contracts/engine.d.ts.map +1 -1
  15. package/dist/contracts/engine.js +23 -11
  16. package/dist/contracts/engine.js.map +1 -1
  17. package/dist/contracts/orphans.d.ts +18 -122
  18. package/dist/contracts/orphans.d.ts.map +1 -1
  19. package/dist/contracts/orphans.js +36 -134
  20. package/dist/contracts/orphans.js.map +1 -1
  21. package/dist/contracts/paths.d.ts +4 -114
  22. package/dist/contracts/paths.d.ts.map +1 -1
  23. package/dist/contracts/paths.js +7 -140
  24. package/dist/contracts/paths.js.map +1 -1
  25. package/dist/contracts/shapes.d.ts +13 -66
  26. package/dist/contracts/shapes.d.ts.map +1 -1
  27. package/dist/contracts/shapes.js +20 -91
  28. package/dist/contracts/shapes.js.map +1 -1
  29. package/dist/governance/budget.d.ts +12 -48
  30. package/dist/governance/budget.d.ts.map +1 -1
  31. package/dist/governance/budget.js +12 -48
  32. package/dist/governance/budget.js.map +1 -1
  33. package/dist/governance/candidate-boundary.d.ts +4 -32
  34. package/dist/governance/candidate-boundary.d.ts.map +1 -1
  35. package/dist/governance/candidate-boundary.js +4 -32
  36. package/dist/governance/candidate-boundary.js.map +1 -1
  37. package/dist/governance/escalation.d.ts +7 -45
  38. package/dist/governance/escalation.d.ts.map +1 -1
  39. package/dist/governance/escalation.js +7 -45
  40. package/dist/governance/escalation.js.map +1 -1
  41. package/dist/governance/fact-boundary.d.ts +7 -49
  42. package/dist/governance/fact-boundary.d.ts.map +1 -1
  43. package/dist/governance/fact-boundary.js +5 -43
  44. package/dist/governance/fact-boundary.js.map +1 -1
  45. package/dist/governance/finding-funnel.d.ts +11 -72
  46. package/dist/governance/finding-funnel.d.ts.map +1 -1
  47. package/dist/governance/finding-funnel.js +9 -68
  48. package/dist/governance/finding-funnel.js.map +1 -1
  49. package/dist/graph/build.d.ts +9 -90
  50. package/dist/graph/build.d.ts.map +1 -1
  51. package/dist/graph/build.js +15 -62
  52. package/dist/graph/build.js.map +1 -1
  53. package/dist/graph/cross-language.d.ts +4 -43
  54. package/dist/graph/cross-language.d.ts.map +1 -1
  55. package/dist/graph/cross-language.js +9 -77
  56. package/dist/graph/cross-language.js.map +1 -1
  57. package/dist/graph/merge.d.ts +8 -88
  58. package/dist/graph/merge.d.ts.map +1 -1
  59. package/dist/graph/merge.js +9 -93
  60. package/dist/graph/merge.js.map +1 -1
  61. package/dist/graph/observed-tests.d.ts +7 -68
  62. package/dist/graph/observed-tests.d.ts.map +1 -1
  63. package/dist/graph/observed-tests.js +5 -60
  64. package/dist/graph/observed-tests.js.map +1 -1
  65. package/dist/graph/persist.d.ts +2 -25
  66. package/dist/graph/persist.d.ts.map +1 -1
  67. package/dist/graph/persist.js +2 -25
  68. package/dist/graph/persist.js.map +1 -1
  69. package/dist/graph/runtime-confirmation.d.ts +14 -91
  70. package/dist/graph/runtime-confirmation.d.ts.map +1 -1
  71. package/dist/graph/runtime-confirmation.js +19 -103
  72. package/dist/graph/runtime-confirmation.js.map +1 -1
  73. package/dist/ledger/mint.d.ts +9 -43
  74. package/dist/ledger/mint.d.ts.map +1 -1
  75. package/dist/ledger/mint.js +15 -65
  76. package/dist/ledger/mint.js.map +1 -1
  77. package/dist/ledger/resolve.d.ts +13 -81
  78. package/dist/ledger/resolve.d.ts.map +1 -1
  79. package/dist/ledger/resolve.js +13 -76
  80. package/dist/ledger/resolve.js.map +1 -1
  81. package/dist/multipr/fingerprint.d.ts +5 -46
  82. package/dist/multipr/fingerprint.d.ts.map +1 -1
  83. package/dist/multipr/fingerprint.js +22 -74
  84. package/dist/multipr/fingerprint.js.map +1 -1
  85. package/dist/multipr/hidden-dependency.d.ts +13 -73
  86. package/dist/multipr/hidden-dependency.d.ts.map +1 -1
  87. package/dist/multipr/hidden-dependency.js +12 -63
  88. package/dist/multipr/hidden-dependency.js.map +1 -1
  89. package/dist/multipr/mechanical.d.ts +25 -160
  90. package/dist/multipr/mechanical.d.ts.map +1 -1
  91. package/dist/multipr/mechanical.js +21 -137
  92. package/dist/multipr/mechanical.js.map +1 -1
  93. package/dist/multipr/migration-heads.d.ts +18 -105
  94. package/dist/multipr/migration-heads.d.ts.map +1 -1
  95. package/dist/multipr/migration-heads.js +15 -84
  96. package/dist/multipr/migration-heads.js.map +1 -1
  97. package/dist/multipr/overlap.d.ts +16 -94
  98. package/dist/multipr/overlap.d.ts.map +1 -1
  99. package/dist/multipr/overlap.js +25 -105
  100. package/dist/multipr/overlap.js.map +1 -1
  101. package/dist/multipr/scope-store.d.ts +15 -80
  102. package/dist/multipr/scope-store.d.ts.map +1 -1
  103. package/dist/multipr/scope-store.js +17 -87
  104. package/dist/multipr/scope-store.js.map +1 -1
  105. package/dist/multipr/superseded.d.ts +10 -95
  106. package/dist/multipr/superseded.d.ts.map +1 -1
  107. package/dist/multipr/superseded.js +7 -60
  108. package/dist/multipr/superseded.js.map +1 -1
  109. package/dist/query/confirmed-facts.d.ts +12 -58
  110. package/dist/query/confirmed-facts.d.ts.map +1 -1
  111. package/dist/query/confirmed-facts.js +8 -47
  112. package/dist/query/confirmed-facts.js.map +1 -1
  113. package/dist/query/declared-value-closure.d.ts +13 -104
  114. package/dist/query/declared-value-closure.d.ts.map +1 -1
  115. package/dist/query/declared-value-closure.js +15 -104
  116. package/dist/query/declared-value-closure.js.map +1 -1
  117. package/dist/query/memory.d.ts +4 -16
  118. package/dist/query/memory.d.ts.map +1 -1
  119. package/dist/query/memory.js +9 -22
  120. package/dist/query/memory.js.map +1 -1
  121. package/dist/query/prominence.d.ts +6 -55
  122. package/dist/query/prominence.d.ts.map +1 -1
  123. package/dist/query/prominence.js +6 -55
  124. package/dist/query/prominence.js.map +1 -1
  125. package/dist/query/provider.d.ts +27 -93
  126. package/dist/query/provider.d.ts.map +1 -1
  127. package/dist/query/provider.js +8 -29
  128. package/dist/query/provider.js.map +1 -1
  129. package/dist/query/queries.d.ts +15 -65
  130. package/dist/query/queries.d.ts.map +1 -1
  131. package/dist/query/queries.js +30 -104
  132. package/dist/query/queries.js.map +1 -1
  133. package/dist/query/refusal-fetch.d.ts +8 -85
  134. package/dist/query/refusal-fetch.d.ts.map +1 -1
  135. package/dist/query/refusal-fetch.js +11 -93
  136. package/dist/query/refusal-fetch.js.map +1 -1
  137. package/dist/query/refusal-questions.d.ts +17 -92
  138. package/dist/query/refusal-questions.d.ts.map +1 -1
  139. package/dist/query/refusal-questions.js +14 -78
  140. package/dist/query/refusal-questions.js.map +1 -1
  141. package/dist/query/resolution-floor.d.ts +3 -23
  142. package/dist/query/resolution-floor.d.ts.map +1 -1
  143. package/dist/query/resolution-floor.js +3 -23
  144. package/dist/query/resolution-floor.js.map +1 -1
  145. package/dist/query/root-cause-score.d.ts +11 -161
  146. package/dist/query/root-cause-score.d.ts.map +1 -1
  147. package/dist/query/root-cause-score.js +6 -137
  148. package/dist/query/root-cause-score.js.map +1 -1
  149. package/dist/query/row-closure-picture.d.ts +5 -67
  150. package/dist/query/row-closure-picture.d.ts.map +1 -1
  151. package/dist/query/row-closure-picture.js +6 -67
  152. package/dist/query/row-closure-picture.js.map +1 -1
  153. package/dist/query/similar-incidents.d.ts +6 -41
  154. package/dist/query/similar-incidents.d.ts.map +1 -1
  155. package/dist/query/similar-incidents.js +15 -69
  156. package/dist/query/similar-incidents.js.map +1 -1
  157. package/dist/query/sqlite.d.ts +3 -7
  158. package/dist/query/sqlite.d.ts.map +1 -1
  159. package/dist/query/sqlite.js +9 -19
  160. package/dist/query/sqlite.js.map +1 -1
  161. package/dist/query/test-coverage.d.ts +5 -45
  162. package/dist/query/test-coverage.d.ts.map +1 -1
  163. package/dist/query/test-coverage.js +10 -53
  164. package/dist/query/test-coverage.js.map +1 -1
  165. package/dist/query/traverse.d.ts +22 -126
  166. package/dist/query/traverse.d.ts.map +1 -1
  167. package/dist/query/traverse.js +25 -126
  168. package/dist/query/traverse.js.map +1 -1
  169. package/dist/query/unresolved.d.ts +19 -164
  170. package/dist/query/unresolved.d.ts.map +1 -1
  171. package/dist/query/unresolved.js +11 -138
  172. package/dist/query/unresolved.js.map +1 -1
  173. package/dist/query/verification-status.d.ts +12 -109
  174. package/dist/query/verification-status.d.ts.map +1 -1
  175. package/dist/query/verification-status.js +9 -99
  176. package/dist/query/verification-status.js.map +1 -1
  177. package/dist/recording/migrate.d.ts +4 -10
  178. package/dist/recording/migrate.d.ts.map +1 -1
  179. package/dist/recording/migrate.js +4 -10
  180. package/dist/recording/migrate.js.map +1 -1
  181. package/dist/recording/reader.d.ts +2 -7
  182. package/dist/recording/reader.d.ts.map +1 -1
  183. package/dist/recording/reader.js +2 -7
  184. package/dist/recording/reader.js.map +1 -1
  185. package/dist/recording/redact.d.ts +6 -57
  186. package/dist/recording/redact.d.ts.map +1 -1
  187. package/dist/recording/redact.js +8 -64
  188. package/dist/recording/redact.js.map +1 -1
  189. package/dist/recording/schema.d.ts +3 -38
  190. package/dist/recording/schema.d.ts.map +1 -1
  191. package/dist/recording/schema.js +3 -38
  192. package/dist/recording/schema.js.map +1 -1
  193. package/dist/recording/writer.d.ts +11 -74
  194. package/dist/recording/writer.d.ts.map +1 -1
  195. package/dist/recording/writer.js +3 -43
  196. package/dist/recording/writer.js.map +1 -1
  197. package/dist/scoping/fanout.d.ts +6 -68
  198. package/dist/scoping/fanout.d.ts.map +1 -1
  199. package/dist/scoping/fanout.js +6 -68
  200. package/dist/scoping/fanout.js.map +1 -1
  201. package/dist/scoping/score.d.ts +20 -70
  202. package/dist/scoping/score.d.ts.map +1 -1
  203. package/dist/scoping/score.js +20 -70
  204. package/dist/scoping/score.js.map +1 -1
  205. package/dist/scoping/tiers.d.ts +4 -16
  206. package/dist/scoping/tiers.d.ts.map +1 -1
  207. package/dist/scoping/tiers.js +4 -16
  208. package/dist/scoping/tiers.js.map +1 -1
  209. package/dist/scoping/traverse.d.ts +3 -25
  210. package/dist/scoping/traverse.d.ts.map +1 -1
  211. package/dist/scoping/traverse.js +14 -49
  212. package/dist/scoping/traverse.js.map +1 -1
  213. package/dist/scoping/weights.d.ts +10 -74
  214. package/dist/scoping/weights.d.ts.map +1 -1
  215. package/dist/scoping/weights.js +14 -86
  216. package/dist/scoping/weights.js.map +1 -1
  217. package/dist/sources/confirmed/incidents.d.ts +5 -35
  218. package/dist/sources/confirmed/incidents.d.ts.map +1 -1
  219. package/dist/sources/confirmed/incidents.js +14 -48
  220. package/dist/sources/confirmed/incidents.js.map +1 -1
  221. package/dist/sources/git/diff.d.ts +93 -63
  222. package/dist/sources/git/diff.d.ts.map +1 -1
  223. package/dist/sources/git/diff.js +200 -81
  224. package/dist/sources/git/diff.js.map +1 -1
  225. package/dist/sources/git/env.d.ts +7 -0
  226. package/dist/sources/git/env.d.ts.map +1 -1
  227. package/dist/sources/git/env.js +10 -11
  228. package/dist/sources/git/env.js.map +1 -1
  229. package/dist/sources/git/history.d.ts +64 -84
  230. package/dist/sources/git/history.d.ts.map +1 -1
  231. package/dist/sources/git/history.js +141 -112
  232. package/dist/sources/git/history.js.map +1 -1
  233. package/dist/sources/git/incidents.d.ts +13 -75
  234. package/dist/sources/git/incidents.d.ts.map +1 -1
  235. package/dist/sources/git/incidents.js +21 -91
  236. package/dist/sources/git/incidents.js.map +1 -1
  237. package/dist/sources/git/index.d.ts +5 -3
  238. package/dist/sources/git/index.d.ts.map +1 -1
  239. package/dist/sources/git/index.js +3 -2
  240. package/dist/sources/git/index.js.map +1 -1
  241. package/dist/sources/git/source.d.ts +9 -79
  242. package/dist/sources/git/source.d.ts.map +1 -1
  243. package/dist/sources/git/source.js +33 -133
  244. package/dist/sources/git/source.js.map +1 -1
  245. package/dist/sources/migrations/across-change.d.ts +94 -0
  246. package/dist/sources/migrations/across-change.d.ts.map +1 -0
  247. package/dist/sources/migrations/across-change.js +278 -0
  248. package/dist/sources/migrations/across-change.js.map +1 -0
  249. package/dist/sources/migrations/dialects.d.ts +20 -36
  250. package/dist/sources/migrations/dialects.d.ts.map +1 -1
  251. package/dist/sources/migrations/dialects.js +11 -36
  252. package/dist/sources/migrations/dialects.js.map +1 -1
  253. package/dist/sources/migrations/index.d.ts +3 -1
  254. package/dist/sources/migrations/index.d.ts.map +1 -1
  255. package/dist/sources/migrations/index.js +2 -1
  256. package/dist/sources/migrations/index.js.map +1 -1
  257. package/dist/sources/migrations/read.d.ts +14 -79
  258. package/dist/sources/migrations/read.d.ts.map +1 -1
  259. package/dist/sources/migrations/read.js +14 -89
  260. package/dist/sources/migrations/read.js.map +1 -1
  261. package/dist/sources/workspace/workspace.d.ts +6 -42
  262. package/dist/sources/workspace/workspace.d.ts.map +1 -1
  263. package/dist/sources/workspace/workspace.js +10 -53
  264. package/dist/sources/workspace/workspace.js.map +1 -1
  265. package/dist/store/driver/driver.d.ts +9 -38
  266. package/dist/store/driver/driver.d.ts.map +1 -1
  267. package/dist/store/driver/driver.js +4 -22
  268. package/dist/store/driver/driver.js.map +1 -1
  269. package/dist/store/driver/node-sqlite.d.ts +3 -12
  270. package/dist/store/driver/node-sqlite.d.ts.map +1 -1
  271. package/dist/store/driver/node-sqlite.js +4 -18
  272. package/dist/store/driver/node-sqlite.js.map +1 -1
  273. package/dist/store/index.d.ts +2 -7
  274. package/dist/store/index.d.ts.map +1 -1
  275. package/dist/store/index.js +4 -10
  276. package/dist/store/index.js.map +1 -1
  277. package/dist/store/migrate.d.ts +14 -50
  278. package/dist/store/migrate.d.ts.map +1 -1
  279. package/dist/store/migrate.js +15 -52
  280. package/dist/store/migrate.js.map +1 -1
  281. package/dist/store/reader.d.ts +19 -84
  282. package/dist/store/reader.d.ts.map +1 -1
  283. package/dist/store/reader.js +25 -92
  284. package/dist/store/reader.js.map +1 -1
  285. package/dist/store/schema.d.ts +14 -76
  286. package/dist/store/schema.d.ts.map +1 -1
  287. package/dist/store/schema.js +14 -76
  288. package/dist/store/schema.js.map +1 -1
  289. package/dist/store/writer.d.ts +14 -88
  290. package/dist/store/writer.d.ts.map +1 -1
  291. package/dist/store/writer.js +29 -123
  292. package/dist/store/writer.js.map +1 -1
  293. package/dist/tiers/certify.d.ts +46 -281
  294. package/dist/tiers/certify.d.ts.map +1 -1
  295. package/dist/tiers/certify.js +46 -226
  296. package/dist/tiers/certify.js.map +1 -1
  297. package/dist/tiers/ladder.d.ts +7 -51
  298. package/dist/tiers/ladder.d.ts.map +1 -1
  299. package/dist/tiers/ladder.js +13 -89
  300. package/dist/tiers/ladder.js.map +1 -1
  301. package/dist/validation/attributes.d.ts +6 -55
  302. package/dist/validation/attributes.d.ts.map +1 -1
  303. package/dist/validation/attributes.js +6 -55
  304. package/dist/validation/attributes.js.map +1 -1
  305. package/dist/validation/config-graph.d.ts +7 -56
  306. package/dist/validation/config-graph.d.ts.map +1 -1
  307. package/dist/validation/config-graph.js +15 -61
  308. package/dist/validation/config-graph.js.map +1 -1
  309. package/dist/validation/env.d.ts +47 -8
  310. package/dist/validation/env.d.ts.map +1 -1
  311. package/dist/validation/env.js +119 -31
  312. package/dist/validation/env.js.map +1 -1
  313. package/dist/validation/index.d.ts +2 -0
  314. package/dist/validation/index.d.ts.map +1 -1
  315. package/dist/validation/index.js +1 -0
  316. package/dist/validation/index.js.map +1 -1
  317. package/dist/validation/join-substitution.d.ts +22 -120
  318. package/dist/validation/join-substitution.d.ts.map +1 -1
  319. package/dist/validation/join-substitution.js +13 -90
  320. package/dist/validation/join-substitution.js.map +1 -1
  321. package/dist/validation/migration-integrity.d.ts +11 -72
  322. package/dist/validation/migration-integrity.d.ts.map +1 -1
  323. package/dist/validation/migration-integrity.js +16 -79
  324. package/dist/validation/migration-integrity.js.map +1 -1
  325. package/dist/validation/migrations.d.ts +22 -101
  326. package/dist/validation/migrations.d.ts.map +1 -1
  327. package/dist/validation/migrations.js +19 -83
  328. package/dist/validation/migrations.js.map +1 -1
  329. package/dist/validation/nodes.d.ts +3 -1
  330. package/dist/validation/nodes.d.ts.map +1 -1
  331. package/dist/validation/nodes.js +3 -1
  332. package/dist/validation/nodes.js.map +1 -1
  333. package/dist/validation/orm-registration.d.ts +106 -0
  334. package/dist/validation/orm-registration.d.ts.map +1 -0
  335. package/dist/validation/orm-registration.js +191 -0
  336. package/dist/validation/orm-registration.js.map +1 -0
  337. package/dist/validation/rollback.d.ts +10 -73
  338. package/dist/validation/rollback.d.ts.map +1 -1
  339. package/dist/validation/rollback.js +15 -82
  340. package/dist/validation/rollback.js.map +1 -1
  341. package/dist/validation/route-drift.d.ts +9 -62
  342. package/dist/validation/route-drift.d.ts.map +1 -1
  343. package/dist/validation/route-drift.js +7 -52
  344. package/dist/validation/route-drift.js.map +1 -1
  345. package/dist/validation/sources.d.ts +16 -94
  346. package/dist/validation/sources.d.ts.map +1 -1
  347. package/dist/validation/sources.js +51 -147
  348. package/dist/validation/sources.js.map +1 -1
  349. package/dist/worker/pool.d.ts +6 -45
  350. package/dist/worker/pool.d.ts.map +1 -1
  351. package/dist/worker/pool.js +5 -42
  352. package/dist/worker/pool.js.map +1 -1
  353. package/dist/worker/protocol.d.ts +7 -20
  354. package/dist/worker/protocol.d.ts.map +1 -1
  355. package/dist/worker/protocol.js +3 -10
  356. package/dist/worker/protocol.js.map +1 -1
  357. package/dist/worker/traversal.worker.d.ts +2 -21
  358. package/dist/worker/traversal.worker.d.ts.map +1 -1
  359. package/dist/worker/traversal.worker.js +4 -23
  360. package/dist/worker/traversal.worker.js.map +1 -1
  361. package/package.json +11 -2
@@ -1,95 +1,29 @@
1
1
  /**
2
- * Which commits in a history describe a failure, and how we know.
3
- *
4
- * Split out of `source.ts` when the answer stopped being one regex. The git
5
- * source minted an `INCIDENT` for exactly one thing — a commit body carrying
6
- * `This reverts commit <40 hex>` — and that produced **zero** incidents across
7
- * three measured repositories (734/459/203 commits) and two in a real product
8
- * repository. `similarIncidents` was therefore built, tested, correct and
9
- * starved: its recall is not 0%, it is not computable, because it has never
10
- * been given a real incident to find.
11
- *
12
- * ## The rule every mechanism here answers to
13
- *
14
- * `INCIDENT` is an EARNED node (DEC-017). It is never dropped, it survives
15
- * every rebuild, and `INCIDENT_CORRELATED` biases diff-scoping traversal toward
16
- * the files it names for as long as the store exists. A wrong incident is not a
17
- * bad answer that a later run corrects — it is unrecoverable pollution in the
18
- * one table that cannot be recomputed away. So:
19
- *
20
- * **Every mechanism rests on something a person declared. None rests on
21
- * something Descry inferred.**
22
- *
23
- * A revert trailer is written by `git revert`. A `Revert "…"` subject is typed
24
- * by a person or by GitHub's own button on their behalf. `Fixes #123` is a
25
- * developer stating that something was broken and this commit fixed it. What is
26
- * deliberately *not* here is any reading of "fix", "hotfix" or "bug" in prose —
27
- * the original mechanism's own comment says why, and it applies unchanged to
28
- * every mechanism added since: matching on the word "fix" would classify
29
- * ordinary work as an incident.
30
- *
31
- * ## Refusals, not guesses
32
- *
33
- * A `Revert "X"` naming a subject this history does not contain, or containing
34
- * twice, produces a `DetectedRefusal` rather than a ranked guess. Two candidates
35
- * is a genuine ambiguity and picking the nearer one would be recency standing in
36
- * for evidence — the same discipline every resolver in this project follows.
37
- *
38
- * See `DEC-NEXT-incident-minting-beyond-explicit-reverts`.
2
+ * Which commits describe a failure. `INCIDENT` is EARNED (DEC-017, never dropped, biases traversal permanently), so every mechanism rests on something a person declared — never Descry inferring "fix"/"bug" from prose.
3
+ * An ambiguous Revert is a DetectedRefusal, not a ranked guess. See DEC-NEXT-incident-minting-beyond-explicit-reverts.
39
4
  */
40
5
  /** `git revert` writes this. Machine-generated, and the strongest signal available. */
41
6
  const REVERT_TRAILER = /This reverts commit ([0-9a-f]{40})/;
42
- /**
43
- * `Revert "the original subject"` — the subject form, written by a person or by
44
- * GitHub's Revert button, often with no sha anywhere in the commit.
45
- *
46
- * Anchored at the start and requiring the quotes: `Revert the auth change` is
47
- * prose about what the commit does, not a reference to a specific commit, and
48
- * reading it as one would be exactly the inference this module refuses to make.
49
- */
7
+ /** `Revert "the original subject"` form, written by a person or GitHub's
8
+ * button. Anchored + requires quotes: unquoted `Revert the auth change` is
9
+ * prose, not a commit reference, and reading it as one is the inference refused here. */
50
10
  const REVERT_SUBJECT = /^Revert\s+"(.+)"\s*$/;
51
- /**
52
- * A closed list of fix-shaped verbs, and only immediately before the reference.
53
- *
54
- * `Fixes #123` is a developer stating that something was broken. `See #123` and
55
- * `Part of #124` are not — they relate a commit to an issue and say nothing
56
- * about a defect. The verb is what carries the claim, so the verb is what is
57
- * matched; a bare `#123` mints nothing.
58
- *
59
- * `GH-123` is GitHub's own cross-reference form and means the same thing.
60
- */
11
+ /** Closed list of fix-shaped verbs, immediately before the reference. `Fixes
12
+ * #123` claims a defect; `See #123` doesn't — a bare `#123` mints nothing.
13
+ * `GH-123` is GitHub's equivalent cross-reference form. */
61
14
  const ISSUE_VERBS = "fix|fixes|fixed|close|closes|closed|resolve|resolves|resolved";
62
15
  /** In the subject, anywhere: a subject is a claim about the commit itself. */
63
16
  const SUBJECT_ISSUE = new RegExp(`\\b(?:${ISSUE_VERBS})\\s+(?:#|GH-)(\\d+)\\b`, "gi");
64
- /**
65
- * In the body, **only in trailer position** — the start of a line, with nothing
66
- * but whitespace before it.
67
- *
68
- * Measured, not supposed. Run over this repository's own history, the
69
- * anywhere-in-the-body form matched three commits, and all three were prose
70
- * *about* the convention rather than uses of it: a sentence quoting
71
- * `"Fixes #123"` as an example, and a bullet reading
72
- * `- issue-reference: \`Fixes #123\` and its closed list…`. A commit message
73
- * discussing the convention is not a commit message using it, and an EARNED
74
- * node minted from one is permanent.
75
- *
76
- * The trailer position is where the convention actually lives — it is what
77
- * GitHub's own tooling emits and what a template puts there — so this costs
78
- * almost no real recall and removes a whole class of false positive. Rule 2:
79
- * when in doubt, omit.
17
+ /** In the body, only in trailer position (line start). Measured: the
18
+ * anywhere-in-body form matched 3 commits here, all prose *about* the
19
+ * convention, not uses of it — and an EARNED node minted from one is permanent. Trailer position is where the convention actually lives. Rule 2.
80
20
  */
81
21
  const BODY_ISSUE = new RegExp(`^[ \\t]*(?:${ISSUE_VERBS})\\s+(?:#|GH-)(\\d+)\\b`, "gim");
82
22
  function pathsOf(commit) {
83
23
  return [...new Set(commit.changes.map((c) => c.path))].sort();
84
24
  }
85
- /**
86
- * Every incident this history declares, plus every revert whose target it does
87
- * not contain.
88
- *
89
- * `commits` is the history as `readHistory` returns it — newest first. Order is
90
- * not relied on for correctness: a revert's target is found by timestamp, so
91
- * the result is identical for any permutation of the same commits.
92
- */
25
+ /** Every incident this history declares, plus every revert whose target it
26
+ * lacks. Order-independent: a revert's target is found by timestamp. */
93
27
  export function detectIncidents(commits) {
94
28
  const incidents = [];
95
29
  const refusals = [];
@@ -104,9 +38,8 @@ export function detectIncidents(commits) {
104
38
  existing.push(commit);
105
39
  }
106
40
  for (const commit of commits) {
107
- // The trailer first, and exclusively: `git revert` writes both the trailer
108
- // and the `Revert "…"` subject, so reading the subject as an independent
109
- // mechanism would mint one incident twice under two different names.
41
+ // Trailer first, exclusively: git revert writes both trailer and subject,
42
+ // so reading the subject too would mint one incident under two names.
110
43
  const revertedSha = REVERT_TRAILER.exec(commit.body)?.[1];
111
44
  if (revertedSha !== undefined) {
112
45
  const target = bySha.get(revertedSha);
@@ -125,9 +58,8 @@ export function detectIncidents(commits) {
125
58
  }
126
59
  const quoted = REVERT_SUBJECT.exec(commit.subject)?.[1];
127
60
  if (quoted !== undefined) {
128
- // Backwards only. A commit cannot revert something that had not happened
129
- // when it was written, and a same-subject commit landing afterwards is a
130
- // different commit that happens to share a name.
61
+ // Backwards only: a commit can't revert something written after it, and
62
+ // a same-subject commit landing later just happens to share a name.
131
63
  const candidates = (bySubject.get(quoted) ?? []).filter((c) => c.timestamp < commit.timestamp);
132
64
  if (candidates.length === 1) {
133
65
  const target = candidates[0];
@@ -157,10 +89,8 @@ export function detectIncidents(commits) {
157
89
  }
158
90
  continue;
159
91
  }
160
- // An issue reference is a claim about a *defect*, made by the person who
161
- // fixed it. Read from the subject anywhere and from the body only in
162
- // trailer position — see `BODY_ISSUE` for the three false positives that
163
- // distinction was measured against.
92
+ // An issue reference claims a defect. Read from the subject anywhere,
93
+ // from the body only in trailer position — see BODY_ISSUE's measurement.
164
94
  const refs = new Set();
165
95
  for (const match of commit.subject.matchAll(SUBJECT_ISSUE))
166
96
  refs.add(`#${match[1]}`);
@@ -176,8 +106,8 @@ export function detectIncidents(commits) {
176
106
  });
177
107
  }
178
108
  }
179
- // Deterministic: two runs over the same history must produce a byte-identical
180
- // batch, or the store's content hash moves for no reason.
109
+ // Deterministic: two runs must produce a byte-identical batch, or the
110
+ // store's content hash moves for no reason.
181
111
  incidents.sort((a, b) => a.fix.sha.localeCompare(b.fix.sha) || (a.issueRef ?? "").localeCompare(b.issueRef ?? ""));
182
112
  refusals.sort((a, b) => a.fixSha.localeCompare(b.fixSha) || a.rawTarget.localeCompare(b.rawTarget));
183
113
  unresolvedTrailers.sort((a, b) => a.fix.sha.localeCompare(b.fix.sha));
@@ -1 +1 @@
1
- {"version":3,"file":"incidents.js","sourceRoot":"","sources":["../../../src/sources/git/incidents.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"incidents.js","sourceRoot":"","sources":["../../../src/sources/git/incidents.ts"],"names":[],"mappings":"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"}
@@ -1,9 +1,11 @@
1
1
  export { createGitSource, revertedShaOf, GIT_SOURCE_ID, GIT_SOURCE_VERSION, UNDIRECTED_EDGE_TYPES, } from "./source.ts";
2
2
  export type { GitSourceOptions } from "./source.ts";
3
- export { readHistory, gitHead, isGitRepository, filesInCommit, changedFiles, resolveCommitBySha, logForPath, } from "./history.ts";
3
+ export { readHistory, gitHead, isGitRepository, GitUnavailableError, isPathTrackedByGit, filesInCommit, changedFiles, resolveCommitBySha, logForPath, } from "./history.ts";
4
4
  export type { Commit, CommitChange, HistoryOptions, PathLogCommit, PathLogOptions, PathLogResult, } from "./history.ts";
5
- export { gitDiff, gitWorkingTreeDiff, TOTAL_PATCH_BUDGET_REASON_PREFIX } from "./diff.ts";
6
- export type { GitDiffFile, GitDiffOptions, GitWorkingTreeDiffOptions } from "./diff.ts";
5
+ export { addedLineRanges, gitDiff, gitWorkingTreeChange, gitWorkingTreeDiff, TOTAL_PATCH_BUDGET_REASON_PREFIX, } from "./diff.ts";
6
+ export { uncommittedAmong, workingTreeChangedFiles } from "./history.ts";
7
+ export type { WorkingTreeFilesOptions } from "./history.ts";
8
+ export type { GitDiffFile, GitDiffOptions, GitWorkingTreeChange, GitWorkingTreeChangeOptions, GitWorkingTreeDiffOptions, LineRange, } from "./diff.ts";
7
9
  export { detectIncidents } from "./incidents.ts";
8
10
  export type { DetectedIncident, DetectedRefusal, IncidentDetection, IncidentMechanism, UnresolvedTrailer, } from "./incidents.ts";
9
11
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/sources/git/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,aAAa,EACb,aAAa,EACb,kBAAkB,EAClB,qBAAqB,GACtB,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEpD,OAAO,EACL,WAAW,EACX,OAAO,EACP,eAAe,EACf,aAAa,EACb,YAAY,EACZ,kBAAkB,EAClB,UAAU,GACX,MAAM,cAAc,CAAC;AACtB,YAAY,EACV,MAAM,EACN,YAAY,EACZ,cAAc,EACd,aAAa,EACb,cAAc,EACd,aAAa,GACd,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,OAAO,EAAE,kBAAkB,EAAE,gCAAgC,EAAE,MAAM,WAAW,CAAC;AAC1F,YAAY,EAAE,WAAW,EAAE,cAAc,EAAE,yBAAyB,EAAE,MAAM,WAAW,CAAC;AAExF,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,YAAY,EACV,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EACjB,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/sources/git/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,aAAa,EACb,aAAa,EACb,kBAAkB,EAClB,qBAAqB,GACtB,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEpD,OAAO,EACL,WAAW,EACX,OAAO,EACP,eAAe,EACf,mBAAmB,EACnB,kBAAkB,EAClB,aAAa,EACb,YAAY,EACZ,kBAAkB,EAClB,UAAU,GACX,MAAM,cAAc,CAAC;AACtB,YAAY,EACV,MAAM,EACN,YAAY,EACZ,cAAc,EACd,aAAa,EACb,cAAc,EACd,aAAa,GACd,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,eAAe,EACf,OAAO,EACP,oBAAoB,EACpB,kBAAkB,EAClB,gCAAgC,GACjC,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AACzE,YAAY,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AAC5D,YAAY,EACV,WAAW,EACX,cAAc,EACd,oBAAoB,EACpB,2BAA2B,EAC3B,yBAAyB,EACzB,SAAS,GACV,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,YAAY,EACV,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EACjB,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,gBAAgB,CAAC"}
@@ -1,5 +1,6 @@
1
1
  export { createGitSource, revertedShaOf, GIT_SOURCE_ID, GIT_SOURCE_VERSION, UNDIRECTED_EDGE_TYPES, } from "./source.js";
2
- export { readHistory, gitHead, isGitRepository, filesInCommit, changedFiles, resolveCommitBySha, logForPath, } from "./history.js";
3
- export { gitDiff, gitWorkingTreeDiff, TOTAL_PATCH_BUDGET_REASON_PREFIX } from "./diff.js";
2
+ export { readHistory, gitHead, isGitRepository, GitUnavailableError, isPathTrackedByGit, filesInCommit, changedFiles, resolveCommitBySha, logForPath, } from "./history.js";
3
+ export { addedLineRanges, gitDiff, gitWorkingTreeChange, gitWorkingTreeDiff, TOTAL_PATCH_BUDGET_REASON_PREFIX, } from "./diff.js";
4
+ export { uncommittedAmong, workingTreeChangedFiles } from "./history.js";
4
5
  export { detectIncidents } from "./incidents.js";
5
6
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/sources/git/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,aAAa,EACb,aAAa,EACb,kBAAkB,EAClB,qBAAqB,GACtB,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,WAAW,EACX,OAAO,EACP,eAAe,EACf,aAAa,EACb,YAAY,EACZ,kBAAkB,EAClB,UAAU,GACX,MAAM,cAAc,CAAC;AAUtB,OAAO,EAAE,OAAO,EAAE,kBAAkB,EAAE,gCAAgC,EAAE,MAAM,WAAW,CAAC;AAG1F,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/sources/git/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,aAAa,EACb,aAAa,EACb,kBAAkB,EAClB,qBAAqB,GACtB,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,WAAW,EACX,OAAO,EACP,eAAe,EACf,mBAAmB,EACnB,kBAAkB,EAClB,aAAa,EACb,YAAY,EACZ,kBAAkB,EAClB,UAAU,GACX,MAAM,cAAc,CAAC;AAUtB,OAAO,EACL,eAAe,EACf,OAAO,EACP,oBAAoB,EACpB,kBAAkB,EAClB,gCAAgC,GACjC,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AAWzE,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC"}
@@ -1,93 +1,23 @@
1
1
  /**
2
- * The git history `IRSource` — architecture §11.6 and §11.7.
3
- *
4
- * It is an `IRSource` and **not** a `LanguageAdapter`, which is the whole reason
5
- * that split exists: history is a producer of IR with no parser, no language and
6
- * no resolution beyond R0, and without the narrower interface it would need a
7
- * second write path — and a second write path is how un-provenanced rows reach
8
- * storage.
9
- *
10
- * ## Everything here is R0, and that is not a formality
11
- *
12
- * Co-change is not code analysis. It observes that two files were edited in the
13
- * same commit, which is evidence about *people*, not about program structure.
14
- * R0's confidence ceiling (DEC-019) therefore caps every edge this source emits
15
- * at 0.5, and §11A.5's reliability cap makes any finding resting on one Class C
16
- * — a behavioural prediction that must be live-confirmed or dropped. That is the
17
- * correct treatment: "these two files usually change together" is a hint for a
18
- * human, never a claim about what breaks.
19
- *
20
- * ## Precision over recall, applied three times
21
- *
22
- * 1. **Merge commits are excluded from co-change.** A merge's file list is the
23
- * union of both branches, so counting it would report every file in a large
24
- * merge as coupled to every other. This exclusion is scoped to co-change —
25
- * it does **not** apply to resolving what a revert names (see below): a
26
- * revert of "Merge pull request #N" is a real incident whose target
27
- * happens to be a merge commit, and excluding it from co-change is not a
28
- * reason to also make it unresolvable as an incident.
29
- * 2. **Large commits are excluded.** A commit touching hundreds of files is a
30
- * reformat or a dependency bump; including it adds O(n²) edges that mean
31
- * nothing.
32
- * 3. **Only explicit reverts become incidents.** A commit whose message merely
33
- * contains "fix" is not evidence of an incident. `git revert` writes a
34
- * machine-generated `This reverts commit <sha>.` line, and that is the only
35
- * signal used.
36
- *
37
- * ## Resolving what a revert names
38
- *
39
- * `readHistory` indexes commits reachable from `HEAD`, minus merges. A revert
40
- * commit's target sha can miss that index for two reasons that have nothing to
41
- * do with whether the incident is real: the target is a merge commit (excluded
42
- * above), or the target was never merged as itself — a squash/rebase-merge
43
- * workflow (GitHub's default) discards the original commits and only the
44
- * squashed commit survives on `HEAD`, so "Revert PR #N" names a sha that is
45
- * either real-but-unreachable (still sitting on an abandoned branch) or
46
- * genuinely gone (garbage-collected after the branch was deleted). Measured
47
- * against 5 real repos, 6 of 9 real reverts fell into these two buckets and
48
- * were silently dropped by a naive index lookup.
49
- *
50
- * `resolveCommitBySha` is the fallback: it goes straight to the object
51
- * database (`git cat-file` / `git diff-tree`), which enforces neither
52
- * constraint `readHistory` applies. It resolves the merge case and the
53
- * unreachable-but-present case. Only the genuinely-gone case still fails, and
54
- * that failure is disclosed via `unresolved` (below) rather than dropped with
55
- * no trace — this is the fallback CLAUDE.md rule 7 requires labelling.
2
+ * Git history `IRSource` (§11.6/§11.7) — an `IRSource`, not a `LanguageAdapter`: one write path, no un-provenanced rows. Everything is R0; DEC-019 caps confidence at 0.5 and §11A.5 caps any finding at Class C — co-change is evidence about people, not code.
3
+ * Precision over recall: merge commits excluded from co-change (not from revert resolution below), large commits excluded, only explicit-revert trailers become incidents.
4
+ * `resolveCommitBySha` recovers reverts the primary index misses (6/9 real reverts, 5 repos, needed it); a genuinely-gone target is disclosed via `unresolved`, never dropped (rule 7).
56
5
  */
57
6
  import { type IRSource } from "@descryy/ir";
58
7
  import { type Commit, type HistoryOptions } from "./history.ts";
59
8
  export declare const GIT_SOURCE_ID = "git-history";
60
9
  export declare const GIT_SOURCE_VERSION = "0.1.0";
61
- /**
62
- * `CHANGES_WITH` is a symmetric relationship stored in one canonical direction.
63
- *
64
- * Emitting both directions would double the edge count and make the pair count
65
- * twice in any per-edge aggregate. The cost is that a caller must traverse it
66
- * undirected — `direction: "both"` — and forgetting that yields a *missing*
67
- * edge, which is a disclosed gap rather than a wrong answer. That asymmetry is
68
- * why this is the safe default and not the convenient one.
69
- */
10
+ /** `CHANGES_WITH` is symmetric, stored one direction only — a caller must
11
+ * traverse `direction: "both"`, or gets a disclosed missing edge, not a wrong one. */
70
12
  export declare const UNDIRECTED_EDGE_TYPES: readonly ["CHANGES_WITH"];
71
13
  export interface GitSourceOptions extends HistoryOptions {
72
14
  readonly repo: string;
73
15
  readonly cwd: string;
74
- /**
75
- * Minimum times two files must change together before an edge is emitted.
76
- *
77
- * **Provisional.** The architecture's own illustration is that 18x co-change
78
- * is a warning and 2x is noise, which fixes the shape of the threshold but not
79
- * its value; §32's tuning register has no number for it either. 5 is a
80
- * defensible floor for a repo with a few hundred commits and is expected to
81
- * move once measured. See DEC-033.
82
- */
16
+ /** Minimum times two files must co-change before an edge is emitted.
17
+ * Provisional — 5 is a defensible floor, expected to move once measured (DEC-033). */
83
18
  readonly minSupport?: number;
84
- /**
85
- * Minimum `support / timesTheSourceFileChanged`.
86
- *
87
- * Support alone over-reports the files that change constantly: a config file
88
- * touched in half of all commits co-occurs with everything. Confidence is what
89
- * separates "coupled" from "always busy".
90
- */
19
+ /** Minimum `support / timesFileChanged` — support alone over-reports files
20
+ * that change constantly; this separates "coupled" from "always busy". */
91
21
  readonly minConfidence?: number;
92
22
  }
93
23
  export declare function revertedShaOf(commit: Commit): string | null;
@@ -1 +1 @@
1
- {"version":3,"file":"source.d.ts","sourceRoot":"","sources":["../../../src/sources/git/source.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuDG;AAEH,OAAO,EAQL,KAAK,QAAQ,EAGd,MAAM,aAAa,CAAC;AAErB,OAAO,EAKL,KAAK,MAAM,EACX,KAAK,cAAc,EACpB,MAAM,cAAc,CAAC;AAGtB,eAAO,MAAM,aAAa,gBAAgB,CAAC;AAC3C,eAAO,MAAM,kBAAkB,UAAU,CAAC;AAG1C;;;;;;;;GAQG;AACH,eAAO,MAAM,qBAAqB,2BAA4B,CAAC;AAE/D,MAAM,WAAW,gBAAiB,SAAQ,cAAc;IACtD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB;;;;;;;;OAQG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B;;;;;;OAMG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;CACjC;AAiBD,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAG3D;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,gBAAgB,GAAG,QAAQ,CA0WnE"}
1
+ {"version":3,"file":"source.d.ts","sourceRoot":"","sources":["../../../src/sources/git/source.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAQL,KAAK,QAAQ,EAGd,MAAM,aAAa,CAAC;AAErB,OAAO,EAKL,KAAK,MAAM,EACX,KAAK,cAAc,EACpB,MAAM,cAAc,CAAC;AAGtB,eAAO,MAAM,aAAa,gBAAgB,CAAC;AAC3C,eAAO,MAAM,kBAAkB,UAAU,CAAC;AAG1C;uFACuF;AACvF,eAAO,MAAM,qBAAqB,2BAA4B,CAAC;AAE/D,MAAM,WAAW,gBAAiB,SAAQ,cAAc;IACtD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB;2FACuF;IACvF,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B;+EAC2E;IAC3E,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;CACjC;AAWD,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAG3D;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,gBAAgB,GAAG,QAAQ,CAkUnE"}
@@ -1,58 +1,7 @@
1
1
  /**
2
- * The git history `IRSource` — architecture §11.6 and §11.7.
3
- *
4
- * It is an `IRSource` and **not** a `LanguageAdapter`, which is the whole reason
5
- * that split exists: history is a producer of IR with no parser, no language and
6
- * no resolution beyond R0, and without the narrower interface it would need a
7
- * second write path — and a second write path is how un-provenanced rows reach
8
- * storage.
9
- *
10
- * ## Everything here is R0, and that is not a formality
11
- *
12
- * Co-change is not code analysis. It observes that two files were edited in the
13
- * same commit, which is evidence about *people*, not about program structure.
14
- * R0's confidence ceiling (DEC-019) therefore caps every edge this source emits
15
- * at 0.5, and §11A.5's reliability cap makes any finding resting on one Class C
16
- * — a behavioural prediction that must be live-confirmed or dropped. That is the
17
- * correct treatment: "these two files usually change together" is a hint for a
18
- * human, never a claim about what breaks.
19
- *
20
- * ## Precision over recall, applied three times
21
- *
22
- * 1. **Merge commits are excluded from co-change.** A merge's file list is the
23
- * union of both branches, so counting it would report every file in a large
24
- * merge as coupled to every other. This exclusion is scoped to co-change —
25
- * it does **not** apply to resolving what a revert names (see below): a
26
- * revert of "Merge pull request #N" is a real incident whose target
27
- * happens to be a merge commit, and excluding it from co-change is not a
28
- * reason to also make it unresolvable as an incident.
29
- * 2. **Large commits are excluded.** A commit touching hundreds of files is a
30
- * reformat or a dependency bump; including it adds O(n²) edges that mean
31
- * nothing.
32
- * 3. **Only explicit reverts become incidents.** A commit whose message merely
33
- * contains "fix" is not evidence of an incident. `git revert` writes a
34
- * machine-generated `This reverts commit <sha>.` line, and that is the only
35
- * signal used.
36
- *
37
- * ## Resolving what a revert names
38
- *
39
- * `readHistory` indexes commits reachable from `HEAD`, minus merges. A revert
40
- * commit's target sha can miss that index for two reasons that have nothing to
41
- * do with whether the incident is real: the target is a merge commit (excluded
42
- * above), or the target was never merged as itself — a squash/rebase-merge
43
- * workflow (GitHub's default) discards the original commits and only the
44
- * squashed commit survives on `HEAD`, so "Revert PR #N" names a sha that is
45
- * either real-but-unreachable (still sitting on an abandoned branch) or
46
- * genuinely gone (garbage-collected after the branch was deleted). Measured
47
- * against 5 real repos, 6 of 9 real reverts fell into these two buckets and
48
- * were silently dropped by a naive index lookup.
49
- *
50
- * `resolveCommitBySha` is the fallback: it goes straight to the object
51
- * database (`git cat-file` / `git diff-tree`), which enforces neither
52
- * constraint `readHistory` applies. It resolves the merge case and the
53
- * unreachable-but-present case. Only the genuinely-gone case still fails, and
54
- * that failure is disclosed via `unresolved` (below) rather than dropped with
55
- * no trace — this is the fallback CLAUDE.md rule 7 requires labelling.
2
+ * Git history `IRSource` (§11.6/§11.7) — an `IRSource`, not a `LanguageAdapter`: one write path, no un-provenanced rows. Everything is R0; DEC-019 caps confidence at 0.5 and §11A.5 caps any finding at Class C — co-change is evidence about people, not code.
3
+ * Precision over recall: merge commits excluded from co-change (not from revert resolution below), large commits excluded, only explicit-revert trailers become incidents.
4
+ * `resolveCommitBySha` recovers reverts the primary index misses (6/9 real reverts, 5 repos, needed it); a genuinely-gone target is disclosed via `unresolved`, never dropped (rule 7).
56
5
  */
57
6
  import { edgeId, fileQsp, nodeId, } from "@descryy/ir";
58
7
  import { gitHead, isGitRepository, readHistory, resolveCommitBySha, } from "./history.js";
@@ -60,24 +9,11 @@ import { detectIncidents } from "./incidents.js";
60
9
  export const GIT_SOURCE_ID = "git-history";
61
10
  export const GIT_SOURCE_VERSION = "0.1.0";
62
11
  const PRODUCED_BY = `${GIT_SOURCE_ID}@${GIT_SOURCE_VERSION}`;
63
- /**
64
- * `CHANGES_WITH` is a symmetric relationship stored in one canonical direction.
65
- *
66
- * Emitting both directions would double the edge count and make the pair count
67
- * twice in any per-edge aggregate. The cost is that a caller must traverse it
68
- * undirected — `direction: "both"` — and forgetting that yields a *missing*
69
- * edge, which is a disclosed gap rather than a wrong answer. That asymmetry is
70
- * why this is the safe default and not the convenient one.
71
- */
12
+ /** `CHANGES_WITH` is symmetric, stored one direction only — a caller must
13
+ * traverse `direction: "both"`, or gets a disclosed missing edge, not a wrong one. */
72
14
  export const UNDIRECTED_EDGE_TYPES = ["CHANGES_WITH"];
73
- /**
74
- * Detect a revert and the commit it reverted.
75
- *
76
- * `git revert` writes `This reverts commit <40 hex>.` into the body. Nothing
77
- * else is trusted: matching on the word "fix" would classify ordinary work as an
78
- * incident, and an `INCIDENT` node is a durable, earned fact (DEC-017) that
79
- * outlives every rebuild.
80
- */
15
+ /** Detects a revert and the commit it reverted, via `git revert`'s machine-written
16
+ * trailer only — an `INCIDENT` node is a durable, earned fact (DEC-017). */
81
17
  const REVERTS = /This reverts commit ([0-9a-f]{40})/;
82
18
  export function revertedShaOf(commit) {
83
19
  const match = REVERTS.exec(commit.body);
@@ -92,18 +28,15 @@ export function createGitSource(options) {
92
28
  async emit(ctx) {
93
29
  const repo = options.repo || ctx.root.repo;
94
30
  const cwd = options.cwd;
95
- // INCIDENT and FIX_PATTERN are workspace-scoped (DEC-054), FILE is
96
- // repo-scoped, and `scopeOf` picks between them per type — this source does
97
- // not choose, and must not.
31
+ // INCIDENT/FIX_PATTERN are workspace-scoped (DEC-054), FILE repo-scoped.
98
32
  const scope = { repo, workspace: ctx.root.workspace };
99
33
  if (!(await isGitRepository(cwd))) {
100
- // Not an error. A repo with no history is a repo about which this source
101
- // has nothing to say, and an empty batch says exactly that.
34
+ // Not an error — a repo with no history has nothing to say here.
102
35
  return emptyBatch(repo, ctx.root.workspace, ctx.root.commitSha);
103
36
  }
104
37
  const commits = await readHistory(cwd, options);
105
38
  const head = await gitHead(cwd);
106
- // --- co-change (§11.7) ------------------------------------------------
39
+ // Co-change (§11.7).
107
40
  const fileChanges = new Map();
108
41
  const pairs = new Map();
109
42
  const touched = new Set();
@@ -128,28 +61,17 @@ export function createGitSource(options) {
128
61
  }
129
62
  }
130
63
  }
131
- // --- incidents (§11.6) ------------------------------------------------
64
+ // Incidents (§11.6).
132
65
  const maxFilesPerCommit = options.maxFilesPerCommit ?? 50;
133
- // Which commits describe a failure, and how we know — `incidents.ts`.
134
- // Three mechanisms now, all of them resting on something a person
135
- // declared: the trailer `git revert` writes, the `Revert "…"` subject a
136
- // person or GitHub's own button writes, and a `Fixes #123` a developer
137
- // wrote to say something was broken. Nothing here reads "fix" out of
138
- // prose; see that module's header for why an EARNED node cannot be minted
139
- // from an inference.
66
+ // Three declared mechanisms (incidents.ts): a revert trailer, a `Revert
67
+ // "…"` subject, or a `Fixes #123` — never inferred from prose like "fix".
140
68
  const detected = detectIncidents(commits);
141
69
  const incidents = [...detected.incidents];
142
- // A revert whose target sha could not be resolved by any means — real,
143
- // per the commit's own machine-generated message, but with no commit to
144
- // hang an INCIDENT on. Disclosed via `unresolved`, never dropped with no
145
- // trace (CLAUDE.md rule 7).
70
+ // Real per the commit's own message but unresolvable to a commit — disclosed
71
+ // via `unresolved`, never silently dropped (rule 7).
146
72
  const unresolvedReverts = [];
147
73
  for (const trailer of detected.unresolvedTrailers) {
148
- // Not in the primary, HEAD-reachable, --no-merges index. Try the
149
- // object database directly before giving up — see the module doc's
150
- // "Resolving what a revert names". `detectIncidents` is synchronous and
151
- // cannot do this, which is why it hands the case back rather than
152
- // refusing it itself.
74
+ // Not in the primary index — try the object database (see module doc).
153
75
  const reverted = await resolveCommitBySha(cwd, trailer.revertedSha, maxFilesPerCommit);
154
76
  if (reverted === null) {
155
77
  unresolvedReverts.push({
@@ -168,9 +90,8 @@ export function createGitSource(options) {
168
90
  correlatedPaths: [...new Set(reverted.changes.map((c) => c.path))].sort(),
169
91
  });
170
92
  }
171
- // A `Revert "…"` whose quoted subject this history does not contain, or
172
- // contains twice. Not resolvable out of band the way a sha is — a subject
173
- // is not an identity — so these are refusals as detected.
93
+ // A quoted subject not found (or found twice) — a subject isn't an
94
+ // identity, so unresolvable out of band, unlike a sha.
174
95
  for (const refusal of detected.refusals) {
175
96
  const fix = commits.find((c) => c.sha === refusal.fixSha);
176
97
  if (fix === undefined)
@@ -182,7 +103,7 @@ export function createGitSource(options) {
182
103
  for (const path of found.correlatedPaths)
183
104
  touched.add(path);
184
105
  }
185
- // --- nodes ------------------------------------------------------------
106
+ // Nodes.
186
107
  const nodes = [];
187
108
  const sourceFiles = [...touched].sort();
188
109
  for (const path of sourceFiles) {
@@ -192,26 +113,16 @@ export function createGitSource(options) {
192
113
  name: path.split("/").pop() ?? path,
193
114
  file: path,
194
115
  range: null,
195
- // History cannot tell what language a file is written in, and guessing
196
- // from the extension would be a language decision made by a source
197
- // that has no business making one (DEC-026).
116
+ // Guessing language from the extension would be a language decision
117
+ // made by a source with no business making one (DEC-026).
198
118
  language: null,
199
119
  producedBy: PRODUCED_BY,
200
120
  resolution: 0,
201
121
  attrs: { changeCount: fileChanges.get(path) ?? 0 },
202
122
  });
203
123
  }
204
- /**
205
- * One incident can be reached by more than one fix — two commits both
206
- * saying `Fixes #7` are one defect fixed twice, not two defects. So the
207
- * `INCIDENT` node is keyed and emitted once; the `FIX_PATTERN` and the
208
- * `FIXED_BY` edge are per-fix.
209
- *
210
- * The issue form's qualified symbol path carries the repository even
211
- * though `INCIDENT` is workspace-scoped (DEC-054), because `#123` in one
212
- * repository is not `#123` in another and a bare number would collide two
213
- * unrelated defects into one node across a linked workspace.
214
- */
124
+ /** One incident, multiple fixes — `INCIDENT` keyed and emitted once, `FIX_PATTERN`
125
+ * per-fix. Issue id carries the repo (DEC-054) so `#123` doesn't collide across repos. */
215
126
  const incidentIdOf = (found) => found.incidentCommit !== null
216
127
  ? nodeId(scope, "INCIDENT", found.incidentCommit.sha, null)
217
128
  : nodeId(scope, "INCIDENT", `issue:${repo}${found.issueRef ?? ""}`, null);
@@ -239,10 +150,7 @@ export function createGitSource(options) {
239
150
  : {
240
151
  id,
241
152
  type: "INCIDENT",
242
- // The issue reference and nothing more. Descry reads no tracker
243
- // and must not imply it knows the issue's title, or even that
244
- // the issue was filed as a defect — only that the developer who
245
- // closed it said their commit fixed something.
153
+ // Issue reference only — no tracker is read, so no title or defect status is implied.
246
154
  name: `${repo}${found.issueRef ?? ""}`,
247
155
  file: null,
248
156
  range: null,
@@ -275,13 +183,9 @@ export function createGitSource(options) {
275
183
  },
276
184
  });
277
185
  }
278
- // The fix commit is real and independently verifiable (it exists, its
279
- // sha and message are facts) even when its target is not — so it still
280
- // earns a FIX_PATTERN node. What it does NOT get is an INCIDENT, a
281
- // FIXED_BY edge or any INCIDENT_CORRELATED edge, because none of those
282
- // can be built without a resolved target. The gap is recorded below in
283
- // `unresolved`, not implied by a node that silently has no incoming
284
- // FIXED_BY edge.
186
+ // The fix commit is real, so it earns a FIX_PATTERN node — but no INCIDENT,
187
+ // FIXED_BY or INCIDENT_CORRELATED edge, since none can be built without a
188
+ // resolved target; the gap is recorded in `unresolved` instead.
285
189
  for (const { fix } of unresolvedReverts) {
286
190
  nodes.push({
287
191
  id: nodeId(scope, "FIX_PATTERN", fix.sha, null),
@@ -295,7 +199,7 @@ export function createGitSource(options) {
295
199
  attrs: { commitSha: fix.sha, revertedShaUnresolved: true },
296
200
  });
297
201
  }
298
- // --- edges ------------------------------------------------------------
202
+ // Edges.
299
203
  const nodeIds = new Set(nodes.map((n) => n.id));
300
204
  const edges = [];
301
205
  const unresolved = [];
@@ -313,9 +217,8 @@ export function createGitSource(options) {
313
217
  to: nodeId(scope, "FILE", fileQsp(b), null),
314
218
  type: "CHANGES_WITH",
315
219
  resolution: 0,
316
- // Clamped to the R0 ceiling by the Normaliser. Passing the raw ratio
317
- // and letting it clamp is deliberate — the clamp is recorded, so the
318
- // graph shows that history was capped rather than that it was weak.
220
+ // Raw ratio passed through; the Normaliser's R0 clamp is recorded,
221
+ // showing history was capped rather than weak.
319
222
  confidence,
320
223
  producedBy: PRODUCED_BY,
321
224
  attrs: {
@@ -339,9 +242,8 @@ export function createGitSource(options) {
339
242
  attrs: { commitSha: fix.sha, refusalClass: "capability-gap" },
340
243
  });
341
244
  }
342
- // One INCIDENT_CORRELATED edge set per incident, not per fix: two commits
343
- // closing one issue would otherwise write the same file edge twice, and
344
- // the second write says nothing the first did not.
245
+ // Per incident, not per fix — two commits closing one issue would
246
+ // otherwise write the same file edge twice.
345
247
  const correlated = new Set();
346
248
  for (const found of incidents) {
347
249
  const incidentId = incidentIdOf(found);
@@ -391,9 +293,7 @@ export function createGitSource(options) {
391
293
  });
392
294
  }
393
295
  }
394
- // Deterministic ordering. Two runs over the same history must produce a
395
- // byte-identical batch, or the store's content hash moves for no reason
396
- // and the Step 6 determinism proof stops meaning anything.
296
+ // Deterministic ordering — two runs must produce a byte-identical batch.
397
297
  nodes.sort((a, b) => a.id.localeCompare(b.id));
398
298
  edges.sort((a, b) => edgeId(a.from, a.to, a.type).localeCompare(edgeId(b.from, b.to, b.type)));
399
299
  unresolved.sort((a, b) => `${a.fromNodeId}${a.rawTarget}`.localeCompare(`${b.fromNodeId}${b.rawTarget}`));