@descryy/core 0.3.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (362) hide show
  1. package/dist/budget/reply.d.ts +11 -46
  2. package/dist/budget/reply.d.ts.map +1 -1
  3. package/dist/budget/reply.js +10 -39
  4. package/dist/budget/reply.js.map +1 -1
  5. package/dist/budget/size.d.ts +2 -21
  6. package/dist/budget/size.d.ts.map +1 -1
  7. package/dist/budget/size.js +3 -24
  8. package/dist/budget/size.js.map +1 -1
  9. package/dist/capabilities/preconditions.d.ts +7 -68
  10. package/dist/capabilities/preconditions.d.ts.map +1 -1
  11. package/dist/capabilities/preconditions.js +6 -57
  12. package/dist/capabilities/preconditions.js.map +1 -1
  13. package/dist/contracts/engine.d.ts +26 -12
  14. package/dist/contracts/engine.d.ts.map +1 -1
  15. package/dist/contracts/engine.js +28 -11
  16. package/dist/contracts/engine.js.map +1 -1
  17. package/dist/contracts/index.d.ts +1 -1
  18. package/dist/contracts/index.d.ts.map +1 -1
  19. package/dist/contracts/index.js.map +1 -1
  20. package/dist/contracts/orphans.d.ts +28 -77
  21. package/dist/contracts/orphans.d.ts.map +1 -1
  22. package/dist/contracts/orphans.js +124 -94
  23. package/dist/contracts/orphans.js.map +1 -1
  24. package/dist/contracts/paths.d.ts +4 -114
  25. package/dist/contracts/paths.d.ts.map +1 -1
  26. package/dist/contracts/paths.js +7 -140
  27. package/dist/contracts/paths.js.map +1 -1
  28. package/dist/contracts/shapes.d.ts +13 -66
  29. package/dist/contracts/shapes.d.ts.map +1 -1
  30. package/dist/contracts/shapes.js +20 -91
  31. package/dist/contracts/shapes.js.map +1 -1
  32. package/dist/governance/budget.d.ts +12 -48
  33. package/dist/governance/budget.d.ts.map +1 -1
  34. package/dist/governance/budget.js +12 -48
  35. package/dist/governance/budget.js.map +1 -1
  36. package/dist/governance/candidate-boundary.d.ts +4 -32
  37. package/dist/governance/candidate-boundary.d.ts.map +1 -1
  38. package/dist/governance/candidate-boundary.js +4 -32
  39. package/dist/governance/candidate-boundary.js.map +1 -1
  40. package/dist/governance/escalation.d.ts +7 -45
  41. package/dist/governance/escalation.d.ts.map +1 -1
  42. package/dist/governance/escalation.js +7 -45
  43. package/dist/governance/escalation.js.map +1 -1
  44. package/dist/governance/fact-boundary.d.ts +7 -49
  45. package/dist/governance/fact-boundary.d.ts.map +1 -1
  46. package/dist/governance/fact-boundary.js +5 -43
  47. package/dist/governance/fact-boundary.js.map +1 -1
  48. package/dist/governance/finding-funnel.d.ts +11 -72
  49. package/dist/governance/finding-funnel.d.ts.map +1 -1
  50. package/dist/governance/finding-funnel.js +9 -68
  51. package/dist/governance/finding-funnel.js.map +1 -1
  52. package/dist/graph/build.d.ts +13 -75
  53. package/dist/graph/build.d.ts.map +1 -1
  54. package/dist/graph/build.js +0 -0
  55. package/dist/graph/build.js.map +1 -1
  56. package/dist/graph/cross-language.d.ts +4 -43
  57. package/dist/graph/cross-language.d.ts.map +1 -1
  58. package/dist/graph/cross-language.js +9 -77
  59. package/dist/graph/cross-language.js.map +1 -1
  60. package/dist/graph/index.d.ts +1 -1
  61. package/dist/graph/index.d.ts.map +1 -1
  62. package/dist/graph/merge.d.ts +8 -76
  63. package/dist/graph/merge.d.ts.map +1 -1
  64. package/dist/graph/merge.js +27 -77
  65. package/dist/graph/merge.js.map +1 -1
  66. package/dist/graph/observed-tests.d.ts +7 -68
  67. package/dist/graph/observed-tests.d.ts.map +1 -1
  68. package/dist/graph/observed-tests.js +5 -60
  69. package/dist/graph/observed-tests.js.map +1 -1
  70. package/dist/graph/persist.d.ts +2 -25
  71. package/dist/graph/persist.d.ts.map +1 -1
  72. package/dist/graph/persist.js +2 -25
  73. package/dist/graph/persist.js.map +1 -1
  74. package/dist/graph/runtime-confirmation.d.ts +14 -91
  75. package/dist/graph/runtime-confirmation.d.ts.map +1 -1
  76. package/dist/graph/runtime-confirmation.js +19 -103
  77. package/dist/graph/runtime-confirmation.js.map +1 -1
  78. package/dist/ledger/mint.d.ts +9 -43
  79. package/dist/ledger/mint.d.ts.map +1 -1
  80. package/dist/ledger/mint.js +15 -65
  81. package/dist/ledger/mint.js.map +1 -1
  82. package/dist/ledger/resolve.d.ts +13 -81
  83. package/dist/ledger/resolve.d.ts.map +1 -1
  84. package/dist/ledger/resolve.js +13 -76
  85. package/dist/ledger/resolve.js.map +1 -1
  86. package/dist/multipr/fingerprint.d.ts +5 -46
  87. package/dist/multipr/fingerprint.d.ts.map +1 -1
  88. package/dist/multipr/fingerprint.js +22 -74
  89. package/dist/multipr/fingerprint.js.map +1 -1
  90. package/dist/multipr/hidden-dependency.d.ts +13 -73
  91. package/dist/multipr/hidden-dependency.d.ts.map +1 -1
  92. package/dist/multipr/hidden-dependency.js +12 -63
  93. package/dist/multipr/hidden-dependency.js.map +1 -1
  94. package/dist/multipr/mechanical.d.ts +25 -160
  95. package/dist/multipr/mechanical.d.ts.map +1 -1
  96. package/dist/multipr/mechanical.js +21 -137
  97. package/dist/multipr/mechanical.js.map +1 -1
  98. package/dist/multipr/migration-heads.d.ts +18 -105
  99. package/dist/multipr/migration-heads.d.ts.map +1 -1
  100. package/dist/multipr/migration-heads.js +15 -84
  101. package/dist/multipr/migration-heads.js.map +1 -1
  102. package/dist/multipr/overlap.d.ts +16 -94
  103. package/dist/multipr/overlap.d.ts.map +1 -1
  104. package/dist/multipr/overlap.js +25 -105
  105. package/dist/multipr/overlap.js.map +1 -1
  106. package/dist/multipr/scope-store.d.ts +15 -80
  107. package/dist/multipr/scope-store.d.ts.map +1 -1
  108. package/dist/multipr/scope-store.js +17 -87
  109. package/dist/multipr/scope-store.js.map +1 -1
  110. package/dist/multipr/superseded.d.ts +10 -95
  111. package/dist/multipr/superseded.d.ts.map +1 -1
  112. package/dist/multipr/superseded.js +7 -60
  113. package/dist/multipr/superseded.js.map +1 -1
  114. package/dist/query/confirmed-facts.d.ts +12 -58
  115. package/dist/query/confirmed-facts.d.ts.map +1 -1
  116. package/dist/query/confirmed-facts.js +8 -47
  117. package/dist/query/confirmed-facts.js.map +1 -1
  118. package/dist/query/declared-value-closure.d.ts +13 -104
  119. package/dist/query/declared-value-closure.d.ts.map +1 -1
  120. package/dist/query/declared-value-closure.js +15 -104
  121. package/dist/query/declared-value-closure.js.map +1 -1
  122. package/dist/query/memory.d.ts +5 -9
  123. package/dist/query/memory.d.ts.map +1 -1
  124. package/dist/query/memory.js +31 -15
  125. package/dist/query/memory.js.map +1 -1
  126. package/dist/query/prominence.d.ts +6 -55
  127. package/dist/query/prominence.d.ts.map +1 -1
  128. package/dist/query/prominence.js +6 -55
  129. package/dist/query/prominence.js.map +1 -1
  130. package/dist/query/provider.d.ts +28 -81
  131. package/dist/query/provider.d.ts.map +1 -1
  132. package/dist/query/provider.js +8 -29
  133. package/dist/query/provider.js.map +1 -1
  134. package/dist/query/queries.d.ts +15 -65
  135. package/dist/query/queries.d.ts.map +1 -1
  136. package/dist/query/queries.js +43 -100
  137. package/dist/query/queries.js.map +1 -1
  138. package/dist/query/refusal-fetch.d.ts +8 -85
  139. package/dist/query/refusal-fetch.d.ts.map +1 -1
  140. package/dist/query/refusal-fetch.js +11 -93
  141. package/dist/query/refusal-fetch.js.map +1 -1
  142. package/dist/query/refusal-questions.d.ts +17 -92
  143. package/dist/query/refusal-questions.d.ts.map +1 -1
  144. package/dist/query/refusal-questions.js +14 -78
  145. package/dist/query/refusal-questions.js.map +1 -1
  146. package/dist/query/resolution-floor.d.ts +3 -23
  147. package/dist/query/resolution-floor.d.ts.map +1 -1
  148. package/dist/query/resolution-floor.js +3 -23
  149. package/dist/query/resolution-floor.js.map +1 -1
  150. package/dist/query/root-cause-score.d.ts +11 -161
  151. package/dist/query/root-cause-score.d.ts.map +1 -1
  152. package/dist/query/root-cause-score.js +6 -137
  153. package/dist/query/root-cause-score.js.map +1 -1
  154. package/dist/query/row-closure-picture.d.ts +5 -67
  155. package/dist/query/row-closure-picture.d.ts.map +1 -1
  156. package/dist/query/row-closure-picture.js +6 -67
  157. package/dist/query/row-closure-picture.js.map +1 -1
  158. package/dist/query/similar-incidents.d.ts +6 -41
  159. package/dist/query/similar-incidents.d.ts.map +1 -1
  160. package/dist/query/similar-incidents.js +15 -69
  161. package/dist/query/similar-incidents.js.map +1 -1
  162. package/dist/query/sqlite.d.ts +3 -7
  163. package/dist/query/sqlite.d.ts.map +1 -1
  164. package/dist/query/sqlite.js +13 -16
  165. package/dist/query/sqlite.js.map +1 -1
  166. package/dist/query/test-coverage.d.ts +5 -45
  167. package/dist/query/test-coverage.d.ts.map +1 -1
  168. package/dist/query/test-coverage.js +10 -53
  169. package/dist/query/test-coverage.js.map +1 -1
  170. package/dist/query/traverse.d.ts +22 -126
  171. package/dist/query/traverse.d.ts.map +1 -1
  172. package/dist/query/traverse.js +0 -0
  173. package/dist/query/traverse.js.map +1 -1
  174. package/dist/query/unresolved.d.ts +19 -164
  175. package/dist/query/unresolved.d.ts.map +1 -1
  176. package/dist/query/unresolved.js +11 -138
  177. package/dist/query/unresolved.js.map +1 -1
  178. package/dist/query/verification-status.d.ts +12 -109
  179. package/dist/query/verification-status.d.ts.map +1 -1
  180. package/dist/query/verification-status.js +9 -99
  181. package/dist/query/verification-status.js.map +1 -1
  182. package/dist/recording/migrate.d.ts +4 -10
  183. package/dist/recording/migrate.d.ts.map +1 -1
  184. package/dist/recording/migrate.js +4 -10
  185. package/dist/recording/migrate.js.map +1 -1
  186. package/dist/recording/reader.d.ts +2 -7
  187. package/dist/recording/reader.d.ts.map +1 -1
  188. package/dist/recording/reader.js +2 -7
  189. package/dist/recording/reader.js.map +1 -1
  190. package/dist/recording/redact.d.ts +6 -57
  191. package/dist/recording/redact.d.ts.map +1 -1
  192. package/dist/recording/redact.js +8 -64
  193. package/dist/recording/redact.js.map +1 -1
  194. package/dist/recording/schema.d.ts +3 -38
  195. package/dist/recording/schema.d.ts.map +1 -1
  196. package/dist/recording/schema.js +3 -38
  197. package/dist/recording/schema.js.map +1 -1
  198. package/dist/recording/writer.d.ts +11 -74
  199. package/dist/recording/writer.d.ts.map +1 -1
  200. package/dist/recording/writer.js +3 -43
  201. package/dist/recording/writer.js.map +1 -1
  202. package/dist/scoping/fanout.d.ts +6 -68
  203. package/dist/scoping/fanout.d.ts.map +1 -1
  204. package/dist/scoping/fanout.js +6 -68
  205. package/dist/scoping/fanout.js.map +1 -1
  206. package/dist/scoping/score.d.ts +20 -70
  207. package/dist/scoping/score.d.ts.map +1 -1
  208. package/dist/scoping/score.js +20 -70
  209. package/dist/scoping/score.js.map +1 -1
  210. package/dist/scoping/tiers.d.ts +4 -16
  211. package/dist/scoping/tiers.d.ts.map +1 -1
  212. package/dist/scoping/tiers.js +4 -16
  213. package/dist/scoping/tiers.js.map +1 -1
  214. package/dist/scoping/traverse.d.ts +3 -25
  215. package/dist/scoping/traverse.d.ts.map +1 -1
  216. package/dist/scoping/traverse.js +14 -49
  217. package/dist/scoping/traverse.js.map +1 -1
  218. package/dist/scoping/weights.d.ts +10 -74
  219. package/dist/scoping/weights.d.ts.map +1 -1
  220. package/dist/scoping/weights.js +14 -86
  221. package/dist/scoping/weights.js.map +1 -1
  222. package/dist/sources/confirmed/incidents.d.ts +5 -35
  223. package/dist/sources/confirmed/incidents.d.ts.map +1 -1
  224. package/dist/sources/confirmed/incidents.js +14 -48
  225. package/dist/sources/confirmed/incidents.js.map +1 -1
  226. package/dist/sources/git/diff.d.ts +71 -65
  227. package/dist/sources/git/diff.d.ts.map +1 -1
  228. package/dist/sources/git/diff.js +136 -83
  229. package/dist/sources/git/diff.js.map +1 -1
  230. package/dist/sources/git/env.d.ts +7 -0
  231. package/dist/sources/git/env.d.ts.map +1 -1
  232. package/dist/sources/git/env.js +10 -11
  233. package/dist/sources/git/env.js.map +1 -1
  234. package/dist/sources/git/history.d.ts +64 -84
  235. package/dist/sources/git/history.d.ts.map +1 -1
  236. package/dist/sources/git/history.js +141 -112
  237. package/dist/sources/git/history.js.map +1 -1
  238. package/dist/sources/git/incidents.d.ts +13 -75
  239. package/dist/sources/git/incidents.d.ts.map +1 -1
  240. package/dist/sources/git/incidents.js +21 -91
  241. package/dist/sources/git/incidents.js.map +1 -1
  242. package/dist/sources/git/index.d.ts +5 -3
  243. package/dist/sources/git/index.d.ts.map +1 -1
  244. package/dist/sources/git/index.js +3 -2
  245. package/dist/sources/git/index.js.map +1 -1
  246. package/dist/sources/git/source.d.ts +9 -79
  247. package/dist/sources/git/source.d.ts.map +1 -1
  248. package/dist/sources/git/source.js +0 -0
  249. package/dist/sources/git/source.js.map +1 -1
  250. package/dist/sources/migrations/across-change.d.ts +94 -0
  251. package/dist/sources/migrations/across-change.d.ts.map +1 -0
  252. package/dist/sources/migrations/across-change.js +278 -0
  253. package/dist/sources/migrations/across-change.js.map +1 -0
  254. package/dist/sources/migrations/dialects.d.ts +20 -36
  255. package/dist/sources/migrations/dialects.d.ts.map +1 -1
  256. package/dist/sources/migrations/dialects.js +11 -36
  257. package/dist/sources/migrations/dialects.js.map +1 -1
  258. package/dist/sources/migrations/index.d.ts +3 -1
  259. package/dist/sources/migrations/index.d.ts.map +1 -1
  260. package/dist/sources/migrations/index.js +2 -1
  261. package/dist/sources/migrations/index.js.map +1 -1
  262. package/dist/sources/migrations/read.d.ts +14 -79
  263. package/dist/sources/migrations/read.d.ts.map +1 -1
  264. package/dist/sources/migrations/read.js +14 -89
  265. package/dist/sources/migrations/read.js.map +1 -1
  266. package/dist/sources/workspace/workspace.d.ts +6 -42
  267. package/dist/sources/workspace/workspace.d.ts.map +1 -1
  268. package/dist/sources/workspace/workspace.js +10 -53
  269. package/dist/sources/workspace/workspace.js.map +1 -1
  270. package/dist/store/driver/driver.d.ts +9 -38
  271. package/dist/store/driver/driver.d.ts.map +1 -1
  272. package/dist/store/driver/driver.js +4 -22
  273. package/dist/store/driver/driver.js.map +1 -1
  274. package/dist/store/driver/node-sqlite.d.ts +3 -12
  275. package/dist/store/driver/node-sqlite.d.ts.map +1 -1
  276. package/dist/store/driver/node-sqlite.js +4 -18
  277. package/dist/store/driver/node-sqlite.js.map +1 -1
  278. package/dist/store/index.d.ts +2 -7
  279. package/dist/store/index.d.ts.map +1 -1
  280. package/dist/store/index.js +4 -10
  281. package/dist/store/index.js.map +1 -1
  282. package/dist/store/migrate.d.ts +14 -50
  283. package/dist/store/migrate.d.ts.map +1 -1
  284. package/dist/store/migrate.js +15 -52
  285. package/dist/store/migrate.js.map +1 -1
  286. package/dist/store/reader.d.ts +19 -84
  287. package/dist/store/reader.d.ts.map +1 -1
  288. package/dist/store/reader.js +25 -92
  289. package/dist/store/reader.js.map +1 -1
  290. package/dist/store/schema.d.ts +14 -76
  291. package/dist/store/schema.d.ts.map +1 -1
  292. package/dist/store/schema.js +14 -76
  293. package/dist/store/schema.js.map +1 -1
  294. package/dist/store/writer.d.ts +14 -88
  295. package/dist/store/writer.d.ts.map +1 -1
  296. package/dist/store/writer.js +29 -123
  297. package/dist/store/writer.js.map +1 -1
  298. package/dist/tiers/certify.d.ts +46 -281
  299. package/dist/tiers/certify.d.ts.map +1 -1
  300. package/dist/tiers/certify.js +46 -226
  301. package/dist/tiers/certify.js.map +1 -1
  302. package/dist/tiers/ladder.d.ts +7 -51
  303. package/dist/tiers/ladder.d.ts.map +1 -1
  304. package/dist/tiers/ladder.js +13 -89
  305. package/dist/tiers/ladder.js.map +1 -1
  306. package/dist/validation/attributes.d.ts +47 -0
  307. package/dist/validation/attributes.d.ts.map +1 -0
  308. package/dist/validation/attributes.js +130 -0
  309. package/dist/validation/attributes.js.map +1 -0
  310. package/dist/validation/config-graph.d.ts +7 -56
  311. package/dist/validation/config-graph.d.ts.map +1 -1
  312. package/dist/validation/config-graph.js +15 -61
  313. package/dist/validation/config-graph.js.map +1 -1
  314. package/dist/validation/env.d.ts +53 -2
  315. package/dist/validation/env.d.ts.map +1 -1
  316. package/dist/validation/env.js +99 -4
  317. package/dist/validation/env.js.map +1 -1
  318. package/dist/validation/index.d.ts +5 -1
  319. package/dist/validation/index.d.ts.map +1 -1
  320. package/dist/validation/index.js +3 -1
  321. package/dist/validation/index.js.map +1 -1
  322. package/dist/validation/join-substitution.d.ts +22 -120
  323. package/dist/validation/join-substitution.d.ts.map +1 -1
  324. package/dist/validation/join-substitution.js +13 -90
  325. package/dist/validation/join-substitution.js.map +1 -1
  326. package/dist/validation/migration-integrity.d.ts +72 -0
  327. package/dist/validation/migration-integrity.d.ts.map +1 -0
  328. package/dist/validation/migration-integrity.js +238 -0
  329. package/dist/validation/migration-integrity.js.map +1 -0
  330. package/dist/validation/migrations.d.ts +23 -88
  331. package/dist/validation/migrations.d.ts.map +1 -1
  332. package/dist/validation/migrations.js +20 -79
  333. package/dist/validation/migrations.js.map +1 -1
  334. package/dist/validation/nodes.d.ts +3 -1
  335. package/dist/validation/nodes.d.ts.map +1 -1
  336. package/dist/validation/nodes.js +3 -1
  337. package/dist/validation/nodes.js.map +1 -1
  338. package/dist/validation/rollback.d.ts +10 -73
  339. package/dist/validation/rollback.d.ts.map +1 -1
  340. package/dist/validation/rollback.js +23 -81
  341. package/dist/validation/rollback.js.map +1 -1
  342. package/dist/validation/route-drift.d.ts +9 -62
  343. package/dist/validation/route-drift.d.ts.map +1 -1
  344. package/dist/validation/route-drift.js +7 -52
  345. package/dist/validation/route-drift.js.map +1 -1
  346. package/dist/validation/sources.d.ts +16 -94
  347. package/dist/validation/sources.d.ts.map +1 -1
  348. package/dist/validation/sources.js +51 -147
  349. package/dist/validation/sources.js.map +1 -1
  350. package/dist/worker/pool.d.ts +6 -45
  351. package/dist/worker/pool.d.ts.map +1 -1
  352. package/dist/worker/pool.js +5 -42
  353. package/dist/worker/pool.js.map +1 -1
  354. package/dist/worker/protocol.d.ts +7 -20
  355. package/dist/worker/protocol.d.ts.map +1 -1
  356. package/dist/worker/protocol.js +3 -10
  357. package/dist/worker/protocol.js.map +1 -1
  358. package/dist/worker/traversal.worker.d.ts +2 -21
  359. package/dist/worker/traversal.worker.d.ts.map +1 -1
  360. package/dist/worker/traversal.worker.js +4 -23
  361. package/dist/worker/traversal.worker.js.map +1 -1
  362. package/package.json +11 -2
