@cleocode/core 2026.10.1 → 2026.10.3

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 (389) hide show
  1. package/dist/build-provenance.json +2 -2
  2. package/dist/cloud/http.d.ts +2 -0
  3. package/dist/cloud/http.d.ts.map +1 -1
  4. package/dist/cloud/http.js +3 -0
  5. package/dist/cloud/http.js.map +1 -1
  6. package/dist/cloud/journal.d.ts +9 -5
  7. package/dist/cloud/journal.d.ts.map +1 -1
  8. package/dist/cloud/journal.js +29 -8
  9. package/dist/cloud/journal.js.map +1 -1
  10. package/dist/cloud/manifest-check.d.ts +140 -4
  11. package/dist/cloud/manifest-check.d.ts.map +1 -1
  12. package/dist/cloud/manifest-check.js +322 -10
  13. package/dist/cloud/manifest-check.js.map +1 -1
  14. package/dist/cloud/nexus-attach.d.ts +25 -0
  15. package/dist/cloud/nexus-attach.d.ts.map +1 -1
  16. package/dist/cloud/nexus-attach.js +81 -6
  17. package/dist/cloud/nexus-attach.js.map +1 -1
  18. package/dist/cloud/nexus-cloud-activity.d.ts +37 -0
  19. package/dist/cloud/nexus-cloud-activity.d.ts.map +1 -0
  20. package/dist/cloud/nexus-cloud-activity.js +79 -0
  21. package/dist/cloud/nexus-cloud-activity.js.map +1 -0
  22. package/dist/cloud/nexus-cloud-status.d.ts.map +1 -1
  23. package/dist/cloud/nexus-cloud-status.js +36 -0
  24. package/dist/cloud/nexus-cloud-status.js.map +1 -1
  25. package/dist/cloud/nexus-device.d.ts +1 -1
  26. package/dist/cloud/nexus-enrol.d.ts.map +1 -1
  27. package/dist/cloud/nexus-enrol.js +5 -0
  28. package/dist/cloud/nexus-enrol.js.map +1 -1
  29. package/dist/cloud/nexus-home.d.ts +74 -0
  30. package/dist/cloud/nexus-home.d.ts.map +1 -0
  31. package/dist/cloud/nexus-home.js +97 -0
  32. package/dist/cloud/nexus-home.js.map +1 -0
  33. package/dist/cloud/nexus-vault-keys.d.ts +130 -0
  34. package/dist/cloud/nexus-vault-keys.d.ts.map +1 -0
  35. package/dist/cloud/nexus-vault-keys.js +347 -0
  36. package/dist/cloud/nexus-vault-keys.js.map +1 -0
  37. package/dist/cloud/nexus-vault-state.d.ts +121 -0
  38. package/dist/cloud/nexus-vault-state.d.ts.map +1 -0
  39. package/dist/cloud/nexus-vault-state.js +274 -0
  40. package/dist/cloud/nexus-vault-state.js.map +1 -0
  41. package/dist/cloud/nexus-vault.d.ts +160 -0
  42. package/dist/cloud/nexus-vault.d.ts.map +1 -0
  43. package/dist/cloud/nexus-vault.js +1745 -0
  44. package/dist/cloud/nexus-vault.js.map +1 -0
  45. package/dist/cloud/signing.d.ts +24 -8
  46. package/dist/cloud/signing.d.ts.map +1 -1
  47. package/dist/cloud/signing.js +61 -15
  48. package/dist/cloud/signing.js.map +1 -1
  49. package/dist/docs/export-document.js +8137 -3318
  50. package/dist/docs/export-document.js.map +3 -3
  51. package/dist/doctor/migrations.d.ts +75 -0
  52. package/dist/doctor/migrations.d.ts.map +1 -0
  53. package/dist/doctor/migrations.js +136 -0
  54. package/dist/doctor/migrations.js.map +1 -0
  55. package/dist/doctor/sync-sealer.d.ts +48 -0
  56. package/dist/doctor/sync-sealer.d.ts.map +1 -0
  57. package/dist/doctor/sync-sealer.js +109 -0
  58. package/dist/doctor/sync-sealer.js.map +1 -0
  59. package/dist/doctor/sync-triggers.d.ts +53 -0
  60. package/dist/doctor/sync-triggers.d.ts.map +1 -0
  61. package/dist/doctor/sync-triggers.js +157 -0
  62. package/dist/doctor/sync-triggers.js.map +1 -0
  63. package/dist/init.d.ts.map +1 -1
  64. package/dist/init.js +5 -1
  65. package/dist/init.js.map +1 -1
  66. package/dist/internal.d.ts +1 -1
  67. package/dist/internal.d.ts.map +1 -1
  68. package/dist/internal.js +1 -1
  69. package/dist/internal.js.map +1 -1
  70. package/dist/llm/plugin-facade.js +8442 -3623
  71. package/dist/llm/plugin-facade.js.map +3 -3
  72. package/dist/nexus/projects-clean.d.ts +3 -0
  73. package/dist/nexus/projects-clean.d.ts.map +1 -1
  74. package/dist/nexus/projects-clean.js +9 -3
  75. package/dist/nexus/projects-clean.js.map +1 -1
  76. package/dist/nexus/registry-roots.d.ts +3 -1
  77. package/dist/nexus/registry-roots.d.ts.map +1 -1
  78. package/dist/nexus/registry-roots.js +5 -2
  79. package/dist/nexus/registry-roots.js.map +1 -1
  80. package/dist/nexus/registry.d.ts +8 -1
  81. package/dist/nexus/registry.d.ts.map +1 -1
  82. package/dist/nexus/registry.js +24 -10
  83. package/dist/nexus/registry.js.map +1 -1
  84. package/dist/nexus/workspace.d.ts +4 -1
  85. package/dist/nexus/workspace.d.ts.map +1 -1
  86. package/dist/nexus/workspace.js +10 -4
  87. package/dist/nexus/workspace.js.map +1 -1
  88. package/dist/orchestrate/spawn-ops.d.ts.map +1 -1
  89. package/dist/orchestrate/spawn-ops.js +7 -2
  90. package/dist/orchestrate/spawn-ops.js.map +1 -1
  91. package/dist/orchestrate/worker-verify.d.ts +121 -12
  92. package/dist/orchestrate/worker-verify.d.ts.map +1 -1
  93. package/dist/orchestrate/worker-verify.js +172 -21
  94. package/dist/orchestrate/worker-verify.js.map +1 -1
  95. package/dist/orchestration/spawn-prompt.d.ts.map +1 -1
  96. package/dist/orchestration/spawn-prompt.js +15 -9
  97. package/dist/orchestration/spawn-prompt.js.map +1 -1
  98. package/dist/release/ci-evidence.d.ts +9 -0
  99. package/dist/release/ci-evidence.d.ts.map +1 -1
  100. package/dist/release/ci-evidence.js +9 -2
  101. package/dist/release/ci-evidence.js.map +1 -1
  102. package/dist/resources/backend.d.ts +15 -3
  103. package/dist/resources/backend.d.ts.map +1 -1
  104. package/dist/resources/backend.js +7 -3
  105. package/dist/resources/backend.js.map +1 -1
  106. package/dist/resources/darwin-backend.d.ts +142 -0
  107. package/dist/resources/darwin-backend.d.ts.map +1 -0
  108. package/dist/resources/darwin-backend.js +288 -0
  109. package/dist/resources/darwin-backend.js.map +1 -0
  110. package/dist/resources/governor.d.ts +44 -1
  111. package/dist/resources/governor.d.ts.map +1 -1
  112. package/dist/resources/governor.js +100 -36
  113. package/dist/resources/governor.js.map +1 -1
  114. package/dist/resources/heavy-command.d.ts +132 -0
  115. package/dist/resources/heavy-command.d.ts.map +1 -0
  116. package/dist/resources/heavy-command.js +768 -0
  117. package/dist/resources/heavy-command.js.map +1 -0
  118. package/dist/resources/monitor.d.ts +50 -1
  119. package/dist/resources/monitor.d.ts.map +1 -1
  120. package/dist/resources/monitor.js +83 -1
  121. package/dist/resources/monitor.js.map +1 -1
  122. package/dist/resources/run-admission.d.ts +303 -0
  123. package/dist/resources/run-admission.d.ts.map +1 -0
  124. package/dist/resources/run-admission.js +648 -0
  125. package/dist/resources/run-admission.js.map +1 -0
  126. package/dist/resources/run-class.d.ts +111 -0
  127. package/dist/resources/run-class.d.ts.map +1 -0
  128. package/dist/resources/run-class.js +658 -0
  129. package/dist/resources/run-class.js.map +1 -0
  130. package/dist/resources/run-governed.d.ts +158 -0
  131. package/dist/resources/run-governed.d.ts.map +1 -0
  132. package/dist/resources/run-governed.js +406 -0
  133. package/dist/resources/run-governed.js.map +1 -0
  134. package/dist/resources/slot-holder.d.ts +267 -0
  135. package/dist/resources/slot-holder.d.ts.map +1 -0
  136. package/dist/resources/slot-holder.js +505 -0
  137. package/dist/resources/slot-holder.js.map +1 -0
  138. package/dist/resources/tool-groups.d.ts +74 -0
  139. package/dist/resources/tool-groups.d.ts.map +1 -0
  140. package/dist/resources/tool-groups.js +118 -0
  141. package/dist/resources/tool-groups.js.map +1 -0
  142. package/dist/routing/build-command-groups.d.ts.map +1 -1
  143. package/dist/routing/build-command-groups.js +1 -0
  144. package/dist/routing/build-command-groups.js.map +1 -1
  145. package/dist/selfimprove/fix-gen.js +8446 -3627
  146. package/dist/selfimprove/fix-gen.js.map +3 -3
  147. package/dist/sentient/cross-project-hygiene.d.ts +3 -2
  148. package/dist/sentient/cross-project-hygiene.d.ts.map +1 -1
  149. package/dist/sentient/cross-project-hygiene.js +5 -2
  150. package/dist/sentient/cross-project-hygiene.js.map +1 -1
  151. package/dist/sentient/state.d.ts +7 -0
  152. package/dist/sentient/state.d.ts.map +1 -1
  153. package/dist/sentient/state.js.map +1 -1
  154. package/dist/sentient/tick.d.ts +14 -2
  155. package/dist/sentient/tick.d.ts.map +1 -1
  156. package/dist/sentient/tick.js +63 -4
  157. package/dist/sentient/tick.js.map +1 -1
  158. package/dist/store/backup-recover.d.ts.map +1 -1
  159. package/dist/store/backup-recover.js +5 -0
  160. package/dist/store/backup-recover.js.map +1 -1
  161. package/dist/store/data-accessor.d.ts +1 -0
  162. package/dist/store/data-accessor.d.ts.map +1 -1
  163. package/dist/store/data-accessor.js +7 -0
  164. package/dist/store/data-accessor.js.map +1 -1
  165. package/dist/store/dual-scope-db.d.ts +23 -1
  166. package/dist/store/dual-scope-db.d.ts.map +1 -1
  167. package/dist/store/dual-scope-db.js +126 -36
  168. package/dist/store/dual-scope-db.js.map +1 -1
  169. package/dist/store/exodus/recovery.d.ts.map +1 -1
  170. package/dist/store/exodus/recovery.js +15 -0
  171. package/dist/store/exodus/recovery.js.map +1 -1
  172. package/dist/store/legacy-tasks-lineage.d.ts.map +1 -1
  173. package/dist/store/legacy-tasks-lineage.js +5 -0
  174. package/dist/store/legacy-tasks-lineage.js.map +1 -1
  175. package/dist/store/lock.d.ts +8 -1
  176. package/dist/store/lock.d.ts.map +1 -1
  177. package/dist/store/lock.js +10 -2
  178. package/dist/store/lock.js.map +1 -1
  179. package/dist/store/migration-manager.d.ts +5 -0
  180. package/dist/store/migration-manager.d.ts.map +1 -1
  181. package/dist/store/migration-manager.js +11 -0
  182. package/dist/store/migration-manager.js.map +1 -1
  183. package/dist/store/migration-runner.d.ts +158 -0
  184. package/dist/store/migration-runner.d.ts.map +1 -0
  185. package/dist/store/migration-runner.js +493 -0
  186. package/dist/store/migration-runner.js.map +1 -0
  187. package/dist/store/portable-bundle-import.d.ts +15 -1
  188. package/dist/store/portable-bundle-import.d.ts.map +1 -1
  189. package/dist/store/portable-bundle-import.js +24 -4
  190. package/dist/store/portable-bundle-import.js.map +1 -1
  191. package/dist/store/portable-bundle-relocate.d.ts +43 -0
  192. package/dist/store/portable-bundle-relocate.d.ts.map +1 -1
  193. package/dist/store/portable-bundle-relocate.js +79 -5
  194. package/dist/store/portable-bundle-relocate.js.map +1 -1
  195. package/dist/store/portable-bundle-scan.d.ts +42 -0
  196. package/dist/store/portable-bundle-scan.d.ts.map +1 -1
  197. package/dist/store/portable-bundle-scan.js +132 -25
  198. package/dist/store/portable-bundle-scan.js.map +1 -1
  199. package/dist/store/portable-bundle.d.ts +40 -0
  200. package/dist/store/portable-bundle.d.ts.map +1 -1
  201. package/dist/store/portable-bundle.js +43 -7
  202. package/dist/store/portable-bundle.js.map +1 -1
  203. package/dist/store/row-identity-registry.d.ts +137 -7
  204. package/dist/store/row-identity-registry.d.ts.map +1 -1
  205. package/dist/store/row-identity-registry.js +364 -9
  206. package/dist/store/row-identity-registry.js.map +1 -1
  207. package/dist/store/row-identity.d.ts.map +1 -1
  208. package/dist/store/row-identity.js +9 -10
  209. package/dist/store/row-identity.js.map +1 -1
  210. package/dist/store/sqlite-data-accessor.d.ts.map +1 -1
  211. package/dist/store/sqlite-data-accessor.js +10 -0
  212. package/dist/store/sqlite-data-accessor.js.map +1 -1
  213. package/dist/store/sqlite.d.ts +31 -0
  214. package/dist/store/sqlite.d.ts.map +1 -1
  215. package/dist/store/sqlite.js +5 -1
  216. package/dist/store/sqlite.js.map +1 -1
  217. package/dist/store/sync/capture.d.ts +203 -0
  218. package/dist/store/sync/capture.d.ts.map +1 -0
  219. package/dist/store/sync/capture.js +562 -0
  220. package/dist/store/sync/capture.js.map +1 -0
  221. package/dist/store/sync/clock-store.d.ts.map +1 -1
  222. package/dist/store/sync/clock-store.js +2 -0
  223. package/dist/store/sync/clock-store.js.map +1 -1
  224. package/dist/store/sync/fk-orphans.d.ts +133 -0
  225. package/dist/store/sync/fk-orphans.d.ts.map +1 -0
  226. package/dist/store/sync/fk-orphans.js +265 -0
  227. package/dist/store/sync/fk-orphans.js.map +1 -0
  228. package/dist/store/sync/flags.d.ts +7 -0
  229. package/dist/store/sync/flags.d.ts.map +1 -1
  230. package/dist/store/sync/flags.js +16 -0
  231. package/dist/store/sync/flags.js.map +1 -1
  232. package/dist/store/sync/hlc.d.ts.map +1 -1
  233. package/dist/store/sync/hlc.js +4 -0
  234. package/dist/store/sync/hlc.js.map +1 -1
  235. package/dist/store/sync/identity-fill.d.ts +45 -0
  236. package/dist/store/sync/identity-fill.d.ts.map +1 -0
  237. package/dist/store/sync/identity-fill.js +85 -0
  238. package/dist/store/sync/identity-fill.js.map +1 -0
  239. package/dist/store/sync/machinery.d.ts +27 -0
  240. package/dist/store/sync/machinery.d.ts.map +1 -0
  241. package/dist/store/sync/machinery.js +44 -0
  242. package/dist/store/sync/machinery.js.map +1 -0
  243. package/dist/store/sync/netting.d.ts +120 -0
  244. package/dist/store/sync/netting.d.ts.map +1 -0
  245. package/dist/store/sync/netting.js +336 -0
  246. package/dist/store/sync/netting.js.map +1 -0
  247. package/dist/store/sync/replica.d.ts +27 -2
  248. package/dist/store/sync/replica.d.ts.map +1 -1
  249. package/dist/store/sync/replica.js +47 -3
  250. package/dist/store/sync/replica.js.map +1 -1
  251. package/dist/store/sync/schema.d.ts +12 -0
  252. package/dist/store/sync/schema.d.ts.map +1 -1
  253. package/dist/store/sync/schema.js +21 -0
  254. package/dist/store/sync/schema.js.map +1 -1
  255. package/dist/store/sync/seal-backlog.d.ts +21 -0
  256. package/dist/store/sync/seal-backlog.d.ts.map +1 -0
  257. package/dist/store/sync/seal-backlog.js +24 -0
  258. package/dist/store/sync/seal-backlog.js.map +1 -0
  259. package/dist/store/sync/sealer-values.d.ts +34 -0
  260. package/dist/store/sync/sealer-values.d.ts.map +1 -0
  261. package/dist/store/sync/sealer-values.js +53 -0
  262. package/dist/store/sync/sealer-values.js.map +1 -0
  263. package/dist/store/sync/sealer.d.ts +145 -0
  264. package/dist/store/sync/sealer.d.ts.map +1 -0
  265. package/dist/store/sync/sealer.js +906 -0
  266. package/dist/store/sync/sealer.js.map +1 -0
  267. package/dist/store/sync/structural.d.ts +63 -0
  268. package/dist/store/sync/structural.d.ts.map +1 -0
  269. package/dist/store/sync/structural.js +180 -0
  270. package/dist/store/sync/structural.js.map +1 -0
  271. package/dist/store/sync/timestamps.d.ts +92 -0
  272. package/dist/store/sync/timestamps.d.ts.map +1 -0
  273. package/dist/store/sync/timestamps.js +228 -0
  274. package/dist/store/sync/timestamps.js.map +1 -0
  275. package/dist/store/sync/tombstones.d.ts +75 -0
  276. package/dist/store/sync/tombstones.d.ts.map +1 -0
  277. package/dist/store/sync/tombstones.js +103 -0
  278. package/dist/store/sync/tombstones.js.map +1 -0
  279. package/dist/store/sync/trigger-classes.d.ts +221 -0
  280. package/dist/store/sync/trigger-classes.d.ts.map +1 -0
  281. package/dist/store/sync/trigger-classes.js +441 -0
  282. package/dist/store/sync/trigger-classes.js.map +1 -0
  283. package/dist/store/sync/trigger-suspend-at-path.d.ts +23 -0
  284. package/dist/store/sync/trigger-suspend-at-path.d.ts.map +1 -0
  285. package/dist/store/sync/trigger-suspend-at-path.js +44 -0
  286. package/dist/store/sync/trigger-suspend-at-path.js.map +1 -0
  287. package/dist/store/sync/writer-version.d.ts +43 -0
  288. package/dist/store/sync/writer-version.d.ts.map +1 -0
  289. package/dist/store/sync/writer-version.js +90 -0
  290. package/dist/store/sync/writer-version.js.map +1 -0
  291. package/dist/store/table-classification.d.ts.map +1 -1
  292. package/dist/store/table-classification.js +102 -0
  293. package/dist/store/table-classification.js.map +1 -1
  294. package/dist/store/trigger-suspend-schema.d.ts +44 -0
  295. package/dist/store/trigger-suspend-schema.d.ts.map +1 -0
  296. package/dist/store/trigger-suspend-schema.js +25 -0
  297. package/dist/store/trigger-suspend-schema.js.map +1 -0
  298. package/dist/store/vault-manifest.d.ts +365 -0
  299. package/dist/store/vault-manifest.d.ts.map +1 -0
  300. package/dist/store/vault-manifest.js +812 -0
  301. package/dist/store/vault-manifest.js.map +1 -0
  302. package/dist/store/writer-lease.d.ts +31 -0
  303. package/dist/store/writer-lease.d.ts.map +1 -1
  304. package/dist/store/writer-lease.js +65 -2
  305. package/dist/store/writer-lease.js.map +1 -1
  306. package/dist/system/health.d.ts.map +1 -1
  307. package/dist/system/health.js +21 -0
  308. package/dist/system/health.js.map +1 -1
  309. package/dist/system/project-health.d.ts.map +1 -1
  310. package/dist/system/project-health.js +3 -1
  311. package/dist/system/project-health.js.map +1 -1
  312. package/dist/tasks/affected-packages.d.ts +58 -0
  313. package/dist/tasks/affected-packages.d.ts.map +1 -1
  314. package/dist/tasks/affected-packages.js +75 -6
  315. package/dist/tasks/affected-packages.js.map +1 -1
  316. package/dist/tasks/affected-scope.d.ts +150 -23
  317. package/dist/tasks/affected-scope.d.ts.map +1 -1
  318. package/dist/tasks/affected-scope.js +320 -32
  319. package/dist/tasks/affected-scope.js.map +1 -1
  320. package/dist/tasks/change-set.d.ts +96 -0
  321. package/dist/tasks/change-set.d.ts.map +1 -1
  322. package/dist/tasks/change-set.js +169 -4
  323. package/dist/tasks/change-set.js.map +1 -1
  324. package/dist/tasks/complete-ci.d.ts +115 -0
  325. package/dist/tasks/complete-ci.d.ts.map +1 -0
  326. package/dist/tasks/complete-ci.js +171 -0
  327. package/dist/tasks/complete-ci.js.map +1 -0
  328. package/dist/tasks/complete.d.ts.map +1 -1
  329. package/dist/tasks/complete.js +50 -17
  330. package/dist/tasks/complete.js.map +1 -1
  331. package/dist/tasks/compute-task-view.d.ts.map +1 -1
  332. package/dist/tasks/compute-task-view.js +7 -0
  333. package/dist/tasks/compute-task-view.js.map +1 -1
  334. package/dist/tasks/done-plan.d.ts.map +1 -1
  335. package/dist/tasks/done-plan.js +51 -30
  336. package/dist/tasks/done-plan.js.map +1 -1
  337. package/dist/tasks/done-record.d.ts +6 -0
  338. package/dist/tasks/done-record.d.ts.map +1 -1
  339. package/dist/tasks/done-record.js +9 -3
  340. package/dist/tasks/done-record.js.map +1 -1
  341. package/dist/tasks/evidence.d.ts +3 -2
  342. package/dist/tasks/evidence.d.ts.map +1 -1
  343. package/dist/tasks/evidence.js +143 -12
  344. package/dist/tasks/evidence.js.map +1 -1
  345. package/dist/tasks/gate-notes.d.ts +22 -0
  346. package/dist/tasks/gate-notes.d.ts.map +1 -0
  347. package/dist/tasks/gate-notes.js +33 -0
  348. package/dist/tasks/gate-notes.js.map +1 -0
  349. package/dist/tasks/index.d.ts +2 -1
  350. package/dist/tasks/index.d.ts.map +1 -1
  351. package/dist/tasks/index.js +2 -1
  352. package/dist/tasks/index.js.map +1 -1
  353. package/dist/tasks/test-run-binding.d.ts +117 -0
  354. package/dist/tasks/test-run-binding.d.ts.map +1 -0
  355. package/dist/tasks/test-run-binding.js +365 -0
  356. package/dist/tasks/test-run-binding.js.map +1 -0
  357. package/dist/tasks/tool-cache-env.d.ts +123 -0
  358. package/dist/tasks/tool-cache-env.d.ts.map +1 -0
  359. package/dist/tasks/tool-cache-env.js +287 -0
  360. package/dist/tasks/tool-cache-env.js.map +1 -0
  361. package/dist/tasks/tool-cache-failed-first.d.ts +155 -0
  362. package/dist/tasks/tool-cache-failed-first.d.ts.map +1 -0
  363. package/dist/tasks/tool-cache-failed-first.js +285 -0
  364. package/dist/tasks/tool-cache-failed-first.js.map +1 -0
  365. package/dist/tasks/tool-cache.d.ts +375 -55
  366. package/dist/tasks/tool-cache.d.ts.map +1 -1
  367. package/dist/tasks/tool-cache.js +912 -303
  368. package/dist/tasks/tool-cache.js.map +1 -1
  369. package/dist/tasks/tool-resolver.d.ts +4 -3
  370. package/dist/tasks/tool-resolver.d.ts.map +1 -1
  371. package/dist/tasks/tool-resolver.js +15 -4
  372. package/dist/tasks/tool-resolver.js.map +1 -1
  373. package/dist/tasks/tool-semaphore.d.ts +67 -7
  374. package/dist/tasks/tool-semaphore.d.ts.map +1 -1
  375. package/dist/tasks/tool-semaphore.js +134 -56
  376. package/dist/tasks/tool-semaphore.js.map +1 -1
  377. package/dist/upgrade.d.ts.map +1 -1
  378. package/dist/upgrade.js +4 -0
  379. package/dist/upgrade.js.map +1 -1
  380. package/dist/validation/engine-ops.d.ts +6 -0
  381. package/dist/validation/engine-ops.d.ts.map +1 -1
  382. package/dist/validation/engine-ops.js +8 -0
  383. package/dist/validation/engine-ops.js.map +1 -1
  384. package/migrations/drizzle-cleo-project/20260930170000_t12819-trigger-suspend-clause/migration.sql +367 -0
  385. package/migrations/sync-journal/20260930120000_t12343-capture/migration.sql +47 -0
  386. package/migrations/sync-journal/20261001170000_t12984-sealer/migration.sql +101 -0
  387. package/package.json +13 -13
  388. package/templates/CLEO-INJECTION.md +5 -5
  389. package/templates/CLEO-REFERENCE.md +8 -4
