@cleocode/core 2026.5.133 → 2026.6.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 (560) 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/local-transport.d.ts +1 -1
  19. package/dist/conduit/local-transport.d.ts.map +1 -1
  20. package/dist/conduit/local-transport.js +69 -43
  21. package/dist/conduit/local-transport.js.map +1 -1
  22. package/dist/dispatch/mutate-projection.d.ts.map +1 -1
  23. package/dist/dispatch/mutate-projection.js +11 -0
  24. package/dist/dispatch/mutate-projection.js.map +1 -1
  25. package/dist/docs/docs-read-model.d.ts +7 -0
  26. package/dist/docs/docs-read-model.d.ts.map +1 -1
  27. package/dist/docs/docs-read-model.js +5 -0
  28. package/dist/docs/docs-read-model.js.map +1 -1
  29. package/dist/docs/supersede.d.ts.map +1 -1
  30. package/dist/docs/supersede.js +12 -7
  31. package/dist/docs/supersede.js.map +1 -1
  32. package/dist/doctor/db-substrate.d.ts.map +1 -1
  33. package/dist/doctor/db-substrate.js +10 -9
  34. package/dist/doctor/db-substrate.js.map +1 -1
  35. package/dist/git-shim-export.d.ts +18 -0
  36. package/dist/git-shim-export.d.ts.map +1 -0
  37. package/dist/git-shim-export.js +18 -0
  38. package/dist/git-shim-export.js.map +1 -0
  39. package/dist/hooks/payload-schemas.d.ts +2 -2
  40. package/dist/init.d.ts.map +1 -1
  41. package/dist/init.js +39 -32
  42. package/dist/init.js.map +1 -1
  43. package/dist/internal.d.ts +11 -3
  44. package/dist/internal.d.ts.map +1 -1
  45. package/dist/internal.js +14 -5
  46. package/dist/internal.js.map +1 -1
  47. package/dist/lafs-export.d.ts +18 -0
  48. package/dist/lafs-export.d.ts.map +1 -0
  49. package/dist/lafs-export.js +18 -0
  50. package/dist/lafs-export.js.map +1 -0
  51. package/dist/lifecycle/effective-stage.js +1 -1
  52. package/dist/lifecycle/index.js +1 -1
  53. package/dist/lifecycle/index.js.map +1 -1
  54. package/dist/lifecycle/rollup.js +1 -1
  55. package/dist/llm/credential-pool.d.ts +17 -0
  56. package/dist/llm/credential-pool.d.ts.map +1 -1
  57. package/dist/llm/credential-pool.js +40 -1
  58. package/dist/llm/credential-pool.js.map +1 -1
  59. package/dist/llm/plugin-facade.d.ts.map +1 -1
  60. package/dist/llm/plugin-facade.js +11 -19
  61. package/dist/llm/plugin-facade.js.map +1 -1
  62. package/dist/llm/role-executor.d.ts +8 -0
  63. package/dist/llm/role-executor.d.ts.map +1 -1
  64. package/dist/llm/role-executor.js +96 -4
  65. package/dist/llm/role-executor.js.map +1 -1
  66. package/dist/llm/role-resolver.d.ts.map +1 -1
  67. package/dist/llm/role-resolver.js +56 -1
  68. package/dist/llm/role-resolver.js.map +1 -1
  69. package/dist/llm/transports/codex-oauth-headers.d.ts +51 -0
  70. package/dist/llm/transports/codex-oauth-headers.d.ts.map +1 -0
  71. package/dist/llm/transports/codex-oauth-headers.js +89 -0
  72. package/dist/llm/transports/codex-oauth-headers.js.map +1 -0
  73. package/dist/memory/claude-mem-migration.d.ts.map +1 -1
  74. package/dist/memory/claude-mem-migration.js +1 -3
  75. package/dist/memory/claude-mem-migration.js.map +1 -1
  76. package/dist/memory/decisions.d.ts.map +1 -1
  77. package/dist/memory/decisions.js +77 -23
  78. package/dist/memory/decisions.js.map +1 -1
  79. package/dist/memory/graph-memory-bridge.d.ts.map +1 -1
  80. package/dist/memory/graph-memory-bridge.js +12 -6
  81. package/dist/memory/graph-memory-bridge.js.map +1 -1
  82. package/dist/memory/learnings.d.ts +2 -2
  83. package/dist/memory/nexus-plasticity.d.ts +21 -9
  84. package/dist/memory/nexus-plasticity.d.ts.map +1 -1
  85. package/dist/memory/nexus-plasticity.js +44 -22
  86. package/dist/memory/nexus-plasticity.js.map +1 -1
  87. package/dist/memory/patterns.d.ts +2 -2
  88. package/dist/memory/redaction.d.ts +19 -3
  89. package/dist/memory/redaction.d.ts.map +1 -1
  90. package/dist/memory/redaction.js +22 -94
  91. package/dist/memory/redaction.js.map +1 -1
  92. package/dist/metrics/token-service.d.ts +8 -2
  93. package/dist/metrics/token-service.d.ts.map +1 -1
  94. package/dist/metrics/token-service.js +1 -1
  95. package/dist/metrics/token-service.js.map +1 -1
  96. package/dist/nexus/analyze-orchestrator.d.ts.map +1 -1
  97. package/dist/nexus/analyze-orchestrator.js +6 -8
  98. package/dist/nexus/analyze-orchestrator.js.map +1 -1
  99. package/dist/nexus/api-extractors/http-extractor.d.ts.map +1 -1
  100. package/dist/nexus/api-extractors/http-extractor.js +3 -3
  101. package/dist/nexus/api-extractors/http-extractor.js.map +1 -1
  102. package/dist/nexus/clusters.d.ts.map +1 -1
  103. package/dist/nexus/clusters.js +3 -2
  104. package/dist/nexus/clusters.js.map +1 -1
  105. package/dist/nexus/context.d.ts.map +1 -1
  106. package/dist/nexus/context.js +10 -16
  107. package/dist/nexus/context.js.map +1 -1
  108. package/dist/nexus/diff.d.ts.map +1 -1
  109. package/dist/nexus/diff.js +6 -4
  110. package/dist/nexus/diff.js.map +1 -1
  111. package/dist/nexus/export.d.ts.map +1 -1
  112. package/dist/nexus/export.js +7 -4
  113. package/dist/nexus/export.js.map +1 -1
  114. package/dist/nexus/flows.d.ts.map +1 -1
  115. package/dist/nexus/flows.js +3 -1
  116. package/dist/nexus/flows.js.map +1 -1
  117. package/dist/nexus/impact.d.ts +1 -1
  118. package/dist/nexus/impact.d.ts.map +1 -1
  119. package/dist/nexus/impact.js +31 -17
  120. package/dist/nexus/impact.js.map +1 -1
  121. package/dist/nexus/living-brain.d.ts.map +1 -1
  122. package/dist/nexus/living-brain.js +27 -15
  123. package/dist/nexus/living-brain.js.map +1 -1
  124. package/dist/nexus/nexus-bridge.d.ts.map +1 -1
  125. package/dist/nexus/nexus-bridge.js +28 -29
  126. package/dist/nexus/nexus-bridge.js.map +1 -1
  127. package/dist/nexus/plasticity-queries.d.ts +4 -2
  128. package/dist/nexus/plasticity-queries.d.ts.map +1 -1
  129. package/dist/nexus/plasticity-queries.js +27 -15
  130. package/dist/nexus/plasticity-queries.js.map +1 -1
  131. package/dist/nexus/query.d.ts.map +1 -1
  132. package/dist/nexus/query.js +6 -2
  133. package/dist/nexus/query.js.map +1 -1
  134. package/dist/nexus/registry.d.ts.map +1 -1
  135. package/dist/nexus/registry.js +65 -30
  136. package/dist/nexus/registry.js.map +1 -1
  137. package/dist/nexus/route-analysis.d.ts +3 -2
  138. package/dist/nexus/route-analysis.d.ts.map +1 -1
  139. package/dist/nexus/route-analysis.js +11 -10
  140. package/dist/nexus/route-analysis.js.map +1 -1
  141. package/dist/nexus/sigil.d.ts.map +1 -1
  142. package/dist/nexus/sigil.js +60 -13
  143. package/dist/nexus/sigil.js.map +1 -1
  144. package/dist/nexus/user-profile.d.ts +2 -1
  145. package/dist/nexus/user-profile.d.ts.map +1 -1
  146. package/dist/nexus/user-profile.js +8 -4
  147. package/dist/nexus/user-profile.js.map +1 -1
  148. package/dist/orchestrate/index.d.ts +1 -1
  149. package/dist/orchestrate/index.d.ts.map +1 -1
  150. package/dist/orchestrate/index.js +1 -1
  151. package/dist/orchestrate/index.js.map +1 -1
  152. package/dist/orchestrate/plan.d.ts +3 -3
  153. package/dist/orchestrate/plan.d.ts.map +1 -1
  154. package/dist/orchestrate/plan.js +7 -7
  155. package/dist/orchestrate/plan.js.map +1 -1
  156. package/dist/orchestrate/spawn-ops.js +2 -2
  157. package/dist/orchestrate/spawn-ops.js.map +1 -1
  158. package/dist/orchestration/classify.d.ts +2 -2
  159. package/dist/orchestration/classify.js +3 -3
  160. package/dist/orchestration/classify.js.map +1 -1
  161. package/dist/orchestration/validate-spawn.d.ts.map +1 -1
  162. package/dist/orchestration/validate-spawn.js +5 -5
  163. package/dist/orchestration/validate-spawn.js.map +1 -1
  164. package/dist/paths-export.d.ts +18 -0
  165. package/dist/paths-export.d.ts.map +1 -0
  166. package/dist/paths-export.js +18 -0
  167. package/dist/paths-export.js.map +1 -0
  168. package/dist/paths.d.ts.map +1 -1
  169. package/dist/paths.js +24 -11
  170. package/dist/paths.js.map +1 -1
  171. package/dist/playbooks/index.d.ts +1 -0
  172. package/dist/playbooks/index.d.ts.map +1 -1
  173. package/dist/playbooks/index.js +4 -0
  174. package/dist/playbooks/index.js.map +1 -1
  175. package/dist/playbooks/skill-node-executor.d.ts +155 -0
  176. package/dist/playbooks/skill-node-executor.d.ts.map +1 -0
  177. package/dist/playbooks/skill-node-executor.js +156 -0
  178. package/dist/playbooks/skill-node-executor.js.map +1 -0
  179. package/dist/repair.d.ts +3 -7
  180. package/dist/repair.d.ts.map +1 -1
  181. package/dist/repair.js +5 -43
  182. package/dist/repair.js.map +1 -1
  183. package/dist/sagas/migrate-containment.js +7 -7
  184. package/dist/sagas/migrate-containment.js.map +1 -1
  185. package/dist/scaffold/ensure-dirs.d.ts +8 -2
  186. package/dist/scaffold/ensure-dirs.d.ts.map +1 -1
  187. package/dist/scaffold/ensure-dirs.js +24 -11
  188. package/dist/scaffold/ensure-dirs.js.map +1 -1
  189. package/dist/scaffold/project-detection.d.ts +5 -1
  190. package/dist/scaffold/project-detection.d.ts.map +1 -1
  191. package/dist/scaffold/project-detection.js +9 -5
  192. package/dist/scaffold/project-detection.js.map +1 -1
  193. package/dist/sentient/hygiene-scan.js +6 -6
  194. package/dist/sentient/hygiene-scan.js.map +1 -1
  195. package/dist/sentient/proposal-dedup.js +2 -2
  196. package/dist/sentient/proposal-rate-limiter.js +1 -1
  197. package/dist/sentient/propose-tick.js +5 -5
  198. package/dist/sentient/propose-tick.js.map +1 -1
  199. package/dist/sentient/stage-drift-tick.js +3 -3
  200. package/dist/sentient/stage-drift-tick.js.map +1 -1
  201. package/dist/sequence/index.d.ts.map +1 -1
  202. package/dist/sequence/index.js +6 -2
  203. package/dist/sequence/index.js.map +1 -1
  204. package/dist/setup/sections/verification.js +2 -2
  205. package/dist/setup/sections/verification.js.map +1 -1
  206. package/dist/shutdown.d.ts +81 -0
  207. package/dist/shutdown.d.ts.map +1 -0
  208. package/dist/shutdown.js +105 -0
  209. package/dist/shutdown.js.map +1 -0
  210. package/dist/skills/index.d.ts +2 -0
  211. package/dist/skills/index.d.ts.map +1 -1
  212. package/dist/skills/index.js +1 -0
  213. package/dist/skills/index.js.map +1 -1
  214. package/dist/skills/skill-executor-adapter.d.ts +136 -0
  215. package/dist/skills/skill-executor-adapter.d.ts.map +1 -0
  216. package/dist/skills/skill-executor-adapter.js +137 -0
  217. package/dist/skills/skill-executor-adapter.js.map +1 -0
  218. package/dist/skills/usage-recorder.d.ts.map +1 -1
  219. package/dist/skills/usage-recorder.js +30 -0
  220. package/dist/skills/usage-recorder.js.map +1 -1
  221. package/dist/skills-export.d.ts +23 -0
  222. package/dist/skills-export.d.ts.map +1 -0
  223. package/dist/skills-export.js +23 -0
  224. package/dist/skills-export.js.map +1 -0
  225. package/dist/stats/index.d.ts.map +1 -1
  226. package/dist/stats/index.js +8 -3
  227. package/dist/stats/index.js.map +1 -1
  228. package/dist/store/agent-doctor.d.ts +3 -3
  229. package/dist/store/agent-doctor.d.ts.map +1 -1
  230. package/dist/store/agent-doctor.js +18 -13
  231. package/dist/store/agent-doctor.js.map +1 -1
  232. package/dist/store/agent-install.d.ts +6 -5
  233. package/dist/store/agent-install.d.ts.map +1 -1
  234. package/dist/store/agent-install.js +20 -16
  235. package/dist/store/agent-install.js.map +1 -1
  236. package/dist/store/agent-registry-accessor.d.ts +66 -28
  237. package/dist/store/agent-registry-accessor.d.ts.map +1 -1
  238. package/dist/store/agent-registry-accessor.js +248 -167
  239. package/dist/store/agent-registry-accessor.js.map +1 -1
  240. package/dist/store/agent-registry-store.d.ts +242 -0
  241. package/dist/store/agent-registry-store.d.ts.map +1 -0
  242. package/dist/store/agent-registry-store.js +501 -0
  243. package/dist/store/agent-registry-store.js.map +1 -0
  244. package/dist/store/agent-resolver.d.ts +8 -8
  245. package/dist/store/agent-resolver.d.ts.map +1 -1
  246. package/dist/store/agent-resolver.js +19 -17
  247. package/dist/store/agent-resolver.js.map +1 -1
  248. package/dist/store/backup-pack.d.ts.map +1 -1
  249. package/dist/store/backup-pack.js +24 -8
  250. package/dist/store/backup-pack.js.map +1 -1
  251. package/dist/store/conduit-sqlite.d.ts +181 -74
  252. package/dist/store/conduit-sqlite.d.ts.map +1 -1
  253. package/dist/store/conduit-sqlite.js +307 -528
  254. package/dist/store/conduit-sqlite.js.map +1 -1
  255. package/dist/store/cross-db-cleanup.d.ts +5 -5
  256. package/dist/store/cross-db-cleanup.d.ts.map +1 -1
  257. package/dist/store/cross-db-cleanup.js +12 -10
  258. package/dist/store/cross-db-cleanup.js.map +1 -1
  259. package/dist/store/data-accessor.d.ts +4 -4
  260. package/dist/store/data-accessor.js +5 -5
  261. package/dist/store/data-accessor.js.map +1 -1
  262. package/dist/store/data-safety-central.d.ts +83 -1
  263. package/dist/store/data-safety-central.d.ts.map +1 -1
  264. package/dist/store/data-safety-central.js +257 -0
  265. package/dist/store/data-safety-central.js.map +1 -1
  266. package/dist/store/db-helpers.d.ts +8 -2
  267. package/dist/store/db-helpers.d.ts.map +1 -1
  268. package/dist/store/db-helpers.js +6 -2
  269. package/dist/store/db-helpers.js.map +1 -1
  270. package/dist/store/dual-scope-db.d.ts +46 -4
  271. package/dist/store/dual-scope-db.d.ts.map +1 -1
  272. package/dist/store/dual-scope-db.js +103 -9
  273. package/dist/store/dual-scope-db.js.map +1 -1
  274. package/dist/store/exodus/__fixtures__/representative-fixture.d.ts +116 -0
  275. package/dist/store/exodus/__fixtures__/representative-fixture.d.ts.map +1 -0
  276. package/dist/store/exodus/__fixtures__/representative-fixture.js +274 -0
  277. package/dist/store/exodus/__fixtures__/representative-fixture.js.map +1 -0
  278. package/dist/store/exodus/index.d.ts +18 -0
  279. package/dist/store/exodus/index.d.ts.map +1 -0
  280. package/dist/store/exodus/index.js +18 -0
  281. package/dist/store/exodus/index.js.map +1 -0
  282. package/dist/store/exodus/migrate.d.ts +160 -0
  283. package/dist/store/exodus/migrate.d.ts.map +1 -0
  284. package/dist/store/exodus/migrate.js +1220 -0
  285. package/dist/store/exodus/migrate.js.map +1 -0
  286. package/dist/store/exodus/on-open.d.ts +189 -0
  287. package/dist/store/exodus/on-open.d.ts.map +1 -0
  288. package/dist/store/exodus/on-open.js +464 -0
  289. package/dist/store/exodus/on-open.js.map +1 -0
  290. package/dist/store/exodus/plan.d.ts +44 -0
  291. package/dist/store/exodus/plan.d.ts.map +1 -0
  292. package/dist/store/exodus/plan.js +178 -0
  293. package/dist/store/exodus/plan.js.map +1 -0
  294. package/dist/store/exodus/status.d.ts +22 -0
  295. package/dist/store/exodus/status.d.ts.map +1 -0
  296. package/dist/store/exodus/status.js +88 -0
  297. package/dist/store/exodus/status.js.map +1 -0
  298. package/dist/store/exodus/table-name-map.d.ts +173 -0
  299. package/dist/store/exodus/table-name-map.d.ts.map +1 -0
  300. package/dist/store/exodus/table-name-map.js +660 -0
  301. package/dist/store/exodus/table-name-map.js.map +1 -0
  302. package/dist/store/exodus/types.d.ts +169 -0
  303. package/dist/store/exodus/types.d.ts.map +1 -0
  304. package/dist/store/exodus/types.js +21 -0
  305. package/dist/store/exodus/types.js.map +1 -0
  306. package/dist/store/exodus/verify-migration.d.ts +72 -0
  307. package/dist/store/exodus/verify-migration.d.ts.map +1 -0
  308. package/dist/store/exodus/verify-migration.js +678 -0
  309. package/dist/store/exodus/verify-migration.js.map +1 -0
  310. package/dist/store/exodus/verify.d.ts +58 -0
  311. package/dist/store/exodus/verify.d.ts.map +1 -0
  312. package/dist/store/exodus/verify.js +74 -0
  313. package/dist/store/exodus/verify.js.map +1 -0
  314. package/dist/store/index.d.ts +2 -3
  315. package/dist/store/index.d.ts.map +1 -1
  316. package/dist/store/index.js +2 -3
  317. package/dist/store/index.js.map +1 -1
  318. package/dist/store/memory-accessor.d.ts +31 -0
  319. package/dist/store/memory-accessor.d.ts.map +1 -1
  320. package/dist/store/memory-accessor.js +38 -0
  321. package/dist/store/memory-accessor.js.map +1 -1
  322. package/dist/store/memory-sqlite.d.ts +86 -13
  323. package/dist/store/memory-sqlite.d.ts.map +1 -1
  324. package/dist/store/memory-sqlite.js +326 -528
  325. package/dist/store/memory-sqlite.js.map +1 -1
  326. package/dist/store/migrate-signaldock-to-conduit.d.ts +1 -1
  327. package/dist/store/migrate-signaldock-to-conduit.d.ts.map +1 -1
  328. package/dist/store/migrate-signaldock-to-conduit.js +126 -35
  329. package/dist/store/migrate-signaldock-to-conduit.js.map +1 -1
  330. package/dist/store/migration-manager.d.ts +49 -0
  331. package/dist/store/migration-manager.d.ts.map +1 -1
  332. package/dist/store/migration-manager.js +167 -67
  333. package/dist/store/migration-manager.js.map +1 -1
  334. package/dist/store/migration-sqlite.d.ts +1 -1
  335. package/dist/store/migration-sqlite.d.ts.map +1 -1
  336. package/dist/store/migration-sqlite.js +32 -3
  337. package/dist/store/migration-sqlite.js.map +1 -1
  338. package/dist/store/nexus-sqlite.d.ts +152 -29
  339. package/dist/store/nexus-sqlite.d.ts.map +1 -1
  340. package/dist/store/nexus-sqlite.js +496 -177
  341. package/dist/store/nexus-sqlite.js.map +1 -1
  342. package/dist/store/nexus-validation-schemas.d.ts +32 -32
  343. package/dist/store/open-cleo-db.d.ts +37 -40
  344. package/dist/store/open-cleo-db.d.ts.map +1 -1
  345. package/dist/store/open-cleo-db.js +76 -153
  346. package/dist/store/open-cleo-db.js.map +1 -1
  347. package/dist/store/role-accessors-impl.d.ts +4 -4
  348. package/dist/store/role-accessors-impl.d.ts.map +1 -1
  349. package/dist/store/role-accessors-impl.js +18 -15
  350. package/dist/store/role-accessors-impl.js.map +1 -1
  351. package/dist/store/schema/{signaldock-schema.d.ts → agent-registry-schema.d.ts} +15 -5
  352. package/dist/store/schema/agent-registry-schema.d.ts.map +1 -0
  353. package/dist/store/schema/{signaldock-schema.js → agent-registry-schema.js} +15 -5
  354. package/dist/store/schema/agent-registry-schema.js.map +1 -0
  355. package/dist/store/schema/agent-schema.d.ts +1 -1
  356. package/dist/store/schema/agent-schema.js +4 -4
  357. package/dist/store/schema/agent-schema.js.map +1 -1
  358. package/dist/store/schema/attachments.d.ts +1 -1
  359. package/dist/store/schema/audit.d.ts +15 -5
  360. package/dist/store/schema/audit.d.ts.map +1 -1
  361. package/dist/store/schema/audit.js +12 -2
  362. package/dist/store/schema/audit.js.map +1 -1
  363. package/dist/store/schema/background-jobs.d.ts +1 -1
  364. package/dist/store/schema/cleo-global/{signaldock.d.ts → agent-registry.d.ts} +277 -271
  365. package/dist/store/schema/cleo-global/agent-registry.d.ts.map +1 -0
  366. package/dist/store/schema/cleo-global/{signaldock.js → agent-registry.js} +136 -125
  367. package/dist/store/schema/cleo-global/agent-registry.js.map +1 -0
  368. package/dist/store/schema/cleo-global/index.d.ts +29 -22
  369. package/dist/store/schema/cleo-global/index.d.ts.map +1 -1
  370. package/dist/store/schema/cleo-global/index.js +29 -22
  371. package/dist/store/schema/cleo-global/index.js.map +1 -1
  372. package/dist/store/schema/cleo-global/nexus.d.ts +36 -1034
  373. package/dist/store/schema/cleo-global/nexus.d.ts.map +1 -1
  374. package/dist/store/schema/cleo-global/nexus.js +32 -337
  375. package/dist/store/schema/cleo-global/nexus.js.map +1 -1
  376. package/dist/store/schema/cleo-global/skills.d.ts +16 -0
  377. package/dist/store/schema/cleo-global/skills.d.ts.map +1 -1
  378. package/dist/store/schema/cleo-global/skills.js +11 -0
  379. package/dist/store/schema/cleo-global/skills.js.map +1 -1
  380. package/dist/store/schema/{cleo-project → cleo-global}/telemetry.d.ts +33 -17
  381. package/dist/store/schema/cleo-global/telemetry.d.ts.map +1 -0
  382. package/dist/store/schema/{cleo-project → cleo-global}/telemetry.js +30 -18
  383. package/dist/store/schema/cleo-global/telemetry.js.map +1 -0
  384. package/dist/store/schema/cleo-project/audit.d.ts +8 -8
  385. package/dist/store/schema/cleo-project/audit.d.ts.map +1 -1
  386. package/dist/store/schema/cleo-project/audit.js +2 -6
  387. package/dist/store/schema/cleo-project/audit.js.map +1 -1
  388. package/dist/store/schema/cleo-project/docs.d.ts +1 -1
  389. package/dist/store/schema/cleo-project/index.d.ts +29 -12
  390. package/dist/store/schema/cleo-project/index.d.ts.map +1 -1
  391. package/dist/store/schema/cleo-project/index.js +29 -12
  392. package/dist/store/schema/cleo-project/index.js.map +1 -1
  393. package/dist/store/schema/cleo-project/lifecycle.d.ts +2 -2
  394. package/dist/store/schema/cleo-project/nexus-graph.d.ts +1067 -0
  395. package/dist/store/schema/cleo-project/nexus-graph.d.ts.map +1 -0
  396. package/dist/store/schema/cleo-project/nexus-graph.js +407 -0
  397. package/dist/store/schema/cleo-project/nexus-graph.js.map +1 -0
  398. package/dist/store/schema/cleo-project/provenance-orphans.d.ts +385 -0
  399. package/dist/store/schema/cleo-project/provenance-orphans.d.ts.map +1 -0
  400. package/dist/store/schema/cleo-project/provenance-orphans.js +142 -0
  401. package/dist/store/schema/cleo-project/provenance-orphans.js.map +1 -0
  402. package/dist/store/schema/cleo-project/provenance-rest.d.ts +1 -1
  403. package/dist/store/schema/cleo-project/runtime.d.ts +1 -1
  404. package/dist/store/schema/cleo-project/tasks-core-batch2.d.ts +1 -1
  405. package/dist/store/schema/cleo-project/tasks-core.d.ts +3 -3
  406. package/dist/store/schema/cleo-shared/brain.d.ts +711 -494
  407. package/dist/store/schema/cleo-shared/brain.d.ts.map +1 -1
  408. package/dist/store/schema/cleo-shared/brain.js +215 -134
  409. package/dist/store/schema/cleo-shared/brain.js.map +1 -1
  410. package/dist/store/schema/conduit-schema.d.ts +63 -51
  411. package/dist/store/schema/conduit-schema.d.ts.map +1 -1
  412. package/dist/store/schema/conduit-schema.js +23 -11
  413. package/dist/store/schema/conduit-schema.js.map +1 -1
  414. package/dist/store/schema/goal.d.ts +3 -2
  415. package/dist/store/schema/goal.d.ts.map +1 -1
  416. package/dist/store/schema/goal.js +3 -2
  417. package/dist/store/schema/goal.js.map +1 -1
  418. package/dist/store/schema/index.d.ts +1 -0
  419. package/dist/store/schema/index.d.ts.map +1 -1
  420. package/dist/store/schema/index.js +1 -0
  421. package/dist/store/schema/index.js.map +1 -1
  422. package/dist/store/schema/lifecycle.d.ts +2 -2
  423. package/dist/store/schema/memory-schema.d.ts +2 -2
  424. package/dist/store/schema/nexus-schema.d.ts +174 -115
  425. package/dist/store/schema/nexus-schema.d.ts.map +1 -1
  426. package/dist/store/schema/nexus-schema.js +175 -55
  427. package/dist/store/schema/nexus-schema.js.map +1 -1
  428. package/dist/store/schema/provenance/releases.d.ts +1 -1
  429. package/dist/store/schema/schema-utils.d.ts +78 -0
  430. package/dist/store/schema/schema-utils.d.ts.map +1 -0
  431. package/dist/store/schema/schema-utils.js +49 -0
  432. package/dist/store/schema/schema-utils.js.map +1 -0
  433. package/dist/store/schema/skills-schema.d.ts +81 -44
  434. package/dist/store/schema/skills-schema.d.ts.map +1 -1
  435. package/dist/store/schema/skills-schema.js +49 -16
  436. package/dist/store/schema/skills-schema.js.map +1 -1
  437. package/dist/store/schema/tasks.d.ts +3 -3
  438. package/dist/store/skills-db.d.ts +90 -50
  439. package/dist/store/skills-db.d.ts.map +1 -1
  440. package/dist/store/skills-db.js +132 -146
  441. package/dist/store/skills-db.js.map +1 -1
  442. package/dist/store/sqlite-backup.d.ts +2 -2
  443. package/dist/store/sqlite-backup.d.ts.map +1 -1
  444. package/dist/store/sqlite-backup.js +11 -10
  445. package/dist/store/sqlite-backup.js.map +1 -1
  446. package/dist/store/sqlite-data-accessor.d.ts.map +1 -1
  447. package/dist/store/sqlite-data-accessor.js +25 -18
  448. package/dist/store/sqlite-data-accessor.js.map +1 -1
  449. package/dist/store/sqlite.d.ts +72 -12
  450. package/dist/store/sqlite.d.ts.map +1 -1
  451. package/dist/store/sqlite.js +153 -89
  452. package/dist/store/sqlite.js.map +1 -1
  453. package/dist/store/tasks-schema.d.ts +4 -0
  454. package/dist/store/tasks-schema.d.ts.map +1 -1
  455. package/dist/store/tasks-schema.js +60 -0
  456. package/dist/store/tasks-schema.js.map +1 -1
  457. package/dist/store/tasks-sqlite.d.ts +2 -2
  458. package/dist/store/tasks-sqlite.d.ts.map +1 -1
  459. package/dist/store/tasks-sqlite.js +10 -5
  460. package/dist/store/tasks-sqlite.js.map +1 -1
  461. package/dist/store/umbrella-data-accessor.d.ts +17 -6
  462. package/dist/store/umbrella-data-accessor.d.ts.map +1 -1
  463. package/dist/store/umbrella-data-accessor.js +8 -8
  464. package/dist/store/umbrella-data-accessor.js.map +1 -1
  465. package/dist/store/validation-schemas.d.ts +241 -208
  466. package/dist/store/validation-schemas.d.ts.map +1 -1
  467. package/dist/system/health.d.ts.map +1 -1
  468. package/dist/system/health.js +11 -6
  469. package/dist/system/health.js.map +1 -1
  470. package/dist/system/project-health.d.ts.map +1 -1
  471. package/dist/system/project-health.js +58 -12
  472. package/dist/system/project-health.js.map +1 -1
  473. package/dist/tasks/add.d.ts +8 -0
  474. package/dist/tasks/add.d.ts.map +1 -1
  475. package/dist/tasks/add.js +101 -0
  476. package/dist/tasks/add.js.map +1 -1
  477. package/dist/tasks/cancelled-child-waiver-audit.d.ts +47 -0
  478. package/dist/tasks/cancelled-child-waiver-audit.d.ts.map +1 -0
  479. package/dist/tasks/cancelled-child-waiver-audit.js +34 -0
  480. package/dist/tasks/cancelled-child-waiver-audit.js.map +1 -0
  481. package/dist/tasks/complete.d.ts +22 -2
  482. package/dist/tasks/complete.d.ts.map +1 -1
  483. package/dist/tasks/complete.js +71 -6
  484. package/dist/tasks/complete.js.map +1 -1
  485. package/dist/tasks/compute-task-view.js +1 -1
  486. package/dist/tasks/session-scope.d.ts +5 -0
  487. package/dist/tasks/session-scope.d.ts.map +1 -1
  488. package/dist/tasks/session-scope.js +4 -0
  489. package/dist/tasks/session-scope.js.map +1 -1
  490. package/dist/tools/guard.d.ts +71 -1
  491. package/dist/tools/guard.d.ts.map +1 -1
  492. package/dist/tools/guard.js +73 -1
  493. package/dist/tools/guard.js.map +1 -1
  494. package/dist/tools/index.d.ts +21 -0
  495. package/dist/tools/index.d.ts.map +1 -1
  496. package/dist/tools/index.js +25 -0
  497. package/dist/tools/index.js.map +1 -1
  498. package/dist/upgrade.d.ts.map +1 -1
  499. package/dist/upgrade.js +22 -13
  500. package/dist/upgrade.js.map +1 -1
  501. package/dist/workgraph/containment.js +18 -18
  502. package/dist/workgraph/relations.js +2 -2
  503. package/dist/worktree/list.d.ts +1 -1
  504. package/dist/worktree/list.d.ts.map +1 -1
  505. package/dist/worktree/list.js +19 -21
  506. package/dist/worktree/list.js.map +1 -1
  507. package/dist/worktree-export.d.ts +18 -0
  508. package/dist/worktree-export.d.ts.map +1 -0
  509. package/dist/worktree-export.js +18 -0
  510. package/dist/worktree-export.js.map +1 -0
  511. package/migrations/drizzle-agent-registry/20260412000000_initial-global-agent-registry/migration.sql +29 -0
  512. package/migrations/drizzle-brain/20260601000001_t11522-brain-task-observations/migration.sql +28 -0
  513. package/migrations/drizzle-brain/20260601000002_t11522-inline-only-brain-tables/migration.sql +75 -0
  514. package/migrations/drizzle-cleo-global/20260531000001_t11363-consolidation-cleo-global/migration.sql +49 -144
  515. package/migrations/drizzle-cleo-global/20260531000001_t11363-consolidation-cleo-global/snapshot.json +8 -8
  516. package/migrations/drizzle-cleo-global/20260531000002_t11546-brain-usage-log/migration.sql +16 -0
  517. package/migrations/drizzle-cleo-global/20260601000001_t11544-skills-usage-project-id/migration.sql +12 -0
  518. package/migrations/drizzle-cleo-global/20260602000001_t11622-agent-registry-rename/migration.sql +80 -0
  519. package/migrations/drizzle-cleo-project/20260531000001_t11363-consolidation-cleo-project/migration.sql +26 -167
  520. package/migrations/drizzle-cleo-project/20260531000001_t11363-consolidation-cleo-project/snapshot.json +8 -8
  521. package/migrations/drizzle-cleo-project/20260531000002_t11546-brain-usage-log/migration.sql +21 -0
  522. package/migrations/drizzle-cleo-project/20260601000001_t11549-agent-credentials-brain-release-links/migration.sql +49 -0
  523. package/migrations/drizzle-cleo-project/20260601000002_t11538-project-nexus-graph/migration.sql +140 -0
  524. package/migrations/drizzle-cleo-project/20260602000002_t11649-token-usage-transport-mcp/migration.sql +146 -0
  525. package/migrations/drizzle-conduit/20260601000003_t11523-conduit-inline-schema/migration.sql +82 -0
  526. package/migrations/drizzle-nexus/20260421200001_t1165-baseline-reset/migration.sql +26 -8
  527. package/migrations/drizzle-nexus/20260601000001_t11545-nexus-relation-weights-partition/migration.sql +97 -0
  528. package/package.json +43 -11
  529. package/scripts/install-supervisor-binary.mjs +50 -201
  530. package/scripts/napi-binary-picker.mjs +267 -0
  531. package/dist/agents/agent-registry.d.ts.map +0 -1
  532. package/dist/agents/agent-registry.js.map +0 -1
  533. package/dist/store/data-safety.d.ts +0 -92
  534. package/dist/store/data-safety.d.ts.map +0 -1
  535. package/dist/store/data-safety.js +0 -274
  536. package/dist/store/data-safety.js.map +0 -1
  537. package/dist/store/schema/cleo-global/signaldock.d.ts.map +0 -1
  538. package/dist/store/schema/cleo-global/signaldock.js.map +0 -1
  539. package/dist/store/schema/cleo-project/telemetry.d.ts.map +0 -1
  540. package/dist/store/schema/cleo-project/telemetry.js.map +0 -1
  541. package/dist/store/schema/signaldock-schema.d.ts.map +0 -1
  542. package/dist/store/schema/signaldock-schema.js.map +0 -1
  543. package/dist/store/signaldock-sqlite.d.ts +0 -173
  544. package/dist/store/signaldock-sqlite.d.ts.map +0 -1
  545. package/dist/store/signaldock-sqlite.js +0 -445
  546. package/dist/store/signaldock-sqlite.js.map +0 -1
  547. package/migrations/drizzle-nexus/20260318205558_initial/migration.sql +0 -46
  548. package/migrations/drizzle-nexus/20260412000001_t529-nexus-graph-tables/migration.sql +0 -49
  549. package/migrations/drizzle-nexus/20260415000001_t622-project-registry-paths/migration.sql +0 -12
  550. package/migrations/drizzle-nexus/20260419000001_t998-nexus-plasticity/migration.sql +0 -13
  551. package/migrations/drizzle-nexus/20260423052640_t1077-add-user-profile-table/migration.sql +0 -16
  552. package/migrations/drizzle-nexus/20260423052640_t1077-add-user-profile-table/snapshot.json +0 -1531
  553. package/migrations/drizzle-nexus/20260424140538_t1148-add-sigils-table/migration.sql +0 -13
  554. package/migrations/drizzle-nexus/20260424140538_t1148-add-sigils-table/snapshot.json +0 -1652
  555. package/migrations/drizzle-nexus/20260504000001_t1839-fts5-nexus-symbols/migration.sql +0 -68
  556. package/migrations/drizzle-nexus/20260507135519_t9163-nexus-is-external/migration.sql +0 -20
  557. package/migrations/drizzle-nexus/20260507135519_t9163-nexus-is-external/snapshot.json +0 -1652
  558. package/migrations/drizzle-nexus/20260526222449_t11025-project-id-aliases/migration.sql +0 -16
  559. package/migrations/drizzle-signaldock/20260412000000_initial-global-signaldock/migration.sql +0 -209
  560. package/migrations/drizzle-signaldock/20260412000000_initial-global-signaldock/snapshot.json +0 -2060