@@ -1,41 +1,7 @@
1
1
  /**
2
- * The merge policy — DEC-012.
3
- *
4
- * Two adapters finding the same relationship produce the same edge id, by
5
- * construction: `hash(from, to, type)` deliberately excludes resolution,
6
- * confidence and producer. On the prior-art graphs measured for this build, 30%
7
- * of edges were exact duplicates, so this is the common path rather than an
8
- * edge case.
9
- *
10
- * ## The rule
11
- *
12
- * higher `resolution` wins
13
- * → tie: higher `confidence` wins
14
- * → tie: lexicographically smaller `producedBy` wins
15
- *
16
- * ## What the rule refuses to do
17
- *
18
- * **Confidence is never combined.** Two adapters each 0.8 confident does not
19
- * make 0.96, or 0.8, or anything else — there is no evidence-combination model
20
- * here, the two adapters are not independent observers, and inventing a formula
21
- * would silently move every impact score in §12.4 with nothing in the output to
22
- * show it happened. Corroboration is recorded as a fact (`attrs.corroboratedBy`)
23
- * rather than folded into a number.
24
- *
25
- * The third tie-break exists only to make the result independent of the order
26
- * batches arrive in. Lexicographic order is arbitrary; determinism is not.
27
- *
28
- * ## Why the rule is written twice
29
- *
30
- * The merge has to hold in two places: in memory, when the Graph Builder folds
31
- * several batches together, and in SQL, when a later batch upserts onto an edge
32
- * an earlier one already wrote. A rule enforced in only the first is not
33
- * enforced at all, because the writer is reachable directly.
34
- *
35
- * So it appears as a TypeScript predicate and as a SQL `WHERE` fragment, side by
36
- * side, with a differential test that runs the same case table through both.
37
- * Two copies with a test that they agree beats one copy that only covers one of
38
- * the two paths.
2
+ * Merge policy (DEC-012): higher `resolution` wins, then `confidence`, then smaller `producedBy`.
3
+ * Confidence is never combined — recorded as `attrs.corroboratedBy` instead of folded into a number.
4
+ * Enforced twice, TypeScript predicate + SQL `WHERE` fragment, with a differential test proving they agree.
39
5
  */