@@ -0,0 +1,367 @@
1
+ -- T12819 (C2) — the trigger-suspension flag table, and the owned guard and
2
+ -- side-effect triggers rewritten with its WHEN clause. Journal spec
3
+ -- t12342-t12343-journal-design §3.5 Rule 4 and §2.3a rules 4, 9 and 10.
4
+ --
5
+ -- cleo_trigger_suspend(scope) is a flag table in MAIN. A frame that must run
6
+ -- with a class of triggers off inserts a scope row inside its own transaction
7
+ -- and deletes it before COMMIT. Under WAL no other connection sees the
8
+ -- uncommitted row, so everyone else keeps every trigger. A crash rolls the row
9
+ -- back, and the open pass asserts the table is empty.
10
+ --
11
+ -- The table is schema-owned and never dropped (not a _sync_ table): the
12
+ -- triggers below read it, so writes to tasks, sessions and acceptance
13
+ -- criteria, and any ALTER ... RENAME (which re-validates every trigger), need
14
+ -- it. The open pass also creates it, IF NOT EXISTS, before migrations.
15
+ --
16
+ -- Each owned trigger keeps its original text and gains
17
+ -- NOT EXISTS (SELECT 1 FROM cleo_trigger_suspend WHERE scope IN (<class>, all))
18
+ -- ANDed with its own WHEN. The table name is deliberately unqualified: a
19
+ -- persistent trigger resolves it in its own schema, so the trigger keeps
20
+ -- working when the store is ATTACHed under another name (exodus, backup).
21
+ -- A `main.` qualifier makes such a schema unreadable.
22
+ -- Released files that first created these triggers
23
+ -- (t11884, t12502, t12736, t12886) are never edited; this file replaces the
24
+ -- triggers. It is dated after t12886 (the dependency cycle guard, 9.26) so
25
+ -- that file stays a released, pre-clause migration.
26
+ -- The T12341 AC graveyard trigger is owned too, but its DDL lives in code
27
+ -- (store/sync/trigger-classes.ts): a store whose t12341 migration was
28
+ -- probe-stamped has no graveyard TABLE, and creating the trigger here would
29
+ -- make every acceptance-criterion delete fail. The open pass installs it
30
+ -- only where its table exists.
31
+ -- The ownership map lives in packages/core/src/store/sync/trigger-classes.ts.
32
+ --
33
+ -- Idempotent (CREATE TABLE IF NOT EXISTS; DROP TRIGGER IF EXISTS before each
34
+ -- CREATE), and must always RUN: reconcileJournal never probe-stamps it.
35
+ -- cleo:probe-never-stamp
36
+ --
37
+ -- @task T12819
38
+ -- @epic T12323
39
+
40
+ CREATE TABLE IF NOT EXISTS `cleo_trigger_suspend` (
41
+ `scope` TEXT PRIMARY KEY NOT NULL CHECK (`scope` IN ('capture', 'guard', 'side-effect', 'all'))
42
+ );
43
+ --> statement-breakpoint
44
+ DROP TRIGGER IF EXISTS `tasks_tasks_parent_cycle_guard_insert`;
45
+ --> statement-breakpoint
46
+ CREATE TRIGGER `tasks_tasks_parent_cycle_guard_insert`
47
+ BEFORE INSERT ON `tasks_tasks`
48
+ WHEN (NEW.`parent_id` IS NOT NULL)
49
+ AND NOT EXISTS (SELECT 1 FROM cleo_trigger_suspend WHERE scope IN ('guard', 'all'))
50
+ BEGIN
51
+ SELECT RAISE(ABORT, 'E_TASK_PARENT_CYCLE: tasks.parent_id cannot create a containment cycle')
52
+ WHERE EXISTS (
53
+ WITH RECURSIVE ancestors(`id`, `parent_id`) AS (
54
+ SELECT parent.`id`, parent.`parent_id`
55
+ FROM `tasks_tasks` parent
56
+ WHERE parent.`id` = NEW.`parent_id`
57
+ UNION ALL
58
+ SELECT next_parent.`id`, next_parent.`parent_id`
59
+ FROM `tasks_tasks` next_parent
60
+ JOIN ancestors ON next_parent.`id` = ancestors.`parent_id`
61
+ WHERE ancestors.`parent_id` IS NOT NULL
62
+ )
63
+ SELECT 1 FROM ancestors WHERE ancestors.`id` = NEW.`id`
64
+ );
65
+ END;
66
+ --> statement-breakpoint
67
+ DROP TRIGGER IF EXISTS `tasks_tasks_parent_cycle_guard_update`;
68
+ --> statement-breakpoint
69
+ CREATE TRIGGER `tasks_tasks_parent_cycle_guard_update`
70
+ BEFORE UPDATE OF `parent_id` ON `tasks_tasks`
71
+ WHEN (NEW.`parent_id` IS NOT NULL)
72
+ AND NOT EXISTS (SELECT 1 FROM cleo_trigger_suspend WHERE scope IN ('guard', 'all'))
73
+ BEGIN
74
+ SELECT RAISE(ABORT, 'E_TASK_PARENT_CYCLE: tasks.parent_id cannot create a containment cycle')
75
+ WHERE EXISTS (
76
+ WITH RECURSIVE ancestors(`id`, `parent_id`) AS (
77
+ SELECT parent.`id`, parent.`parent_id`
78
+ FROM `tasks_tasks` parent
79
+ WHERE parent.`id` = NEW.`parent_id`
80
+ UNION ALL
81
+ SELECT next_parent.`id`, next_parent.`parent_id`
82
+ FROM `tasks_tasks` next_parent
83
+ JOIN ancestors ON next_parent.`id` = ancestors.`parent_id`
84
+ WHERE ancestors.`parent_id` IS NOT NULL
85
+ )
86
+ SELECT 1 FROM ancestors WHERE ancestors.`id` = NEW.`id`
87
+ );
88
+ END;
89
+ --> statement-breakpoint
90
+ DROP TRIGGER IF EXISTS `tasks_tasks_parent_type_matrix_insert`;
91
+ --> statement-breakpoint
92
+ CREATE TRIGGER `tasks_tasks_parent_type_matrix_insert`
93
+ BEFORE INSERT ON `tasks_tasks`
94
+ WHEN (NEW.`parent_id` IS NOT NULL
95
+ AND NEW.`type` IS NOT NULL
96
+ AND EXISTS (SELECT 1 FROM `tasks_tasks` parent WHERE parent.`id` = NEW.`parent_id` AND parent.`type` IS NOT NULL)
97
+ AND NOT EXISTS (
98
+ SELECT 1
99
+ FROM `tasks_tasks` parent
100
+ WHERE parent.`id` = NEW.`parent_id`
101
+ AND (
102
+ (NEW.`type` = 'epic' AND parent.`type` = 'saga')
103
+ OR (NEW.`type` = 'task' AND parent.`type` = 'epic')
104
+ OR (NEW.`type` = 'subtask' AND parent.`type` IN ('epic', 'task'))
105
+ )
106
+ ))
107
+ AND NOT EXISTS (SELECT 1 FROM cleo_trigger_suspend WHERE scope IN ('guard', 'all'))
108
+ BEGIN
109
+ SELECT RAISE(ABORT, 'E_TASK_PARENT_TYPE_MATRIX: tasks.parent_id must follow saga->epic, epic->task|subtask, and task->subtask; sagas/tasks must be roots');
110
+ END;
111
+ --> statement-breakpoint
112
+ DROP TRIGGER IF EXISTS `tasks_tasks_parent_type_matrix_update`;
113
+ --> statement-breakpoint
114
+ CREATE TRIGGER `tasks_tasks_parent_type_matrix_update`
115
+ BEFORE UPDATE OF `parent_id`, `type` ON `tasks_tasks`
116
+ WHEN (NEW.`parent_id` IS NOT NULL
117
+ AND NEW.`type` IS NOT NULL
118
+ AND EXISTS (SELECT 1 FROM `tasks_tasks` parent WHERE parent.`id` = NEW.`parent_id` AND parent.`type` IS NOT NULL)
119
+ AND NOT EXISTS (
120
+ SELECT 1
121
+ FROM `tasks_tasks` parent
122
+ WHERE parent.`id` = NEW.`parent_id`
123
+ AND (
124
+ (NEW.`type` = 'epic' AND parent.`type` = 'saga')
125
+ OR (NEW.`type` = 'task' AND parent.`type` = 'epic')
126
+ OR (NEW.`type` = 'subtask' AND parent.`type` IN ('epic', 'task'))
127
+ )
128
+ ))
129
+ AND NOT EXISTS (SELECT 1 FROM cleo_trigger_suspend WHERE scope IN ('guard', 'all'))
130
+ BEGIN
131
+ SELECT RAISE(ABORT, 'E_TASK_PARENT_TYPE_MATRIX: tasks.parent_id must follow saga->epic, epic->task|subtask, and task->subtask; sagas/tasks must be roots');
132
+ END;
133
+ --> statement-breakpoint
134
+ DROP TRIGGER IF EXISTS `trg_tasks_tasks_status_pipeline_insert`;
135
+ --> statement-breakpoint
136
+ CREATE TRIGGER `trg_tasks_tasks_status_pipeline_insert`
137
+ BEFORE INSERT ON `tasks_tasks`
138
+ FOR EACH ROW
139
+ WHEN ((NEW.`status` = 'done' AND (NEW.`pipeline_stage` IS NULL OR NEW.`pipeline_stage` NOT IN ('contribution','cancelled')))
140
+ OR (NEW.`status` = 'cancelled' AND (NEW.`pipeline_stage` IS NULL OR NEW.`pipeline_stage` != 'cancelled')))
141
+ AND NOT EXISTS (SELECT 1 FROM cleo_trigger_suspend WHERE scope IN ('guard', 'all'))
142
+ BEGIN
143
+ SELECT RAISE(ABORT, 'T877_INVARIANT_VIOLATION: status/pipeline_stage mismatch. status=done requires pipeline_stage IN (contribution,cancelled); status=cancelled requires pipeline_stage=cancelled.');
144
+ END;
145
+ --> statement-breakpoint
146
+ DROP TRIGGER IF EXISTS `trg_tasks_tasks_status_pipeline_update`;
147
+ --> statement-breakpoint
148
+ CREATE TRIGGER `trg_tasks_tasks_status_pipeline_update`
149
+ BEFORE UPDATE OF `status`, `pipeline_stage` ON `tasks_tasks`
150
+ FOR EACH ROW
151
+ WHEN ((NEW.`status` = 'done' AND (NEW.`pipeline_stage` IS NULL OR NEW.`pipeline_stage` NOT IN ('contribution','cancelled')))
152
+ OR (NEW.`status` = 'cancelled' AND (NEW.`pipeline_stage` IS NULL OR NEW.`pipeline_stage` != 'cancelled')))
153
+ AND NOT EXISTS (SELECT 1 FROM cleo_trigger_suspend WHERE scope IN ('guard', 'all'))
154
+ BEGIN
155
+ SELECT RAISE(ABORT, 'T877_INVARIANT_VIOLATION: status/pipeline_stage mismatch. status=done requires pipeline_stage IN (contribution,cancelled); status=cancelled requires pipeline_stage=cancelled.');
156
+ END;
157
+ --> statement-breakpoint
158
+ DROP TRIGGER IF EXISTS `tasks_task_relations_non_containment_insert`;
159
+ --> statement-breakpoint
160
+ CREATE TRIGGER `tasks_task_relations_non_containment_insert`
161
+ BEFORE INSERT ON `tasks_task_relations`
162
+ WHEN (EXISTS (
163
+ SELECT 1
164
+ FROM `tasks_tasks` child
165
+ WHERE child.`id` = NEW.`task_id`
166
+ AND child.`parent_id` = NEW.`related_to`
167
+ ) OR EXISTS (
168
+ SELECT 1
169
+ FROM `tasks_tasks` child
170
+ WHERE child.`id` = NEW.`related_to`
171
+ AND child.`parent_id` = NEW.`task_id`
172
+ ))
173
+ AND NOT EXISTS (SELECT 1 FROM cleo_trigger_suspend WHERE scope IN ('guard', 'all'))
174
+ BEGIN
175
+ SELECT RAISE(ABORT, 'E_TASK_RELATION_CONTAINMENT: task_relations is non-containment-only; use tasks.parent_id for parent/child edges');
176
+ END;
177
+ --> statement-breakpoint
178
+ DROP TRIGGER IF EXISTS `tasks_task_relations_non_containment_update`;
179
+ --> statement-breakpoint
180
+ CREATE TRIGGER `tasks_task_relations_non_containment_update`
181
+ BEFORE UPDATE OF `task_id`, `related_to` ON `tasks_task_relations`
182
+ WHEN (EXISTS (
183
+ SELECT 1
184
+ FROM `tasks_tasks` child
185
+ WHERE child.`id` = NEW.`task_id`
186
+ AND child.`parent_id` = NEW.`related_to`
187
+ ) OR EXISTS (
188
+ SELECT 1
189
+ FROM `tasks_tasks` child
190
+ WHERE child.`id` = NEW.`related_to`
191
+ AND child.`parent_id` = NEW.`task_id`
192
+ ))
193
+ AND NOT EXISTS (SELECT 1 FROM cleo_trigger_suspend WHERE scope IN ('guard', 'all'))
194
+ BEGIN
195
+ SELECT RAISE(ABORT, 'E_TASK_RELATION_CONTAINMENT: task_relations is non-containment-only; use tasks.parent_id for parent/child edges');
196
+ END;
197
+ --> statement-breakpoint
198
+ DROP TRIGGER IF EXISTS `tasks_task_acceptance_child_target_insert`;
199
+ --> statement-breakpoint
200
+ CREATE TRIGGER `tasks_task_acceptance_child_target_insert`
201
+ BEFORE INSERT ON `tasks_task_acceptance_criteria`
202
+ WHEN (NEW.`target_task_id` IS NOT NULL
203
+ AND (
204
+ NEW.`kind` <> 'child_task'
205
+ OR NOT EXISTS (
206
+ SELECT 1
207
+ FROM `tasks_tasks` child
208
+ WHERE child.`id` = NEW.`target_task_id`
209
+ AND child.`parent_id` = NEW.`task_id`
210
+ )
211
+ ))
212
+ AND NOT EXISTS (SELECT 1 FROM cleo_trigger_suspend WHERE scope IN ('guard', 'all'))
213
+ BEGIN
214
+ SELECT RAISE(ABORT, 'E_CHILD_TASK_TARGET_CONTAINMENT: child_task acceptance target_task_id must be a direct child of task_id; non-child_task criteria must not set target_task_id');
215
+ END;
216
+ --> statement-breakpoint
217
+ DROP TRIGGER IF EXISTS `tasks_task_acceptance_child_target_update`;
218
+ --> statement-breakpoint
219
+ CREATE TRIGGER `tasks_task_acceptance_child_target_update`
220
+ BEFORE UPDATE OF `task_id`, `kind`, `target_task_id` ON `tasks_task_acceptance_criteria`
221
+ WHEN (NEW.`target_task_id` IS NOT NULL
222
+ AND (
223
+ NEW.`kind` <> 'child_task'
224
+ OR NOT EXISTS (
225
+ SELECT 1
226
+ FROM `tasks_tasks` child
227
+ WHERE child.`id` = NEW.`target_task_id`
228
+ AND child.`parent_id` = NEW.`task_id`
229
+ )
230
+ ))
231
+ AND NOT EXISTS (SELECT 1 FROM cleo_trigger_suspend WHERE scope IN ('guard', 'all'))
232
+ BEGIN
233
+ SELECT RAISE(ABORT, 'E_CHILD_TASK_TARGET_CONTAINMENT: child_task acceptance target_task_id must be a direct child of task_id; non-child_task criteria must not set target_task_id');
234
+ END;
235
+ --> statement-breakpoint
236
+ DROP TRIGGER IF EXISTS `trg_tasks_session_handoff_no_update`;
237
+ --> statement-breakpoint
238
+ CREATE TRIGGER `trg_tasks_session_handoff_no_update`
239
+ BEFORE UPDATE ON `tasks_session_handoff_entries`
240
+ FOR EACH ROW
241
+ WHEN NOT EXISTS (SELECT 1 FROM cleo_trigger_suspend WHERE scope IN ('guard', 'all'))
242
+ BEGIN
243
+ SELECT RAISE(
244
+ ABORT,
245
+ 'T1609_HANDOFF_IMMUTABLE: session_handoff_entries rows are write-once. Use persistHandoff() exactly once per session.'
246
+ );
247
+ END;
248
+ --> statement-breakpoint
249
+ DROP TRIGGER IF EXISTS `tasks_tasks_lease_iso_insert`;
250
+ --> statement-breakpoint
251
+ CREATE TRIGGER `tasks_tasks_lease_iso_insert`
252
+ BEFORE INSERT ON `tasks_tasks`
253
+ WHEN ((NEW.`claimed_at` IS NOT NULL AND NEW.`claimed_at` NOT GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]*')
254
+ OR (NEW.`lease_expires_at` IS NOT NULL AND NEW.`lease_expires_at` NOT GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]*'))
255
+ AND NOT EXISTS (SELECT 1 FROM cleo_trigger_suspend WHERE scope IN ('guard', 'all'))
256
+ BEGIN
257
+ SELECT RAISE(ABORT, 'tasks_tasks.claimed_at and lease_expires_at must be ISO-8601 timestamps (T12736)');
258
+ END;
259
+ --> statement-breakpoint
260
+ DROP TRIGGER IF EXISTS `tasks_tasks_lease_iso_update`;
261
+ --> statement-breakpoint
262
+ CREATE TRIGGER `tasks_tasks_lease_iso_update`
263
+ BEFORE UPDATE OF `claimed_at`, `lease_expires_at` ON `tasks_tasks`
264
+ WHEN ((NEW.`claimed_at` IS NOT NULL AND NEW.`claimed_at` NOT GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]*')
265
+ OR (NEW.`lease_expires_at` IS NOT NULL AND NEW.`lease_expires_at` NOT GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]*'))
266
+ AND NOT EXISTS (SELECT 1 FROM cleo_trigger_suspend WHERE scope IN ('guard', 'all'))
267
+ BEGIN
268
+ SELECT RAISE(ABORT, 'tasks_tasks.claimed_at and lease_expires_at must be ISO-8601 timestamps (T12736)');
269
+ END;
270
+ --> statement-breakpoint
271
+ DROP TRIGGER IF EXISTS `trg_tasks_session_handoff_mirror`;
272
+ --> statement-breakpoint
273
+ CREATE TRIGGER `trg_tasks_session_handoff_mirror`
274
+ AFTER INSERT ON `tasks_session_handoff_entries`
275
+ FOR EACH ROW
276
+ WHEN NOT EXISTS (SELECT 1 FROM cleo_trigger_suspend WHERE scope IN ('side-effect', 'all'))
277
+ BEGIN
278
+ UPDATE `tasks_sessions`
279
+ SET `handoff_json` = NEW.handoff_json
280
+ WHERE `id` = NEW.session_id;
281
+ END;
282
+ --> statement-breakpoint
283
+ DROP TRIGGER IF EXISTS `tasks_sessions_release_claims_on_end`;
284
+ --> statement-breakpoint
285
+ CREATE TRIGGER `tasks_sessions_release_claims_on_end`
286
+ AFTER UPDATE OF `status` ON `tasks_sessions`
287
+ WHEN (NEW.`status` IN ('ended', 'orphaned'))
288
+ AND NOT EXISTS (SELECT 1 FROM cleo_trigger_suspend WHERE scope IN ('side-effect', 'all'))
289
+ BEGIN
290
+ UPDATE `tasks_tasks`
291
+ SET `claimed_by_session` = NULL, `claimed_by_agent` = NULL,
292
+ `claimed_at` = NULL, `lease_expires_at` = NULL
293
+ WHERE `claimed_by_session` = NEW.`id`;
294
+ END;
295
+ --> statement-breakpoint
296
+ DROP TRIGGER IF EXISTS `tasks_sessions_release_claims_on_delete`;
297
+ --> statement-breakpoint
298
+ CREATE TRIGGER `tasks_sessions_release_claims_on_delete`
299
+ AFTER DELETE ON `tasks_sessions`
300
+ WHEN NOT EXISTS (SELECT 1 FROM cleo_trigger_suspend WHERE scope IN ('side-effect', 'all'))
301
+ BEGIN
302
+ UPDATE `tasks_tasks`
303
+ SET `claimed_by_session` = NULL, `claimed_by_agent` = NULL,
304
+ `claimed_at` = NULL, `lease_expires_at` = NULL
305
+ WHERE `claimed_by_session` = OLD.`id`;
306
+ END;
307
+ --> statement-breakpoint
308
+ DROP TRIGGER IF EXISTS `tasks_tasks_release_claim_on_terminal`;
309
+ --> statement-breakpoint
310
+ CREATE TRIGGER `tasks_tasks_release_claim_on_terminal`
311
+ AFTER UPDATE OF `status` ON `tasks_tasks`
312
+ WHEN (NEW.`status` IN ('done', 'cancelled', 'archived') AND NEW.`claimed_by_session` IS NOT NULL)
313
+ AND NOT EXISTS (SELECT 1 FROM cleo_trigger_suspend WHERE scope IN ('side-effect', 'all'))
314
+ BEGIN
315
+ UPDATE `tasks_tasks`
316
+ SET `claimed_by_session` = NULL, `claimed_by_agent` = NULL,
317
+ `claimed_at` = NULL, `lease_expires_at` = NULL
318
+ WHERE `id` = NEW.`id`;
319
+ END;
320
+ --> statement-breakpoint
321
+ DROP TRIGGER IF EXISTS `tasks_task_dependencies_cycle_guard_insert`;
322
+ --> statement-breakpoint
323
+ CREATE TRIGGER `tasks_task_dependencies_cycle_guard_insert`
324
+ BEFORE INSERT ON `tasks_task_dependencies`
325
+ WHEN (NOT EXISTS (
326
+ SELECT 1
327
+ FROM `tasks_task_dependencies` existing
328
+ WHERE existing.`task_id` = NEW.`task_id`
329
+ AND existing.`depends_on` = NEW.`depends_on`
330
+ ))
331
+ AND NOT EXISTS (SELECT 1 FROM cleo_trigger_suspend WHERE scope IN ('guard', 'all'))
332
+ BEGIN
333
+ SELECT RAISE(ABORT, 'E_TASK_DEPENDENCY_CYCLE: tasks_task_dependencies edge would close a dependency cycle (a task cannot depend on itself or on a task that already depends on it)')
334
+ WHERE NEW.`task_id` = NEW.`depends_on`
335
+ OR EXISTS (
336
+ WITH RECURSIVE reachable(`id`) AS (
337
+ SELECT NEW.`depends_on`
338
+ UNION
339
+ SELECT dep.`depends_on`
340
+ FROM `tasks_task_dependencies` dep
341
+ JOIN reachable ON dep.`task_id` = reachable.`id`
342
+ )
343
+ SELECT 1 FROM reachable WHERE reachable.`id` = NEW.`task_id`
344
+ );
345
+ END;
346
+ --> statement-breakpoint
347
+ DROP TRIGGER IF EXISTS `tasks_task_dependencies_cycle_guard_update`;
348
+ --> statement-breakpoint
349
+ CREATE TRIGGER `tasks_task_dependencies_cycle_guard_update`
350
+ BEFORE UPDATE OF `task_id`, `depends_on` ON `tasks_task_dependencies`
351
+ WHEN (NEW.`task_id` IS NOT OLD.`task_id` OR NEW.`depends_on` IS NOT OLD.`depends_on`)
352
+ AND NOT EXISTS (SELECT 1 FROM cleo_trigger_suspend WHERE scope IN ('guard', 'all'))
353
+ BEGIN
354
+ SELECT RAISE(ABORT, 'E_TASK_DEPENDENCY_CYCLE: tasks_task_dependencies edge would close a dependency cycle (a task cannot depend on itself or on a task that already depends on it)')
355
+ WHERE NEW.`task_id` = NEW.`depends_on`
356
+ OR EXISTS (
357
+ WITH RECURSIVE reachable(`id`) AS (
358
+ SELECT NEW.`depends_on`
359
+ UNION
360
+ SELECT dep.`depends_on`
361
+ FROM `tasks_task_dependencies` dep
362
+ JOIN reachable ON dep.`task_id` = reachable.`id`
363
+ WHERE NOT (dep.`task_id` = OLD.`task_id` AND dep.`depends_on` = OLD.`depends_on`)
364
+ )
365
+ SELECT 1 FROM reachable WHERE reachable.`id` = NEW.`task_id`
366
+ );
367
+ END;
@@ -0,0 +1,47 @@
1
+ -- T12343 — change journal (S2): the capture outbox, transaction frames and the
2
+ -- undo log. Journal spec t12342-t12343-journal-design §2.3 and §3.5 Rule 2.
3
+ --
4
+ -- Applied lazily by packages/core/src/store/sync/schema.ts when a sync.* flag
5
+ -- is first enabled (never at open with every flag off); journaled in
6
+ -- _sync_meta by sha256, never in __drizzle_migrations. All tables are
7
+ -- local-only. Capture triggers (_sync_cap_*) are generated per table by the
8
+ -- open pass (store/sync/capture.ts) and are never part of any migration.
9
+ --
10
+ -- @task T12343
11
+
12
+ CREATE TABLE IF NOT EXISTS _sync_capture (
13
+ seq INTEGER PRIMARY KEY AUTOINCREMENT,
14
+ tbl TEXT NOT NULL,
15
+ op TEXT NOT NULL CHECK (op IN ('I', 'U', 'D', 'K')),
16
+ rk TEXT NOT NULL,
17
+ uid TEXT,
18
+ img TEXT NOT NULL,
19
+ at_ms INTEGER NOT NULL,
20
+ conn TEXT,
21
+ frame TEXT,
22
+ kind TEXT,
23
+ state TEXT NOT NULL DEFAULT 'live' CHECK (state IN ('live', 'inherited', 'folded'))
24
+ );
25
+ --> statement-breakpoint
26
+ CREATE INDEX IF NOT EXISTS _sync_capture_frame ON _sync_capture (frame) WHERE frame IS NOT NULL;
27
+ --> statement-breakpoint
28
+ CREATE INDEX IF NOT EXISTS _sync_capture_key ON _sync_capture (tbl, rk, op);
29
+ --> statement-breakpoint
30
+ CREATE TABLE IF NOT EXISTS _sync_frame (
31
+ frame TEXT PRIMARY KEY,
32
+ kind TEXT NOT NULL,
33
+ actor TEXT,
34
+ first_seq INTEGER
35
+ ) WITHOUT ROWID;
36
+ --> statement-breakpoint
37
+ CREATE TABLE IF NOT EXISTS _sync_undo (
38
+ seq INTEGER PRIMARY KEY,
39
+ txn_local TEXT,
40
+ kind TEXT,
41
+ tbl TEXT NOT NULL,
42
+ rk TEXT NOT NULL,
43
+ uid TEXT,
44
+ op TEXT NOT NULL,
45
+ before_full TEXT,
46
+ after_full TEXT
47
+ );
@@ -0,0 +1,101 @@
1
+ -- T12984 (S3a) — the sealer's outbox and row metadata. Journal spec
2
+ -- t12342-t12343-journal-design §1.6, §2.5, §2.6, §4.3.
3
+ --
4
+ -- _sync_txn / _sync_op: sealed transactions and their ops, in local commit
5
+ -- order. `local_seq` is this replica's transaction counter; `txn` is
6
+ -- `<replica>:<local_seq>` (§2.6). The counter is persisted in
7
+ -- _sync_meta ('sealer.local_seq') and only ever rises, so a txn id is never
8
+ -- reused after old rows are collected. `state`: sealed -> segmented when a
9
+ -- persisted segment carries the transaction (S4); `inherited` for rows a
10
+ -- copied store carries from its original replica (§1.5); `folded` for
11
+ -- transactions at or below a stream's genesis cut (§2.11 §10). `unframed`
12
+ -- marks a singleton sealed from a capture with no validated frame (ruling (c));
13
+ -- `partial` a frame sealed without a capture the sealer had to quarantine
14
+ -- (T13041).
15
+ --
16
+ -- _sync_row_meta: per-row replication metadata (§1.6). Local-only; travels
17
+ -- inside checkpoint bundles (shash stripped). `bfp` is a minted row's
18
+ -- birth_fp, kept across a delete or re-key so every op carries it (T13030). `_sync_row_meta_tomb` indexes
19
+ -- FULL tombstones only (version > 0), the ones GC scans by HLC; a compacted
20
+ -- minimal tombstone (version 0, §1.7) is found by its key and needs no index
21
+ -- entry, which keeps it near the spec's ~190 B (T12986 measured ~155 B).
22
+ --
23
+ -- _sync_ledger: per sync-set table, the sealed row count (`live`) and the
24
+ -- rows a rebase holds unreplayed (`held`, §3.5 Rule 5). The ledger check
25
+ -- (§4.3) compares count(*) + held with it.
26
+ --
27
+ -- _sync_quarantine: captures the sealer could not read (a table that left
28
+ -- the sync set, a malformed image), moved out of the outbox so they never
29
+ -- stall it (T13036). A table with rows here is suspect: S3d's repair diff
30
+ -- re-derives it, and `cleo doctor` reports it.
31
+ --
32
+ -- Do not edit this file once applied: its hash is recorded per store.
33
+ -- (Unreleased until #1779 merges. It was edited during review; a dev or
34
+ -- Gate B scratch store that applied an earlier text fails with
35
+ -- E_SYNC_SCHEMA_HASH_DRIFT: reset it with dropSyncMachinery, or recreate it.)
36
+ CREATE TABLE IF NOT EXISTS _sync_txn (
37
+ txn TEXT PRIMARY KEY,
38
+ local_seq INTEGER NOT NULL UNIQUE,
39
+ replica TEXT NOT NULL,
40
+ hlc TEXT NOT NULL,
41
+ scope TEXT NOT NULL CHECK (scope IN ('project', 'global')),
42
+ via TEXT NOT NULL,
43
+ kind TEXT NOT NULL,
44
+ actor TEXT,
45
+ frame TEXT,
46
+ unframed INTEGER NOT NULL DEFAULT 0,
47
+ partial INTEGER NOT NULL DEFAULT 0,
48
+ op_count INTEGER NOT NULL,
49
+ state TEXT NOT NULL DEFAULT 'sealed'
50
+ CHECK (state IN ('sealed', 'segmented', 'inherited', 'folded')),
51
+ sealed_at_ms INTEGER NOT NULL
52
+ ) WITHOUT ROWID;
53
+ CREATE INDEX IF NOT EXISTS _sync_txn_state ON _sync_txn (state, local_seq);
54
+ CREATE TABLE IF NOT EXISTS _sync_op (
55
+ txn TEXT NOT NULL,
56
+ idx INTEGER NOT NULL,
57
+ tbl TEXT NOT NULL,
58
+ uid TEXT NOT NULL,
59
+ o TEXT NOT NULL CHECK (o IN ('I', 'U', 'D', 'K')),
60
+ hlc TEXT NOT NULL,
61
+ body TEXT NOT NULL,
62
+ PRIMARY KEY (txn, idx)
63
+ ) WITHOUT ROWID;
64
+ CREATE INDEX IF NOT EXISTS _sync_op_row ON _sync_op (tbl, uid);
65
+ CREATE TABLE IF NOT EXISTS _sync_row_meta (
66
+ tbl TEXT NOT NULL,
67
+ uid TEXT NOT NULL,
68
+ hlc TEXT NOT NULL,
69
+ fhlc TEXT,
70
+ origin TEXT NOT NULL,
71
+ actor TEXT,
72
+ version INTEGER NOT NULL,
73
+ deleted INTEGER NOT NULL DEFAULT 0,
74
+ key_json TEXT,
75
+ sent INTEGER NOT NULL DEFAULT 0,
76
+ fk_excluded INTEGER NOT NULL DEFAULT 0,
77
+ held INTEGER NOT NULL DEFAULT 0,
78
+ chash TEXT,
79
+ shash TEXT,
80
+ bfp TEXT,
81
+ PRIMARY KEY (tbl, uid)
82
+ ) WITHOUT ROWID;
83
+ CREATE INDEX IF NOT EXISTS _sync_row_meta_tomb ON _sync_row_meta (hlc) WHERE deleted = 1 AND version > 0;
84
+ CREATE TABLE IF NOT EXISTS _sync_ledger (
85
+ tbl TEXT PRIMARY KEY,
86
+ live INTEGER NOT NULL,
87
+ held INTEGER NOT NULL DEFAULT 0
88
+ ) WITHOUT ROWID;
89
+ CREATE TABLE IF NOT EXISTS _sync_quarantine (
90
+ seq INTEGER PRIMARY KEY,
91
+ tbl TEXT NOT NULL,
92
+ op TEXT NOT NULL,
93
+ rk TEXT NOT NULL,
94
+ uid TEXT,
95
+ img TEXT NOT NULL,
96
+ at_ms INTEGER NOT NULL,
97
+ frame TEXT,
98
+ reason TEXT NOT NULL,
99
+ quarantined_at_ms INTEGER NOT NULL
100
+ );
101
+ CREATE INDEX IF NOT EXISTS _sync_quarantine_tbl ON _sync_quarantine (tbl);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cleocode/core",
3
- "version": "2026.10.1",
3
+ "version": "2026.10.3",
4
4
  "description": "CLEO core business logic kernel — tasks, sessions, memory, orchestration, lifecycle, with bundled SQLite store",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -491,16 +491,16 @@
491
491
  "write-file-atomic": "^7.0.1",
492
492
  "yaml": "^2.8.3",
493
493
  "zod": "^4.3.6",
494
- "@cleocode/adapters": "2026.10.1",
495
- "@cleocode/agents": "2026.10.1",
496
- "@cleocode/caamp": "2026.10.1",
497
- "@cleocode/contracts": "2026.10.1",
498
- "@cleocode/git-shim": "2026.10.1",
499
- "@cleocode/lafs": "2026.10.1",
500
- "@cleocode/nexus": "2026.10.1",
501
- "@cleocode/paths": "2026.10.1",
502
- "@cleocode/skills": "2026.10.1",
503
- "@cleocode/worktree": "2026.10.1"
494
+ "@cleocode/agents": "2026.10.3",
495
+ "@cleocode/adapters": "2026.10.3",
496
+ "@cleocode/caamp": "2026.10.3",
497
+ "@cleocode/contracts": "2026.10.3",
498
+ "@cleocode/git-shim": "2026.10.3",
499
+ "@cleocode/lafs": "2026.10.3",
500
+ "@cleocode/nexus": "2026.10.3",
501
+ "@cleocode/paths": "2026.10.3",
502
+ "@cleocode/skills": "2026.10.3",
503
+ "@cleocode/worktree": "2026.10.3"
504
504
  },
505
505
  "engines": {
506
506
  "node": ">=24.16.0"
@@ -526,7 +526,7 @@
526
526
  "@types/proper-lockfile": "^4.1.4",
527
527
  "@types/tar": "^6.1.13",
528
528
  "@types/write-file-atomic": "^4.0.3",
529
- "@cleocode/utils": "2026.10.1"
529
+ "@cleocode/utils": "2026.10.3"
530
530
  },
531
531
  "repository": {
532
532
  "type": "git",
@@ -535,7 +535,7 @@
535
535
  },
536
536
  "optionalDependencies": {
537
537
  "llmtxt": "^2026.5.15",
538
- "@cleocode/studio": "^2026.10.1"
538
+ "@cleocode/studio": "^2026.10.3"
539
539
  },
540
540
  "scripts": {
541
541
  "build": "tsc && node scripts/copy-selfimprove-fixtures.mjs && node scripts/write-build-provenance.mjs",
@@ -1,6 +1,6 @@
1
1
  # CLEO Protocol
2
2
 
3
- Version: 2.24.3 | CLI-only dispatch | `cleo <command> [args]`
3
+ Version: 2.24.4 | CLI-only dispatch | `cleo <command> [args]`
4
4
 
5
5
  <!-- CLEO-INJECTION:section=session-start -->
6
6
  ## Universal protocol
@@ -55,7 +55,7 @@ Discovery: `cleo focus <id>` to orient, `cleo find "query"` to search (default p
55
55
  | Task acceptance criterion contains "test" | Propose an `AcceptanceGate` with `kind:"test"` via `cleo req add` |
56
56
  | Session token budget ≈ 80% consumed | Run `cleo session end --note "..."` and hand off |
57
57
  | Multiple related tasks ready in parallel | Run `cleo orchestrate ready <epicId>` for the wave set |
58
- | About to call `cleo complete` | First: check gates via `cleo show <id> --full` → run tests → then complete |
58
+ | About to call `cleo complete` | `cleo done <id> --plan`, record what it names, then complete |
59
59
  | Writing a canonical doc (spec/adr/research/handoff/note/llm-readme) | Use `cleo docs add --type <kind> --slug <kebab-handle>` — NEVER raw fs write to `.cleo/adrs/`, `.cleo/research/`, `.cleo/agent-outputs/`, or `docs/` |
60
60
  | Reading an ADR/spec/research note/handoff | `cleo docs fetch <slug>` — never grep the filesystem for canonical docs |
61
61
  | New device, restore or migration; known repo "Not inside a CLEO project"; unreachable registry path; nexus `ENOENT` | `cleo doctor global-delivery` (hub + skills resolve; `--repair`), `cleo doctor projects` (dry run; `--apply`/`--rollback <id>`), `cleo doctor project-identity`, `cleo doctor --all-projects`, `cleo nexus projects clean --orphans --dry-run` (`--dry-run` mandatory: it deletes moved projects), `cleo doctor credentials`; report. Never delete rows of projects that may have moved |
@@ -126,15 +126,15 @@ Before `cleo complete <id>`, every gate requires programmatic evidence validated
126
126
  | gate | evidence that satisfies it |
127
127
  |------|----------------------------|
128
128
  | `implemented` | `commit:<sha>;files:path/a.ts,path/b.ts` — or `pr:<number>` with `files:<changed-paths>`, or `decision:<id>` for decision-only tasks |
129
- | `testsPassed` | `tool:test` (canonical) or `test-run:<json>` |
130
- | `qaPassed` | `tool:lint;tool:typecheck` |
129
+ | `testsPassed` | `ci:<pr>` if merged and `evidence.ciSatisfies`; else `tool:test-affected` (needs `testing.affectedCommand`), changed-file `test-run:<json>`, or `tool:test` |
130
+ | `qaPassed` | `ci:<pr>` likewise, else `tool:lint;tool:typecheck` |
131
131
  | `documented` | `files:docs/spec.md` |
132
132
  | `securityPassed` | `tool:security-scan` |
133
133
  | `cleanupDone` | `note:removed dead branches` |
134
134
 
135
135
  Name the acceptance criteria each result proves: `cleo verify T1234 --gate implemented --evidence "commit:abc123;files:src/fix.ts;satisfies:T1234#AC1"`. Record `testsPassed` and `qaPassed` separately with actual verification results and explicit criterion links. Documentation-only PRs cannot implement a code-fix task; changed criteria require fresh evidence, and a child waiver does not waive parent criteria. Then `cleo complete T###` re-validates every hard atom (commit reachable, file sha256, test-run hash); tampering → `E_EVIDENCE_STALE`. Typed gates, `pr:` rules, tool timeouts and the audited owner override: `cleo briefing inject --section evidence`.
136
136
 
137
- Anti-patterns: completing without running tests · `cleo verify --all` without `--evidence` · self-attesting without programmatic proof · modifying files between `cleo verify` and `cleo complete`.
137
+ Anti-patterns: completing without running tests · `cleo verify --all` without `--evidence` · self-attesting without programmatic proof · running tests by hand, then again via `tool:test` · modifying files between `cleo verify` and `cleo complete`.
138
138
  <!-- /CLEO-INJECTION:section=pre-complete-gate -->
139
139
 
140
140
  <!-- CLEO-INJECTION:section=rules -->
@@ -1,6 +1,6 @@
1
1
  # CLEO Protocol — on-demand reference
2
2
 
3
- Version: 2.24.3 | Companion to the always-loaded `CLEO-INJECTION.md` core
3
+ Version: 2.24.4 | Companion to the always-loaded `CLEO-INJECTION.md` core
4
4
 
5
5
  Not injected into agent context. Print one section with `cleo briefing inject --section <name>`; tier-2 spawn prompts embed this whole file. Section names are the `CLEO-INJECTION:section` markers below.
6
6
 
@@ -270,7 +270,7 @@ A merged PR and green CI provide provenance. For `implemented`, pair `pr:<number
270
270
 
271
271
  | Exit | Code | Fix |
272
272
  |:----:|------|-----|
273
- | — | `E_EVIDENCE_TESTS_FAILED` | Fix failing tests before re-verifying with `tool:pnpm-test` or `test-run:<json>` |
273
+ | — | `E_EVIDENCE_TESTS_FAILED` | Fix failing tests before re-verifying with `tool:test-affected` (needs `testing.affectedCommand`), a targeted `test-run:<json>` or `tool:test`, or `ci:<pr>` once merged (needs `evidence.ciSatisfies`) |
274
274
  | — | `E_EVIDENCE_INVALID_DECISION` | `decision:<id>` atom — decision ID not found or not accepted/proposed in BRAIN |
275
275
  | — | `E_EVIDENCE_GIT_ROOT` | The CLEO root is not a git checkout — a LAYOUT fact, not a failing atom. One child repo, or a `commit:` SHA that exists in exactly one child, resolves automatically. Otherwise declare it: `"evidence": { "gitRoot": "<subdir>" }` in `.cleo/project-context.json`, or `CLEO_EVIDENCE_GIT_ROOT=<repo>` for one invocation |
276
276
  | — | `E_FLAG_REMOVED` | `cleo complete --force` removed per ADR-051. Use `--evidence` or `CLEO_OWNER_OVERRIDE=1` |
@@ -295,7 +295,11 @@ All overrides append a line to `.cleo/audit/force-bypass.jsonl`. Use sparingly.
295
295
 
296
296
  ### Tool resolution + result cache (ADR-061)
297
297
 
298
- `tool:<name>` resolves through `.cleo/project-context.json`, then the project's `package.json` script of that name (`<pm> run <name>`), then `primaryType` fallbacks (references-only tsconfig → `tsc -b`, which emits). A script that writes files (an auto-fixing `lint`) edits the checkout and later fails `E_EVIDENCE_STALE`; keep verification scripts read-only. Cache `.cleo/cache/evidence/<key>.json`: `(canonical, cmd, args, HEAD, dirty-tree fingerprint)`. Parallel verifies coalesce; cross-worktree semaphores: `~/.local/share/cleo/locks/tool-<canonical>/`, limit `CLEO_TOOL_CONCURRENCY_<TOOL>=<n>`. Deadlines: **1800000 ms (30 min) for `test` and `build`**, otherwise 300000 ms (5 min). Positive-integer override: `CLEO_TOOL_TIMEOUT_<TOOL>=<ms>`; invalid values explicitly fail with the tool default. Timeouts cache nothing; increase the deadline before an unchanged retry (gh#1221).
298
+ `tool:<name>` resolves through `.cleo/project-context.json`, then the project's `package.json` script of that name (`<pm> run <name>`), then `primaryType` fallbacks (references-only tsconfig → `tsc -b`, which emits). A script that writes files (an auto-fixing `lint`) edits the checkout and later fails `E_EVIDENCE_STALE`; keep verification scripts read-only. Cache `.cleo/cache/evidence/<key>.json`, keyed on the command `(canonical, cmd, args)` and the tree content under test: identical tree content shares one result across worktrees and commits, and a repeat verify on an unchanged tree never re-runs. After a failure the previously failing test files re-run first, and a failure that passes on its single rerun is recorded as `flaky`. Parallel verifies coalesce; cross-worktree semaphores: `~/.local/share/cleo/locks/tool-<canonical>/`, limit `CLEO_TOOL_CONCURRENCY_<TOOL>=<n>`. Deadlines: **1800000 ms (30 min) for `test` and `build`**, otherwise 300000 ms (5 min). Positive-integer override: `CLEO_TOOL_TIMEOUT_<TOOL>=<ms>`; invalid values explicitly fail with the tool default. Timeouts cache nothing; increase the deadline before an unchanged retry (gh#1221). `cleo verify --fresh` (or `CLEO_EVIDENCE_FRESH=1`) bypasses the cache for one call.
299
+
300
+ ### Test evidence without churn (T12957)
301
+
302
+ The evidence run is the one run. Start with `cleo done <id> --plan`, which picks affected → ci → full and shows each tool's cache state. When the PR has merged and the project sets `evidence.ciSatisfies`, record `testsPassed`/`qaPassed` with `ci:<pr>` and run nothing locally. Otherwise, when `testing.affectedCommand` is configured, use `tool:test-affected` (packages the diff touches plus dependents); a full `tool:test` is then only for changes to root config, which affected planning refuses. Without it, use a targeted `test-run:<json>` of the test files you changed, or `tool:test`. While iterating, run only the failing or changed test files; never run the suite by hand and then again through `tool:test`. On macOS heavy `test`/`build` runs take one machine-wide slot by default (`CLEO_TOOL_CONCURRENCY_TEST=<n>` raises it).
299
303
 
300
304
  ### `pr:<number>` retroactive atom (T9764)
301
305
 
@@ -307,5 +311,5 @@ A task PR merged into an integration branch is a component: `pr:<component>@<int
307
311
 
308
312
  With `evidence.ciSatisfies: true`, `ci:<number>` attests `testsPassed`/`qaPassed` from the required checks (`evidence.ciChecks`) green on the merged PR's merge commit, or on a final PR head whose tree equals it. When a concurrency group CANCELLED (or skipped) the merge commit's own push run, a later default-branch commit's green `push` run may stand in (T12742). That run proves the DESCENDANT's tree, not the merge tree, so it counts only when all of these hold: no merge-commit run or job failed; the PR's final head has a green latest `pull_request` run for every stood-in check; the commit descends from the merge commit and is one of the first 10 first-parent commits within 7 days; NO commit between them, merge commits included, touched the PR's changed files, a pinned workflow file or `.github/actions`; and it is the first candidate with a decisive verdict. A red first decisive candidate refuses, and a pending one refuses with "wait for <sha>"; only cancelled, skipped or never-started runs move on. The atom records `descendantSha`, `descendantRange` and `descendantPrHeadSha`, and `cleo complete` re-fetches both runs' latest attempts, because a re-run can turn a completed check red.
309
313
 
310
- Required checks: explicit configuration or target repository protection. `release.prRequiredWorkflows: []` requires no checks; it proves neither testing nor review. `.cleo/cache/evidence/pr-<num>.json` retains provenance and changed files; obsolete versions reject. Use `tool:test` or `test-run:<json>` plus appropriate QA tools, linking each result to verified criteria.
314
+ Required checks: explicit configuration or target repository protection. `release.prRequiredWorkflows: []` requires no checks; it proves neither testing nor review. `.cleo/cache/evidence/pr-<num>.json` retains provenance and changed files; obsolete versions reject. Use `tool:test-affected` when `testing.affectedCommand` is configured (a full `tool:test` then only for root-config changes, which affected planning refuses), otherwise a targeted `test-run:<json>` or `tool:test`, plus appropriate QA tools, linking each result to verified criteria.
311
315
  <!-- /CLEO-INJECTION:section=evidence -->