@cleocode/core 2026.5.134 → 2026.6.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 (557) hide show
  1. package/binaries/README.md +49 -27
  2. package/dist/agents/{agent-registry.d.ts → agent-capacity-tracker.d.ts} +2 -2
  3. package/dist/agents/agent-capacity-tracker.d.ts.map +1 -0
  4. package/dist/agents/{agent-registry.js → agent-capacity-tracker.js} +2 -2
  5. package/dist/agents/agent-capacity-tracker.js.map +1 -0
  6. package/dist/agents/index.d.ts +1 -1
  7. package/dist/agents/index.d.ts.map +1 -1
  8. package/dist/agents/index.js +4 -2
  9. package/dist/agents/index.js.map +1 -1
  10. package/dist/agents/seed-install.d.ts +1 -1
  11. package/dist/agents/seed-install.d.ts.map +1 -1
  12. package/dist/agents/seed-install.js +42 -36
  13. package/dist/agents/seed-install.js.map +1 -1
  14. package/dist/caamp-export.d.ts +18 -0
  15. package/dist/caamp-export.d.ts.map +1 -0
  16. package/dist/caamp-export.js +18 -0
  17. package/dist/caamp-export.js.map +1 -0
  18. package/dist/conduit/http-transport.d.ts +7 -13
  19. package/dist/conduit/http-transport.d.ts.map +1 -1
  20. package/dist/conduit/http-transport.js +12 -59
  21. package/dist/conduit/http-transport.js.map +1 -1
  22. package/dist/conduit/local-transport.d.ts +1 -1
  23. package/dist/conduit/local-transport.d.ts.map +1 -1
  24. package/dist/conduit/local-transport.js +69 -43
  25. package/dist/conduit/local-transport.js.map +1 -1
  26. package/dist/dispatch/mutate-projection.d.ts.map +1 -1
  27. package/dist/dispatch/mutate-projection.js +11 -0
  28. package/dist/dispatch/mutate-projection.js.map +1 -1
  29. package/dist/docs/docs-read-model.d.ts +7 -0
  30. package/dist/docs/docs-read-model.d.ts.map +1 -1
  31. package/dist/docs/docs-read-model.js +5 -0
  32. package/dist/docs/docs-read-model.js.map +1 -1
  33. package/dist/docs/export-document.js +40526 -281
  34. package/dist/docs/export-document.js.map +6 -1
  35. package/dist/docs/supersede.d.ts.map +1 -1
  36. package/dist/docs/supersede.js +12 -7
  37. package/dist/docs/supersede.js.map +1 -1
  38. package/dist/doctor/db-substrate.d.ts.map +1 -1
  39. package/dist/doctor/db-substrate.js +10 -9
  40. package/dist/doctor/db-substrate.js.map +1 -1
  41. package/dist/git-shim-export.d.ts +18 -0
  42. package/dist/git-shim-export.d.ts.map +1 -0
  43. package/dist/git-shim-export.js +18 -0
  44. package/dist/git-shim-export.js.map +1 -0
  45. package/dist/hooks/payload-schemas.d.ts +2 -2
  46. package/dist/init.d.ts.map +1 -1
  47. package/dist/init.js +39 -32
  48. package/dist/init.js.map +1 -1
  49. package/dist/internal.d.ts +11 -3
  50. package/dist/internal.d.ts.map +1 -1
  51. package/dist/internal.js +14 -5
  52. package/dist/internal.js.map +1 -1
  53. package/dist/lafs-export.d.ts +18 -0
  54. package/dist/lafs-export.d.ts.map +1 -0
  55. package/dist/lafs-export.js +18 -0
  56. package/dist/lafs-export.js.map +1 -0
  57. package/dist/lifecycle/effective-stage.js +1 -1
  58. package/dist/lifecycle/index.js +1 -1
  59. package/dist/lifecycle/index.js.map +1 -1
  60. package/dist/lifecycle/rollup.js +1 -1
  61. package/dist/llm/credential-pool.d.ts +17 -0
  62. package/dist/llm/credential-pool.d.ts.map +1 -1
  63. package/dist/llm/credential-pool.js +40 -1
  64. package/dist/llm/credential-pool.js.map +1 -1
  65. package/dist/llm/plugin-facade.d.ts.map +1 -1
  66. package/dist/llm/plugin-facade.js +43392 -354
  67. package/dist/llm/plugin-facade.js.map +6 -1
  68. package/dist/llm/role-executor.d.ts +8 -0
  69. package/dist/llm/role-executor.d.ts.map +1 -1
  70. package/dist/llm/role-executor.js +96 -4
  71. package/dist/llm/role-executor.js.map +1 -1
  72. package/dist/llm/role-resolver.d.ts.map +1 -1
  73. package/dist/llm/role-resolver.js +56 -1
  74. package/dist/llm/role-resolver.js.map +1 -1
  75. package/dist/llm/transports/codex-oauth-headers.d.ts +51 -0
  76. package/dist/llm/transports/codex-oauth-headers.d.ts.map +1 -0
  77. package/dist/llm/transports/codex-oauth-headers.js +89 -0
  78. package/dist/llm/transports/codex-oauth-headers.js.map +1 -0
  79. package/dist/memory/claude-mem-migration.d.ts.map +1 -1
  80. package/dist/memory/claude-mem-migration.js +1 -3
  81. package/dist/memory/claude-mem-migration.js.map +1 -1
  82. package/dist/memory/decisions.d.ts.map +1 -1
  83. package/dist/memory/decisions.js +77 -23
  84. package/dist/memory/decisions.js.map +1 -1
  85. package/dist/memory/graph-memory-bridge.d.ts.map +1 -1
  86. package/dist/memory/graph-memory-bridge.js +12 -6
  87. package/dist/memory/graph-memory-bridge.js.map +1 -1
  88. package/dist/memory/learnings.d.ts +2 -2
  89. package/dist/memory/nexus-plasticity.d.ts +21 -9
  90. package/dist/memory/nexus-plasticity.d.ts.map +1 -1
  91. package/dist/memory/nexus-plasticity.js +44 -22
  92. package/dist/memory/nexus-plasticity.js.map +1 -1
  93. package/dist/memory/patterns.d.ts +2 -2
  94. package/dist/memory/redaction.d.ts +19 -3
  95. package/dist/memory/redaction.d.ts.map +1 -1
  96. package/dist/memory/redaction.js +64 -129
  97. package/dist/memory/redaction.js.map +6 -1
  98. package/dist/metrics/token-service.d.ts +8 -2
  99. package/dist/metrics/token-service.d.ts.map +1 -1
  100. package/dist/metrics/token-service.js +1 -1
  101. package/dist/metrics/token-service.js.map +1 -1
  102. package/dist/nexus/analyze-orchestrator.d.ts.map +1 -1
  103. package/dist/nexus/analyze-orchestrator.js +6 -8
  104. package/dist/nexus/analyze-orchestrator.js.map +1 -1
  105. package/dist/nexus/api-extractors/http-extractor.d.ts.map +1 -1
  106. package/dist/nexus/api-extractors/http-extractor.js +3 -3
  107. package/dist/nexus/api-extractors/http-extractor.js.map +1 -1
  108. package/dist/nexus/clusters.d.ts.map +1 -1
  109. package/dist/nexus/clusters.js +3 -2
  110. package/dist/nexus/clusters.js.map +1 -1
  111. package/dist/nexus/context.d.ts.map +1 -1
  112. package/dist/nexus/context.js +10 -16
  113. package/dist/nexus/context.js.map +1 -1
  114. package/dist/nexus/diff.d.ts.map +1 -1
  115. package/dist/nexus/diff.js +6 -4
  116. package/dist/nexus/diff.js.map +1 -1
  117. package/dist/nexus/export.d.ts.map +1 -1
  118. package/dist/nexus/export.js +7 -4
  119. package/dist/nexus/export.js.map +1 -1
  120. package/dist/nexus/flows.d.ts.map +1 -1
  121. package/dist/nexus/flows.js +3 -1
  122. package/dist/nexus/flows.js.map +1 -1
  123. package/dist/nexus/impact.d.ts +1 -1
  124. package/dist/nexus/impact.d.ts.map +1 -1
  125. package/dist/nexus/impact.js +31 -17
  126. package/dist/nexus/impact.js.map +1 -1
  127. package/dist/nexus/living-brain.d.ts.map +1 -1
  128. package/dist/nexus/living-brain.js +27 -15
  129. package/dist/nexus/living-brain.js.map +1 -1
  130. package/dist/nexus/nexus-bridge.d.ts.map +1 -1
  131. package/dist/nexus/nexus-bridge.js +28 -29
  132. package/dist/nexus/nexus-bridge.js.map +1 -1
  133. package/dist/nexus/plasticity-queries.d.ts +4 -2
  134. package/dist/nexus/plasticity-queries.d.ts.map +1 -1
  135. package/dist/nexus/plasticity-queries.js +27 -15
  136. package/dist/nexus/plasticity-queries.js.map +1 -1
  137. package/dist/nexus/query.d.ts.map +1 -1
  138. package/dist/nexus/query.js +6 -2
  139. package/dist/nexus/query.js.map +1 -1
  140. package/dist/nexus/registry.d.ts.map +1 -1
  141. package/dist/nexus/registry.js +65 -30
  142. package/dist/nexus/registry.js.map +1 -1
  143. package/dist/nexus/route-analysis.d.ts +3 -2
  144. package/dist/nexus/route-analysis.d.ts.map +1 -1
  145. package/dist/nexus/route-analysis.js +11 -10
  146. package/dist/nexus/route-analysis.js.map +1 -1
  147. package/dist/nexus/sigil.d.ts.map +1 -1
  148. package/dist/nexus/sigil.js +60 -13
  149. package/dist/nexus/sigil.js.map +1 -1
  150. package/dist/nexus/user-profile.d.ts +2 -1
  151. package/dist/nexus/user-profile.d.ts.map +1 -1
  152. package/dist/nexus/user-profile.js +8 -4
  153. package/dist/nexus/user-profile.js.map +1 -1
  154. package/dist/orchestrate/index.d.ts +1 -1
  155. package/dist/orchestrate/index.d.ts.map +1 -1
  156. package/dist/orchestrate/index.js +1 -1
  157. package/dist/orchestrate/index.js.map +1 -1
  158. package/dist/orchestrate/plan.d.ts +3 -3
  159. package/dist/orchestrate/plan.d.ts.map +1 -1
  160. package/dist/orchestrate/plan.js +7 -7
  161. package/dist/orchestrate/plan.js.map +1 -1
  162. package/dist/orchestrate/spawn-ops.js +2 -2
  163. package/dist/orchestrate/spawn-ops.js.map +1 -1
  164. package/dist/orchestration/classify.d.ts +2 -2
  165. package/dist/orchestration/classify.js +3 -3
  166. package/dist/orchestration/classify.js.map +1 -1
  167. package/dist/orchestration/validate-spawn.d.ts.map +1 -1
  168. package/dist/orchestration/validate-spawn.js +5 -5
  169. package/dist/orchestration/validate-spawn.js.map +1 -1
  170. package/dist/paths-export.d.ts +18 -0
  171. package/dist/paths-export.d.ts.map +1 -0
  172. package/dist/paths-export.js +18 -0
  173. package/dist/paths-export.js.map +1 -0
  174. package/dist/paths.d.ts.map +1 -1
  175. package/dist/paths.js +24 -11
  176. package/dist/paths.js.map +1 -1
  177. package/dist/playbooks/index.d.ts +1 -0
  178. package/dist/playbooks/index.d.ts.map +1 -1
  179. package/dist/playbooks/index.js +4 -0
  180. package/dist/playbooks/index.js.map +1 -1
  181. package/dist/playbooks/skill-node-executor.d.ts +155 -0
  182. package/dist/playbooks/skill-node-executor.d.ts.map +1 -0
  183. package/dist/playbooks/skill-node-executor.js +156 -0
  184. package/dist/playbooks/skill-node-executor.js.map +1 -0
  185. package/dist/repair.d.ts +3 -7
  186. package/dist/repair.d.ts.map +1 -1
  187. package/dist/repair.js +5 -43
  188. package/dist/repair.js.map +1 -1
  189. package/dist/sagas/migrate-containment.js +7 -7
  190. package/dist/sagas/migrate-containment.js.map +1 -1
  191. package/dist/scaffold/ensure-dirs.d.ts +8 -2
  192. package/dist/scaffold/ensure-dirs.d.ts.map +1 -1
  193. package/dist/scaffold/ensure-dirs.js +24 -11
  194. package/dist/scaffold/ensure-dirs.js.map +1 -1
  195. package/dist/scaffold/project-detection.d.ts +5 -1
  196. package/dist/scaffold/project-detection.d.ts.map +1 -1
  197. package/dist/scaffold/project-detection.js +9 -5
  198. package/dist/scaffold/project-detection.js.map +1 -1
  199. package/dist/sentient/hygiene-scan.js +6 -6
  200. package/dist/sentient/hygiene-scan.js.map +1 -1
  201. package/dist/sentient/proposal-dedup.js +2 -2
  202. package/dist/sentient/proposal-rate-limiter.js +1 -1
  203. package/dist/sentient/propose-tick.js +5 -5
  204. package/dist/sentient/propose-tick.js.map +1 -1
  205. package/dist/sentient/stage-drift-tick.js +3 -3
  206. package/dist/sentient/stage-drift-tick.js.map +1 -1
  207. package/dist/sequence/index.d.ts.map +1 -1
  208. package/dist/sequence/index.js +6 -2
  209. package/dist/sequence/index.js.map +1 -1
  210. package/dist/sessions/briefing.d.ts.map +1 -1
  211. package/dist/sessions/briefing.js +18 -4
  212. package/dist/sessions/briefing.js.map +1 -1
  213. package/dist/setup/sections/verification.js +2 -2
  214. package/dist/setup/sections/verification.js.map +1 -1
  215. package/dist/shutdown.d.ts +91 -0
  216. package/dist/shutdown.d.ts.map +1 -0
  217. package/dist/shutdown.js +120 -0
  218. package/dist/shutdown.js.map +1 -0
  219. package/dist/skills/index.d.ts +2 -0
  220. package/dist/skills/index.d.ts.map +1 -1
  221. package/dist/skills/index.js +1 -0
  222. package/dist/skills/index.js.map +1 -1
  223. package/dist/skills/skill-executor-adapter.d.ts +136 -0
  224. package/dist/skills/skill-executor-adapter.d.ts.map +1 -0
  225. package/dist/skills/skill-executor-adapter.js +137 -0
  226. package/dist/skills/skill-executor-adapter.js.map +1 -0
  227. package/dist/skills/usage-recorder.d.ts.map +1 -1
  228. package/dist/skills/usage-recorder.js +30 -0
  229. package/dist/skills/usage-recorder.js.map +1 -1
  230. package/dist/skills-export.d.ts +23 -0
  231. package/dist/skills-export.d.ts.map +1 -0
  232. package/dist/skills-export.js +23 -0
  233. package/dist/skills-export.js.map +1 -0
  234. package/dist/stats/index.d.ts.map +1 -1
  235. package/dist/stats/index.js +8 -3
  236. package/dist/stats/index.js.map +1 -1
  237. package/dist/store/agent-doctor.d.ts +3 -3
  238. package/dist/store/agent-doctor.d.ts.map +1 -1
  239. package/dist/store/agent-doctor.js +18 -13
  240. package/dist/store/agent-doctor.js.map +1 -1
  241. package/dist/store/agent-install.d.ts +6 -5
  242. package/dist/store/agent-install.d.ts.map +1 -1
  243. package/dist/store/agent-install.js +20 -16
  244. package/dist/store/agent-install.js.map +1 -1
  245. package/dist/store/agent-registry-accessor.d.ts +66 -28
  246. package/dist/store/agent-registry-accessor.d.ts.map +1 -1
  247. package/dist/store/agent-registry-accessor.js +248 -167
  248. package/dist/store/agent-registry-accessor.js.map +1 -1
  249. package/dist/store/agent-registry-store.d.ts +242 -0
  250. package/dist/store/agent-registry-store.d.ts.map +1 -0
  251. package/dist/store/agent-registry-store.js +501 -0
  252. package/dist/store/agent-registry-store.js.map +1 -0
  253. package/dist/store/agent-resolver.d.ts +8 -8
  254. package/dist/store/agent-resolver.d.ts.map +1 -1
  255. package/dist/store/agent-resolver.js +19 -17
  256. package/dist/store/agent-resolver.js.map +1 -1
  257. package/dist/store/backup-pack.d.ts.map +1 -1
  258. package/dist/store/backup-pack.js +24 -8
  259. package/dist/store/backup-pack.js.map +1 -1
  260. package/dist/store/conduit-sqlite.d.ts +181 -74
  261. package/dist/store/conduit-sqlite.d.ts.map +1 -1
  262. package/dist/store/conduit-sqlite.js +307 -528
  263. package/dist/store/conduit-sqlite.js.map +1 -1
  264. package/dist/store/cross-db-cleanup.d.ts +5 -5
  265. package/dist/store/cross-db-cleanup.d.ts.map +1 -1
  266. package/dist/store/cross-db-cleanup.js +12 -10
  267. package/dist/store/cross-db-cleanup.js.map +1 -1
  268. package/dist/store/data-accessor.d.ts +4 -4
  269. package/dist/store/data-accessor.js +5 -5
  270. package/dist/store/data-accessor.js.map +1 -1
  271. package/dist/store/data-safety-central.d.ts +83 -1
  272. package/dist/store/data-safety-central.d.ts.map +1 -1
  273. package/dist/store/data-safety-central.js +257 -0
  274. package/dist/store/data-safety-central.js.map +1 -1
  275. package/dist/store/db-helpers.d.ts +8 -2
  276. package/dist/store/db-helpers.d.ts.map +1 -1
  277. package/dist/store/db-helpers.js +6 -2
  278. package/dist/store/db-helpers.js.map +1 -1
  279. package/dist/store/dual-scope-db.d.ts +46 -4
  280. package/dist/store/dual-scope-db.d.ts.map +1 -1
  281. package/dist/store/dual-scope-db.js +103 -9
  282. package/dist/store/dual-scope-db.js.map +1 -1
  283. package/dist/store/exodus/__fixtures__/representative-fixture.d.ts +116 -0
  284. package/dist/store/exodus/__fixtures__/representative-fixture.d.ts.map +1 -0
  285. package/dist/store/exodus/__fixtures__/representative-fixture.js +274 -0
  286. package/dist/store/exodus/__fixtures__/representative-fixture.js.map +1 -0
  287. package/dist/store/exodus/index.d.ts +3 -1
  288. package/dist/store/exodus/index.d.ts.map +1 -1
  289. package/dist/store/exodus/index.js +3 -1
  290. package/dist/store/exodus/index.js.map +1 -1
  291. package/dist/store/exodus/migrate.d.ts +120 -1
  292. package/dist/store/exodus/migrate.d.ts.map +1 -1
  293. package/dist/store/exodus/migrate.js +923 -119
  294. package/dist/store/exodus/migrate.js.map +1 -1
  295. package/dist/store/exodus/on-open.d.ts +189 -0
  296. package/dist/store/exodus/on-open.d.ts.map +1 -0
  297. package/dist/store/exodus/on-open.js +464 -0
  298. package/dist/store/exodus/on-open.js.map +1 -0
  299. package/dist/store/exodus/table-name-map.d.ts +173 -0
  300. package/dist/store/exodus/table-name-map.d.ts.map +1 -0
  301. package/dist/store/exodus/table-name-map.js +660 -0
  302. package/dist/store/exodus/table-name-map.js.map +1 -0
  303. package/dist/store/exodus/verify-migration.d.ts +72 -0
  304. package/dist/store/exodus/verify-migration.d.ts.map +1 -0
  305. package/dist/store/exodus/verify-migration.js +678 -0
  306. package/dist/store/exodus/verify-migration.js.map +1 -0
  307. package/dist/store/exodus/verify.d.ts +32 -8
  308. package/dist/store/exodus/verify.d.ts.map +1 -1
  309. package/dist/store/exodus/verify.js +48 -142
  310. package/dist/store/exodus/verify.js.map +1 -1
  311. package/dist/store/index.d.ts +2 -3
  312. package/dist/store/index.d.ts.map +1 -1
  313. package/dist/store/index.js +2 -3
  314. package/dist/store/index.js.map +1 -1
  315. package/dist/store/memory-accessor.d.ts +31 -0
  316. package/dist/store/memory-accessor.d.ts.map +1 -1
  317. package/dist/store/memory-accessor.js +38 -0
  318. package/dist/store/memory-accessor.js.map +1 -1
  319. package/dist/store/memory-sqlite.d.ts +86 -13
  320. package/dist/store/memory-sqlite.d.ts.map +1 -1
  321. package/dist/store/memory-sqlite.js +326 -528
  322. package/dist/store/memory-sqlite.js.map +1 -1
  323. package/dist/store/migrate-signaldock-to-conduit.d.ts +1 -1
  324. package/dist/store/migrate-signaldock-to-conduit.d.ts.map +1 -1
  325. package/dist/store/migrate-signaldock-to-conduit.js +126 -35
  326. package/dist/store/migrate-signaldock-to-conduit.js.map +1 -1
  327. package/dist/store/migration-manager.d.ts +49 -0
  328. package/dist/store/migration-manager.d.ts.map +1 -1
  329. package/dist/store/migration-manager.js +167 -67
  330. package/dist/store/migration-manager.js.map +1 -1
  331. package/dist/store/migration-sqlite.d.ts +1 -1
  332. package/dist/store/migration-sqlite.d.ts.map +1 -1
  333. package/dist/store/migration-sqlite.js +32 -3
  334. package/dist/store/migration-sqlite.js.map +1 -1
  335. package/dist/store/nexus-sqlite.d.ts +152 -29
  336. package/dist/store/nexus-sqlite.d.ts.map +1 -1
  337. package/dist/store/nexus-sqlite.js +496 -177
  338. package/dist/store/nexus-sqlite.js.map +1 -1
  339. package/dist/store/nexus-validation-schemas.d.ts +32 -32
  340. package/dist/store/open-cleo-db.d.ts +37 -40
  341. package/dist/store/open-cleo-db.d.ts.map +1 -1
  342. package/dist/store/open-cleo-db.js +76 -153
  343. package/dist/store/open-cleo-db.js.map +1 -1
  344. package/dist/store/role-accessors-impl.d.ts +4 -4
  345. package/dist/store/role-accessors-impl.d.ts.map +1 -1
  346. package/dist/store/role-accessors-impl.js +18 -15
  347. package/dist/store/role-accessors-impl.js.map +1 -1
  348. package/dist/store/schema/{signaldock-schema.d.ts → agent-registry-schema.d.ts} +15 -5
  349. package/dist/store/schema/agent-registry-schema.d.ts.map +1 -0
  350. package/dist/store/schema/{signaldock-schema.js → agent-registry-schema.js} +15 -5
  351. package/dist/store/schema/agent-registry-schema.js.map +1 -0
  352. package/dist/store/schema/agent-schema.d.ts +1 -1
  353. package/dist/store/schema/agent-schema.js +4 -4
  354. package/dist/store/schema/agent-schema.js.map +1 -1
  355. package/dist/store/schema/attachments.d.ts +1 -1
  356. package/dist/store/schema/audit.d.ts +15 -5
  357. package/dist/store/schema/audit.d.ts.map +1 -1
  358. package/dist/store/schema/audit.js +12 -2
  359. package/dist/store/schema/audit.js.map +1 -1
  360. package/dist/store/schema/background-jobs.d.ts +1 -1
  361. package/dist/store/schema/cleo-global/{signaldock.d.ts → agent-registry.d.ts} +277 -271
  362. package/dist/store/schema/cleo-global/agent-registry.d.ts.map +1 -0
  363. package/dist/store/schema/cleo-global/{signaldock.js → agent-registry.js} +136 -125
  364. package/dist/store/schema/cleo-global/agent-registry.js.map +1 -0
  365. package/dist/store/schema/cleo-global/index.d.ts +29 -22
  366. package/dist/store/schema/cleo-global/index.d.ts.map +1 -1
  367. package/dist/store/schema/cleo-global/index.js +29 -22
  368. package/dist/store/schema/cleo-global/index.js.map +1 -1
  369. package/dist/store/schema/cleo-global/nexus.d.ts +36 -1034
  370. package/dist/store/schema/cleo-global/nexus.d.ts.map +1 -1
  371. package/dist/store/schema/cleo-global/nexus.js +32 -337
  372. package/dist/store/schema/cleo-global/nexus.js.map +1 -1
  373. package/dist/store/schema/cleo-global/skills.d.ts +16 -0
  374. package/dist/store/schema/cleo-global/skills.d.ts.map +1 -1
  375. package/dist/store/schema/cleo-global/skills.js +11 -0
  376. package/dist/store/schema/cleo-global/skills.js.map +1 -1
  377. package/dist/store/schema/{cleo-project → cleo-global}/telemetry.d.ts +33 -17
  378. package/dist/store/schema/cleo-global/telemetry.d.ts.map +1 -0
  379. package/dist/store/schema/{cleo-project → cleo-global}/telemetry.js +30 -18
  380. package/dist/store/schema/cleo-global/telemetry.js.map +1 -0
  381. package/dist/store/schema/cleo-project/audit.d.ts +8 -8
  382. package/dist/store/schema/cleo-project/audit.d.ts.map +1 -1
  383. package/dist/store/schema/cleo-project/audit.js +2 -6
  384. package/dist/store/schema/cleo-project/audit.js.map +1 -1
  385. package/dist/store/schema/cleo-project/docs.d.ts +1 -1
  386. package/dist/store/schema/cleo-project/index.d.ts +29 -12
  387. package/dist/store/schema/cleo-project/index.d.ts.map +1 -1
  388. package/dist/store/schema/cleo-project/index.js +29 -12
  389. package/dist/store/schema/cleo-project/index.js.map +1 -1
  390. package/dist/store/schema/cleo-project/lifecycle.d.ts +2 -2
  391. package/dist/store/schema/cleo-project/nexus-graph.d.ts +1067 -0
  392. package/dist/store/schema/cleo-project/nexus-graph.d.ts.map +1 -0
  393. package/dist/store/schema/cleo-project/nexus-graph.js +407 -0
  394. package/dist/store/schema/cleo-project/nexus-graph.js.map +1 -0
  395. package/dist/store/schema/cleo-project/provenance-orphans.d.ts +385 -0
  396. package/dist/store/schema/cleo-project/provenance-orphans.d.ts.map +1 -0
  397. package/dist/store/schema/cleo-project/provenance-orphans.js +142 -0
  398. package/dist/store/schema/cleo-project/provenance-orphans.js.map +1 -0
  399. package/dist/store/schema/cleo-project/provenance-rest.d.ts +1 -1
  400. package/dist/store/schema/cleo-project/runtime.d.ts +1 -1
  401. package/dist/store/schema/cleo-project/tasks-core-batch2.d.ts +1 -1
  402. package/dist/store/schema/cleo-project/tasks-core.d.ts +3 -3
  403. package/dist/store/schema/cleo-shared/brain.d.ts +711 -494
  404. package/dist/store/schema/cleo-shared/brain.d.ts.map +1 -1
  405. package/dist/store/schema/cleo-shared/brain.js +215 -134
  406. package/dist/store/schema/cleo-shared/brain.js.map +1 -1
  407. package/dist/store/schema/conduit-schema.d.ts +63 -51
  408. package/dist/store/schema/conduit-schema.d.ts.map +1 -1
  409. package/dist/store/schema/conduit-schema.js +23 -11
  410. package/dist/store/schema/conduit-schema.js.map +1 -1
  411. package/dist/store/schema/goal.d.ts +3 -2
  412. package/dist/store/schema/goal.d.ts.map +1 -1
  413. package/dist/store/schema/goal.js +3 -2
  414. package/dist/store/schema/goal.js.map +1 -1
  415. package/dist/store/schema/index.d.ts +1 -0
  416. package/dist/store/schema/index.d.ts.map +1 -1
  417. package/dist/store/schema/index.js +1 -0
  418. package/dist/store/schema/index.js.map +1 -1
  419. package/dist/store/schema/lifecycle.d.ts +2 -2
  420. package/dist/store/schema/memory-schema.d.ts +2 -2
  421. package/dist/store/schema/nexus-schema.d.ts +174 -115
  422. package/dist/store/schema/nexus-schema.d.ts.map +1 -1
  423. package/dist/store/schema/nexus-schema.js +175 -55
  424. package/dist/store/schema/nexus-schema.js.map +1 -1
  425. package/dist/store/schema/provenance/releases.d.ts +1 -1
  426. package/dist/store/schema/schema-utils.d.ts +78 -0
  427. package/dist/store/schema/schema-utils.d.ts.map +1 -0
  428. package/dist/store/schema/schema-utils.js +49 -0
  429. package/dist/store/schema/schema-utils.js.map +1 -0
  430. package/dist/store/schema/skills-schema.d.ts +81 -44
  431. package/dist/store/schema/skills-schema.d.ts.map +1 -1
  432. package/dist/store/schema/skills-schema.js +49 -16
  433. package/dist/store/schema/skills-schema.js.map +1 -1
  434. package/dist/store/schema/tasks.d.ts +3 -3
  435. package/dist/store/skills-db.d.ts +90 -50
  436. package/dist/store/skills-db.d.ts.map +1 -1
  437. package/dist/store/skills-db.js +132 -146
  438. package/dist/store/skills-db.js.map +1 -1
  439. package/dist/store/sqlite-backup.d.ts +2 -2
  440. package/dist/store/sqlite-backup.d.ts.map +1 -1
  441. package/dist/store/sqlite-backup.js +11 -10
  442. package/dist/store/sqlite-backup.js.map +1 -1
  443. package/dist/store/sqlite-data-accessor.d.ts.map +1 -1
  444. package/dist/store/sqlite-data-accessor.js +25 -18
  445. package/dist/store/sqlite-data-accessor.js.map +1 -1
  446. package/dist/store/sqlite.d.ts +72 -12
  447. package/dist/store/sqlite.d.ts.map +1 -1
  448. package/dist/store/sqlite.js +153 -89
  449. package/dist/store/sqlite.js.map +1 -1
  450. package/dist/store/tasks-schema.d.ts +4 -0
  451. package/dist/store/tasks-schema.d.ts.map +1 -1
  452. package/dist/store/tasks-schema.js +60 -0
  453. package/dist/store/tasks-schema.js.map +1 -1
  454. package/dist/store/tasks-sqlite.d.ts +2 -2
  455. package/dist/store/tasks-sqlite.d.ts.map +1 -1
  456. package/dist/store/tasks-sqlite.js +10 -5
  457. package/dist/store/tasks-sqlite.js.map +1 -1
  458. package/dist/store/umbrella-data-accessor.d.ts +17 -6
  459. package/dist/store/umbrella-data-accessor.d.ts.map +1 -1
  460. package/dist/store/umbrella-data-accessor.js +8 -8
  461. package/dist/store/umbrella-data-accessor.js.map +1 -1
  462. package/dist/store/validation-schemas.d.ts +241 -208
  463. package/dist/store/validation-schemas.d.ts.map +1 -1
  464. package/dist/system/health.d.ts.map +1 -1
  465. package/dist/system/health.js +11 -6
  466. package/dist/system/health.js.map +1 -1
  467. package/dist/system/project-health.d.ts.map +1 -1
  468. package/dist/system/project-health.js +58 -12
  469. package/dist/system/project-health.js.map +1 -1
  470. package/dist/tasks/add.d.ts +8 -0
  471. package/dist/tasks/add.d.ts.map +1 -1
  472. package/dist/tasks/add.js +101 -0
  473. package/dist/tasks/add.js.map +1 -1
  474. package/dist/tasks/cancelled-child-waiver-audit.d.ts +47 -0
  475. package/dist/tasks/cancelled-child-waiver-audit.d.ts.map +1 -0
  476. package/dist/tasks/cancelled-child-waiver-audit.js +34 -0
  477. package/dist/tasks/cancelled-child-waiver-audit.js.map +1 -0
  478. package/dist/tasks/complete.d.ts +22 -2
  479. package/dist/tasks/complete.d.ts.map +1 -1
  480. package/dist/tasks/complete.js +71 -6
  481. package/dist/tasks/complete.js.map +1 -1
  482. package/dist/tasks/compute-task-view.js +1 -1
  483. package/dist/tasks/session-scope.d.ts +5 -0
  484. package/dist/tasks/session-scope.d.ts.map +1 -1
  485. package/dist/tasks/session-scope.js +4 -0
  486. package/dist/tasks/session-scope.js.map +1 -1
  487. package/dist/tools/guard.d.ts +71 -1
  488. package/dist/tools/guard.d.ts.map +1 -1
  489. package/dist/tools/guard.js +73 -1
  490. package/dist/tools/guard.js.map +1 -1
  491. package/dist/tools/index.d.ts +21 -0
  492. package/dist/tools/index.d.ts.map +1 -1
  493. package/dist/tools/index.js +25 -0
  494. package/dist/tools/index.js.map +1 -1
  495. package/dist/upgrade.d.ts.map +1 -1
  496. package/dist/upgrade.js +22 -13
  497. package/dist/upgrade.js.map +1 -1
  498. package/dist/workgraph/containment.js +18 -18
  499. package/dist/workgraph/relations.js +2 -2
  500. package/dist/worktree/list.d.ts +1 -1
  501. package/dist/worktree/list.d.ts.map +1 -1
  502. package/dist/worktree/list.js +19 -21
  503. package/dist/worktree/list.js.map +1 -1
  504. package/dist/worktree-export.d.ts +18 -0
  505. package/dist/worktree-export.d.ts.map +1 -0
  506. package/dist/worktree-export.js +18 -0
  507. package/dist/worktree-export.js.map +1 -0
  508. package/migrations/drizzle-agent-registry/20260412000000_initial-global-agent-registry/migration.sql +29 -0
  509. package/migrations/drizzle-brain/20260601000001_t11522-brain-task-observations/migration.sql +28 -0
  510. package/migrations/drizzle-brain/20260601000002_t11522-inline-only-brain-tables/migration.sql +75 -0
  511. package/migrations/drizzle-cleo-global/20260531000001_t11363-consolidation-cleo-global/migration.sql +49 -144
  512. package/migrations/drizzle-cleo-global/20260531000001_t11363-consolidation-cleo-global/snapshot.json +8 -8
  513. package/migrations/drizzle-cleo-global/20260531000002_t11546-brain-usage-log/migration.sql +16 -0
  514. package/migrations/drizzle-cleo-global/20260601000001_t11544-skills-usage-project-id/migration.sql +12 -0
  515. package/migrations/drizzle-cleo-global/20260602000001_t11622-agent-registry-rename/migration.sql +80 -0
  516. package/migrations/drizzle-cleo-project/20260531000001_t11363-consolidation-cleo-project/migration.sql +26 -167
  517. package/migrations/drizzle-cleo-project/20260531000001_t11363-consolidation-cleo-project/snapshot.json +8 -8
  518. package/migrations/drizzle-cleo-project/20260531000002_t11546-brain-usage-log/migration.sql +21 -0
  519. package/migrations/drizzle-cleo-project/20260601000001_t11549-agent-credentials-brain-release-links/migration.sql +49 -0
  520. package/migrations/drizzle-cleo-project/20260601000002_t11538-project-nexus-graph/migration.sql +140 -0
  521. package/migrations/drizzle-cleo-project/20260602000002_t11649-token-usage-transport-mcp/migration.sql +146 -0
  522. package/migrations/drizzle-conduit/20260601000003_t11523-conduit-inline-schema/migration.sql +82 -0
  523. package/migrations/drizzle-nexus/20260421200001_t1165-baseline-reset/migration.sql +26 -8
  524. package/migrations/drizzle-nexus/20260601000001_t11545-nexus-relation-weights-partition/migration.sql +97 -0
  525. package/package.json +45 -13
  526. package/scripts/install-supervisor-binary.mjs +50 -201
  527. package/scripts/napi-binary-picker.mjs +267 -0
  528. package/dist/agents/agent-registry.d.ts.map +0 -1
  529. package/dist/agents/agent-registry.js.map +0 -1
  530. package/dist/store/data-safety.d.ts +0 -92
  531. package/dist/store/data-safety.d.ts.map +0 -1
  532. package/dist/store/data-safety.js +0 -274
  533. package/dist/store/data-safety.js.map +0 -1
  534. package/dist/store/schema/cleo-global/signaldock.d.ts.map +0 -1
  535. package/dist/store/schema/cleo-global/signaldock.js.map +0 -1
  536. package/dist/store/schema/cleo-project/telemetry.d.ts.map +0 -1
  537. package/dist/store/schema/cleo-project/telemetry.js.map +0 -1
  538. package/dist/store/schema/signaldock-schema.d.ts.map +0 -1
  539. package/dist/store/schema/signaldock-schema.js.map +0 -1
  540. package/dist/store/signaldock-sqlite.d.ts +0 -173
  541. package/dist/store/signaldock-sqlite.d.ts.map +0 -1
  542. package/dist/store/signaldock-sqlite.js +0 -445
  543. package/dist/store/signaldock-sqlite.js.map +0 -1
  544. package/migrations/drizzle-nexus/20260318205558_initial/migration.sql +0 -46
  545. package/migrations/drizzle-nexus/20260412000001_t529-nexus-graph-tables/migration.sql +0 -49
  546. package/migrations/drizzle-nexus/20260415000001_t622-project-registry-paths/migration.sql +0 -12
  547. package/migrations/drizzle-nexus/20260419000001_t998-nexus-plasticity/migration.sql +0 -13
  548. package/migrations/drizzle-nexus/20260423052640_t1077-add-user-profile-table/migration.sql +0 -16
  549. package/migrations/drizzle-nexus/20260423052640_t1077-add-user-profile-table/snapshot.json +0 -1531
  550. package/migrations/drizzle-nexus/20260424140538_t1148-add-sigils-table/migration.sql +0 -13
  551. package/migrations/drizzle-nexus/20260424140538_t1148-add-sigils-table/snapshot.json +0 -1652
  552. package/migrations/drizzle-nexus/20260504000001_t1839-fts5-nexus-symbols/migration.sql +0 -68
  553. package/migrations/drizzle-nexus/20260507135519_t9163-nexus-is-external/migration.sql +0 -20
  554. package/migrations/drizzle-nexus/20260507135519_t9163-nexus-is-external/snapshot.json +0 -1652
  555. package/migrations/drizzle-nexus/20260526222449_t11025-project-id-aliases/migration.sql +0 -16
  556. package/migrations/drizzle-signaldock/20260412000000_initial-global-signaldock/migration.sql +0 -209
  557. package/migrations/drizzle-signaldock/20260412000000_initial-global-signaldock/snapshot.json +0 -2060