40
6
  import type { IREdge, IRNode } from "@descryy/ir";
41
7
  /** The fields the merge decides between. Both the graph and a stored row satisfy it. */
@@ -44,52 +10,18 @@ export interface Mergeable {
44
10
  readonly confidence: number;
45
11
  readonly producedBy: string;
46
12
  }
47
- /**
48
- * Should `incoming` replace `existing`?
49
- *
50
- * Strict: an exact tie on all three keeps what is already there, so re-ingesting
51
- * the same batch is a no-op rather than a rewrite.
52
- */
13
+ /** Should `incoming` replace `existing`? Strict: an exact tie keeps what's there — re-ingest is a no-op. */
53
14
  export declare function preferIncoming(incoming: Mergeable, existing: Mergeable): boolean;
54
- /**
55
- * The same rule as a SQL `WHERE` clause on an upsert's `DO UPDATE`.
56
- *
57
- * `excluded` is the incoming row, `edges` the one already stored — SQLite's
58
- * upsert names them that way. Kept adjacent to `preferIncoming` on purpose:
59
- * `merge.test.ts` runs one case table through both and fails if they disagree.
60
- */
15
+ /** Same rule as SQL `WHERE` on an upsert. `excluded` = incoming, `edges` = stored; `merge.test.ts` checks both agree. */
61
16
  export declare const EDGE_MERGE_CONDITION = "\n excluded.resolution > edges.resolution\n OR (excluded.resolution = edges.resolution AND excluded.confidence > edges.confidence)\n OR (excluded.resolution = edges.resolution\n AND excluded.confidence = edges.confidence\n AND excluded.produced_by < edges.produced_by)\n";