@@ -1,34 +1,56 @@
1
1
  /**
2
2
  * Agent Registry Accessor — cross-DB CRUD for agent data.
3
3
  *
4
- * Post-T310 (ADR-037), agent identity lives in the GLOBAL
5
- * `$XDG_DATA_HOME/cleo/signaldock.db:agents` table; per-project
6
- * visibility and overrides live in the PROJECT
7
- * `.cleo/conduit.db:project_agent_refs` table.
4
+ * Post-T11622 cutover (folds T11578 AC2), agent identity lives in the GLOBAL
5
+ * PREFIXED `agent_registry_agents` table (+ `agent_registry_capabilities` /
6
+ * `agent_registry_skills` / `agent_registry_agent_capabilities` /
7
+ * `agent_registry_agent_skills`); per-project visibility and overrides live in the
8
+ * PROJECT `conduit_project_agent_refs` table (T11578 · AC4 — conduit namespace
9
+ * cutover). The bare legacy `agents` shape is no longer read or written.
8
10
  *
9
- * This module provides three module-level functions that perform the
10
- * in-memory cross-DB join, plus the backward-compatible
11
- * `AgentRegistryAccessor` class that wraps them.
11
+ * Post-E6-L5 (T11525) / E6-L6 (T11526), both tables are hosted inside the
12
+ * CONSOLIDATED dual-scope `cleo.db` files (global `$XDG_DATA_HOME/cleo/cleo.db`
13
+ * and project `.cleo/cleo.db`) the standalone `signaldock.db` / `conduit.db`
14
+ * files are gone. The global `agent_registry_*` tables are owned by the
15
+ * consolidated cleo-global migration (T11622 rename of `signaldock_*`);
16
+ * `ensureGlobalAgentRegistryDb()` opens the shared consolidated handle. The
17
+ * prefixed conduit `conduit_project_agent_refs` table is created by the
18
+ * consolidated cleo-project migration (T11578 · AC4) and `ensureConduitDb()`
19
+ * ensures the project `cleo.db` is open. The read path MUST therefore go through
20
+ * those `ensure*` calls so it shares the same handle as the write path (T11562 —
21
+ * agents read/write path divergence regression).
22
+ *
23
+ * The consolidated `agent_registry_agents` table carries TEXT ISO-8601 timestamps
24
+ * (`created_at` / `updated_at` / `last_used_at`, each with a GLOB CHECK) — every
25
+ * write path below stamps ISO strings, not the legacy epoch integers (T11622
26
+ * write-path constraint reconciliation).
27
+ *
28
+ * This module provides three module-level functions that perform the in-memory
29
+ * cross-DB join, plus the backward-compatible `AgentRegistryAccessor` class that
30
+ * wraps them.
12
31
  *
13
32
  * Architecture:
14
- * global signaldock.db — canonical identity (openGlobalDb)
15
- * project conduit.db project_agent_refs (openConduitDb)
33
+ * global cleo.db — canonical identity `agent_registry_agents` (openGlobalDb → ensureGlobalAgentRegistryDb)
34
+ * project cleo.db `conduit_project_agent_refs` (openConduitDb)
16
35
  * Join performed in Node (SQLite cannot cross-file-handle JOIN).
17
36
  *
18
37
  * @see .cleo/rcasd/T310/specification/T310-specification.md §3.5
19
38
  * @see .cleo/adrs/ADR-037-conduit-signaldock-separation.md
20
39
  * @task T355
40
+ * @task T11562
41
+ * @task T11622
21
42
  * @epic T310
43
+ * @epic T11249
22
44
  */