@@ -0,0 +1,464 @@
1
+ /**
2
+ * Exodus-on-open — lazy, idempotent, parity-gated auto-migration of the legacy
3
+ * multi-DB fleet into the consolidated dual-scope `cleo.db` on first open.
4
+ *
5
+ * ## Why this exists (data-continuity safety net · T11553)
6
+ *
7
+ * E6 routes every `getDb`/`getBrainDb`/etc read at the consolidated `cleo.db`.
8
+ * On an *existing* install the consolidated DB is freshly migrated but **empty**
9
+ * (0 base-table rows), while the user's real data still lives in the legacy
10
+ * `tasks.db` / `brain.db` / `conduit.db` / `signaldock.db` fleet (e.g. 4465
11
+ * tasks). Without an auto-migration the E8/T11251 cutover would make every
12
+ * user's data **invisible**. This module wires the existing `runExodusMigrate`
13
+ * engine to run **once, automatically, on first open** — gated by the
14
+ * `verifyMigration` (T11551) parity check so a partial or lossy migration NEVER
15
+ * becomes the live source of truth.
16
+ *
17
+ * ## Trigger condition (AC1)
18
+ *
19
+ * On first `openDualScopeDb(scope)` the hook runs iff **both**:
20
+ * 1. the consolidated `cleo.db` for that scope is EMPTY (the canonical first
21
+ * base table has zero rows), AND
22
+ * 2. at least one legacy source DB for that scope has rows.
23
+ *
24
+ * ## Idempotency (AC1)
25
+ *
26
+ * After a successful migration the consolidated DB is non-empty, so the
27
+ * emptiness check short-circuits on every subsequent open — a second open is a
28
+ * no-op. The check is also re-evaluated *inside* the single-flight lock
29
+ * (double-checked locking) so the process that loses a concurrency race never
30
+ * re-migrates.
31
+ *
32
+ * ## Parity gate + clean abort (AC2)
33
+ *
34
+ * After the copy, `verifyMigration` (T11551) compares row counts + canonical
35
+ * digests + FK integrity + enum drift legacy↔consolidated. The data-continuity
36
+ * gate is **row-count parity + zero migration-INTRODUCED FK orphans** (hash/enum
37
+ * drift are the expected normalisation diagnostics, and pre-existing SOURCE FK
38
+ * orphans are tolerated as zero-loss — see {@link isDataContinuityOk}). If a
39
+ * genuine deficit/introduced-orphan is detected the hook **aborts the cutover**:
40
+ * it rolls the half-migrated consolidated tables back to EMPTY (`DELETE FROM`
41
+ * every user table — see {@link rollbackConsolidatedToEmpty}) so the legacy DBs
42
+ * remain the source of truth, no half-migrated `cleo.db` is exposed, and there
43
+ * are no silent `INSERT OR IGNORE` row drops. The file is never unlinked; the
44
+ * chokepoint re-opens a fresh handle afterwards (the migrate engine closes the
45
+ * handles it opened, so the rollback re-opens the scope before truncating it).
46
+ *
47
+ * ## Retry correctness — journal invalidation on abort (T11572)
48
+ *
49
+ * `runExodusMigrate` is resumable: it journals each table `done` and SKIPS
50
+ * already-`done` tables on a re-run. On abort we truncate the consolidated rows
51
+ * back to empty, so a stale `done` journal would make the next open re-trigger
52
+ * (target empty), copy NOTHING (journal says done), re-verify the still-empty
53
+ * target, and re-abort — a permanent loop. The abort path therefore also calls
54
+ * `clearExodusJournal(plan.stagingDir)` so a post-abort retry RE-COPIES from
55
+ * scratch.
56
+ *
57
+ * ## Concurrency safety (AC6 · reconcile with T11554 / R13-T11278)
58
+ *
59
+ * Two processes opening a brand-new empty `cleo.db` simultaneously must not both
60
+ * migrate. A `proper-lockfile` single-flight lock on
61
+ * `<cleo.db>.exodus-on-open.lock` serialises the attempt; the loser re-checks
62
+ * emptiness under the lock and bails. This is the same first-run-race concern
63
+ * T11554 raises for schema bootstrap — both are solved by serialising the
64
+ * first-open mutation.
65
+ *
66
+ * @module
67
+ * @task T11553 (E6 · exodus-on-open)
68
+ * @epic T11249 (E6)
69
+ * @saga T11242 (SG-DB-SUBSTRATE-V2)
70
+ * @see packages/core/src/store/exodus/migrate.ts — runExodusMigrate engine
71
+ * @see packages/core/src/store/exodus/verify-migration.ts — verifyMigration parity gate (T11551)
72
+ * @see packages/core/src/store/dual-scope-db.ts — the open chokepoint that calls this
73
+ */
74
+ import { existsSync } from 'node:fs';
75
+ import { getLogger } from '../../logger.js';
76
+ import { withLock } from '../lock.js';
77
+ const log = getLogger('exodus-on-open');
78
+ /**
79
+ * Re-entrancy guard. `runExodusMigrate` itself calls `openDualScopeDb` for both
80
+ * scopes to create + populate the consolidated schema. Those nested opens MUST
81
+ * NOT recursively trigger another exodus-on-open. This flag is set for the
82
+ * duration of an auto-migration so the chokepoint skips the hook while a
83
+ * migration is already in flight.
84
+ */
85
+ let _exodusInProgress = false;
86
+ /**
87
+ * Opt-out env flag. Set `CLEO_DISABLE_EXODUS_ON_OPEN=1` to skip the lazy
88
+ * auto-migration entirely (e.g. for tooling that intentionally inspects an
89
+ * empty consolidated DB). The manual `cleo exodus migrate` path is unaffected.
90
+ */
91
+ function isDisabledByEnv() {
92
+ const v = process.env.CLEO_DISABLE_EXODUS_ON_OPEN;
93
+ return v === '1' || v === 'true';
94
+ }
95
+ /**
96
+ * The canonical "first base table" for each scope — the same existence anchor
97
+ * used by the migration journal reconciliation. If this table has zero rows the
98
+ * consolidated DB is considered empty for the purposes of the trigger.
99
+ *
100
+ * - project → `tasks_tasks`
101
+ * - global → `nexus_project_registry`
102
+ */
103
+ function baseTableForScope(scope) {
104
+ return scope === 'project' ? 'tasks_tasks' : 'nexus_project_registry';
105
+ }
106
+ /**
107
+ * Count rows in `table` on `nativeDb`, returning `0` if the table does not yet
108
+ * exist or the query fails. Used to decide whether the consolidated DB is empty.
109
+ */
110
+ function safeRowCount(nativeDb, table) {
111
+ try {
112
+ const row = nativeDb.prepare(`SELECT COUNT(*) AS n FROM "${table}"`).get();
113
+ return row?.n ?? 0;
114
+ }
115
+ catch {
116
+ // Table missing (pre-migration) or other read error → treat as empty.
117
+ return 0;
118
+ }
119
+ }
120
+ /**
121
+ * Return `true` if the consolidated `cleo.db` for `scope` is empty — i.e. the
122
+ * canonical base table for that scope has zero rows.
123
+ */
124
+ function consolidatedIsEmpty(nativeDb, scope) {
125
+ return safeRowCount(nativeDb, baseTableForScope(scope)) === 0;
126
+ }
127
+ /**
128
+ * Roll a half-migrated consolidated `cleo.db` back to EMPTY **in place**, on the
129
+ * caller's live handle — without closing the handle or deleting the file.
130
+ *
131
+ * Called on a parity-failure abort. `runExodusMigrate` writes into the SAME
132
+ * cached native handle the chokepoint caller is using (the cache is keyed by
133
+ * path), so we must NOT close it or unlink the file out from under the caller
134
+ * (`getBrainDb`/`ensureConduitDb` would then hit "database is not open"). Instead
135
+ * we `DELETE FROM` every user table inside a single transaction with foreign
136
+ * keys OFF, restoring the post-migration *empty* schema. The caller then
137
+ * proceeds with an empty `cleo.db` and the legacy DBs remain the source of
138
+ * truth — exactly the AC2 "no half-migrated cleo.db" contract, achieved without
139
+ * destroying the open handle.
140
+ *
141
+ * The schema (tables, indexes, drizzle journal) is preserved; only data rows are
142
+ * removed. Idempotent and best-effort: a failure to clear one table is logged
143
+ * but does not throw (the next open's emptiness check still sees a populated
144
+ * base table and could re-attempt, which is acceptable — it will re-abort).
145
+ *
146
+ * @param nativeDb - The live consolidated handle to truncate.
147
+ * @param scope - Scope label for logging.
148
+ */
149
+ function rollbackConsolidatedToEmpty(nativeDb, scope) {
150
+ let userTables = [];
151
+ try {
152
+ userTables = nativeDb
153
+ .prepare("SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' AND name NOT LIKE '__drizzle_%'")
154
+ .all().map((r) => r.name);
155
+ }
156
+ catch (err) {
157
+ log.error({ err, scope }, 'exodus-on-open: failed to enumerate tables for rollback');
158
+ return;
159
+ }
160
+ try {
161
+ nativeDb.exec('PRAGMA foreign_keys = OFF');
162
+ nativeDb.exec('BEGIN');
163
+ for (const table of userTables) {
164
+ try {
165
+ nativeDb.exec(`DELETE FROM "${table}"`);
166
+ }
167
+ catch (err) {
168
+ log.warn({ err, table, scope }, 'exodus-on-open: failed to clear table during rollback');
169
+ }
170
+ }
171
+ nativeDb.exec('COMMIT');
172
+ }
173
+ catch (err) {
174
+ try {
175
+ nativeDb.exec('ROLLBACK');
176
+ }
177
+ catch {
178
+ // ignore — nothing to roll back
179
+ }
180
+ log.error({ err, scope }, 'exodus-on-open: rollback transaction failed');
181
+ }
182
+ finally {
183
+ try {
184
+ nativeDb.exec('PRAGMA foreign_keys = ON');
185
+ }
186
+ catch {
187
+ // ignore
188
+ }
189
+ }
190
+ }
191
+ /**
192
+ * Roll BOTH consolidated scopes back to empty after a failed auto-migration.
193
+ *
194
+ * IMPORTANT: `runExodusMigrate` closes the dual-scope handles it opened (and
195
+ * evicts them from the chokepoint cache) when it finishes — including on
196
+ * failure. Any `nativeDb` reference captured before the migrate ran is therefore
197
+ * already CLOSED, so we must NOT operate on it. Instead we re-open each scope
198
+ * fresh from the chokepoint (a cache-miss → a new live handle on the same
199
+ * on-disk file, which still holds the half-migrated rows) and truncate THAT.
200
+ * `_exodusInProgress` is still `true`, so the re-opens do not recurse into the
201
+ * hook.
202
+ *
203
+ * @param scope - The scope being opened (logging context only; both scopes are
204
+ * cleared because `runExodusMigrate` populates both).
205
+ */
206
+ async function rollbackBothScopes(scope) {
207
+ const { openDualScopeDb } = await import('../dual-scope-db.js');
208
+ for (const s of ['project', 'global']) {
209
+ try {
210
+ const handle = s === 'project' ? await openDualScopeDb('project') : await openDualScopeDb('global');
211
+ const native = handle.db.$client;
212
+ if (native) {
213
+ rollbackConsolidatedToEmpty(native, s);
214
+ }
215
+ }
216
+ catch (err) {
217
+ log.warn({ err, scope: s, openingScope: scope }, 'exodus-on-open: could not roll back scope (best-effort)');
218
+ }
219
+ }
220
+ }
221
+ /**
222
+ * Decide whether a {@link verifyMigration} result clears the **data-continuity**
223
+ * gate — the campaign-aligned zero-loss invariant (DHQ-045 · T11551).
224
+ *
225
+ * `verifyMigration().ok` is intentionally STRICTER than data-continuity: it also
226
+ * requires `hashMatch` and zero enum-drift findings. After a CORRECT migration
227
+ * those two will legitimately be `false`, because the migration NORMALISES the
228
+ * data (legacy enum aliases like `'ACCEPTED'`→`'accepted'`, epoch→ISO
229
+ * timestamps) — so the consolidated content digest differs from the un-normalised
230
+ * source, and the source still reports its raw drift as a diagnostic. Treating
231
+ * that as a parity failure would abort EVERY real migration.
232
+ *
233
+ * The zero-loss invariant the exodus campaign actually proves (and the one the
234
+ * representative real-data parity test asserts) is:
235
+ *
236
+ * 1. every data-bearing base table copied with NO ROW DEFICIT
237
+ * (`targetCount >= sourceCount` — you cannot LOSE a row you have MORE of),
238
+ * AND
239
+ * 2. NO referential orphans the migration INTRODUCED on the consolidated
240
+ * target (`introducedForeignKeyViolations` empty).
241
+ *
242
+ * ## A row SURPLUS is NOT data loss (T11577)
243
+ *
244
+ * Data loss means rows are MISSING: `targetCount < sourceCount` (a DEFICIT).
245
+ * A SURPLUS (`targetCount > sourceCount`) cannot be loss — every source row is
246
+ * still present, plus extra. The canonical benign surplus is the migration's
247
+ * OWN audit trail: `runExodusMigrate` opens the nexus registry, whose
248
+ * `writeNexusAudit` (`nexus/registry.ts`) appends rows to `nexus_audit_log`
249
+ * DURING the migrating open, so the consolidated `nexus_audit_log` legitimately
250
+ * has a few MORE rows than the legacy source (e.g. 161923 → 161926). Gating on
251
+ * exact `countMatch` (`source === target`) wrongly aborts the cutover on that
252
+ * append. The gate therefore fails ONLY on a genuine DEFICIT; a surplus is
253
+ * tolerated and logged as a WARN (with the table + delta) so it stays visible
254
+ * and a double-copy on a non-append table could still be spotted by an operator.
255
+ * Deficits are NEVER tolerated — that is the real data-loss class.
256
+ *
257
+ * ## Pre-existing source orphans are tolerated (T11572)
258
+ *
259
+ * A legacy source DB can already contain referential orphans (e.g. a
260
+ * `tasks_task_relations` row pointing at a task that was deleted long before the
261
+ * migration). Those rows copy through faithfully — that is ZERO loss, not a
262
+ * migration defect — so they appear on BOTH sides and `verifyMigration`
263
+ * classifies them as `preExistingForeignKeyViolations`. Gating on the *total*
264
+ * orphan set (`foreignKeyViolations`) would permanently abort every real cutover
265
+ * over a defect the data already had. The gate therefore fails ONLY on
266
+ * `introducedForeignKeyViolations` — orphans present on the target that the
267
+ * source did not have (i.e. the migration dropped a parent row). Pre-existing
268
+ * orphans are logged as a WARN for a data-hygiene follow-up.
269
+ *
270
+ * Hash mismatch + source enum-drift are surfaced as WARN diagnostics (a true
271
+ * content corruption would normally also show up as an introduced FK orphan or a
272
+ * count deficit), but they do NOT, on their own, indicate data loss.
273
+ *
274
+ * @param result - The {@link VerifyMigrationResult} from `verifyMigration`.
275
+ * @returns `true` when NO base table has a row DEFICIT (`targetCount <
276
+ * sourceCount`) and the migration introduced no new FK orphans — i.e. the
277
+ * cutover is safe. A surplus (`targetCount > sourceCount`) is tolerated.
278
+ *
279
+ * @task T11577 (deficit-only gate — tolerate benign migration-time surplus)
280
+ */
281
+ export function isDataContinuityOk(result) {
282
+ // A DEFICIT (target has FEWER rows than source) is the genuine data-loss
283
+ // class — abort. A SURPLUS (target has MORE, e.g. nexus_audit_log gaining the
284
+ // migration's own audit writes) is NOT loss; tolerate it but log a WARN so the
285
+ // table + delta stay visible (a surplus on a non-append table could hint at a
286
+ // double-copy worth an operator's attention).
287
+ const deficits = result.tables.filter((t) => t.targetCount < t.sourceCount);
288
+ const surpluses = result.tables.filter((t) => t.targetCount > t.sourceCount);
289
+ if (surpluses.length > 0) {
290
+ log.warn({
291
+ surpluses: surpluses.map((t) => ({
292
+ table: t.targetTable,
293
+ scope: t.scope,
294
+ source: t.sourceCount,
295
+ target: t.targetCount,
296
+ delta: t.targetCount - t.sourceCount,
297
+ })),
298
+ }, `exodus-on-open: ${surpluses.length} table(s) have MORE rows in target than source ` +
299
+ `(row surplus — NOT data loss, tolerated; e.g. migration-time nexus_audit_log writes). ` +
300
+ `Verify none is an unexpected double-copy on a non-append table.`);
301
+ }
302
+ return deficits.length === 0 && result.introducedForeignKeyViolations.length === 0;
303
+ }
304
+ /**
305
+ * Lazily migrate the legacy fleet into the consolidated `cleo.db` on first open.
306
+ *
307
+ * This is the thin guard wired into {@link openDualScopeDb}. It is invoked AFTER
308
+ * the consolidated schema migrations have run (so the base tables exist) but
309
+ * BEFORE the handle is returned to the caller. It is a no-op unless the trigger
310
+ * condition (AC1) holds.
311
+ *
312
+ * Re-entrancy, concurrency, parity gating, and clean abort are all handled here
313
+ * — see the module docs. The heavy lifting (copy, journal, backup, attach-leak
314
+ * safety) is delegated to the existing {@link runExodusMigrate} engine; this
315
+ * function adds only the *when* (lazy trigger) and the *safety envelope*
316
+ * (single-flight + verify-or-rollback).
317
+ *
318
+ * On a parity-failure abort the migration's writes are rolled back IN PLACE on
319
+ * the caller's live handle (see {@link rollbackConsolidatedToEmpty}) — the
320
+ * handle is never closed and the file is never deleted, so the chokepoint caller
321
+ * (`getBrainDb`/`ensureConduitDb`/…) keeps a valid, empty `cleo.db` and the
322
+ * legacy DBs remain the source of truth.
323
+ *
324
+ * @param scope - The scope being opened (`'project'` | `'global'`).
325
+ * @param dbPath - Absolute path to the consolidated `cleo.db` for `scope`.
326
+ * @param nativeDb - The freshly-opened native handle (post-migration). This is
327
+ * the SAME cached handle `runExodusMigrate` writes through,
328
+ * so the rollback truncates it in place rather than deleting.
329
+ * @param cwd - Working directory used to resolve the project root.
330
+ * @returns The {@link ExodusOnOpenResult} describing what happened.
331
+ *
332
+ * @task T11553 (AC1, AC2, AC6)
333
+ * @epic T11249 (E6)
334
+ * @saga T11242
335
+ */
336
+ export async function maybeRunExodusOnOpen(scope, dbPath, nativeDb, cwd) {
337
+ // Re-entrancy: the nested opens from runExodusMigrate must never recurse.
338
+ if (_exodusInProgress) {
339
+ return { outcome: 'skipped', reason: 're-entrant open during active migration' };
340
+ }
341
+ if (isDisabledByEnv()) {
342
+ return { outcome: 'skipped', reason: 'CLEO_DISABLE_EXODUS_ON_OPEN set' };
343
+ }
344
+ // Fast path (unlocked): if the consolidated DB already has data, nothing to do.
345
+ // This makes the second-open case a cheap COUNT(*) with no lock acquisition.
346
+ if (!consolidatedIsEmpty(nativeDb, scope)) {
347
+ return { outcome: 'skipped', reason: 'consolidated cleo.db already populated' };
348
+ }
349
+ // Lazy-load the exodus engine via dynamic import to break the import cycle
350
+ // (exodus/migrate.ts imports openDualScopeDb from dual-scope-db.ts).
351
+ const { buildExodusPlan, runExodusMigrate, verifyMigration, clearExodusJournal } = await import('./index.js');
352
+ const plan = buildExodusPlan(cwd);
353
+ // Trigger ONLY on sources that belong to the SCOPE being opened. A
354
+ // project-scope open must not fire because a GLOBAL legacy DB (e.g.
355
+ // signaldock.db) happens to exist — that would (a) wrongly migrate global
356
+ // data on a project read and (b) collide with the legacy signaldock→conduit
357
+ // migration, which legitimately opens an empty project `cleo.db` while a
358
+ // global signaldock.db is present. The migration engine still consolidates
359
+ // BOTH scopes once triggered; this gate only decides WHEN to fire.
360
+ const scopeSources = plan.sources.filter((s) => s.targetScope === scope);
361
+ if (!scopeSources.some((s) => existsSync(s.path))) {
362
+ return {
363
+ outcome: 'skipped',
364
+ reason: `no legacy ${scope}-scope source DBs present (fresh install or cross-scope-only)`,
365
+ };
366
+ }
367
+ // Single-flight: serialise the first-open migration across processes so two
368
+ // concurrent opens never both migrate (AC6 · T11554 first-run race).
369
+ const lockPath = `${dbPath}.exodus-on-open.lock`;
370
+ return withLock(lockPath, async () => {
371
+ // Double-checked locking: a process that lost the race will find the DB
372
+ // already populated (by the winner) and bail without re-migrating.
373
+ if (!consolidatedIsEmpty(nativeDb, scope)) {
374
+ return { outcome: 'skipped', reason: 'migrated by a concurrent process (lock winner)' };
375
+ }
376
+ log.info({
377
+ scope,
378
+ dbPath,
379
+ sources: plan.sources.filter((s) => existsSync(s.path)).map((s) => s.name),
380
+ }, 'exodus-on-open: consolidated cleo.db is empty and legacy data present — auto-migrating');
381
+ _exodusInProgress = true;
382
+ try {
383
+ // 1. Run the migration engine (copies BOTH scopes; idempotent + journaled).
384
+ const migrateResult = await runExodusMigrate(plan, false, (msg) => log.debug({ scope }, `exodus-on-open: ${msg}`));
385
+ if (!migrateResult.ok) {
386
+ // Migration itself failed mid-copy — abort the cutover cleanly by
387
+ // rolling the consolidated tables back to empty IN PLACE (handle stays
388
+ // open; legacy DBs remain the source of truth).
389
+ await rollbackBothScopes(scope);
390
+ // T11572: invalidate the journal so the NEXT open re-copies instead of
391
+ // resuming a half-done journal against the now-empty target (abort loop).
392
+ clearExodusJournal(migrateResult.stagingDir);
393
+ const reason = `migration failed: ${migrateResult.error ?? 'unknown error'} — legacy DBs kept as source`;
394
+ log.error({ scope, error: migrateResult.error }, `exodus-on-open: ${reason}`);
395
+ return { outcome: 'aborted', reason };
396
+ }
397
+ // 2. PARITY GATE (AC2): verifyMigration (T11551) — row-count + content
398
+ // digest + FK integrity + enum-drift equivalence legacy↔consolidated.
399
+ const verifyResult = verifyMigration(plan.sources, plan.projectDbPath, plan.globalDbPath, (msg) => log.debug({ scope }, `exodus-on-open verify: ${msg}`));
400
+ // Surface diagnostics (hash mismatch / source enum-drift) but do NOT
401
+ // abort on them — see isDataContinuityOk(). A correct normalising
402
+ // migration legitimately produces both; only a row-count deficit or an
403
+ // FK orphan means actual data loss.
404
+ if (!verifyResult.ok) {
405
+ log.warn({
406
+ scope,
407
+ enumDrift: verifyResult.enumDrift.length,
408
+ hashMismatches: verifyResult.tables.filter((t) => !t.hashMatch).length,
409
+ }, 'exodus-on-open: verifyMigration reported non-fatal drift (normalisation expected); checking data-continuity gate');
410
+ }
411
+ if (!isDataContinuityOk(verifyResult)) {
412
+ // DATA LOSS (count deficit or FK orphan) → abort. Roll the half-migrated
413
+ // consolidated tables back to EMPTY in place so legacy remains the
414
+ // source of truth. Never expose a lossy consolidated DB; never close the
415
+ // caller's handle.
416
+ await rollbackBothScopes(scope);
417
+ // T11572: invalidate the journal so a retry re-copies (see above).
418
+ clearExodusJournal(plan.stagingDir);
419
+ // T11577: report only genuine DEFICITS (target < source) — a surplus
420
+ // is tolerated by isDataContinuityOk() and must not appear as a cause.
421
+ const deficits = verifyResult.tables
422
+ .filter((t) => t.targetCount < t.sourceCount)
423
+ .map((t) => `${t.targetTable}(${t.sourceCount}→${t.targetCount})`);
424
+ const reason = `parity verification failed — cutover aborted, legacy DBs kept as source. ` +
425
+ `count deficits: [${deficits.join(', ')}]; ` +
426
+ `INTRODUCED fk orphans: ${verifyResult.introducedForeignKeyViolations.length} ` +
427
+ `(pre-existing source orphans tolerated: ${verifyResult.preExistingForeignKeyViolations.length}). ` +
428
+ `${verifyResult.error ?? ''}`.trim();
429
+ log.error({
430
+ scope,
431
+ countDeficits: deficits,
432
+ introducedFkViolations: verifyResult.introducedForeignKeyViolations.length,
433
+ preExistingFkViolations: verifyResult.preExistingForeignKeyViolations.length,
434
+ }, 'exodus-on-open: data-continuity FAILED — consolidated cleo.db rolled back to empty, legacy kept');
435
+ return { outcome: 'aborted', reason };
436
+ }
437
+ const rowsCopied = migrateResult.tables
438
+ .filter((t) => !t.skipped)
439
+ .reduce((n, t) => n + t.rowsCopied, 0);
440
+ log.info({ scope, rowsCopied, tables: migrateResult.tables.length }, 'exodus-on-open: parity verified — legacy data migrated into consolidated cleo.db');
441
+ return {
442
+ outcome: 'migrated',
443
+ reason: `migrated ${rowsCopied} rows across ${migrateResult.tables.length} tables; parity verified`,
444
+ rowsCopied,
445
+ };
446
+ }
447
+ finally {
448
+ _exodusInProgress = false;
449
+ }
450
+ },
451
+ // Tolerate a slow migration: a large fleet copy can take a while, so allow a
452
+ // generous stale window and a few retries while the winner holds the lock.
453
+ { stale: 600_000, retries: 30 });
454
+ }
455
+ /**
456
+ * Test-only accessor: whether an exodus migration is currently in flight. Used
457
+ * to assert the re-entrancy guard does not recurse.
458
+ *
459
+ * @internal
460
+ */
461
+ export function _isExodusInProgress() {
462
+ return _exodusInProgress;
463
+ }
464
+ //# sourceMappingURL=on-open.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"on-open.js","sourceRoot":"","sources":["../../../src/store/exodus/on-open.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,173 @@
1
+ /**
2
+ * Deterministic legacy-to-consolidated table-name resolver for exodus migration.
3
+ *
4
+ * ## Problem (ROOT CAUSE 1 — T11532)
5
+ *
6
+ * Legacy source DBs use UNPREFIXED table names (`tasks`, `messages`, `skills`, …)
7
+ * while the consolidated dual-scope `cleo.db` uses DOMAIN-PREFIXED names
8
+ * (`tasks_tasks`, `conduit_messages`, `skills_skills`, …). Without a mapping,
9
+ * every `INSERT OR IGNORE INTO main."<name>"` silently copies 0 rows because the
10
+ * target table is absent under the legacy name.
11
+ *
12
+ * ## Design
13
+ *
14
+ * The mapping is a static lookup table derived from reading every
15
+ * `cleo-project/` and `cleo-global/` schema file and matching the physical
16
+ * `sqliteTable('<consolidated-name>', …)` names against each legacy DB's schema.
17
+ *
18
+ * Rules:
19
+ * - If a legacy table is already domain-prefixed in the consolidated schema
20
+ * (e.g. `brain_observations`, `nexus_audit_log`, `tasks_goal`), map identity.
21
+ * - If a legacy table has NO consolidated counterpart (virtual tables, orphan
22
+ * telemetry tables, …), return `null` so the caller can log + skip explicitly
23
+ * rather than silently discarding rows.
24
+ *
25
+ * ## Source-DB scope
26
+ *
27
+ * The resolver takes a `sourceName` (the `LegacyDbDescriptor.name` value, e.g.
28
+ * `"tasks"`, `"brain (project)"`, `"conduit"`) to disambiguate tables that
29
+ * share the same legacy name across multiple DBs (e.g. `"attachments"` lives in
30
+ * both conduit.db and attachments.ts/tasks.db; `"sessions"` lives in both
31
+ * tasks.db and signaldock.db).
32
+ *
33
+ * ## Nexus code-graph residency move (ADR-090 · T11539)
34
+ *
35
+ * The four nexus code-graph tables — `nexus_nodes`, `nexus_relations`,
36
+ * `nexus_contracts`, `nexus_code_index` (ADR-090 "Category A") — were removed
37
+ * from the GLOBAL schema (`../schema/cleo-global/nexus.ts`) and now reside in
38
+ * PROJECT scope (`../schema/cleo-project/nexus-graph.ts`). They are still
39
+ * extracted from the legacy GLOBAL `nexus.db` source, but exodus MUST route them
40
+ * into the PROJECT-scope consolidated `cleo.db`, not the global one. The source
41
+ * descriptor `nexus` carries `targetScope: 'global'`, so a per-table scope
42
+ * override is required for these four tables — see
43
+ * {@link NEXUS_GRAPH_PROJECT_TABLES} and {@link resolveTableTargetScope}. The
44
+ * six registry/identity tables (`nexus_project_registry`,
45
+ * `nexus_project_id_aliases`, `nexus_audit_log`, `nexus_schema_meta`,
46
+ * `nexus_user_profile`, `nexus_sigils`) stay GLOBAL.
47
+ *
48
+ * @task T11532 (ROOT CAUSE 1 — name-mapping gap)
49
+ * @task T11533 (ROOT CAUSE 3 — signaldock skills mapping + brain_release_links skip +
50
+ * brain_session_narrative mapping)
51
+ * @task T11546 (no-home-table fixes — schema_meta→tasks_schema_meta, brain_usage_log mapping,
52
+ * brain_schema_meta mapping)
53
+ * @task T11539 (nexus code-graph residency — route the 4 graph tables to PROJECT scope)
54
+ * @epic T11248
55
+ * @saga T11242
56
+ */
57
+ import type { ExodusScope } from './types.js';
58
+ /**
59
+ * Legacy table names of the four nexus code-graph tables that moved from GLOBAL
60
+ * to PROJECT scope (ADR-090 · T11538/T11539).
61
+ *
62
+ * Keyed by the LEGACY physical name as it appears in `nexus.db`:
63
+ * - `nexus_nodes`, `nexus_relations`, `nexus_contracts` — already prefixed.
64
+ * - `code_index` — bare in legacy `nexus.db`; → `nexus_code_index` consolidated.
65
+ *
66
+ * Membership drives {@link resolveTableTargetScope}: exodus copies/verifies
67
+ * these against the PROJECT consolidated `cleo.db`, NOT the GLOBAL one, even
68
+ * though the `nexus` source descriptor's `targetScope` is `'global'`.
69
+ *
70
+ * @task T11539
71
+ * @epic T11248
72
+ * @saga T11242
73
+ * @see cleo docs fetch adr-090-nexus-graph-residency-split
74
+ */
75
+ export declare const NEXUS_GRAPH_PROJECT_TABLES: ReadonlySet<string>;
76
+ /**
77
+ * Resolve the consolidated TARGET SCOPE for a legacy source table.
78
+ *
79
+ * Most tables share the scope of their source DB descriptor (`sourceScope`).
80
+ * The exception is the four nexus code-graph tables — they are extracted from
81
+ * the GLOBAL legacy `nexus.db` but land in PROJECT scope per ADR-090 (T11539).
82
+ *
83
+ * This is the SSoT consumed by BOTH the exodus migrate runner (insert target DB)
84
+ * and the exodus verifier (verify target DB) so the two never disagree.
85
+ *
86
+ * @param sourceName - `LegacyDbDescriptor.name` (e.g. `"nexus"`, `"tasks"`).
87
+ * @param legacyTable - Physical table name in the legacy source DB.
88
+ * @param sourceScope - The source descriptor's `targetScope`.
89
+ * @returns The scope of the consolidated `cleo.db` this table copies into.
90
+ *
91
+ * @task T11539
92
+ * @epic T11248
93
+ * @saga T11242
94
+ */
95
+ export declare function resolveTableTargetScope(sourceName: string, legacyTable: string, sourceScope: ExodusScope): ExodusScope;
96
+ /**
97
+ * Return `true` if `tableName` is a DERIVED or INTERNAL table that must be
98
+ * EXCLUDED from the exodus row-count-parity gate (and from the copy path).
99
+ *
100
+ * This is the single, named, documented classification consumed by BOTH the
101
+ * migrate copy loop and the `verifyMigration` parity check, so the two never
102
+ * disagree about which tables carry migratable user data. It recognises:
103
+ *
104
+ * 1. **FTS5 virtual tables** — a bare `*_fts` name (e.g. `brain_decisions_fts`,
105
+ * `messages_fts`). The virtual table itself cannot be `INSERT … SELECT`-ed
106
+ * and is rebuilt from its content table after migration.
107
+ * 2. **FTS5 shadow/backing tables** — `*_fts_data`, `*_fts_idx`,
108
+ * `*_fts_docsize`, `*_fts_config`, `*_fts_content` (see
109
+ * {@link FTS5_SHADOW_SUFFIXES}). Derived; rebuilt post-migration.
110
+ * 3. **Internal bookkeeping** — any per-source schema-version / migration
111
+ * ledger: `_conduit_meta`, `_conduit_migrations`, `_signaldock_meta`,
112
+ * `_signaldock_migrations`, `_skills_meta`, and — generalised via
113
+ * {@link INTERNAL_LEDGER_PATTERN} — ANY `_<domain>_meta` /
114
+ * `_<domain>_migrations` ledger from a future source DB (see
115
+ * {@link INTERNAL_BOOKKEEPING_TABLES}). Schema-version ledgers with no
116
+ * consolidated home.
117
+ *
118
+ * A migration is "safe" iff every BASE-DATA row survives; these derived/internal
119
+ * tables are NOT base data, so a 0-row consolidated counterpart for them is
120
+ * expected and correct — not data loss.
121
+ *
122
+ * @param tableName - Physical table name from a legacy source DB.
123
+ * @returns `true` when the table is derived/internal and must be skipped.
124
+ *
125
+ * @task T11572 (exodus parity gate: exclude FTS5 + internal/meta shadow tables)
126
+ * @task T11577 (generalise internal-ledger skip to signaldock/skills + any per-source ledger)
127
+ * @epic T11249 (E6)
128
+ * @saga T11242
129
+ */
130
+ export declare function isDerivedOrInternalTable(tableName: string): boolean;
131
+ /**
132
+ * Result of resolving a legacy table name to its consolidated target.
133
+ *
134
+ * `kind === 'mapped'` — `targetName` holds the consolidated physical name.
135
+ * `kind === 'skip'` — table is intentionally excluded (virtual, orphan, etc.);
136
+ * `reason` holds a human-readable explanation.
137
+ * `kind === 'unknown'` — source DB is unrecognized; falls back to identity copy
138
+ * (best-effort for forward-compatibility with future DBs).
139
+ */
140
+ export type TableNameResolution = {
141
+ readonly kind: 'mapped';
142
+ readonly targetName: string;
143
+ } | {
144
+ readonly kind: 'skip';
145
+ readonly reason: string;
146
+ } | {
147
+ readonly kind: 'unknown';
148
+ readonly targetName: string;
149
+ };
150
+ /**
151
+ * Resolve the consolidated target table name for a legacy source table.
152
+ *
153
+ * @param sourceName - `LegacyDbDescriptor.name` (e.g. `"tasks"`, `"brain (project)"`).
154
+ * @param legacyTable - Physical table name from the legacy source DB.
155
+ * @returns A `TableNameResolution` describing how to copy (or skip) the table.
156
+ */
157
+ export declare function resolveConsolidatedTableName(sourceName: string, legacyTable: string): TableNameResolution;
158
+ /**
159
+ * Reverse-lookup: given a consolidated target table name, return the set of
160
+ * legacy (sourceName, legacyTableName) pairs that map to it.
161
+ *
162
+ * Used by `runExodusVerify()` to compare legacy source counts against the
163
+ * correct consolidated target table rather than the legacy table name.
164
+ *
165
+ * Returns an empty array if no legacy table maps to the given consolidated name.
166
+ */
167
+ export declare function reverseLookup(consolidatedTable: string, sources: ReadonlyArray<{
168
+ readonly name: string;
169
+ }>): Array<{
170
+ sourceName: string;
171
+ legacyTable: string;
172
+ }>;
173
+ //# sourceMappingURL=table-name-map.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"table-name-map.d.ts","sourceRoot":"","sources":["../../../src/store/exodus/table-name-map.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuDG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AA4O9C;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,0BAA0B,EAAE,WAAW,CAAC,MAAM,CAKzD,CAAC;AAEH;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,uBAAuB,CACrC,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,WAAW,GACvB,WAAW,CAKb;AAoKD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAUnE;AAMD;;;;;;;;GAQG;AACH,MAAM,MAAM,mBAAmB,GAC3B;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GACxD;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAClD;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC;AAE9D;;;;;;GAMG;AACH,wBAAgB,4BAA4B,CAC1C,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,GAClB,mBAAmB,CA6DrB;AAyBD;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAC3B,iBAAiB,EAAE,MAAM,EACzB,OAAO,EAAE,aAAa,CAAC;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,GAChD,KAAK,CAAC;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAAC,CAkCpD"}