62
17
  /** The same, for nodes. Nodes carry no confidence, so the middle key drops out. */
63
18
  export declare const NODE_MERGE_CONDITION = "\n excluded.resolution > nodes.resolution\n OR (excluded.resolution = nodes.resolution AND excluded.produced_by < nodes.produced_by)\n";
64
- /**
65
- * Producers that corroborated a merged item, sorted and de-duplicated.
66
- *
67
- * DEC-012 records this instead of combining confidence. It is not decoration:
68
- * "two independent adapters agree" is a materially different statement from "one
69
- * adapter is fairly sure", and it is the only form in which the graph can carry
70
- * that distinction without inventing an evidence model.
71
- */
19
+ /** Producers that corroborated a merged item, sorted/deduped. DEC-012 records this instead of combining confidence. */
72
20
  export declare function corroborators(existing: Readonly<Record<string, unknown>> | undefined, ...producers: string[]): string[];
73
21
  /** Merge two edges that share an id. Returns the winner, carrying corroboration. */
74
22
  export declare function mergeEdge(incoming: IREdge, existing: IREdge): IREdge;
75
- /**
76
- * Merge two nodes that share an id.
77
- *
78
- * Attributes are NOT unioned. `attrs` is language- and framework-specific detail
79
- * (§11A.4), so pooling two adapters' attributes would produce a node describing
80
- * a thing that does not exist. The winner's attrs are kept whole and the loser is
81
- * recorded as a corroborator.
82
- */
23
+ /** Merge two nodes sharing an id. Unions non-conflicting attrs; on conflict keeps the winner's value and records the key in `attrs.disputedAttrs`. Supersedes DEC-012's all-or-nothing rule. */
83
24
  export declare function mergeNode(incoming: IRNode, existing: IRNode): IRNode;
84
- /**
85
- * The fields two nodes sharing an id must agree on.
86
- *
87
- * Compared as one opaque string rather than field by field. That is not only
88
- * tidier: `n.language !== m.language` reads to the boundary lint as branching on
89
- * a language, and the lint is right to be suspicious — the exception here is
90
- * that this asks whether two nodes *disagree*, never which language either one
91
- * is. Folding both fields into a fingerprint states that intent in the code
92
- * rather than in a lint suppression.
93
- */
25
+ /** Fields two nodes sharing an id must agree on. Compared as one opaque string — field-by-field would read as branching on language to the boundary lint. */
94
26
  export declare function identityFingerprint(node: IRNode): string;
95
27
  //# sourceMappingURL=merge.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"merge.d.ts","sourceRoot":"","sources":["../../src/graph/merge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAElD,wFAAwF;AACxF,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,GAAG,OAAO,CAQhF;AAED;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,gSAMhC,CAAC;AAEF,mFAAmF;AACnF,eAAO,MAAM,oBAAoB,6IAGhC,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,SAAS,EACvD,GAAG,SAAS,EAAE,MAAM,EAAE,GACrB,MAAM,EAAE,CAKV;AAED,oFAAoF;AACpF,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAWpE;AAED;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAcpE;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAExD"}