23
45
  import { randomBytes } from 'node:crypto';
24
46
  import { existsSync, mkdirSync, readFileSync, statSync, writeFileSync } from 'node:fs';
25
47
  import { createRequire } from 'node:module';
26
48
  import { join } from 'node:path';
27
49
  import { getCleoHome } from '../paths.js';
50
+ import { ensureGlobalAgentRegistryDb, getGlobalAgentRegistryNativeDb, } from './agent-registry-store.js';
28
51
  import { deriveApiKey } from './api-key-kdf.js';
29
52
  import { ensureConduitDb, getConduitDbPath } from './conduit-sqlite.js';
30
53
  import { getGlobalSalt } from './global-salt.js';
31
- import { ensureGlobalSignaldockDb, getGlobalSignaldockDbPath } from './signaldock-sqlite.js';
32
54
  import { applyPerfPragmas } from './sqlite-pragmas.js';
33
55
  // ---------------------------------------------------------------------------
34
56
  // node:sqlite interop (createRequire for ESM / Vitest compat)
@@ -96,12 +118,12 @@ function rowToProjectRef(row) {
96
118
  };
97
119
  }
98
120
  /**
99
- * Convert a global signaldock.db:agents row to an `AgentCredential`.
121
+ * Convert a global cleo.db:agent_registry_agents row to an `AgentCredential`.
100
122
  * API key is stored as binary (derived via KDF) — returned as hex string.
101
123
  * Legacy encrypted values (pre-T310) are left as-is; the reauth flag handles
102
124
  * forced re-authentication at the CLI layer.
103
125
  *
104
- * @param row - Raw SQLite row from global signaldock.db:agents.
126
+ * @param row - Raw SQLite row from global cleo.db:agent_registry_agents.
105
127
  * @returns Typed `AgentCredential` (apiKey is hex-encoded derived bytes or empty).
106
128
  * @task T355
107
129
  * @epic T310
@@ -122,9 +144,11 @@ function rowToCredential(row) {
122
144
  transportType: (row.transport_type ?? 'http'),
123
145
  transportConfig: JSON.parse(row.transport_config),
124
146
  isActive: row.is_active === 1,
125
- lastUsedAt: row.last_used_at ? new Date(row.last_used_at * 1000).toISOString() : undefined,
126
- createdAt: new Date(row.created_at * 1000).toISOString(),
127
- updatedAt: new Date(row.updated_at * 1000).toISOString(),
147
+ // T11622 cutover: `agent_registry_agents` timestamps are TEXT ISO-8601 read
148
+ // through as-is (no epoch→ms conversion).
149
+ lastUsedAt: row.last_used_at ?? undefined,
150
+ createdAt: row.created_at,
151
+ updatedAt: row.updated_at,
128
152
  };
129
153
  }
130
154
  /**
@@ -149,7 +173,7 @@ function coerceTier(value) {
149
173
  * 'fallback', canSpawn: false, orchLevel: 2). Callers that need strict
150
174
  * migration presence MUST check `row.tier !== undefined` before invoking.
151
175
  *
152
- * @param row - Raw SQLite row from signaldock.db:agents
176
+ * @param row - Raw SQLite row from cleo.db:agent_registry_agents
153
177
  * @returns The extended field block, with safe fallbacks for absent columns
154
178
  * @task T897
155
179
  * @epic T889
@@ -181,7 +205,7 @@ function rowToExtendedFields(row) {
181
205
  * never been bound to a `.cant`). Callers that need a synthesized fallback
182
206
  * envelope MUST handle the null return explicitly.
183
207
  *
184
- * @param row - Raw agents row from signaldock.db
208
+ * @param row - Raw agent_registry_agents row from the global cleo.db
185
209
  * @returns A ResolvedAgent envelope, or null when provenance is missing
186
210
  * @task T897
187
211
  * @epic T889
@@ -209,7 +233,7 @@ export function rowToResolvedAgent(row) {
209
233
  * Merge a global agent row with an optional project_agent_refs row into an
210
234
  * `AgentWithProjectOverride` object.
211
235
  *
212
- * @param agentRow - Row from global signaldock.db:agents.
236
+ * @param agentRow - Row from global cleo.db:agent_registry_agents.
213
237
  * @param refRow - Row from conduit.db:project_agent_refs, or null.
214
238
  * @returns Merged `AgentWithProjectOverride`.
215
239
  * @task T355
@@ -225,16 +249,43 @@ function mergeToAgentWithOverride(agentRow, refRow) {
225
249
  // Database handle helpers (short-lived, caller closes)
226
250
  // ---------------------------------------------------------------------------
227
251
  /**
228
- * Open a short-lived read/write handle to the GLOBAL signaldock.db.
229
- * Caller MUST call `db.close()` when done.
252
+ * Acquire the SHARED, fully-migrated handle to the GLOBAL agent identity DB —
253
+ * the consolidated dual-scope global `cleo.db` (post-E6-L5 / T11525).
254
+ *
255
+ * Routes through {@link ensureGlobalAgentRegistryDb}, which opens the consolidated
256
+ * `cleo.db` via `openDualScopeDb('global')` (whose consolidated cleo-global
257
+ * migration creates the prefixed `agent_registry_*` tables this accessor's raw SQL
258
+ * now queries, post-T11622 cutover), reconciles the health-probe ledger, and
259
+ * stores the native handle for reuse. The returned handle is the SAME one the
260
+ * write path uses — reads and writes are aligned to `cleo.db` (T11562).
261
+ *
262
+ * Replaces the previous `new DatabaseSync(getGlobalAgentRegistryDbPath())` raw-open,
263
+ * which diverged from the write path (T11562).
264
+ *
265
+ * The handle is SHARED and co-owned by the nexus / skills global domains — its
266
+ * lifecycle is owned by `openDualScopeDb`. Callers MUST NOT call `db.close()` on
267
+ * it (doing so would break in-flight sibling queries). This is why every former
268
+ * `globalDb.close()` in this module was removed (T11562).
230
269
  *
270
+ * @returns The shared consolidated global `cleo.db` native handle.
271
+ * @throws {Error} If the shared handle is unexpectedly absent after ensure.
231
272
  * @task T355
273
+ * @task T11562
232
274
  * @epic T310
275
+ * @epic T11249
233
276
  */
234
- function openGlobalDb() {
235
- const dbPath = getGlobalSignaldockDbPath();
236
- const db = new DatabaseSync(dbPath);
237
- applyPerfPragmas(db); // replaces inline PRAGMA calls with SSoT set (T9023)
277
+ async function openGlobalDb() {
278
+ // Idempotent: opens the consolidated global cleo.db, runs the legacy
279
+ // (the consolidated cleo-global migration creates the agent_registry_* tables),
280
+ // and caches the shared native handle (T11622 cutover).
281
+ await ensureGlobalAgentRegistryDb();
282
+ const db = getGlobalAgentRegistryNativeDb();
283
+ if (!db) {
284
+ throw new Error('openGlobalDb: ensureGlobalAgentRegistryDb() did not yield a shared global ' +
285
+ 'cleo.db handle (getGlobalAgentRegistryNativeDb() returned null). This indicates ' +
286
+ 'the dual-scope global chokepoint failed to initialize — fix the caller, do ' +
287
+ 'not suppress.');
288
+ }
238
289
  return db;
239
290
  }
240
291
  /**
@@ -252,13 +303,13 @@ function openConduitDb(projectRoot) {
252
303
  return db;
253
304
  }
254
305
  // ---------------------------------------------------------------------------
255
- // junction table sync (global signaldock.db only)
306
+ // junction table sync (global cleo.db (Agent Registry) only)
256
307
  // ---------------------------------------------------------------------------
257
308
  /**
258
- * Sync capabilities/skills to junction tables in global signaldock.db.
309
+ * Sync capabilities/skills to junction tables in global cleo.db (Agent Registry).
259
310
  * Junction tables are the SSoT — JSON columns are a materialized cache.
260
311
  *
261
- * @param db - Open handle to global signaldock.db.
312
+ * @param db - Open handle to global cleo.db (Agent Registry).
262
313
  * @param agentUuid - The `id` (UUID primary key) from the agents row.
263
314
  * @param capabilities - Array of capability slugs.
264
315
  * @param skills - Array of skill slugs.
@@ -266,18 +317,20 @@ function openConduitDb(projectRoot) {
266
317
  * @epic T310
267
318
  */
268
319
  function syncJunctionTables(db, agentUuid, capabilities, skills) {
269
- db.prepare('DELETE FROM agent_capabilities WHERE agent_id = ?').run(agentUuid);
270
- db.prepare('DELETE FROM agent_skills WHERE agent_id = ?').run(agentUuid);
320
+ db.prepare('DELETE FROM agent_registry_agent_capabilities WHERE agent_id = ?').run(agentUuid);
321
+ db.prepare('DELETE FROM agent_registry_agent_skills WHERE agent_id = ?').run(agentUuid);
271
322
  for (const cap of capabilities) {
272
- const capRow = db.prepare('SELECT id FROM capabilities WHERE slug = ?').get(cap);
323
+ const capRow = db
324
+ .prepare('SELECT id FROM agent_registry_capabilities WHERE slug = ?')
325
+ .get(cap);
273
326
  if (capRow) {
274
- db.prepare('INSERT OR IGNORE INTO agent_capabilities (agent_id, capability_id) VALUES (?, ?)').run(agentUuid, capRow.id);
327
+ db.prepare('INSERT OR IGNORE INTO agent_registry_agent_capabilities (agent_id, capability_id) VALUES (?, ?)').run(agentUuid, capRow.id);
275
328
  }
276
329
  }
277
330
  for (const skill of skills) {
278
- const skillRow = db.prepare('SELECT id FROM skills WHERE slug = ?').get(skill);
331
+ const skillRow = db.prepare('SELECT id FROM agent_registry_skills WHERE slug = ?').get(skill);
279
332
  if (skillRow) {
280
- db.prepare('INSERT OR IGNORE INTO agent_skills (agent_id, skill_id) VALUES (?, ?)').run(agentUuid, skillRow.id);
333
+ db.prepare('INSERT OR IGNORE INTO agent_registry_agent_skills (agent_id, skill_id) VALUES (?, ?)').run(agentUuid, skillRow.id);
281
334
  }
282
335
  }
283
336
  }
@@ -285,7 +338,7 @@ function syncJunctionTables(db, agentUuid, capabilities, skills) {
285
338
  // Module-level cross-DB functions (spec §3.5)
286
339
  // ---------------------------------------------------------------------------
287
340
  /**
288
- * Cross-DB agent lookup. Opens both the global signaldock.db and the
341
+ * Cross-DB agent lookup. Opens both the global cleo.db (Agent Registry) and the
289
342
  * current project's conduit.db, joins project_agent_refs ⨝ agents by
290
343
  * agentId, and returns the merged view.
291
344
  *
@@ -299,27 +352,42 @@ function syncJunctionTables(db, agentUuid, capabilities, skills) {
299
352
  * Dangling soft-FK detection: if a project_agent_refs row exists but the
300
353
  * referenced global agent does not, logs a WARN and returns null.
301
354
  *
355
+ * Both `agents` (global) and `project_agent_refs` (project) tables are
356
+ * materialized into their consolidated `cleo.db` files lazily, so this function
357
+ * ensures both DBs (via the shared `openGlobalDb` / `ensureConduitDb`
358
+ * chokepoints) before reading — keeping the read path aligned with the write
359
+ * path (T11562). It is therefore async.
360
+ *
302
361
  * @param projectRoot - Absolute path to the project root directory.
303
362
  * @param agentId - Agent business identifier.
304
363
  * @param opts.includeGlobal - When true, returns global identity even without project ref.
305
364
  * @returns Merged agent record or null if not found.
306
365
  *
307
366
  * @task T355
367
+ * @task T11562
308
368
  * @epic T310
369
+ * @epic T11249
309
370
  */
310
- export function lookupAgent(projectRoot, agentId, opts) {
371
+ export async function lookupAgent(projectRoot, agentId, opts) {
311
372
  const includeGlobal = opts?.includeGlobal ?? false;
312
- const globalDb = openGlobalDb();
373
+ // Ensure the consolidated project cleo.db has the prefixed
374
+ // `conduit_project_agent_refs` table (T11578 · AC4) before the raw-open read
375
+ // below (mirrors the global side, which is ensured inside openGlobalDb).
376
+ await ensureConduitDb(projectRoot);
377
+ // SHARED global cleo.db handle — do NOT close (lifecycle owned by openDualScopeDb).
378
+ const globalDb = await openGlobalDb();
313
379
  const conduitDb = openConduitDb(projectRoot);
314
380
  try {
315
- const agentRow = globalDb.prepare('SELECT * FROM agents WHERE agent_id = ?').get(agentId);
381
+ const agentRow = globalDb
382
+ .prepare('SELECT * FROM agent_registry_agents WHERE agent_id = ?')
383
+ .get(agentId);
316
384
  const refRow = conduitDb
317
- .prepare('SELECT * FROM project_agent_refs WHERE agent_id = ?')
385
+ .prepare('SELECT * FROM conduit_project_agent_refs WHERE agent_id = ?')
318
386
  .get(agentId);
319
387
  // Dangling soft-FK: ref exists in conduit but not in global
320
388
  if (refRow && !agentRow) {
321
389
  console.warn(`[agent-registry-accessor] WARN: dangling project_agent_refs row for agent_id="${agentId}". ` +
322
- `No matching row in global signaldock.db:agents. Row will be ignored.`);
390
+ `No matching row in global cleo.db:agents. Row will be ignored.`);
323
391
  return null;
324
392
  }
325
393
  // Agent does not exist globally at all
@@ -336,7 +404,7 @@ export function lookupAgent(projectRoot, agentId, opts) {
336
404
  return mergeToAgentWithOverride(agentRow, effectiveRef);
337
405
  }
338
406
  finally {
339
- globalDb.close();
407
+ // NOTE: globalDb is the SHARED dual-scope handle — never close it (T11562).
340
408
  conduitDb.close();
341
409
  }
342
410
  }
@@ -352,25 +420,38 @@ export function lookupAgent(projectRoot, agentId, opts) {
352
420
  * includeDisabled=true: also returns agents with enabled=0 in project_agent_refs.
353
421
  * Ignored when includeGlobal=true (all global agents are returned regardless).
354
422
  *
423
+ * Both `agents` (global) and `project_agent_refs` (project) tables are
424
+ * materialized into their consolidated `cleo.db` files lazily, so this function
425
+ * ensures both DBs (via the shared `openGlobalDb` / `ensureConduitDb`
426
+ * chokepoints) before reading — keeping the read path aligned with the write
427
+ * path (T11562). It is therefore async.
428
+ *
355
429
  * @param projectRoot - Absolute path to the project root directory.
356
430
  * @param opts.includeGlobal - Include all global agents (bypasses project filter).
357
431
  * @param opts.includeDisabled - Include agents with enabled=0 in project_agent_refs.
358
432
  * @returns Array of merged agent records.
359
433
  *
360
434
  * @task T355
435
+ * @task T11562
361
436
  * @epic T310
437
+ * @epic T11249
362
438
  */
363
- export function listAgentsForProject(projectRoot, opts) {
439
+ export async function listAgentsForProject(projectRoot, opts) {
364
440
  const includeGlobal = opts?.includeGlobal ?? false;
365
441
  const includeDisabled = opts?.includeDisabled ?? false;
366
- const globalDb = openGlobalDb();
442
+ // Ensure the consolidated project cleo.db has the prefixed
443
+ // `conduit_project_agent_refs` table (T11578 · AC4) before the raw-open read
444
+ // below (mirrors the global side, which is ensured inside openGlobalDb).
445
+ await ensureConduitDb(projectRoot);
446
+ // SHARED global cleo.db handle — do NOT close (lifecycle owned by openDualScopeDb).
447
+ const globalDb = await openGlobalDb();
367
448
  const conduitDb = openConduitDb(projectRoot);
368
449
  try {
369
450
  const allAgents = globalDb
370
- .prepare('SELECT * FROM agents ORDER BY name ASC')
451
+ .prepare('SELECT * FROM agent_registry_agents ORDER BY name ASC')
371
452
  .all();
372
453
  const allRefs = conduitDb
373
- .prepare('SELECT * FROM project_agent_refs')
454
+ .prepare('SELECT * FROM conduit_project_agent_refs')
374
455
  .all();
375
456
  // Build a map from agentId → ref row for O(1) lookup during join
376
457
  const refMap = new Map();
@@ -397,12 +478,12 @@ export function listAgentsForProject(projectRoot, opts) {
397
478
  return result;
398
479
  }
399
480
  finally {
400
- globalDb.close();
481
+ // NOTE: globalDb is the SHARED dual-scope handle — never close it (T11562).
401
482
  conduitDb.close();
402
483
  }
403
484
  }
404
485
  /**
405
- * Creates a new agent: writes identity row to global signaldock.db AND attaches
486
+ * Creates a new agent: writes identity row to global cleo.db (Agent Registry) AND attaches
406
487
  * it to the current project via conduit.db:project_agent_refs.
407
488
  *
408
489
  * Write order: global first, then project ref. If the project ref write fails,
@@ -417,9 +498,12 @@ export function listAgentsForProject(projectRoot, opts) {
417
498
  * @task T355
418
499
  * @epic T310
419
500
  */
420
- export function createProjectAgent(projectRoot, spec) {
421
- ensureGlobalSignaldockDb();
422
- ensureConduitDb(projectRoot);
501
+ export async function createProjectAgent(projectRoot, spec) {
502
+ // E6-L3 (T11523): ensureConduitDb is now async (routes through the dual-scope
503
+ // cleo.db chokepoint). ensureGlobalAgentRegistryDb is already async. Await both so
504
+ // the bare schema exists before the short-lived raw handles below read/write it.
505
+ await ensureGlobalAgentRegistryDb();
506
+ await ensureConduitDb(projectRoot);
423
507
  const nowTs = Math.floor(Date.now() / 1000);
424
508
  const nowIso = new Date(nowTs * 1000).toISOString();
425
509
  // Derive API key using the T310 KDF
@@ -432,52 +516,53 @@ export function createProjectAgent(projectRoot, spec) {
432
516
  });
433
517
  // Store as hex string in the encrypted column
434
518
  const apiKeyEncrypted = derivedKey.toString('hex');
435
- const globalDb = openGlobalDb();
436
- try {
519
+ // SHARED global cleo.db handle — do NOT close (lifecycle owned by openDualScopeDb).
520
+ const globalDb = await openGlobalDb();
521
+ {
437
522
  const existing = globalDb
438
- .prepare('SELECT id FROM agents WHERE agent_id = ?')
523
+ .prepare('SELECT id FROM agent_registry_agents WHERE agent_id = ?')
439
524
  .get(spec.agentId);
440
525
  let agentUuid;
441
526
  if (!existing) {
442
527
  agentUuid = crypto.randomUUID();
443
528
  globalDb
444
- .prepare(`INSERT INTO agents (id, agent_id, name, class, privacy_tier, capabilities, skills,
529
+ .prepare(`INSERT INTO agent_registry_agents (id, agent_id, name, class, privacy_tier, capabilities, skills,
445
530
  transport_type, api_key_encrypted, api_base_url, classification, transport_config,
446
531
  is_active, last_used_at, status, created_at, updated_at, requires_reauth)
447
532
  VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'online', ?, ?, 0)`)
448
- .run(agentUuid, spec.agentId, spec.displayName, spec.classification ?? 'custom', spec.privacyTier, JSON.stringify(spec.capabilities), JSON.stringify(spec.skills), spec.transportType ?? 'http', apiKeyEncrypted, spec.apiBaseUrl, spec.classification ?? null, JSON.stringify(spec.transportConfig), spec.isActive ? 1 : 0, spec.lastUsedAt ? Math.floor(new Date(spec.lastUsedAt).getTime() / 1000) : null, nowTs, nowTs);
533
+ .run(agentUuid, spec.agentId, spec.displayName, spec.classification ?? 'custom', spec.privacyTier, JSON.stringify(spec.capabilities), JSON.stringify(spec.skills), spec.transportType ?? 'http', apiKeyEncrypted, spec.apiBaseUrl, spec.classification ?? null, JSON.stringify(spec.transportConfig), spec.isActive ? 1 : 0,
534
+ // T11622 cutover: TEXT ISO-8601 to satisfy the consolidated GLOB CHECK.
535
+ spec.lastUsedAt ? new Date(spec.lastUsedAt).toISOString() : null, nowIso, nowIso);
449
536
  syncJunctionTables(globalDb, agentUuid, spec.capabilities, spec.skills);
450
537
  }
451
538
  else {
452
539
  agentUuid = existing.id;
453
540
  // Update identity in global DB (idempotent re-register)
454
541
  globalDb
455
- .prepare(`UPDATE agents SET name = ?, class = ?, privacy_tier = ?, capabilities = ?, skills = ?,
542
+ .prepare(`UPDATE agent_registry_agents SET name = ?, class = ?, privacy_tier = ?, capabilities = ?, skills = ?,
456
543
  transport_type = ?, api_key_encrypted = ?, api_base_url = ?, classification = ?,
457
544
  transport_config = ?, is_active = ?, updated_at = ? WHERE agent_id = ?`)
458
- .run(spec.displayName, spec.classification ?? 'custom', spec.privacyTier, JSON.stringify(spec.capabilities), JSON.stringify(spec.skills), spec.transportType ?? 'http', apiKeyEncrypted, spec.apiBaseUrl, spec.classification ?? null, JSON.stringify(spec.transportConfig), spec.isActive ? 1 : 0, nowTs, spec.agentId);
545
+ .run(spec.displayName, spec.classification ?? 'custom', spec.privacyTier, JSON.stringify(spec.capabilities), JSON.stringify(spec.skills), spec.transportType ?? 'http', apiKeyEncrypted, spec.apiBaseUrl, spec.classification ?? null, JSON.stringify(spec.transportConfig), spec.isActive ? 1 : 0, nowIso, spec.agentId);
459
546
  syncJunctionTables(globalDb, agentUuid, spec.capabilities, spec.skills);
460
547
  }
461
548
  }
462
- finally {
463
- globalDb.close();
464
- }
549
+ // NOTE: globalDb is the SHARED dual-scope handle — never close it (T11562).
465
550
  // Attach to project via conduit.db:project_agent_refs
466
551
  const conduitDb = openConduitDb(projectRoot);
467
552
  try {
468
553
  const existingRef = conduitDb
469
- .prepare('SELECT agent_id, enabled FROM project_agent_refs WHERE agent_id = ?')
554
+ .prepare('SELECT agent_id, enabled FROM conduit_project_agent_refs WHERE agent_id = ?')
470
555
  .get(spec.agentId);
471
556
  if (!existingRef) {
472
557
  conduitDb
473
- .prepare(`INSERT INTO project_agent_refs (agent_id, attached_at, role, capabilities_override, last_used_at, enabled)
558
+ .prepare(`INSERT INTO conduit_project_agent_refs (agent_id, attached_at, role, capabilities_override, last_used_at, enabled)
474
559
  VALUES (?, ?, NULL, NULL, NULL, 1)`)
475
560
  .run(spec.agentId, nowIso);
476
561
  }
477
562
  else if (existingRef.enabled === 0) {
478
563
  // Re-enable a previously detached agent
479
564
  conduitDb
480
- .prepare(`UPDATE project_agent_refs SET enabled = 1, attached_at = ? WHERE agent_id = ?`)
565
+ .prepare(`UPDATE conduit_project_agent_refs SET enabled = 1, attached_at = ? WHERE agent_id = ?`)
481
566
  .run(nowIso, spec.agentId);
482
567
  }
483
568
  // If enabled=1 already, leave the existing ref intact
@@ -485,7 +570,7 @@ export function createProjectAgent(projectRoot, spec) {
485
570
  finally {
486
571
  conduitDb.close();
487
572
  }
488
- const result = lookupAgent(projectRoot, spec.agentId, { includeGlobal: false });
573
+ const result = await lookupAgent(projectRoot, spec.agentId, { includeGlobal: false });
489
574
  if (!result) {
490
575
  throw new Error(`createProjectAgent: failed to retrieve agent after creation: ${spec.agentId}`);
491
576
  }
@@ -501,7 +586,7 @@ export function createProjectAgent(projectRoot, spec) {
501
586
  * with `enabled=0`, it is re-enabled (idempotent). If the row already has
502
587
  * `enabled=1`, this is a no-op.
503
588
  *
504
- * The agent MUST already exist in the global `signaldock.db:agents` table.
589
+ * The agent MUST already exist in the global `cleo.db:agent_registry_agents` table.
505
590
  * This function does NOT validate global existence — callers must check via
506
591
  * `lookupAgent(..., { includeGlobal: true })` first.
507
592
  *
@@ -518,17 +603,17 @@ export function attachAgentToProject(projectRoot, agentId, opts) {
518
603
  const nowIso = new Date().toISOString();
519
604
  try {
520
605
  const existingRef = conduitDb
521
- .prepare('SELECT agent_id, enabled FROM project_agent_refs WHERE agent_id = ?')
606
+ .prepare('SELECT agent_id, enabled FROM conduit_project_agent_refs WHERE agent_id = ?')
522
607
  .get(agentId);
523
608
  if (!existingRef) {
524
609
  conduitDb
525
- .prepare(`INSERT INTO project_agent_refs (agent_id, attached_at, role, capabilities_override, last_used_at, enabled)
610
+ .prepare(`INSERT INTO conduit_project_agent_refs (agent_id, attached_at, role, capabilities_override, last_used_at, enabled)
526
611
  VALUES (?, ?, ?, ?, NULL, 1)`)
527
612
  .run(agentId, nowIso, opts?.role ?? null, opts?.capabilitiesOverride ?? null);
528
613
  }
529
614
  else if (existingRef.enabled === 0) {
530
615
  conduitDb
531
- .prepare(`UPDATE project_agent_refs SET enabled = 1, attached_at = ?, role = ?, capabilities_override = ? WHERE agent_id = ?`)
616
+ .prepare(`UPDATE conduit_project_agent_refs SET enabled = 1, attached_at = ?, role = ?, capabilities_override = ? WHERE agent_id = ?`)
532
617
  .run(nowIso, opts?.role ?? null, opts?.capabilitiesOverride ?? null, agentId);
533
618
  }
534
619
  // enabled=1 already — no-op
@@ -540,7 +625,7 @@ export function attachAgentToProject(projectRoot, agentId, opts) {
540
625
  /**
541
626
  * Detach an agent from the current project by setting `project_agent_refs.enabled=0`.
542
627
  *
543
- * This is a soft-delete: the global `signaldock.db:agents` row is preserved.
628
+ * This is a soft-delete: the global `cleo.db:agent_registry_agents` row is preserved.
544
629
  * The agent can be re-attached later via `attachAgentToProject`.
545
630
  *
546
631
  * Returns `false` if no row exists in `project_agent_refs` for the given agentId
@@ -557,11 +642,13 @@ export function detachAgentFromProject(projectRoot, agentId) {
557
642
  const conduitDb = openConduitDb(projectRoot);
558
643
  try {
559
644
  const ref = conduitDb
560
- .prepare('SELECT agent_id FROM project_agent_refs WHERE agent_id = ?')
645
+ .prepare('SELECT agent_id FROM conduit_project_agent_refs WHERE agent_id = ?')
561
646
  .get(agentId);
562
647
  if (!ref)
563
648
  return false;
564
- conduitDb.prepare('UPDATE project_agent_refs SET enabled = 0 WHERE agent_id = ?').run(agentId);
649
+ conduitDb
650
+ .prepare('UPDATE conduit_project_agent_refs SET enabled = 0 WHERE agent_id = ?')
651
+ .run(agentId);
565
652
  return true;
566
653
  }
567
654
  finally {
@@ -584,7 +671,7 @@ export function getProjectAgentRef(projectRoot, agentId) {
584
671
  const conduitDb = openConduitDb(projectRoot);
585
672
  try {
586
673
  const row = conduitDb
587
- .prepare('SELECT * FROM project_agent_refs WHERE agent_id = ?')
674
+ .prepare('SELECT * FROM conduit_project_agent_refs WHERE agent_id = ?')
588
675
  .get(agentId);
589
676
  if (!row)
590
677
  return null;
@@ -625,12 +712,14 @@ export class AgentRegistryAccessor {
625
712
  * @task T355
626
713
  * @epic T310
627
714
  */
628
- ensureDbs() {
629
- ensureGlobalSignaldockDb();
630
- ensureConduitDb(this.projectPath);
715
+ async ensureDbs() {
716
+ // E6-L3 (T11523): ensureConduitDb is now async (dual-scope cleo.db
717
+ // chokepoint); ensureGlobalAgentRegistryDb is already async. Await both.
718
+ await ensureGlobalAgentRegistryDb();
719
+ await ensureConduitDb(this.projectPath);
631
720
  }
632
721
  /**
633
- * Register (create or update) an agent in global signaldock.db and attach
722
+ * Register (create or update) an agent in global cleo.db (Agent Registry) and attach
634
723
  * it to the current project via conduit.db:project_agent_refs.
635
724
  *
636
725
  * @param credential - Agent spec (without createdAt/updatedAt).
@@ -639,7 +728,7 @@ export class AgentRegistryAccessor {
639
728
  * @epic T310
640
729
  */
641
730
  async register(credential) {
642
- this.ensureDbs();
731
+ await this.ensureDbs();
643
732
  return createProjectAgent(this.projectPath, credential);
644
733
  }
645
734
  /**
@@ -652,7 +741,7 @@ export class AgentRegistryAccessor {
652
741
  * @epic T310
653
742
  */
654
743
  async get(agentId, opts) {
655
- this.ensureDbs();
744
+ await this.ensureDbs();
656
745
  return lookupAgent(this.projectPath, agentId, opts);
657
746
  }
658
747
  /**
@@ -664,8 +753,8 @@ export class AgentRegistryAccessor {
664
753
  * @epic T310
665
754
  */
666
755
  async list(filter) {
667
- this.ensureDbs();
668
- const results = listAgentsForProject(this.projectPath, { includeGlobal: false });
756
+ await this.ensureDbs();
757
+ const results = await listAgentsForProject(this.projectPath, { includeGlobal: false });
669
758
  if (filter?.active !== undefined) {
670
759
  return results.filter((a) => a.isActive === filter.active);
671
760
  }
@@ -680,24 +769,20 @@ export class AgentRegistryAccessor {
680
769
  * @epic T310
681
770
  */
682
771
  async listGlobal(filter) {
683
- this.ensureDbs();
684
- const globalDb = openGlobalDb();
685
- try {
686
- const rows = filter?.active !== undefined
687
- ? globalDb
688
- .prepare('SELECT * FROM agents WHERE is_active = ? ORDER BY name ASC')
689
- .all(filter.active ? 1 : 0)
690
- : globalDb
691
- .prepare('SELECT * FROM agents ORDER BY name ASC')
692
- .all();
693
- return rows.map(rowToCredential);
694
- }
695
- finally {
696
- globalDb.close();
697
- }
772
+ await this.ensureDbs();
773
+ // SHARED global cleo.db handle — do NOT close (lifecycle owned by openDualScopeDb).
774
+ const globalDb = await openGlobalDb();
775
+ const rows = filter?.active !== undefined
776
+ ? globalDb
777
+ .prepare('SELECT * FROM agent_registry_agents WHERE is_active = ? ORDER BY name ASC')
778
+ .all(filter.active ? 1 : 0)
779
+ : globalDb
780
+ .prepare('SELECT * FROM agent_registry_agents ORDER BY name ASC')
781
+ .all();
782
+ return rows.map(rowToCredential);
698
783
  }
699
784
  /**
700
- * Update agent identity fields in global signaldock.db.
785
+ * Update agent identity fields in global cleo.db (Agent Registry).
701
786
  * Project-specific fields (role, capabilitiesOverride) require direct
702
787
  * conduit.db manipulation (not yet exposed by this method).
703
788
  *
@@ -708,15 +793,17 @@ export class AgentRegistryAccessor {
708
793
  * @epic T310
709
794
  */
710
795
  async update(agentId, updates) {
711
- this.ensureDbs();
796
+ await this.ensureDbs();
712
797
  const existing = await this.get(agentId, { includeGlobal: true });
713
798
  if (!existing)
714
799
  throw new Error(`Agent not found: ${agentId}`);
715
- const nowTs = Math.floor(Date.now() / 1000);
716
- const globalDb = openGlobalDb();
717
- try {
800
+ // T11622 cutover: `agent_registry_agents.updated_at` is TEXT ISO-8601 (GLOB CHECK).
801
+ const nowIso = new Date().toISOString();
802
+ // SHARED global cleo.db handle — do NOT close (lifecycle owned by openDualScopeDb).
803
+ const globalDb = await openGlobalDb();
804
+ {
718
805
  const sets = ['updated_at = ?'];
719
- const params = [nowTs];
806
+ const params = [nowIso];
720
807
  if (updates.displayName !== undefined) {
721
808
  sets.push('name = ?');
722
809
  params.push(updates.displayName);
@@ -763,21 +850,19 @@ export class AgentRegistryAccessor {
763
850
  }
764
851
  params.push(agentId);
765
852
  globalDb
766
- .prepare(`UPDATE agents SET ${sets.join(', ')} WHERE agent_id = ?`)
853
+ .prepare(`UPDATE agent_registry_agents SET ${sets.join(', ')} WHERE agent_id = ?`)
767
854
  .run(...params);
768
855
  // Sync junction tables if capabilities or skills changed
769
856
  if (updates.capabilities !== undefined || updates.skills !== undefined) {
770
857
  const agentRow = globalDb
771
- .prepare('SELECT id FROM agents WHERE agent_id = ?')
858
+ .prepare('SELECT id FROM agent_registry_agents WHERE agent_id = ?')
772
859
  .get(agentId);
773
860
  if (agentRow) {
774
861
  syncJunctionTables(globalDb, agentRow.id, updates.capabilities ?? existing.capabilities, updates.skills ?? existing.skills);
775
862
  }
776
863
  }
777
864
  }
778
- finally {
779
- globalDb.close();
780
- }
865
+ // NOTE: globalDb is the SHARED dual-scope handle — never close it (T11562).
781
866
  const result = await this.get(agentId, { includeGlobal: true });
782
867
  if (!result)
783
868
  throw new Error(`Agent not found after update: ${agentId}`);
@@ -785,24 +870,24 @@ export class AgentRegistryAccessor {
785
870
  }
786
871
  /**
787
872
  * Remove agent from current project (sets project_agent_refs.enabled=0).
788
- * Does NOT delete from global signaldock.db (per ADR-037 §6 / Q4=C).
873
+ * Does NOT delete from global cleo.db (Agent Registry) (per ADR-037 §6 / Q4=C).
789
874
  *
790
875
  * @param agentId - Agent business identifier.
791
876
  * @task T355
792
877
  * @epic T310
793
878
  */
794
879
  async remove(agentId) {
795
- this.ensureDbs();
880
+ await this.ensureDbs();
796
881
  const conduitDb = openConduitDb(this.projectPath);
797
882
  try {
798
883
  const ref = conduitDb
799
- .prepare('SELECT agent_id FROM project_agent_refs WHERE agent_id = ?')
884
+ .prepare('SELECT agent_id FROM conduit_project_agent_refs WHERE agent_id = ?')
800
885
  .get(agentId);
801
886
  if (!ref) {
802
887
  throw new Error(`Agent not found in current project: ${agentId}`);
803
888
  }
804
889
  conduitDb
805
- .prepare('UPDATE project_agent_refs SET enabled = 0 WHERE agent_id = ?')
890
+ .prepare('UPDATE conduit_project_agent_refs SET enabled = 0 WHERE agent_id = ?')
806
891
  .run(agentId);
807
892
  }
808
893
  finally {
@@ -810,7 +895,7 @@ export class AgentRegistryAccessor {
810
895
  }
811
896
  }
812
897
  /**
813
- * Remove agent from global signaldock.db.
898
+ * Remove agent from global cleo.db (Agent Registry).
814
899
  * Requires explicit opt-in. Warns if cross-project refs may exist.
815
900
  *
816
901
  * @param agentId - Agent business identifier.
@@ -819,38 +904,37 @@ export class AgentRegistryAccessor {
819
904
  * @epic T310
820
905
  */
821
906
  async removeGlobal(agentId, opts) {
822
- this.ensureDbs();
823
- const globalDb = openGlobalDb();
824
- try {
825
- const existing = globalDb.prepare('SELECT id FROM agents WHERE agent_id = ?').get(agentId);
826
- if (!existing) {
827
- throw new Error(`Agent not found globally: ${agentId}`);
828
- }
829
- if (!opts?.force) {
830
- // Best-effort cross-project scan: check the current project's conduit.db
831
- const conduitDb = openConduitDb(this.projectPath);
832
- try {
833
- const ref = conduitDb
834
- .prepare('SELECT agent_id FROM project_agent_refs WHERE agent_id = ? AND enabled = 1')
835
- .get(agentId);
836
- if (ref) {
837
- throw new Error(`Agent "${agentId}" still has project references in the current project. ` +
838
- `Use removeGlobal(id, { force: true }) to skip this check.`);
839
- }
840
- }
841
- finally {
842
- conduitDb.close();
907
+ await this.ensureDbs();
908
+ // SHARED global cleo.db handle — do NOT close (lifecycle owned by openDualScopeDb).
909
+ const globalDb = await openGlobalDb();
910
+ const existing = globalDb
911
+ .prepare('SELECT id FROM agent_registry_agents WHERE agent_id = ?')
912
+ .get(agentId);
913
+ if (!existing) {
914
+ throw new Error(`Agent not found globally: ${agentId}`);
915
+ }
916
+ if (!opts?.force) {
917
+ // Best-effort cross-project scan: check the current project's conduit.db
918
+ const conduitDb = openConduitDb(this.projectPath);
919
+ try {
920
+ const ref = conduitDb
921
+ .prepare('SELECT agent_id FROM conduit_project_agent_refs WHERE agent_id = ? AND enabled = 1')
922
+ .get(agentId);
923
+ if (ref) {
924
+ throw new Error(`Agent "${agentId}" still has project references in the current project. ` +
925
+ `Use removeGlobal(id, { force: true }) to skip this check.`);
843
926
  }
844
927
  }
845
- globalDb.prepare('DELETE FROM agents WHERE agent_id = ?').run(agentId);
846
- }
847
- finally {
848
- globalDb.close();
928
+ finally {
929
+ conduitDb.close();
930
+ }
849
931
  }
932
+ globalDb.prepare('DELETE FROM agent_registry_agents WHERE agent_id = ?').run(agentId);
933
+ // NOTE: globalDb is the SHARED dual-scope handle — never close it (T11562).
850
934
  }
851
935
  /**
852
936
  * Rotate API key via cloud endpoint and re-encrypt with the new T310 KDF
853
- * in global signaldock.db.
937
+ * in global cleo.db (Agent Registry).
854
938
  *
855
939
  * @param agentId - Agent business identifier.
856
940
  * @returns Object with agentId and a redacted new API key string.
@@ -858,7 +942,7 @@ export class AgentRegistryAccessor {
858
942
  * @epic T310
859
943
  */
860
944
  async rotateKey(agentId) {
861
- this.ensureDbs();
945
+ await this.ensureDbs();
862
946
  const credential = await this.get(agentId, { includeGlobal: true });
863
947
  if (!credential)
864
948
  throw new Error(`Agent not found: ${agentId}`);
@@ -880,16 +964,14 @@ export class AgentRegistryAccessor {
880
964
  const machineKey = readMachineKey();
881
965
  const globalSalt = getGlobalSalt();
882
966
  const derivedKey = deriveApiKey({ machineKey, globalSalt, agentId });
883
- const nowTs = Math.floor(Date.now() / 1000);
884
- const globalDb = openGlobalDb();
885
- try {
886
- globalDb
887
- .prepare('UPDATE agents SET api_key_encrypted = ?, updated_at = ?, requires_reauth = 0 WHERE agent_id = ?')
888
- .run(derivedKey.toString('hex'), nowTs, agentId);
889
- }
890
- finally {
891
- globalDb.close();
892
- }
967
+ // T11622 cutover: `updated_at` is TEXT ISO-8601 (GLOB CHECK).
968
+ const nowIso = new Date().toISOString();
969
+ // SHARED global cleo.db handle — do NOT close (lifecycle owned by openDualScopeDb).
970
+ const globalDb = await openGlobalDb();
971
+ globalDb
972
+ .prepare('UPDATE agent_registry_agents SET api_key_encrypted = ?, updated_at = ?, requires_reauth = 0 WHERE agent_id = ?')
973
+ .run(derivedKey.toString('hex'), nowIso, agentId);
974
+ // NOTE: globalDb is the SHARED dual-scope handle — never close it (T11562).
893
975
  return { agentId, newApiKey: `${newApiKey.substring(0, 8)}...rotated` };
894
976
  }
895
977
  /**
@@ -900,36 +982,37 @@ export class AgentRegistryAccessor {
900
982
  * @epic T310
901
983
  */
902
984
  async getActive() {
903
- this.ensureDbs();
904
- const globalDb = openGlobalDb();
985
+ await this.ensureDbs();
986
+ // SHARED global cleo.db handle — do NOT close (lifecycle owned by openDualScopeDb).
987
+ const globalDb = await openGlobalDb();
905
988
  const conduitDb = openConduitDb(this.projectPath);
906
989
  try {
907
990
  // Get all project-attached, enabled agent IDs ordered by project last_used_at
908
991
  const enabledRefs = conduitDb
909
- .prepare('SELECT agent_id, last_used_at FROM project_agent_refs WHERE enabled = 1 ORDER BY last_used_at DESC')
992
+ .prepare('SELECT agent_id, last_used_at FROM conduit_project_agent_refs WHERE enabled = 1 ORDER BY last_used_at DESC')
910
993
  .all();
911
994
  for (const ref of enabledRefs) {
912
995
  const agentRow = globalDb
913
- .prepare('SELECT * FROM agents WHERE agent_id = ? AND is_active = 1')
996
+ .prepare('SELECT * FROM agent_registry_agents WHERE agent_id = ? AND is_active = 1')
914
997
  .get(ref.agent_id);
915
998
  if (agentRow)
916
999
  return rowToCredential(agentRow);
917
1000
  }
918
1001
  // Fall back to global last_used_at if no project-local activity recorded
919
1002
  const row = globalDb
920
- .prepare('SELECT * FROM agents WHERE is_active = 1 ORDER BY last_used_at DESC, created_at DESC LIMIT 1')
1003
+ .prepare('SELECT * FROM agent_registry_agents WHERE is_active = 1 ORDER BY last_used_at DESC, created_at DESC LIMIT 1')
921
1004
  .get();
922
1005
  if (!row)
923
1006
  return null;
924
1007
  return rowToCredential(row);
925
1008
  }
926
1009
  finally {
927
- globalDb.close();
1010
+ // NOTE: globalDb is the SHARED dual-scope handle — never close it (T11562).
928
1011
  conduitDb.close();
929
1012
  }
930
1013
  }
931
1014
  /**
932
- * Update last_used_at in both global signaldock.db:agents and
1015
+ * Update last_used_at in both global cleo.db:agent_registry_agents and
933
1016
  * conduit.db:project_agent_refs.
934
1017
  *
935
1018
  * @param agentId - Agent business identifier.
@@ -937,22 +1020,20 @@ export class AgentRegistryAccessor {
937
1020
  * @epic T310
938
1021
  */
939
1022
  async markUsed(agentId) {
940
- this.ensureDbs();
941
- const nowTs = Math.floor(Date.now() / 1000);
942
- const nowIso = new Date(nowTs * 1000).toISOString();
943
- const globalDb = openGlobalDb();
944
- try {
945
- globalDb
946
- .prepare('UPDATE agents SET last_used_at = ?, updated_at = ? WHERE agent_id = ?')
947
- .run(nowTs, nowTs, agentId);
948
- }
949
- finally {
950
- globalDb.close();
951
- }
1023
+ await this.ensureDbs();
1024
+ // T11622 cutover: `last_used_at` / `updated_at` are TEXT ISO-8601 (GLOB CHECK)
1025
+ // in `agent_registry_agents`; `conduit_project_agent_refs.last_used_at` is also ISO.
1026
+ const nowIso = new Date().toISOString();
1027
+ // SHARED global cleo.db handle — do NOT close (lifecycle owned by openDualScopeDb).
1028
+ const globalDb = await openGlobalDb();
1029
+ globalDb
1030
+ .prepare('UPDATE agent_registry_agents SET last_used_at = ?, updated_at = ? WHERE agent_id = ?')
1031
+ .run(nowIso, nowIso, agentId);
1032
+ // NOTE: globalDb is the SHARED dual-scope handle — never close it (T11562).
952
1033
  const conduitDb = openConduitDb(this.projectPath);
953
1034
  try {
954
1035
  conduitDb
955
- .prepare('UPDATE project_agent_refs SET last_used_at = ? WHERE agent_id = ?')
1036
+ .prepare('UPDATE conduit_project_agent_refs SET last_used_at = ? WHERE agent_id = ?')
956
1037
  .run(nowIso, agentId);
957
1038
  }
958
1039
  finally {