1
+ {"version":3,"file":"merge.d.ts","sourceRoot":"","sources":["../../src/graph/merge.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAElD,wFAAwF;AACxF,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED,4GAA4G;AAC5G,wBAAgB,cAAc,CAAC,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,GAAG,OAAO,CAQhF;AAED,yHAAyH;AACzH,eAAO,MAAM,oBAAoB,gSAMhC,CAAC;AAEF,mFAAmF;AACnF,eAAO,MAAM,oBAAoB,6IAGhC,CAAC;AAEF,uHAAuH;AACvH,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,SAAS,EACvD,GAAG,SAAS,EAAE,MAAM,EAAE,GACrB,MAAM,EAAE,CAKV;AAED,oFAAoF;AACpF,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAWpE;AAKD,gMAAgM;AAChM,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAkCpE;AAED,6JAA6J;AAC7J,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAExD"}
@@ -1,48 +1,9 @@
1
1
  /**
2
- * The merge policy — DEC-012.
3
- *
4
- * Two adapters finding the same relationship produce the same edge id, by
5
- * construction: `hash(from, to, type)` deliberately excludes resolution,
6
- * confidence and producer. On the prior-art graphs measured for this build, 30%
7
- * of edges were exact duplicates, so this is the common path rather than an
8
- * edge case.
9
- *
10
- * ## The rule
11
- *
12
- * higher `resolution` wins
13
- * → tie: higher `confidence` wins
14
- * → tie: lexicographically smaller `producedBy` wins
15
- *
16
- * ## What the rule refuses to do
17
- *
18
- * **Confidence is never combined.** Two adapters each 0.8 confident does not
19
- * make 0.96, or 0.8, or anything else — there is no evidence-combination model
20
- * here, the two adapters are not independent observers, and inventing a formula
21
- * would silently move every impact score in §12.4 with nothing in the output to
22
- * show it happened. Corroboration is recorded as a fact (`attrs.corroboratedBy`)
23
- * rather than folded into a number.
24
- *
25
- * The third tie-break exists only to make the result independent of the order
26
- * batches arrive in. Lexicographic order is arbitrary; determinism is not.
27
- *
28
- * ## Why the rule is written twice
29
- *
30
- * The merge has to hold in two places: in memory, when the Graph Builder folds
31
- * several batches together, and in SQL, when a later batch upserts onto an edge
32
- * an earlier one already wrote. A rule enforced in only the first is not
33
- * enforced at all, because the writer is reachable directly.
34
- *
35
- * So it appears as a TypeScript predicate and as a SQL `WHERE` fragment, side by
36
- * side, with a differential test that runs the same case table through both.
37
- * Two copies with a test that they agree beats one copy that only covers one of
38
- * the two paths.
39
- */
40
- /**
41
- * Should `incoming` replace `existing`?
42
- *
43
- * Strict: an exact tie on all three keeps what is already there, so re-ingesting
44
- * the same batch is a no-op rather than a rewrite.
2
+ * Merge policy (DEC-012): higher `resolution` wins, then `confidence`, then smaller `producedBy`.
3
+ * Confidence is never combined — recorded as `attrs.corroboratedBy` instead of folded into a number.
4
+ * Enforced twice, TypeScript predicate + SQL `WHERE` fragment, with a differential test proving they agree.
45
5
  */
6
+ /** Should `incoming` replace `existing`? Strict: an exact tie keeps what's there — re-ingest is a no-op. */
46
7
  export function preferIncoming(incoming, existing) {
47
8
  if (incoming.resolution !== existing.resolution) {
48
9
  return incoming.resolution > existing.resolution;
@@ -52,13 +13,7 @@ export function preferIncoming(incoming, existing) {
52
13
  }
53
14
  return incoming.producedBy < existing.producedBy;
54
15
  }
55
- /**
56
- * The same rule as a SQL `WHERE` clause on an upsert's `DO UPDATE`.
57
- *
58
- * `excluded` is the incoming row, `edges` the one already stored — SQLite's
59
- * upsert names them that way. Kept adjacent to `preferIncoming` on purpose:
60
- * `merge.test.ts` runs one case table through both and fails if they disagree.
61
- */
16
+ /** Same rule as SQL `WHERE` on an upsert. `excluded` = incoming, `edges` = stored; `merge.test.ts` checks both agree. */
62
17
  export const EDGE_MERGE_CONDITION = `
63
18
  excluded.resolution > edges.resolution
64
19
  OR (excluded.resolution = edges.resolution AND excluded.confidence > edges.confidence)
@@ -71,14 +26,7 @@ export const NODE_MERGE_CONDITION = `
71
26
  excluded.resolution > nodes.resolution
72
27
  OR (excluded.resolution = nodes.resolution AND excluded.produced_by < nodes.produced_by)
73
28
  `;
74
- /**
75
- * Producers that corroborated a merged item, sorted and de-duplicated.
76
- *
77
- * DEC-012 records this instead of combining confidence. It is not decoration:
78
- * "two independent adapters agree" is a materially different statement from "one
79
- * adapter is fairly sure", and it is the only form in which the graph can carry
80
- * that distinction without inventing an evidence model.
81
- */
29
+ /** Producers that corroborated a merged item, sorted/deduped. DEC-012 records this instead of combining confidence. */
82
30
  export function corroborators(existing, ...producers) {
83
31
  const prior = existing?.["corroboratedBy"];
84
32
  const all = new Set(Array.isArray(prior) ? prior : []);
@@ -95,36 +43,38 @@ export function mergeEdge(incoming, existing) {
95
43
  attrs: { ...(winner.attrs ?? {}), corroboratedBy },
96
44
  };
97
45
  }
98
- /**
99
- * Merge two nodes that share an id.
100
- *
101
- * Attributes are NOT unioned. `attrs` is language- and framework-specific detail
102
- * (§11A.4), so pooling two adapters' attributes would produce a node describing
103
- * a thing that does not exist. The winner's attrs are kept whole and the loser is
104
- * recorded as a corroborator.
105
- */
46
+ /** Bookkeeping keys `mergeNode` itself writes — never unioned/disputed as ordinary data, always recomputed. */
47
+ const MERGE_BOOKKEEPING_KEYS = new Set(["corroboratedBy", "disputedAttrs"]);
48
+ /** Merge two nodes sharing an id. Unions non-conflicting attrs; on conflict keeps the winner's value and records the key in `attrs.disputedAttrs`. Supersedes DEC-012's all-or-nothing rule. */
106
49
  export function mergeNode(incoming, existing) {
107
50
  const winner = preferIncoming({ ...incoming, confidence: 0 }, { ...existing, confidence: 0 })
108
51
  ? incoming
109
52
  : existing;
53
+ const loser = winner === incoming ? existing : incoming;
54
+ const winnerAttrs = winner.attrs ?? {};
55
+ const loserAttrs = loser.attrs ?? {};
56
+ const merged = { ...winnerAttrs };
57
+ const disputed = new Set(Array.isArray(winnerAttrs["disputedAttrs"]) ? winnerAttrs["disputedAttrs"] : []);
58
+ for (const key of Object.keys(loserAttrs)) {
59
+ if (MERGE_BOOKKEEPING_KEYS.has(key))
60
+ continue;
61
+ if (!(key in winnerAttrs)) {
62
+ merged[key] = loserAttrs[key];
63
+ }
64
+ else if (JSON.stringify(winnerAttrs[key]) !== JSON.stringify(loserAttrs[key])) {
65
+ disputed.add(key);
66
+ }
67
+ }
110
68
  return {
111
69
  ...winner,
112
70
  attrs: {
113
- ...winner.attrs,
71
+ ...merged,
114
72
  corroboratedBy: corroborators(existing.attrs, existing.producedBy, incoming.producedBy),
73
+ ...(disputed.size > 0 ? { disputedAttrs: [...disputed].sort() } : {}),
115
74
  },
116
75
  };
117
76
  }
118
- /**
119
- * The fields two nodes sharing an id must agree on.
120
- *
121
- * Compared as one opaque string rather than field by field. That is not only
122
- * tidier: `n.language !== m.language` reads to the boundary lint as branching on
123
- * a language, and the lint is right to be suspicious — the exception here is
124
- * that this asks whether two nodes *disagree*, never which language either one
125
- * is. Folding both fields into a fingerprint states that intent in the code
126
- * rather than in a lint suppression.
127
- */
77
+ /** Fields two nodes sharing an id must agree on. Compared as one opaque string — field-by-field would read as branching on language to the boundary lint. */
128
78
  export function identityFingerprint(node) {
129
79
  return JSON.stringify([node.type, node.language]);
130
80
  }
@@ -1 +1 @@
1
- {"version":3,"file":"merge.js","sourceRoot":"","sources":["../../src/graph/merge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAWH;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,QAAmB,EAAE,QAAmB;IACrE,IAAI,QAAQ,CAAC,UAAU,KAAK,QAAQ,CAAC,UAAU,EAAE,CAAC;QAChD,OAAO,QAAQ,CAAC,UAAU,GAAG,QAAQ,CAAC,UAAU,CAAC;IACnD,CAAC;IACD,IAAI,QAAQ,CAAC,UAAU,KAAK,QAAQ,CAAC,UAAU,EAAE,CAAC;QAChD,OAAO,QAAQ,CAAC,UAAU,GAAG,QAAQ,CAAC,UAAU,CAAC;IACnD,CAAC;IACD,OAAO,QAAQ,CAAC,UAAU,GAAG,QAAQ,CAAC,UAAU,CAAC;AACnD,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG;;;;;;CAMnC,CAAC;AAEF,mFAAmF;AACnF,MAAM,CAAC,MAAM,oBAAoB,GAAG;;;CAGnC,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,UAAU,aAAa,CAC3B,QAAuD,EACvD,GAAG,SAAmB;IAEtB,MAAM,KAAK,GAAG,QAAQ,EAAE,CAAC,gBAAgB,CAAC,CAAC;IAC3C,MAAM,GAAG,GAAG,IAAI,GAAG,CAAS,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAE,KAAkB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAC7E,KAAK,MAAM,CAAC,IAAI,SAAS;QAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACtC,OAAO,CAAC,GAAG,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;AACzB,CAAC;AAED,oFAAoF;AACpF,MAAM,UAAU,SAAS,CAAC,QAAgB,EAAE,QAAgB;IAC1D,MAAM,MAAM,GAAG,cAAc,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC;IACxE,MAAM,cAAc,GAAG,aAAa,CAClC,EAAE,GAAG,QAAQ,CAAC,KAAK,EAAE,GAAG,QAAQ,CAAC,KAAK,EAAE,EACxC,QAAQ,CAAC,UAAU,EACnB,QAAQ,CAAC,UAAU,CACpB,CAAC;IACF,OAAO;QACL,GAAG,MAAM;QACT,KAAK,EAAE,EAAE,GAAG,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC,EAAE,cAAc,EAAE;KACnD,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,SAAS,CAAC,QAAgB,EAAE,QAAgB;IAC1D,MAAM,MAAM,GAAG,cAAc,CAC3B,EAAE,GAAG,QAAQ,EAAE,UAAU,EAAE,CAAC,EAAE,EAC9B,EAAE,GAAG,QAAQ,EAAE,UAAU,EAAE,CAAC,EAAE,CAC/B;QACC,CAAC,CAAC,QAAQ;QACV,CAAC,CAAC,QAAQ,CAAC;IACb,OAAO;QACL,GAAG,MAAM;QACT,KAAK,EAAE;YACL,GAAG,MAAM,CAAC,KAAK;YACf,cAAc,EAAE,aAAa,CAAC,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,UAAU,EAAE,QAAQ,CAAC,UAAU,CAAC;SACxF;KACF,CAAC;AACJ,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAAY;IAC9C,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;AACpD,CAAC"}
1
+ {"version":3,"file":"merge.js","sourceRoot":"","sources":["../../src/graph/merge.ts"],"names":[],"mappings":"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"}
@@ -1,55 +1,7 @@
1
1
  /**
2
- * `observed_tests` — the EARNED record of which tests actually ran.
3
- *
4
- * This is the coverage axis, and coverage is deliberately not confidence: AI
5
- * layer §20 separates *"what I actually verified"* from *"how sure am I"*, and
6
- * the five report categories say nothing about the first. This module is the
7
- * carrier for that separation, ruled in
8
- * `documents/decisions-inbox/DEC-NEXT-test-run-coverage-has-no-carrier.md`.
9
- *
10
- * ## Why this is a table and not an R4 edge promotion
11
- *
12
- * The obvious-looking design is to run the suite and promote each `TESTS` edge
13
- * it exercised to R4, reusing {@link applyRuntimeObservations}. That is not
14
- * available, and the reason is the same one `observe-runtime.ts`'s header
15
- * already gives for refusing to derive edges from correlated evidence.
16
- *
17
- * An edge needs **two endpoints and a witnessed relationship between them**. A
18
- * test-runner's evidence carries no stack — every item it emits has
19
- * `stackTrace: null` — so an observed test names exactly one node, its own
20
- * `TEST_CASE`. Nothing in the run witnesses which function that test reached.
21
- * Pairing the test with a function that merely co-occurred in the same run
22
- * would mint an edge from temporal coincidence, which is precisely the
23
- * wrong-direction failure rule 2 exists to prevent, arriving through the one
24
- * mechanism built to make the graph *more* trustworthy.
25
- *
26
- * So the honest fact a test run establishes is a fact about **one node**: this
27
- * test case executed, and this is what happened. That is not an edge and R4 in
28
- * this store is a property of an edge, so it needs a carrier of its own.
29
- *
30
- * ## Why EARNED
31
- *
32
- * Same argument as `observed_edges`, one step over. Nothing in the source says
33
- * which tests ran — the source says which tests *exist*. A rebuild that dropped
34
- * this table would silently turn "what I actually verified" back into "what
35
- * might be affected", which is the exact collapse the coverage axis exists to
36
- * prevent.
37
- *
38
- * ## What this module refuses to do
39
- *
40
- * - **Invent a node.** An observation naming a node this graph does not hold is
41
- * refused with its reason, never created — rule 2, and the same posture
42
- * {@link applyRuntimeObservations} takes for an edge endpoint.
43
- * - **Accept a category error.** A test outcome against a node that is not a
44
- * `TEST_CASE` is refused rather than written. The graph holds the id, so this
45
- * is not a missing-node refusal; it is a claim that would make every later
46
- * coverage read meaningless, and it is far more likely to be a resolver bug
47
- * than a real observation.
48
- * - **Judge anything.** No finding, no hypothesis, no report category. It
49
- * records what ran; whether that is *enough* is a judgement for a layer above
50
- * this one.
51
- *
52
- * @see `packages/core/src/graph/runtime-confirmation.ts` — the edge half.
2
+ * `observed_tests` — EARNED record of which tests ran (coverage axis, separate from confidence per AI layer §20; DEC-NEXT-test-run-coverage-has-no-carrier).
3
+ * Not an R4 edge promotion: a runner's evidence has no stack trace, so it witnesses only its own TEST_CASE node, never which function it reached — pairing on co-occurrence would mint an edge from coincidence (rule 2).
4
+ * EARNED because source says which tests exist, never which ran. Refuses to invent a node, accept a non-TEST_CASE target, or judge anything.
53
5
  */
54
6
  import type { SqlDriver } from "../store/driver/driver.ts";
55
7
  /** What a runner reported for one test. `skipped` covers `.skip` and `.todo` alike. */
@@ -57,14 +9,8 @@ export type ObservedTestOutcome = "passed" | "failed" | "skipped";
57
9
  export interface ObservedTestObservation {
58
10
  /** The `TEST_CASE` node this test resolved to. Resolution happens above this module. */
59
11
  readonly nodeId: string;
60
- /**
61
- * The runner's own suite-prefixed name, kept verbatim.
62
- *
63
- * Stored even though `nodeId` already identifies the test, because the two
64
- * can disagree later: the node id survives a rename, the recorded name is
65
- * what the run actually printed, and a reader comparing them is how a
66
- * mis-resolution becomes visible instead of silently plausible.
67
- */
12
+ /** Runner's own suite-prefixed name, kept verbatim. Stored alongside nodeId
13
+ * so a later mismatch (rename vs. printed name) becomes visible. */
68
14
  readonly qualifiedName: string;
69
15
  readonly outcome: ObservedTestOutcome;
70
16
  /** Null when the runner did not report one — never defaulted to zero, which would read as "instant". */
@@ -101,15 +47,8 @@ export interface ObservedTestRow {
101
47
  export interface Clock {
102
48
  now(): number;
103
49
  }
104
- /**
105
- * Record a run's test observations.
106
- *
107
- * Total over its input: every observation lands in exactly one of
108
- * {@link ObservedTestsResult.recorded} or {@link ObservedTestsResult.refused},
109
- * so a caller can account for all of them without inspecting the store. Never
110
- * throws for an observation it cannot act on — that is a refusal, per the
111
- * five-result-states rule the tool contract applies one layer up.
112
- */
50
+ /** Record a run's test observations. Total over its input: every observation
51
+ * lands in `recorded` or `refused`. Never throws — a refusal instead. */
113
52
  export declare function applyObservedTests(driver: SqlDriver, input: ObservedTestsInput, clock?: Clock): ObservedTestsResult;
114
53
  /** Read the EARNED ledger, newest observation first, optionally for one run. */
115
54
  export declare function observedTests(driver: SqlDriver, options?: {
@@ -1 +1 @@
1
- {"version":3,"file":"observed-tests.d.ts","sourceRoot":"","sources":["../../src/graph/observed-tests.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoDG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAE3D,uFAAuF;AACvF,MAAM,MAAM,mBAAmB,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC;AAElE,MAAM,WAAW,uBAAuB;IACtC,wFAAwF;IACxF,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB;;;;;;;OAOG;IACH,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,OAAO,EAAE,mBAAmB,CAAC;IACtC,wGAAwG;IACxG,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CACpC;AAED,MAAM,WAAW,kBAAkB;IACjC,uFAAuF;IACvF,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,0HAA0H;IAC1H,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,YAAY,EAAE,SAAS,uBAAuB,EAAE,CAAC;CAC3D;AAED,oFAAoF;AACpF,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,mBAAmB;IAClC,wBAAwB;IACxB,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,QAAQ,CAAC,OAAO,EAAE,SAAS,mBAAmB,EAAE,CAAC;CAClD;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,OAAO,EAAE,mBAAmB,CAAC;IACtC,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED,gGAAgG;AAChG,MAAM,WAAW,KAAK;IACpB,GAAG,IAAI,MAAM,CAAC;CACf;AAaD;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,SAAS,EACjB,KAAK,EAAE,kBAAkB,EACzB,KAAK,GAAE,KAAoB,GAC1B,mBAAmB,CAqDrB;AAED,gFAAgF;AAChF,wBAAgB,aAAa,CAC3B,MAAM,EAAE,SAAS,EACjB,OAAO,GAAE;IAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAO,GACxC,SAAS,eAAe,EAAE,CA0B5B"}
1
+ {"version":3,"file":"observed-tests.d.ts","sourceRoot":"","sources":["../../src/graph/observed-tests.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAE3D,uFAAuF;AACvF,MAAM,MAAM,mBAAmB,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC;AAElE,MAAM,WAAW,uBAAuB;IACtC,wFAAwF;IACxF,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB;yEACqE;IACrE,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,OAAO,EAAE,mBAAmB,CAAC;IACtC,wGAAwG;IACxG,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CACpC;AAED,MAAM,WAAW,kBAAkB;IACjC,uFAAuF;IACvF,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,0HAA0H;IAC1H,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,YAAY,EAAE,SAAS,uBAAuB,EAAE,CAAC;CAC3D;AAED,oFAAoF;AACpF,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,mBAAmB;IAClC,wBAAwB;IACxB,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,QAAQ,CAAC,OAAO,EAAE,SAAS,mBAAmB,EAAE,CAAC;CAClD;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,OAAO,EAAE,mBAAmB,CAAC;IACtC,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED,gGAAgG;AAChG,MAAM,WAAW,KAAK;IACpB,GAAG,IAAI,MAAM,CAAC;CACf;AAaD;0EAC0E;AAC1E,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,SAAS,EACjB,KAAK,EAAE,kBAAkB,EACzB,KAAK,GAAE,KAAoB,GAC1B,mBAAmB,CAqDrB;AAED,gFAAgF;AAChF,wBAAgB,aAAa,CAC3B,MAAM,EAAE,SAAS,EACjB,OAAO,GAAE;IAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAO,GACxC,SAAS,eAAe,EAAE,CA0B5B"}
@@ -1,70 +1,15 @@
1
1
  /**
2
- * `observed_tests` — the EARNED record of which tests actually ran.
3
- *
4
- * This is the coverage axis, and coverage is deliberately not confidence: AI
5
- * layer §20 separates *"what I actually verified"* from *"how sure am I"*, and
6
- * the five report categories say nothing about the first. This module is the
7
- * carrier for that separation, ruled in
8
- * `documents/decisions-inbox/DEC-NEXT-test-run-coverage-has-no-carrier.md`.
9
- *
10
- * ## Why this is a table and not an R4 edge promotion
11
- *
12
- * The obvious-looking design is to run the suite and promote each `TESTS` edge
13
- * it exercised to R4, reusing {@link applyRuntimeObservations}. That is not
14
- * available, and the reason is the same one `observe-runtime.ts`'s header
15
- * already gives for refusing to derive edges from correlated evidence.
16
- *
17
- * An edge needs **two endpoints and a witnessed relationship between them**. A
18
- * test-runner's evidence carries no stack — every item it emits has
19
- * `stackTrace: null` — so an observed test names exactly one node, its own
20
- * `TEST_CASE`. Nothing in the run witnesses which function that test reached.
21
- * Pairing the test with a function that merely co-occurred in the same run
22
- * would mint an edge from temporal coincidence, which is precisely the
23
- * wrong-direction failure rule 2 exists to prevent, arriving through the one
24
- * mechanism built to make the graph *more* trustworthy.
25
- *
26
- * So the honest fact a test run establishes is a fact about **one node**: this
27
- * test case executed, and this is what happened. That is not an edge and R4 in
28
- * this store is a property of an edge, so it needs a carrier of its own.
29
- *
30
- * ## Why EARNED
31
- *
32
- * Same argument as `observed_edges`, one step over. Nothing in the source says
33
- * which tests ran — the source says which tests *exist*. A rebuild that dropped
34
- * this table would silently turn "what I actually verified" back into "what
35
- * might be affected", which is the exact collapse the coverage axis exists to
36
- * prevent.
37
- *
38
- * ## What this module refuses to do
39
- *
40
- * - **Invent a node.** An observation naming a node this graph does not hold is
41
- * refused with its reason, never created — rule 2, and the same posture
42
- * {@link applyRuntimeObservations} takes for an edge endpoint.
43
- * - **Accept a category error.** A test outcome against a node that is not a
44
- * `TEST_CASE` is refused rather than written. The graph holds the id, so this
45
- * is not a missing-node refusal; it is a claim that would make every later
46
- * coverage read meaningless, and it is far more likely to be a resolver bug
47
- * than a real observation.
48
- * - **Judge anything.** No finding, no hypothesis, no report category. It
49
- * records what ran; whether that is *enough* is a judgement for a layer above
50
- * this one.
51
- *
52
- * @see `packages/core/src/graph/runtime-confirmation.ts` — the edge half.
2
+ * `observed_tests` — EARNED record of which tests ran (coverage axis, separate from confidence per AI layer §20; DEC-NEXT-test-run-coverage-has-no-carrier).
3
+ * Not an R4 edge promotion: a runner's evidence has no stack trace, so it witnesses only its own TEST_CASE node, never which function it reached — pairing on co-occurrence would mint an edge from coincidence (rule 2).
4
+ * EARNED because source says which tests exist, never which ran. Refuses to invent a node, accept a non-TEST_CASE target, or judge anything.
53
5
  */
54
6
  const SYSTEM_CLOCK = { now: () => Date.now() };
55
7
  function nodeTypeOf(driver, id) {
56
8
  const row = driver.prepare("SELECT type FROM nodes WHERE id = ?").get(id);
57
9
  return row?.type;
58
10
  }
59
- /**
60
- * Record a run's test observations.
61
- *
62
- * Total over its input: every observation lands in exactly one of
63
- * {@link ObservedTestsResult.recorded} or {@link ObservedTestsResult.refused},
64
- * so a caller can account for all of them without inspecting the store. Never
65
- * throws for an observation it cannot act on — that is a refusal, per the
66
- * five-result-states rule the tool contract applies one layer up.
67
- */
11
+ /** Record a run's test observations. Total over its input: every observation
12
+ * lands in `recorded` or `refused`. Never throws — a refusal instead. */
68
13
  export function applyObservedTests(driver, input, clock = SYSTEM_CLOCK) {
69
14
  const recorded = [];
70
15
  const refused = [];
@@ -1 +1 @@
1
- {"version":3,"file":"observed-tests.js","sourceRoot":"","sources":["../../src/graph/observed-tests.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"observed-tests.js","sourceRoot":"","sources":["../../src/graph/observed-tests.ts"],"names":[],"mappings":"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"}
@@ -1,29 +1,6 @@
1
1
  /**
2
- * Writing a built graph back out, split by producer.
3
- *
4
- * `buildGraph` merges many producers into one graph; `writeBatch` invalidates
5
- * and writes **one producer's** rows at a time, because DEC-014's invalidation
6
- * rule is per-adapter — re-running the Python adapter must not evict the
7
- * TypeScript adapter's rows. So the merged graph has to be partitioned back
8
- * before it can be stored.
9
- *
10
- * That partition was written out by hand in every bench script that has ever
11
- * stored a graph, identically, five times. It is not a measurement concern: it
12
- * is the engine's own write path, and the MCP server needs it too. Lifted here
13
- * so there is one copy and one place for it to be wrong.
14
- *
15
- * ## The subtlety worth stating
16
- *
17
- * The rows written for a producer are the **post-merge** ones, not the batch's
18
- * originals. A node supplied by two adapters is merged (DEC-012) and the merged
19
- * row carries the winning `producedBy`; writing the pre-merge originals would
20
- * store the losing version under the loser's producer and then let the next
21
- * incremental run resurrect it. Filtering the merged graph by `producedBy` is
22
- * what makes the store agree with the builder.
23
- *
24
- * A batch that contributed nothing after the merge is still written, with empty
25
- * rows, on purpose: that is how a re-run that *removes* a symbol evicts the row
26
- * it used to own. Skipping empty batches would make deletions invisible.
2
+ * Writing a built graph back out, split by producer. `writeBatch` invalidates per-producer (DEC-014): re-running one adapter must not evict another's rows, so the merged graph is partitioned back before storing.
3
+ * Rows written are post-merge (DEC-012's winning `producedBy`), never pre-merge originals, or the loser gets resurrected next incremental run. An empty-after-merge batch is still written (empty rows) so a removed symbol's row gets evicted, not left invisible.
27
4
  */
28
5
  import type { IRBatch } from "@descryy/ir";
29
6
  import type { SqlDriver } from "../store/driver/driver.ts";
@@ -1 +1 @@
1
- {"version":3,"file":"persist.d.ts","sourceRoot":"","sources":["../../src/graph/persist.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAc,KAAK,YAAY,EAAE,KAAK,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACrF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,MAAM,EAAE,SAAS,WAAW,EAAE,CAAC;IACxC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,4FAA4F;IAC5F,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IACzC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAChC;AAED,wBAAgB,YAAY,CAC1B,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,SAAS,OAAO,EAAE,EAC3B,KAAK,EAAE,WAAW,EAClB,OAAO,GAAE,YAAiB,GACzB,aAAa,CA6Bf"}
1
+ {"version":3,"file":"persist.d.ts","sourceRoot":"","sources":["../../src/graph/persist.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAc,KAAK,YAAY,EAAE,KAAK,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACrF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,MAAM,EAAE,SAAS,WAAW,EAAE,CAAC;IACxC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,4FAA4F;IAC5F,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IACzC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAChC;AAED,wBAAgB,YAAY,CAC1B,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,SAAS,OAAO,EAAE,EAC3B,KAAK,EAAE,WAAW,EAClB,OAAO,GAAE,YAAiB,GACzB,aAAa,CA6Bf"}
@@ -1,29 +1,6 @@
1
1
  /**
2
- * Writing a built graph back out, split by producer.
3
- *
4
- * `buildGraph` merges many producers into one graph; `writeBatch` invalidates
5
- * and writes **one producer's** rows at a time, because DEC-014's invalidation
6
- * rule is per-adapter — re-running the Python adapter must not evict the
7
- * TypeScript adapter's rows. So the merged graph has to be partitioned back
8
- * before it can be stored.
9
- *
10
- * That partition was written out by hand in every bench script that has ever
11
- * stored a graph, identically, five times. It is not a measurement concern: it
12
- * is the engine's own write path, and the MCP server needs it too. Lifted here
13
- * so there is one copy and one place for it to be wrong.
14
- *
15
- * ## The subtlety worth stating
16
- *
17
- * The rows written for a producer are the **post-merge** ones, not the batch's
18
- * originals. A node supplied by two adapters is merged (DEC-012) and the merged
19
- * row carries the winning `producedBy`; writing the pre-merge originals would
20
- * store the losing version under the loser's producer and then let the next
21
- * incremental run resurrect it. Filtering the merged graph by `producedBy` is
22
- * what makes the store agree with the builder.
23
- *
24
- * A batch that contributed nothing after the merge is still written, with empty
25
- * rows, on purpose: that is how a re-run that *removes* a symbol evicts the row
26
- * it used to own. Skipping empty batches would make deletions invisible.
2
+ * Writing a built graph back out, split by producer. `writeBatch` invalidates per-producer (DEC-014): re-running one adapter must not evict another's rows, so the merged graph is partitioned back before storing.
3
+ * Rows written are post-merge (DEC-012's winning `producedBy`), never pre-merge originals, or the loser gets resurrected next incremental run. An empty-after-merge batch is still written (empty rows) so a removed symbol's row gets evicted, not left invisible.
27
4
  */
28
5
  import { writeBatch } from "../store/writer.js";
29
6
  export function persistGraph(driver, batches, built, options = {}) {
@@ -1 +1 @@
1
- {"version":3,"file":"persist.js","sourceRoot":"","sources":["../../src/graph/persist.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAKH,OAAO,EAAE,UAAU,EAAuC,MAAM,oBAAoB,CAAC;AAarF,MAAM,UAAU,YAAY,CAC1B,MAAiB,EACjB,OAA2B,EAC3B,KAAkB,EAClB,UAAwB,EAAE;IAE1B,MAAM,MAAM,GAAkB,EAAE,CAAC;IACjC,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAElC,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,MAAM,CAAC,IAAI,CACT,UAAU,CACR,MAAM,EACN;YACE,GAAG,KAAK;YACR,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,KAAK,KAAK,CAAC,UAAU,CAAC;YACzE,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,KAAK,KAAK,CAAC,UAAU,CAAC;YACzE,UAAU,EAAE,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,UAAU,KAAK,KAAK,CAAC,UAAU,CAAC;SAClF,EACD,OAAO,CACR,CACF,CAAC;IACJ,CAAC;IAED,KAAK,MAAM,KAAK,IAAI,MAAM;QAAE,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,YAAY;YAAE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAErF,OAAO;QACL,MAAM;QACN,YAAY,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC;QAC5D,YAAY,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC;QAC5D,iBAAiB,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,iBAAiB,EAAE,CAAC,CAAC;QACtE,YAAY,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,IAAI,EAAE;QACjC,aAAa,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,aAAa,EAAE,CAAC,CAAC;KAC/D,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"persist.js","sourceRoot":"","sources":["../../src/graph/persist.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,EAAE,UAAU,EAAuC,MAAM,oBAAoB,CAAC;AAarF,MAAM,UAAU,YAAY,CAC1B,MAAiB,EACjB,OAA2B,EAC3B,KAAkB,EAClB,UAAwB,EAAE;IAE1B,MAAM,MAAM,GAAkB,EAAE,CAAC;IACjC,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAElC,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,MAAM,CAAC,IAAI,CACT,UAAU,CACR,MAAM,EACN;YACE,GAAG,KAAK;YACR,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,KAAK,KAAK,CAAC,UAAU,CAAC;YACzE,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,KAAK,KAAK,CAAC,UAAU,CAAC;YACzE,UAAU,EAAE,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,UAAU,KAAK,KAAK,CAAC,UAAU,CAAC;SAClF,EACD,OAAO,CACR,CACF,CAAC;IACJ,CAAC;IAED,KAAK,MAAM,KAAK,IAAI,MAAM;QAAE,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,YAAY;YAAE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAErF,OAAO;QACL,MAAM;QACN,YAAY,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC;QAC5D,YAAY,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC;QAC5D,iBAAiB,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,iBAAiB,EAAE,CAAC,CAAC;QACtE,YAAY,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,IAAI,EAAE;QACjC,aAAa,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,aAAa,EAAE,CAAC,CAAC;KAC/D,CAAC;AACJ,CAAC"}