@cleocode/core 2026.9.8 → 2026.9.10

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 (569) hide show
  1. package/dist/audit/reconstruct.d.ts +13 -43
  2. package/dist/audit/reconstruct.d.ts.map +1 -1
  3. package/dist/audit/reconstruct.js +295 -290
  4. package/dist/audit/reconstruct.js.map +1 -1
  5. package/dist/bootstrap.d.ts.map +1 -1
  6. package/dist/bootstrap.js +8 -2
  7. package/dist/bootstrap.js.map +1 -1
  8. package/dist/compliance/protocol-rules.d.ts.map +1 -1
  9. package/dist/compliance/protocol-rules.js +3 -1
  10. package/dist/compliance/protocol-rules.js.map +1 -1
  11. package/dist/dispatch/mutate-projection.d.ts.map +1 -1
  12. package/dist/dispatch/mutate-projection.js +12 -0
  13. package/dist/dispatch/mutate-projection.js.map +1 -1
  14. package/dist/dispatch/mvi-projection.d.ts +29 -6
  15. package/dist/dispatch/mvi-projection.d.ts.map +1 -1
  16. package/dist/dispatch/mvi-projection.js +109 -139
  17. package/dist/dispatch/mvi-projection.js.map +1 -1
  18. package/dist/docs/docs-read-model.d.ts +3 -2
  19. package/dist/docs/docs-read-model.d.ts.map +1 -1
  20. package/dist/docs/docs-read-model.js +4 -3
  21. package/dist/docs/docs-read-model.js.map +1 -1
  22. package/dist/docs/export-document.js +5129 -2297
  23. package/dist/docs/export-document.js.map +3 -3
  24. package/dist/docs/projection.d.ts +67 -0
  25. package/dist/docs/projection.d.ts.map +1 -0
  26. package/dist/docs/projection.js +370 -0
  27. package/dist/docs/projection.js.map +1 -0
  28. package/dist/doctor/acceptance-drift.d.ts +6 -2
  29. package/dist/doctor/acceptance-drift.d.ts.map +1 -1
  30. package/dist/doctor/acceptance-drift.js +43 -5
  31. package/dist/doctor/acceptance-drift.js.map +1 -1
  32. package/dist/doctor/knowledge-summary.d.ts +41 -0
  33. package/dist/doctor/knowledge-summary.d.ts.map +1 -0
  34. package/dist/doctor/knowledge-summary.js +81 -0
  35. package/dist/doctor/knowledge-summary.js.map +1 -0
  36. package/dist/doctor/knowledge.d.ts +192 -0
  37. package/dist/doctor/knowledge.d.ts.map +1 -0
  38. package/dist/doctor/knowledge.js +1864 -0
  39. package/dist/doctor/knowledge.js.map +1 -0
  40. package/dist/git/work-tree.d.ts +169 -0
  41. package/dist/git/work-tree.d.ts.map +1 -0
  42. package/dist/git/work-tree.js +341 -0
  43. package/dist/git/work-tree.js.map +1 -0
  44. package/dist/hooks/handlers/task-hooks.d.ts +8 -5
  45. package/dist/hooks/handlers/task-hooks.d.ts.map +1 -1
  46. package/dist/hooks/handlers/task-hooks.js +15 -60
  47. package/dist/hooks/handlers/task-hooks.js.map +1 -1
  48. package/dist/identity/cleo-identity.d.ts +13 -0
  49. package/dist/identity/cleo-identity.d.ts.map +1 -1
  50. package/dist/identity/cleo-identity.js +20 -6
  51. package/dist/identity/cleo-identity.js.map +1 -1
  52. package/dist/injection.d.ts.map +1 -1
  53. package/dist/injection.js +29 -13
  54. package/dist/injection.js.map +1 -1
  55. package/dist/internal.d.ts +3 -0
  56. package/dist/internal.d.ts.map +1 -1
  57. package/dist/internal.js +4 -0
  58. package/dist/internal.js.map +1 -1
  59. package/dist/lifecycle/verification/satisfies-validator.d.ts.map +1 -1
  60. package/dist/lifecycle/verification/satisfies-validator.js +124 -120
  61. package/dist/lifecycle/verification/satisfies-validator.js.map +1 -1
  62. package/dist/llm/plugin-facade.js +4047 -1726
  63. package/dist/llm/plugin-facade.js.map +3 -3
  64. package/dist/memory/brain-backfill.d.ts +27 -12
  65. package/dist/memory/brain-backfill.d.ts.map +1 -1
  66. package/dist/memory/brain-backfill.js +325 -134
  67. package/dist/memory/brain-backfill.js.map +1 -1
  68. package/dist/memory/brain-doctor.d.ts +21 -0
  69. package/dist/memory/brain-doctor.d.ts.map +1 -1
  70. package/dist/memory/brain-doctor.js +111 -53
  71. package/dist/memory/brain-doctor.js.map +1 -1
  72. package/dist/memory/brain-links.d.ts.map +1 -1
  73. package/dist/memory/brain-links.js +31 -4
  74. package/dist/memory/brain-links.js.map +1 -1
  75. package/dist/memory/brain-reasoning.d.ts.map +1 -1
  76. package/dist/memory/brain-reasoning.js +28 -2
  77. package/dist/memory/brain-reasoning.js.map +1 -1
  78. package/dist/memory/brain-reconciler.d.ts +14 -19
  79. package/dist/memory/brain-reconciler.d.ts.map +1 -1
  80. package/dist/memory/brain-reconciler.js +70 -97
  81. package/dist/memory/brain-reconciler.js.map +1 -1
  82. package/dist/memory/brain-search.d.ts +2 -0
  83. package/dist/memory/brain-search.d.ts.map +1 -1
  84. package/dist/memory/brain-search.js +59 -29
  85. package/dist/memory/brain-search.js.map +1 -1
  86. package/dist/memory/brain-similarity.d.ts.map +1 -1
  87. package/dist/memory/brain-similarity.js +5 -4
  88. package/dist/memory/brain-similarity.js.map +1 -1
  89. package/dist/memory/brain-stub-prune.d.ts +31 -9
  90. package/dist/memory/brain-stub-prune.d.ts.map +1 -1
  91. package/dist/memory/brain-stub-prune.js +65 -18
  92. package/dist/memory/brain-stub-prune.js.map +1 -1
  93. package/dist/memory/brain-writer-handlers.d.ts +10 -1
  94. package/dist/memory/brain-writer-handlers.d.ts.map +1 -1
  95. package/dist/memory/brain-writer-handlers.js +23 -3
  96. package/dist/memory/brain-writer-handlers.js.map +1 -1
  97. package/dist/memory/brain-writer-thread.d.ts +11 -1
  98. package/dist/memory/brain-writer-thread.d.ts.map +1 -1
  99. package/dist/memory/brain-writer-thread.js +87 -20
  100. package/dist/memory/brain-writer-thread.js.map +1 -1
  101. package/dist/memory/brain-writer-worker.js +8 -1
  102. package/dist/memory/brain-writer-worker.js.map +1 -1
  103. package/dist/memory/decision-cross-link.d.ts +39 -0
  104. package/dist/memory/decision-cross-link.d.ts.map +1 -1
  105. package/dist/memory/decision-cross-link.js +316 -0
  106. package/dist/memory/decision-cross-link.js.map +1 -1
  107. package/dist/memory/decisions.d.ts +4 -1
  108. package/dist/memory/decisions.d.ts.map +1 -1
  109. package/dist/memory/decisions.js +7 -24
  110. package/dist/memory/decisions.js.map +1 -1
  111. package/dist/memory/dispatch-trace.d.ts +12 -5
  112. package/dist/memory/dispatch-trace.d.ts.map +1 -1
  113. package/dist/memory/dispatch-trace.js +17 -7
  114. package/dist/memory/dispatch-trace.js.map +1 -1
  115. package/dist/memory/eligibility.d.ts +51 -0
  116. package/dist/memory/eligibility.d.ts.map +1 -0
  117. package/dist/memory/eligibility.js +77 -0
  118. package/dist/memory/eligibility.js.map +1 -0
  119. package/dist/memory/engine-compat.d.ts +2 -0
  120. package/dist/memory/engine-compat.d.ts.map +1 -1
  121. package/dist/memory/engine-compat.js +10 -0
  122. package/dist/memory/engine-compat.js.map +1 -1
  123. package/dist/memory/extraction-gate.d.ts +21 -7
  124. package/dist/memory/extraction-gate.d.ts.map +1 -1
  125. package/dist/memory/extraction-gate.js +178 -216
  126. package/dist/memory/extraction-gate.js.map +1 -1
  127. package/dist/memory/graph-auto-populate.d.ts +38 -5
  128. package/dist/memory/graph-auto-populate.d.ts.map +1 -1
  129. package/dist/memory/graph-auto-populate.js +182 -60
  130. package/dist/memory/graph-auto-populate.js.map +1 -1
  131. package/dist/memory/graph-memory-bridge.d.ts +14 -1
  132. package/dist/memory/graph-memory-bridge.d.ts.map +1 -1
  133. package/dist/memory/graph-memory-bridge.js +66 -28
  134. package/dist/memory/graph-memory-bridge.js.map +1 -1
  135. package/dist/memory/index.d.ts +1 -19
  136. package/dist/memory/index.d.ts.map +1 -1
  137. package/dist/memory/index.js +1 -50
  138. package/dist/memory/index.js.map +1 -1
  139. package/dist/memory/learnings.d.ts.map +1 -1
  140. package/dist/memory/learnings.js +2 -23
  141. package/dist/memory/learnings.js.map +1 -1
  142. package/dist/memory/manifest-filter.d.ts +21 -0
  143. package/dist/memory/manifest-filter.d.ts.map +1 -0
  144. package/dist/memory/manifest-filter.js +51 -0
  145. package/dist/memory/manifest-filter.js.map +1 -0
  146. package/dist/memory/manifest-ingestion.d.ts +28 -30
  147. package/dist/memory/manifest-ingestion.d.ts.map +1 -1
  148. package/dist/memory/manifest-ingestion.js +104 -235
  149. package/dist/memory/manifest-ingestion.js.map +1 -1
  150. package/dist/memory/observer-reflector.d.ts +2 -0
  151. package/dist/memory/observer-reflector.d.ts.map +1 -1
  152. package/dist/memory/observer-reflector.js +6 -49
  153. package/dist/memory/observer-reflector.js.map +1 -1
  154. package/dist/memory/patterns.d.ts +10 -0
  155. package/dist/memory/patterns.d.ts.map +1 -1
  156. package/dist/memory/patterns.js +25 -33
  157. package/dist/memory/patterns.js.map +1 -1
  158. package/dist/memory/pipeline-manifest-sqlite.d.ts +72 -9
  159. package/dist/memory/pipeline-manifest-sqlite.d.ts.map +1 -1
  160. package/dist/memory/pipeline-manifest-sqlite.js +508 -412
  161. package/dist/memory/pipeline-manifest-sqlite.js.map +1 -1
  162. package/dist/memory/retrieval/build-retrieval-bundle.d.ts.map +1 -1
  163. package/dist/memory/retrieval/build-retrieval-bundle.js +16 -15
  164. package/dist/memory/retrieval/build-retrieval-bundle.js.map +1 -1
  165. package/dist/memory/retrieval/fetch.d.ts +7 -0
  166. package/dist/memory/retrieval/fetch.d.ts.map +1 -1
  167. package/dist/memory/retrieval/fetch.js +14 -11
  168. package/dist/memory/retrieval/fetch.js.map +1 -1
  169. package/dist/memory/retrieval/observe.d.ts +7 -1
  170. package/dist/memory/retrieval/observe.d.ts.map +1 -1
  171. package/dist/memory/retrieval/observe.js +58 -4
  172. package/dist/memory/retrieval/observe.js.map +1 -1
  173. package/dist/memory/retrieval/search.d.ts +14 -1
  174. package/dist/memory/retrieval/search.d.ts.map +1 -1
  175. package/dist/memory/retrieval/search.js +133 -69
  176. package/dist/memory/retrieval/search.js.map +1 -1
  177. package/dist/memory/retrieval/telemetry.d.ts +31 -0
  178. package/dist/memory/retrieval/telemetry.d.ts.map +1 -0
  179. package/dist/memory/retrieval/telemetry.js +53 -0
  180. package/dist/memory/retrieval/telemetry.js.map +1 -0
  181. package/dist/nexus/analyze-orchestrator.d.ts +41 -9
  182. package/dist/nexus/analyze-orchestrator.d.ts.map +1 -1
  183. package/dist/nexus/analyze-orchestrator.js +257 -58
  184. package/dist/nexus/analyze-orchestrator.js.map +1 -1
  185. package/dist/nexus/api-contracts.d.ts +2 -6
  186. package/dist/nexus/api-contracts.d.ts.map +1 -1
  187. package/dist/nexus/api-contracts.js +11 -2
  188. package/dist/nexus/api-contracts.js.map +1 -1
  189. package/dist/nexus/context.d.ts.map +1 -1
  190. package/dist/nexus/context.js +14 -37
  191. package/dist/nexus/context.js.map +1 -1
  192. package/dist/nexus/diff.d.ts.map +1 -1
  193. package/dist/nexus/diff.js +2 -1
  194. package/dist/nexus/diff.js.map +1 -1
  195. package/dist/nexus/identity.d.ts +29 -3
  196. package/dist/nexus/identity.d.ts.map +1 -1
  197. package/dist/nexus/identity.js +63 -12
  198. package/dist/nexus/identity.js.map +1 -1
  199. package/dist/nexus/impact.d.ts +21 -19
  200. package/dist/nexus/impact.d.ts.map +1 -1
  201. package/dist/nexus/impact.js +96 -192
  202. package/dist/nexus/impact.js.map +1 -1
  203. package/dist/nexus/knowledge.d.ts +80 -0
  204. package/dist/nexus/knowledge.d.ts.map +1 -0
  205. package/dist/nexus/knowledge.js +786 -0
  206. package/dist/nexus/knowledge.js.map +1 -0
  207. package/dist/nexus/living-brain.d.ts +8 -5
  208. package/dist/nexus/living-brain.d.ts.map +1 -1
  209. package/dist/nexus/living-brain.js +252 -188
  210. package/dist/nexus/living-brain.js.map +1 -1
  211. package/dist/nexus/registry.d.ts +11 -2
  212. package/dist/nexus/registry.d.ts.map +1 -1
  213. package/dist/nexus/registry.js +144 -128
  214. package/dist/nexus/registry.js.map +1 -1
  215. package/dist/nexus/source-roots.d.ts +16 -0
  216. package/dist/nexus/source-roots.d.ts.map +1 -0
  217. package/dist/nexus/source-roots.js +174 -0
  218. package/dist/nexus/source-roots.js.map +1 -0
  219. package/dist/nexus/task-evidence.d.ts +22 -0
  220. package/dist/nexus/task-evidence.d.ts.map +1 -0
  221. package/dist/nexus/task-evidence.js +210 -0
  222. package/dist/nexus/task-evidence.js.map +1 -0
  223. package/dist/nexus/tasks-bridge.d.ts +14 -7
  224. package/dist/nexus/tasks-bridge.d.ts.map +1 -1
  225. package/dist/nexus/tasks-bridge.js +81 -40
  226. package/dist/nexus/tasks-bridge.js.map +1 -1
  227. package/dist/orchestrate/lifecycle-ops.d.ts.map +1 -1
  228. package/dist/orchestrate/lifecycle-ops.js +170 -120
  229. package/dist/orchestrate/lifecycle-ops.js.map +1 -1
  230. package/dist/orchestrate/query-ops.d.ts +6 -7
  231. package/dist/orchestrate/query-ops.d.ts.map +1 -1
  232. package/dist/orchestrate/query-ops.js +509 -532
  233. package/dist/orchestrate/query-ops.js.map +1 -1
  234. package/dist/orchestration/bootstrap.d.ts +15 -1
  235. package/dist/orchestration/bootstrap.d.ts.map +1 -1
  236. package/dist/orchestration/bootstrap.js +21 -10
  237. package/dist/orchestration/bootstrap.js.map +1 -1
  238. package/dist/orchestration/index.d.ts +35 -3
  239. package/dist/orchestration/index.d.ts.map +1 -1
  240. package/dist/orchestration/index.js +64 -35
  241. package/dist/orchestration/index.js.map +1 -1
  242. package/dist/orchestration/lead-rollup.d.ts +24 -1
  243. package/dist/orchestration/lead-rollup.d.ts.map +1 -1
  244. package/dist/orchestration/lead-rollup.js +31 -11
  245. package/dist/orchestration/lead-rollup.js.map +1 -1
  246. package/dist/orchestration/spawn-prompt.d.ts.map +1 -1
  247. package/dist/orchestration/spawn-prompt.js +25 -45
  248. package/dist/orchestration/spawn-prompt.js.map +1 -1
  249. package/dist/orchestration/unblock.d.ts +15 -1
  250. package/dist/orchestration/unblock.d.ts.map +1 -1
  251. package/dist/orchestration/unblock.js +23 -12
  252. package/dist/orchestration/unblock.js.map +1 -1
  253. package/dist/orchestration/validate-spawn.d.ts.map +1 -1
  254. package/dist/orchestration/validate-spawn.js +3 -3
  255. package/dist/orchestration/validate-spawn.js.map +1 -1
  256. package/dist/orchestration/waves.d.ts +29 -13
  257. package/dist/orchestration/waves.d.ts.map +1 -1
  258. package/dist/orchestration/waves.js +43 -55
  259. package/dist/orchestration/waves.js.map +1 -1
  260. package/dist/paths.d.ts +17 -163
  261. package/dist/paths.d.ts.map +1 -1
  262. package/dist/paths.js +145 -496
  263. package/dist/paths.js.map +1 -1
  264. package/dist/project-info.d.ts +2 -11
  265. package/dist/project-info.d.ts.map +1 -1
  266. package/dist/project-info.js +3 -31
  267. package/dist/project-info.js.map +1 -1
  268. package/dist/project-scope.d.ts +239 -0
  269. package/dist/project-scope.d.ts.map +1 -0
  270. package/dist/project-scope.js +473 -0
  271. package/dist/project-scope.js.map +1 -0
  272. package/dist/release/pr-evidence.d.ts +23 -4
  273. package/dist/release/pr-evidence.d.ts.map +1 -1
  274. package/dist/release/pr-evidence.js +65 -9
  275. package/dist/release/pr-evidence.js.map +1 -1
  276. package/dist/render/nexus/graph/index.d.ts.map +1 -1
  277. package/dist/render/nexus/graph/index.js +4 -2
  278. package/dist/render/nexus/graph/index.js.map +1 -1
  279. package/dist/render/orchestration/audit-reconstruct.d.ts +11 -0
  280. package/dist/render/orchestration/audit-reconstruct.d.ts.map +1 -1
  281. package/dist/render/orchestration/audit-reconstruct.js +21 -6
  282. package/dist/render/orchestration/audit-reconstruct.js.map +1 -1
  283. package/dist/render/tasks/show.js +2 -1
  284. package/dist/render/tasks/show.js.map +1 -1
  285. package/dist/resources/spawn-wrapper.d.ts +82 -14
  286. package/dist/resources/spawn-wrapper.d.ts.map +1 -1
  287. package/dist/resources/spawn-wrapper.js +585 -27
  288. package/dist/resources/spawn-wrapper.js.map +1 -1
  289. package/dist/selfimprove/fix-gen.js +4055 -1734
  290. package/dist/selfimprove/fix-gen.js.map +3 -3
  291. package/dist/sequence/index.d.ts.map +1 -1
  292. package/dist/sequence/index.js +76 -68
  293. package/dist/sequence/index.js.map +1 -1
  294. package/dist/session/canon-lint.d.ts +24 -3
  295. package/dist/session/canon-lint.d.ts.map +1 -1
  296. package/dist/session/canon-lint.js +72 -31
  297. package/dist/session/canon-lint.js.map +1 -1
  298. package/dist/session/engine-ops.d.ts +1 -4
  299. package/dist/session/engine-ops.d.ts.map +1 -1
  300. package/dist/session/engine-ops.js +42 -6
  301. package/dist/session/engine-ops.js.map +1 -1
  302. package/dist/sessions/briefing.d.ts +11 -1
  303. package/dist/sessions/briefing.d.ts.map +1 -1
  304. package/dist/sessions/briefing.js +76 -8
  305. package/dist/sessions/briefing.js.map +1 -1
  306. package/dist/sessions/handoff.d.ts +3 -1
  307. package/dist/sessions/handoff.d.ts.map +1 -1
  308. package/dist/sessions/handoff.js +2 -0
  309. package/dist/sessions/handoff.js.map +1 -1
  310. package/dist/shutdown-deadline.d.ts +24 -33
  311. package/dist/shutdown-deadline.d.ts.map +1 -1
  312. package/dist/shutdown-deadline.js +71 -14
  313. package/dist/shutdown-deadline.js.map +1 -1
  314. package/dist/shutdown.d.ts +21 -10
  315. package/dist/shutdown.d.ts.map +1 -1
  316. package/dist/shutdown.js +89 -42
  317. package/dist/shutdown.js.map +1 -1
  318. package/dist/skills/index.d.ts +1 -1
  319. package/dist/skills/index.d.ts.map +1 -1
  320. package/dist/skills/index.js +1 -1
  321. package/dist/skills/index.js.map +1 -1
  322. package/dist/skills/orchestrator/validator.d.ts +87 -20
  323. package/dist/skills/orchestrator/validator.d.ts.map +1 -1
  324. package/dist/skills/orchestrator/validator.js +330 -241
  325. package/dist/skills/orchestrator/validator.js.map +1 -1
  326. package/dist/store/agent-resolver.d.ts.map +1 -1
  327. package/dist/store/agent-resolver.js +16 -9
  328. package/dist/store/agent-resolver.js.map +1 -1
  329. package/dist/store/attachment-store.d.ts +4 -1
  330. package/dist/store/attachment-store.d.ts.map +1 -1
  331. package/dist/store/attachment-store.js +20 -3
  332. package/dist/store/attachment-store.js.map +1 -1
  333. package/dist/store/background-jobs.d.ts +426 -105
  334. package/dist/store/background-jobs.d.ts.map +1 -1
  335. package/dist/store/background-jobs.js +1208 -252
  336. package/dist/store/background-jobs.js.map +1 -1
  337. package/dist/store/background-ops.d.ts +145 -8
  338. package/dist/store/background-ops.d.ts.map +1 -1
  339. package/dist/store/background-ops.js +459 -15
  340. package/dist/store/background-ops.js.map +1 -1
  341. package/dist/store/backup-inspect.d.ts +48 -4
  342. package/dist/store/backup-inspect.d.ts.map +1 -1
  343. package/dist/store/backup-inspect.js +384 -4
  344. package/dist/store/backup-inspect.js.map +1 -1
  345. package/dist/store/converters.d.ts.map +1 -1
  346. package/dist/store/converters.js +19 -2
  347. package/dist/store/converters.js.map +1 -1
  348. package/dist/store/data-accessor.d.ts +9 -1
  349. package/dist/store/data-accessor.d.ts.map +1 -1
  350. package/dist/store/data-accessor.js +22 -5
  351. package/dist/store/data-accessor.js.map +1 -1
  352. package/dist/store/data-safety-central.d.ts.map +1 -1
  353. package/dist/store/data-safety-central.js +272 -232
  354. package/dist/store/data-safety-central.js.map +1 -1
  355. package/dist/store/db-helpers.d.ts +19 -3
  356. package/dist/store/db-helpers.d.ts.map +1 -1
  357. package/dist/store/db-helpers.js +42 -58
  358. package/dist/store/db-helpers.js.map +1 -1
  359. package/dist/store/dual-scope-db.d.ts +63 -4
  360. package/dist/store/dual-scope-db.d.ts.map +1 -1
  361. package/dist/store/dual-scope-db.js +166 -19
  362. package/dist/store/dual-scope-db.js.map +1 -1
  363. package/dist/store/exodus/archive.d.ts +21 -7
  364. package/dist/store/exodus/archive.d.ts.map +1 -1
  365. package/dist/store/exodus/archive.js +60 -18
  366. package/dist/store/exodus/archive.js.map +1 -1
  367. package/dist/store/exodus/migrate.d.ts.map +1 -1
  368. package/dist/store/exodus/migrate.js +27 -23
  369. package/dist/store/exodus/migrate.js.map +1 -1
  370. package/dist/store/exodus/on-open.d.ts +16 -27
  371. package/dist/store/exodus/on-open.d.ts.map +1 -1
  372. package/dist/store/exodus/on-open.js +121 -169
  373. package/dist/store/exodus/on-open.js.map +1 -1
  374. package/dist/store/exodus/recovery.d.ts +90 -0
  375. package/dist/store/exodus/recovery.d.ts.map +1 -0
  376. package/dist/store/exodus/recovery.js +434 -0
  377. package/dist/store/exodus/recovery.js.map +1 -0
  378. package/dist/store/exodus/types.d.ts +15 -0
  379. package/dist/store/exodus/types.d.ts.map +1 -1
  380. package/dist/store/memory-accessor.d.ts +52 -3
  381. package/dist/store/memory-accessor.d.ts.map +1 -1
  382. package/dist/store/memory-accessor.js +122 -7
  383. package/dist/store/memory-accessor.js.map +1 -1
  384. package/dist/store/nexus-sqlite.d.ts +24 -6
  385. package/dist/store/nexus-sqlite.d.ts.map +1 -1
  386. package/dist/store/nexus-sqlite.js +39 -20
  387. package/dist/store/nexus-sqlite.js.map +1 -1
  388. package/dist/store/ports/domain-binding.d.ts.map +1 -1
  389. package/dist/store/ports/domain-binding.js +27 -5
  390. package/dist/store/ports/domain-binding.js.map +1 -1
  391. package/dist/store/schema/background-jobs.d.ts +181 -2
  392. package/dist/store/schema/background-jobs.d.ts.map +1 -1
  393. package/dist/store/schema/background-jobs.js +27 -3
  394. package/dist/store/schema/background-jobs.js.map +1 -1
  395. package/dist/store/schema/cleo-global/skills.d.ts +2 -2
  396. package/dist/store/schema/cleo-project/lifecycle.d.ts +2 -2
  397. package/dist/store/schema/cleo-project/runtime.d.ts +1 -1
  398. package/dist/store/schema/cleo-project/tasks-core.d.ts +1 -1
  399. package/dist/store/schema/lifecycle.d.ts +2 -2
  400. package/dist/store/schema/skills-schema.d.ts +2 -2
  401. package/dist/store/schema/tasks.d.ts +1 -1
  402. package/dist/store/session-store.d.ts +3 -1
  403. package/dist/store/session-store.d.ts.map +1 -1
  404. package/dist/store/session-store.js +252 -207
  405. package/dist/store/session-store.js.map +1 -1
  406. package/dist/store/sqlite-data-accessor.d.ts +39 -4
  407. package/dist/store/sqlite-data-accessor.d.ts.map +1 -1
  408. package/dist/store/sqlite-data-accessor.js +689 -527
  409. package/dist/store/sqlite-data-accessor.js.map +1 -1
  410. package/dist/store/tasks-sqlite.d.ts +3 -1
  411. package/dist/store/tasks-sqlite.d.ts.map +1 -1
  412. package/dist/store/tasks-sqlite.js +309 -279
  413. package/dist/store/tasks-sqlite.js.map +1 -1
  414. package/dist/store/validation-schemas.d.ts +8 -8
  415. package/dist/store/writer-lease.d.ts +80 -8
  416. package/dist/store/writer-lease.d.ts.map +1 -1
  417. package/dist/store/writer-lease.js +503 -134
  418. package/dist/store/writer-lease.js.map +1 -1
  419. package/dist/system/audit.d.ts +2 -1
  420. package/dist/system/audit.d.ts.map +1 -1
  421. package/dist/system/audit.js +118 -71
  422. package/dist/system/audit.js.map +1 -1
  423. package/dist/system/backup.d.ts.map +1 -1
  424. package/dist/system/backup.js +5 -5
  425. package/dist/system/backup.js.map +1 -1
  426. package/dist/system/inject-generate.js +1 -1
  427. package/dist/task-work/index.d.ts +3 -0
  428. package/dist/task-work/index.d.ts.map +1 -1
  429. package/dist/task-work/index.js +34 -37
  430. package/dist/task-work/index.js.map +1 -1
  431. package/dist/tasks/ac-coverage-gate.d.ts.map +1 -1
  432. package/dist/tasks/ac-coverage-gate.js +4 -0
  433. package/dist/tasks/ac-coverage-gate.js.map +1 -1
  434. package/dist/tasks/ac-immutability.d.ts +7 -4
  435. package/dist/tasks/ac-immutability.d.ts.map +1 -1
  436. package/dist/tasks/ac-immutability.js +19 -17
  437. package/dist/tasks/ac-immutability.js.map +1 -1
  438. package/dist/tasks/ac-table.d.ts +5 -5
  439. package/dist/tasks/ac-table.d.ts.map +1 -1
  440. package/dist/tasks/ac-table.js +26 -12
  441. package/dist/tasks/ac-table.js.map +1 -1
  442. package/dist/tasks/acceptance-input.d.ts +52 -0
  443. package/dist/tasks/acceptance-input.d.ts.map +1 -0
  444. package/dist/tasks/acceptance-input.js +259 -0
  445. package/dist/tasks/acceptance-input.js.map +1 -0
  446. package/dist/tasks/add.d.ts +67 -29
  447. package/dist/tasks/add.d.ts.map +1 -1
  448. package/dist/tasks/add.js +255 -97
  449. package/dist/tasks/add.js.map +1 -1
  450. package/dist/tasks/complete.d.ts +16 -1
  451. package/dist/tasks/complete.d.ts.map +1 -1
  452. package/dist/tasks/complete.js +152 -55
  453. package/dist/tasks/complete.js.map +1 -1
  454. package/dist/tasks/decompose.d.ts +103 -0
  455. package/dist/tasks/decompose.d.ts.map +1 -0
  456. package/dist/tasks/decompose.js +224 -0
  457. package/dist/tasks/decompose.js.map +1 -0
  458. package/dist/tasks/delete.d.ts +5 -8
  459. package/dist/tasks/delete.d.ts.map +1 -1
  460. package/dist/tasks/delete.js +4 -3
  461. package/dist/tasks/delete.js.map +1 -1
  462. package/dist/tasks/dependency-check.d.ts +59 -0
  463. package/dist/tasks/dependency-check.d.ts.map +1 -1
  464. package/dist/tasks/dependency-check.js +73 -0
  465. package/dist/tasks/dependency-check.js.map +1 -1
  466. package/dist/tasks/deps-ready.d.ts +13 -1
  467. package/dist/tasks/deps-ready.d.ts.map +1 -1
  468. package/dist/tasks/deps-ready.js +16 -5
  469. package/dist/tasks/deps-ready.js.map +1 -1
  470. package/dist/tasks/engine-converters.d.ts +7 -0
  471. package/dist/tasks/engine-converters.d.ts.map +1 -1
  472. package/dist/tasks/engine-converters.js +8 -1
  473. package/dist/tasks/engine-converters.js.map +1 -1
  474. package/dist/tasks/evidence.d.ts +88 -27
  475. package/dist/tasks/evidence.d.ts.map +1 -1
  476. package/dist/tasks/evidence.js +344 -43
  477. package/dist/tasks/evidence.js.map +1 -1
  478. package/dist/tasks/find.d.ts +16 -12
  479. package/dist/tasks/find.d.ts.map +1 -1
  480. package/dist/tasks/find.js +107 -93
  481. package/dist/tasks/find.js.map +1 -1
  482. package/dist/tasks/gate-preview.d.ts +73 -0
  483. package/dist/tasks/gate-preview.d.ts.map +1 -0
  484. package/dist/tasks/gate-preview.js +119 -0
  485. package/dist/tasks/gate-preview.js.map +1 -0
  486. package/dist/tasks/gate-runner.d.ts +88 -14
  487. package/dist/tasks/gate-runner.d.ts.map +1 -1
  488. package/dist/tasks/gate-runner.js +719 -250
  489. package/dist/tasks/gate-runner.js.map +1 -1
  490. package/dist/tasks/hierarchy-policy.d.ts +8 -0
  491. package/dist/tasks/hierarchy-policy.d.ts.map +1 -1
  492. package/dist/tasks/hierarchy-policy.js +9 -2
  493. package/dist/tasks/hierarchy-policy.js.map +1 -1
  494. package/dist/tasks/hierarchy.d.ts +67 -1
  495. package/dist/tasks/hierarchy.d.ts.map +1 -1
  496. package/dist/tasks/hierarchy.js +81 -1
  497. package/dist/tasks/hierarchy.js.map +1 -1
  498. package/dist/tasks/index.d.ts +3 -0
  499. package/dist/tasks/index.d.ts.map +1 -1
  500. package/dist/tasks/index.js +3 -0
  501. package/dist/tasks/index.js.map +1 -1
  502. package/dist/tasks/infer-add-params.d.ts +1 -20
  503. package/dist/tasks/infer-add-params.d.ts.map +1 -1
  504. package/dist/tasks/infer-add-params.js +2 -203
  505. package/dist/tasks/infer-add-params.js.map +1 -1
  506. package/dist/tasks/list.d.ts +7 -2
  507. package/dist/tasks/list.d.ts.map +1 -1
  508. package/dist/tasks/list.js +24 -36
  509. package/dist/tasks/list.js.map +1 -1
  510. package/dist/tasks/ops.d.ts +6 -61
  511. package/dist/tasks/ops.d.ts.map +1 -1
  512. package/dist/tasks/ops.js +5 -53
  513. package/dist/tasks/ops.js.map +1 -1
  514. package/dist/tasks/plan.d.ts +15 -1
  515. package/dist/tasks/plan.d.ts.map +1 -1
  516. package/dist/tasks/plan.js +23 -25
  517. package/dist/tasks/plan.js.map +1 -1
  518. package/dist/tasks/population.d.ts +46 -0
  519. package/dist/tasks/population.d.ts.map +1 -0
  520. package/dist/tasks/population.js +88 -0
  521. package/dist/tasks/population.js.map +1 -0
  522. package/dist/tasks/reconcile-scope.d.ts +157 -0
  523. package/dist/tasks/reconcile-scope.d.ts.map +1 -0
  524. package/dist/tasks/reconcile-scope.js +242 -0
  525. package/dist/tasks/reconcile-scope.js.map +1 -0
  526. package/dist/tasks/req.d.ts +51 -12
  527. package/dist/tasks/req.d.ts.map +1 -1
  528. package/dist/tasks/req.js +125 -69
  529. package/dist/tasks/req.js.map +1 -1
  530. package/dist/tasks/session-scope.d.ts +6 -31
  531. package/dist/tasks/session-scope.d.ts.map +1 -1
  532. package/dist/tasks/session-scope.js +3 -17
  533. package/dist/tasks/session-scope.js.map +1 -1
  534. package/dist/tasks/severity-attestation.d.ts +39 -10
  535. package/dist/tasks/severity-attestation.d.ts.map +1 -1
  536. package/dist/tasks/severity-attestation.js +75 -36
  537. package/dist/tasks/severity-attestation.js.map +1 -1
  538. package/dist/tasks/task-next.d.ts +5 -0
  539. package/dist/tasks/task-next.d.ts.map +1 -1
  540. package/dist/tasks/task-next.js +10 -9
  541. package/dist/tasks/task-next.js.map +1 -1
  542. package/dist/tasks/task-reparent.d.ts.map +1 -1
  543. package/dist/tasks/task-reparent.js +3 -13
  544. package/dist/tasks/task-reparent.js.map +1 -1
  545. package/dist/tasks/update.d.ts +20 -43
  546. package/dist/tasks/update.d.ts.map +1 -1
  547. package/dist/tasks/update.js +64 -49
  548. package/dist/tasks/update.js.map +1 -1
  549. package/dist/validation/engine-ops.d.ts +17 -1
  550. package/dist/validation/engine-ops.d.ts.map +1 -1
  551. package/dist/validation/engine-ops.js +149 -11
  552. package/dist/validation/engine-ops.js.map +1 -1
  553. package/dist/workgraph/reparent-preflight.d.ts +1 -1
  554. package/dist/workgraph/reparent-preflight.d.ts.map +1 -1
  555. package/dist/workgraph/reparent-preflight.js +6 -1
  556. package/dist/workgraph/reparent-preflight.js.map +1 -1
  557. package/dist/workgraph/scaffold-apply.d.ts.map +1 -1
  558. package/dist/workgraph/scaffold-apply.js +81 -76
  559. package/dist/workgraph/scaffold-apply.js.map +1 -1
  560. package/dist/workgraph/structure-validation.d.ts +1 -1
  561. package/dist/workgraph/structure-validation.d.ts.map +1 -1
  562. package/dist/workgraph/structure-validation.js +6 -1
  563. package/dist/workgraph/structure-validation.js.map +1 -1
  564. package/migrations/drizzle-tasks/20260919180000_t12263-job-ownership-fences/migration.sql +34 -0
  565. package/migrations/drizzle-tasks/20260919184500_t12265-durable-pending-proposals/migration.sql +4 -0
  566. package/package.json +18 -13
  567. package/schemas/config.schema.json +2 -2
  568. package/schemas/project-context.schema.json +12 -0
  569. package/templates/CLEO-INJECTION.md +114 -101
@@ -602,7 +602,7 @@
602
602
  },
603
603
  "hierarchy": {
604
604
  "type": "object",
605
- "description": "Hierarchy constraints for Epic → Task → Subtask structure. LLM-Agent-First design: limits are organizational, not cognitive.",
605
+ "description": "Hierarchy constraints for the Saga → Epic → Task → Subtask structure. LLM-Agent-First design: limits are organizational, not cognitive.",
606
606
  "additionalProperties": false,
607
607
  "properties": {
608
608
  "maxSiblings": {
@@ -617,7 +617,7 @@
617
617
  "minimum": 1,
618
618
  "maximum": 10,
619
619
  "default": 3,
620
- "description": "Maximum hierarchy depth (epic=0, task=1, subtask=2). Rarely needs changing."
620
+ "description": "Maximum containment depth VALUE, inclusive (saga=0, epic=1, task=2, subtask=3). The default 3 admits the full canonical spine. Rarely needs changing."
621
621
  },
622
622
  "countDoneInLimit": {
623
623
  "type": "boolean",
@@ -228,6 +228,18 @@
228
228
  "description": "Required successful checks for PR evidence atoms."
229
229
  }
230
230
  }
231
+ },
232
+ "evidence": {
233
+ "type": "object",
234
+ "description": "Evidence execution overrides (T12308).",
235
+ "additionalProperties": false,
236
+ "properties": {
237
+ "gitRoot": {
238
+ "type": "string",
239
+ "minLength": 1,
240
+ "description": "Checkout that git/gh evidence tools run in, relative to the CLEO store root (absolute is also accepted). Needed only when the store root is not itself a git work tree and parents more than one repository."
241
+ }
242
+ }
231
243
  }
232
244
  }
233
245
  }
@@ -1,37 +1,25 @@
1
1
  # CLEO Protocol
2
2
 
3
- Version: 2.6.0 | CLI-only dispatch | `cleo <command> [args]`
3
+ Version: 2.20.5 | CLI-only dispatch | `cleo <command> [args]`
4
4
 
5
5
  <!-- CLEO-INJECTION:section=session-start -->
6
- ## MANDATORY: Run `cleo briefing` BEFORE Any Other Tool
6
+ ## Universal protocol
7
7
 
8
- **HARD PROHIBITION**: BEFORE any tool use other than `cleo briefing`, the orchestrator
9
- MUST run `cleo briefing` first.
8
+ 1. **Orient.** Confirm project/worktree; run `cleo briefing` and `cleo focus <id>`. Follow user scope, provider safety, and repository instructions. Failed briefing is a diagnostic, not proof of absent history.
9
+ 2. **Check authority and coverage.** Distinguish current evidence, historical guidance, conflicting claims, and missing knowledge. Fetch cited records and their sourced successors. Recency or similarity alone does not establish authority.
10
+ 3. **Inspect evidence.** Before editing, inspect impact and its coverage. `UNKNOWN` means assessment is incomplete; `NONE` means no impact detected in the assessed graph. Static analysis cannot prove all runtime callers. Resolve ambiguous symbols using qualified candidate identifiers and verify against source.
11
+ 4. **Act.** Use the repair matrix: scope, evidence, repair class, proposed operation, prerequisites, verification, and recovery. Automatic repairs must be bounded and reversible. The calling agent supplies sourced resolutions for ambiguous findings; owner decisions stay explicit. No background LLM is required for repair.
12
+ 5. **Verify.** Run relevant checks, record validated evidence, then complete. Report unresolved and failed findings and missing coverage rather than claiming success.
13
+ 6. **Learn.** Record actionable incident knowledge with source, project, revision, observation, correction, and verification through `cleo memory observe`. Preserve historical handoffs; present corrections separately. Avoid empty completion traces.
10
14
 
11
- Do NOT read `.cleo/agent-outputs/*.md`, `NEXT-SESSION-HANDOFF.md`,
12
- `HONEST-HANDOFF-*.md`, or ANY markdown file as a substitute for `cleo briefing`.
13
- These files are deprecated, go stale, and have historically caused orchestrators to
14
- act on false information. They contain redirect stubs — not state.
15
+ Knowledge repair: `cleo doctor knowledge --dry-run`, then `--prepare FILE --actor AGENT`. Discover retained work with `--jobs --actor AGENT`, `--limit` and returned JSON `--cursor`; follow exact `inspectArgv`, not latest-job guesses. Retain partial diagnostics. Use `--apply JOB`, `--inspect JOB`, `--cancel JOB`, or `--resume JOB` with the original explicit `--actor AGENT --proposal-id PROPOSAL`; never borrow stored actor attribution. Verify receipts and paged lifecycle evidence (`--limit`/`--offset`); retain diagnostic failures and `prepared`/`attemptFailure` recovery details. Cancellation is a request, not rollback. Each invocation shares a default 2000ms budget (`--budget-ms`); a later explicit attempt is fresh, without renewing an active deadline or preempting synchronous SQLite. Resume preserves prior outcomes and uncertain expired attempts; live owners remain fenced. Stale source requires reassessment. After rollback, apply/resume return `E_REPAIR_ROLLED_BACK` with original and rollback receipts in `recoveryState`, not current repaired effects. Use `--rollback RECEIPT --actor AGENT --proposal-id NEW_ID`; inspect both receipts. Versioned quarantine recovery restores only `invalid_at`, preserving validated paired citation usage; protected edits conflict. Legacy receipts require exact images. Prepared rollback still guards the full current image. `cleo doctor repair` remains database recovery.
15
16
 
16
- The ONLY canonical sources of session state are:
17
- - `cleo briefing` — structured handoff + next tasks + BRAIN context
18
- - `cleo focus <id>` — **primary orient surface** — single call replacing 8: identity, scope, blockers, ready wave, docs, git activity, brain context (≤ 1 500 tokens)
19
- - `cleo memory find "<query>"` — BRAIN memory lookup
20
- - `cleo show <taskId> --full` — individual task detail. **Use `--full`.** Bare `cleo show` returns an MVI projection that WITHHOLDS `description` and `verification`; withheld fields are named in `_withheld` (field → size), and a record with no `_withheld` key is complete.
17
+ Use `cleo <command> --help` and the `ct-cleo` skill for command details. Use `cleo show <id> --full` when focus is insufficient: the default projection withholds description and verification, listing them in `_withheld`.
21
18
 
22
- If you find yourself reading a markdown file for orientation, STOP. Run `cleo briefing`.
19
+ Projection markers include omitted empty/null fields and survive repeated projection. `_withheld` maps omitted fields to UTF-8 content bytes (JSON bytes for structured values). A record without `_withheld` is complete. Budgeting preserves coverage, diagnostic failures, authority corrections and pending repair facts before examples. A read budget too small for mandatory facts fails explicitly; request narrower scope or more budget. Never treat this failure as clean coverage.
23
20
 
24
- ## Session Start (cheapest-first)
21
+ An impossible internal mutation budget rejects before execution. If a successful mutation's actual receipt exceeds a viable budget, its success and complete receipt remain available with `_budgetEnforcement.withinBudget: false`; overflow does not mean rollback. Inspect the receipt before retrying a mutation.
25
22
 
26
- **FIRST COMMAND IS ALWAYS `cleo briefing`** — no exceptions.
27
-
28
- 1. `cleo briefing` — canonical session context: handoff note, next tasks, BRAIN digest (~600 tokens)
29
- 2. `cleo session status` — resume existing? (~200 tokens)
30
- 3. `cleo current` — active task? (~100 tokens)
31
- 4. `cleo next` — what to work on (~300 tokens)
32
- 5. `cleo focus {id}` — **preferred orient call** — single envelope with identity + scope + blockers + ready wave + docs + brain context (≤ 1 500 tokens, replaces 8 calls)
33
- 6. `cleo show {id} --full` — the full task record (~400 tokens). Bare `cleo show {id}` is an MVI projection, NOT the full record — see the `_withheld` note under Task Discovery before you act on a field's absence.
34
- 7. `cleo orchestrate start <epicId>` — for epics with ≥ 5 children (~300 tokens, auto-inits LOOM)
35
23
  <!-- /CLEO-INJECTION:section=session-start -->
36
24
 
37
25
  <!-- CLEO-INJECTION:section=work-loop -->
@@ -39,8 +27,8 @@ If you find yourself reading a markdown file for orientation, STOP. Run `cleo br
39
27
 
40
28
  1. `cleo current` or `cleo next` → pick task
41
29
  2. `cleo focus {id}` → orient: identity + blockers + ready wave + docs + brain context (1 call ≤ 1 500 tokens)
42
- 3. Do the work (code, test, document)
43
- 4. `cleo complete {id}` → mark done
30
+ 3. Check authority, coverage, and source evidence; do the work
31
+ 4. Record verification evidence, then `cleo complete {id}` → mark done
44
32
  5. `cleo next` → continue or end session
45
33
  <!-- /CLEO-INJECTION:section=work-loop -->
46
34
 
@@ -54,7 +42,7 @@ If you find yourself reading a markdown file for orientation, STOP. Run `cleo br
54
42
  | Task acceptance criterion contains "test" | Propose an `AcceptanceGate` with `kind:"test"` via `cleo req add` |
55
43
  | Session token budget ≈ 80% consumed | Run `cleo session end --note "..."` and hand off |
56
44
  | Multiple related tasks ready in parallel | Run `cleo orchestrate ready <epicId>` for the wave set |
57
- | About to call `cleo complete` | First: check gates via `cleo show <id>` → run tests → then complete |
45
+ | About to call `cleo complete` | First: check gates via `cleo show <id> --full` → run tests → then complete |
58
46
  | 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/` |
59
47
  | Reading an ADR/spec/research note/handoff | `cleo docs fetch <slug>` — never grep the filesystem for canonical docs |
60
48
  <!-- /CLEO-INJECTION:section=triggers -->
@@ -71,10 +59,11 @@ If you find yourself reading a markdown file for orientation, STOP. Run `cleo br
71
59
  | Preview batch before inserting | `cleo add-batch --file tasks.json --parent <epicId> --dry-run` |
72
60
  | Batch from stdin | `echo '[...]' \| cleo add-batch --file - --parent <epicId>` |
73
61
 
74
- `cleo add-batch` inserts all tasks in a single transaction — ANY failure rolls back ALL inserts.
75
- Use `--dry-run` first; the projected mutation envelope reports `/data/count` and
76
- `/data/wouldCreate` as the predicted create count while `/data/insertedCount` remains `0`.
77
- See `ct-cleo` skill section "Decomposing an epic into N tasks" for the JSON schema and rollback semantic.
62
+ Acceptance input is normalized consistently across add, update, batch, and saga creation: use arrays of strings in JSON parameters, or a JSON-array string / the documented pipe-delimited form for `--acceptance`. Array entries preserve literal pipes and quoted unions. Strings are trimmed and blank strings omitted; nonstring entries or malformed explicit JSON arrays reject the whole mutation. An explicit `[]` on update requests a clear; omitted acceptance stays unchanged. Normalized criteria still obey policy and immutability, including `--reason` for locked changes. Invalid stored criteria are diagnostic failures; never split historical records without original-input provenance and a guarded repair receipt.
63
+
64
+ Explicit `critical` priority on add/update requires a dependency or a nonempty `--depends-waiver`; updates check the resulting dependency set. CLI flags, JSON params, and SDK calls share this policy. Explicit severity changes use the project's signing identity: a nonempty `ownerPubkeys` allowlist restricts signers; an absent or empty list keeps the existing opt-in policy. Unreadable or malformed authority is an explicit configuration failure. Committed severity, duplicate-bypass, and dependency-waiver evidence lives in the task transaction audit. Historical filesystem attestations alone do not prove a task committed. Dry-run creates no committed attestation; failed writes leave no committed receipt.
65
+
66
+ `cleo add-batch` inserts all tasks in a single transaction — ANY failure rolls back ALL inserts. Use `--dry-run` first; the projected mutation envelope reports `/data/count` and `/data/wouldCreate` as the predicted create count while `/data/insertedCount` remains `0`. See `ct-cleo` skill section "Decomposing an epic into N tasks" for the JSON schema and rollback semantic.
78
67
 
79
68
  ### Sagas — PM-Core V2 containment (ADR-088 supersedes ADR-073)
80
69
 
@@ -88,28 +77,56 @@ A **Saga** (`SG-`) is a multi-release theme grouping multiple Epics. `type='saga
88
77
  | List member Epics of a Saga | `cleo saga members <sagaId>` |
89
78
  | Aggregate status across members | `cleo saga rollup <sagaId>` |
90
79
 
91
- Parent matrix: Saga `parent_id IS NULL`; Epic `parent_id` = Saga (or null for standalone);
92
- Task `parent_id` = Epic; Subtask `parent_id` = Task. `task_relations` is non-containment
93
- only — dependencies, ordering, cross-reference, evidence, supersession, provenance.
94
- <!-- /CLEO-INJECTION:section=task-creation -->
80
+ Parent matrix: Saga `parent_id IS NULL`; Epic `parent_id` = Saga (or null for standalone); Task `parent_id` = Epic; Subtask `parent_id` = Task. `task_relations` is non-containment only — dependencies, ordering, cross-reference, evidence, supersession, provenance.
81
+
82
+ ### Depth + decomposition
83
+
84
+ `saga 0 → epic 1 → task 2 → subtask 3`; `hierarchy.maxDepth` (default 3) is the max depth VALUE, **inclusive**, so a subtask under a task is legal. `E_CLEO_DEPTH_EXCEEDED` now means only: you parented under a subtask, the leaf tier. `--type` is honoured verbatim — so `--type subtask --parent <epic>` is REFUSED, not silently retyped. A task is **either** a leaf with its own text ACs **or** a container with children, never both (PM-Core V2 design-point 3) — so the first `cleo add` under a task carrying `--acceptance` text is refused. That is expected. Convert it:
85
+
86
+ | Goal | Command |
87
+ |------|---------|
88
+ | Add the subtask AND convert in one call | `cleo add --type subtask --parent <id> --title "..." --acceptance "..." --auto-decompose` |
89
+ | Convert first, then add normally | `cleo decompose <id>` (`--dry-run`, `--child-title "..."`) |
90
+
91
+ `--auto-decompose` is opt-in: it rewrites the PARENT and reports `autoDecomposed: { childId, movedAcceptance }` — read it, the task you filed is now a container. `cleo update <id> --acceptance ""` does NOT work (enforcement rejects empty).<!-- /CLEO-INJECTION:section=task-creation -->
95
92
 
96
93
  <!-- CLEO-INJECTION:section=task-discovery -->
94
+ ### Overlap reconciliation across a saga
95
+
96
+ `cleo add` checks duplicates only at INSERT time — flat, reject-or-insert — so partial overlap is invisible and post-filing drift is never re-examined. Sweep for it:
97
+
98
+ | Goal | Command |
99
+ |------|---------|
100
+ | Report overlapping scope (read-only) | `cleo reconcile scope <sagaId\|epicId>` |
101
+ | Narrow to strongest signals | `cleo reconcile scope <id> --threshold 0.75` |
102
+ | Write the proposed `relates` edges | `cleo reconcile scope <id> --apply` |
103
+
104
+ Actions: **merge** (same tier+parent, ≥90%) · **absorb** (≥90% across containers) ·
105
+ **split** (shared scope apart — use `cleo decompose`) · **link** (siblings, usually
106
+ intended sequencing). `--apply` writes ONLY `relates` edges — nothing is merged, retitled, reparented or deleted — and the earlier task always survives, so runs are reproducible. Read `link` sceptically: shared naming conventions inflate title similarity. Act on `merge`/`absorb`, which also require a tier+parent match.
107
+
97
108
  ## Task Discovery
98
109
 
110
+ Task search defaults to lexical. For approximate character-subsequence matches, use `cleo find "query" --fuzzy`. Check `match.kind`, `match.fields`, and reason before inferring related work or duplicates. Compact output retains fuzzy provenance; scalar/human output explains it on stderr. `--in title|description|notes|id` restricts fields. Semantic retrieval is separately identified.
111
+
112
+ Compact SDK list/find `_withheld` retains omitted names and original UTF-8 sizes through later CLI projections. Fetch full records; absence is not emptiness.
113
+
114
+ List/find default to excluding archived rows; `--include-archive` applies the same filters to archives. Inspect `data.population` before inferring completeness; `truncated: true` includes nonzero offsets. Budgets cannot silently remove population facts or their rows.
115
+
99
116
  **Use `cleo focus` to orient on a task. Use `cleo find` for discovery. NEVER `cleo list` for browsing.**
100
117
 
101
118
  | Command | ~Tokens | Use |
102
119
  |---------|---------|-----|
103
120
  | `cleo focus <id>` | ≤ 1 500 | **Primary orient surface** — identity + scope + blockers + ready wave + docs + brain context in ONE call |
104
121
  | `cleo find "query"` | 200-400 | Search tasks (default) |
105
- | `cleo show <id> --full` | 300-600 | Full task record (fallback when focus envelope is not sufficient). Bare `cleo show <id>` WITHHOLDS `description` + `verification` and names them in `_withheld`. **Never read a field's absence as "empty" — check `_withheld` first, or pass `--full`.** A record with no `_withheld` key is complete. |
122
+ | `cleo show <id> --full` | 300-600 | Full record beyond focus. Bare show omits description + verification; inspect `_withheld`. |
106
123
  | `cleo list --parent <id>` | 1000-5000 | Direct children only |
107
124
  <!-- /CLEO-INJECTION:section=task-discovery -->
108
125
 
109
126
  <!-- CLEO-INJECTION:section=task-relationships -->
110
127
  ## Task Relationships — depends, blockedBy, relates
111
128
 
112
- CLEO has **three distinct relationship systems**. Do not conflate them.
129
+ Keep these three relationship systems distinct:
113
130
 
114
131
  | System | Semantics | CLI |
115
132
  |--------|-----------|-----|
@@ -117,7 +134,7 @@ CLEO has **three distinct relationship systems**. Do not conflate them.
117
134
  | `blockedBy` | **Free-text reason** why a task is blocked (e.g. "waiting for API key") | `cleo update --blocked-by "reason"` / `--clear-blocked-by` |
118
135
  | `relates` | **Semantic, non-blocking** linkage (`blocks`, `related`, `duplicates`, `absorbs`, `fixes`, `extends`, `supersedes`) | `cleo relates add <from> <to> <type> <reason>` |
119
136
 
120
- **Rule:** `relates` is **never** a blocking dependency. If task B must wait for task A, use `--depends`. `blocked-by` is a human-readable string, not a task ID. For full guidance, see `ct-cleo` skill section "Task Relationship Systems".
137
+ **Rule:** `relates` never blocks execution; use `--depends` to wait for tasks. `blocked-by` takes a reason, not a task ID. Details: `ct-cleo` → "Task Relationship Systems".
121
138
  <!-- /CLEO-INJECTION:section=task-relationships -->
122
139
 
123
140
  <!-- CLEO-INJECTION:section=session-commands -->
@@ -145,14 +162,13 @@ CLEO has **three distinct relationship systems**. Do not conflate them.
145
162
  | LLM status | `cleo memory llm-status` | 50 |
146
163
  | Ground-truth promote | `cleo memory verify <id>` (owner only) | 50 |
147
164
 
148
- Memory context: `cleo memory digest` gives a live project memory summary (this is the default mode; there is no `--brief` flag). Legacy file mode: set `brain.memoryBridge.mode = "file"` in config to restore `@.cleo/memory-bridge.md` injection.
165
+ Memory context: `cleo memory digest` defaults to a live project summary; no `--brief` flag. Set `brain.memoryBridge.mode = "file"` for legacy `@.cleo/memory-bridge.md` injection.
149
166
  <!-- /CLEO-INJECTION:section=memory -->
150
167
 
151
168
  <!-- CLEO-INJECTION:section=data-location -->
152
169
  ## Where the data lives — never read `.cleo/*.db` directly
153
170
 
154
- Store = **`.cleo/cleo.db`**; task rows are in PREFIXED tables (`tasks_tasks`, …).
155
- Three decoys make a HEALTHY project look corrupt:
171
+ Store = **`.cleo/cleo.db`**; task rows are in PREFIXED tables (`tasks_tasks`, …). Three decoys make a HEALTHY project look corrupt:
156
172
 
157
173
  | Decoy | Reality |
158
174
  |-------|---------|
@@ -160,53 +176,35 @@ Three decoys make a HEALTHY project look corrupt:
160
176
  | `.cleo/backups/sqlite/tasks-<ts>.db`, ~100× bigger | Snapshots **of `cleo.db`**; `tasks-` is a legacy label |
161
177
  | bare `tasks` table, 0 rows | Empty relic beside the populated `tasks_tasks` |
162
178
 
163
- A 400 KB `tasks.db` beside 58 MB `tasks-*.db` is the NORMAL migrated layout — not
164
- truncation, not rotation, not `llmtxt.db`. `cleo doctor superseded-store` proves
165
- which DB is real by counting rows in both; `briefing`/`focus` read it already.
166
- <!-- /CLEO-INJECTION:section=data-location -->
167
-
179
+ Small legacy DBs beside large snapshots do not prove corruption. `cleo doctor superseded-store` identifies the live store by row counts; `briefing`/`focus` already read it. Use `cleo backup inspect <snapshot> --record-id <id>` for read-only historical evidence; scoped absence or unknown provenance is not recovery authority.
168
180
 
181
+ <!-- /CLEO-INJECTION:section=data-location -->
169
182
  <!-- CLEO-INJECTION:section=nexus -->
170
183
  ## Nexus — when to use which scope
171
184
 
172
- `cleo nexus` is the code-intelligence surface over THIS repo's symbol graph.
173
- Pick by intent. Every command below is verified to exist — see the gate note.
174
-
175
- | Intent | Command |
176
- |-------------------------------------------|----------------------------------|
177
- | **Check the index before trusting it** | `cleo nexus status` |
178
- | Blast radius before editing a symbol | `cleo nexus impact <symbol>` |
179
- | Callers / callees / community of a symbol | `cleo nexus context <symbol>` |
180
- | Everything about one symbol in one call | `cleo nexus full-context <symbol>` |
181
- | Find a symbol by code text | `cleo nexus search-code "<text>"` |
182
- | Symbols touched by a task | `cleo nexus task-symbols <taskId>` |
183
- | Why does this symbol exist / who needs it | `cleo nexus why <symbol>` |
184
- | Detected communities / execution flows | `cleo nexus clusters` / `flows` |
185
- | Rebuild the index | `cleo nexus analyze` |
186
-
187
- **FIRST CALL IS `cleo nexus status`.** It returns `nodeCount`, `lastIndexedAt`
188
- and `staleFileCount`. The index is NOT auto-refreshed — a symbol added after
189
- the last `analyze` run is simply absent, and a lookup for it returns
190
- `E_NOT_FOUND` that reads identically to "no such symbol". If `staleFileCount`
191
- is a large fraction of `fileCount`, run `cleo nexus analyze` or treat
192
- `git grep` as the ground truth and SAY SO in your response.
193
-
194
- `E_NOT_FOUND` from `impact`/`context` now reports the index size, its median
195
- entry age, and the repair command. Read it — do not infer that nexus is broken.
185
+ `cleo nexus` queries this repo's symbol graph. Commands are checked by the gate below.
186
+
187
+ | Intent | Command |
188
+ | --- | --- |
189
+ | **Check the index before trusting it** | `cleo nexus status` |
190
+ | Blast radius before editing a symbol | `cleo nexus impact <symbol>` |
191
+ | Callers / callees / community of a symbol | `cleo nexus context <symbol>` |
192
+ | Everything about one symbol in one call | `cleo nexus full-context <symbol>` |
193
+ | Find a symbol by code text | `cleo nexus search-code "<text>"` |
194
+ | Symbols touched by a task | `cleo nexus task-symbols <taskId>` |
195
+ | Why does this symbol exist / who needs it | `cleo nexus why <symbol>` |
196
+ | Detected communities / execution flows | `cleo nexus clusters` / `flows` |
197
+ | Rebuild the index | `cleo nexus analyze` |
198
+
199
+ **FIRST CALL IS `cleo nexus status`.** Check `nodeCount`, `lastIndexedAt`, `staleFileCount`/`fileCount`. No auto-refresh: newer symbols may return `E_NOT_FOUND`. For stale coverage, run `cleo nexus analyze` or inspect source with `git grep` and disclose that basis. Impact/context `E_NOT_FOUND` includes index size, median age and a repair command; inspect these first.
196
200
 
197
201
  **Project resolution**: `--project-id` > `--path` > `cwd`.
198
202
  Default ID = `base64url(path).slice(0,32)`.
199
203
 
200
204
  **Rule**: BEFORE editing any symbol, run `cleo nexus impact <symbol>`.
201
- HIGH/CRITICAL = stop and warn. If the index is stale, say that instead of
202
- silently substituting `git grep`.
203
-
204
- > Commands named here are asserted against the live CLI by
205
- > `scripts/lint-injection-commands.mjs` (T12069). Five commands previously
206
- > listed in this section — `nexus report`, `nexus brain find`, `nexus compare`,
207
- > `nexus shared`, `nexus synthesize`, plus `nexus admin` — never existed; the
208
- > gate exists so a protocol that every agent is told to follow can no longer
209
- > drift from the binary.
205
+ HIGH/CRITICAL requires reviewing affected callers before editing. For stale, partial, missing, or failed coverage, inspect source and report the remaining uncertainty. An empty footprint alone never establishes `NONE`.
206
+
207
+ > `scripts/lint-injection-commands.mjs` (T12069) checks these commands against the CLI. Previously documented `nexus report`, `nexus brain find`, `nexus compare`, `nexus shared`, `nexus synthesize`, and `nexus admin` never existed.
210
208
  <!-- /CLEO-INJECTION:section=nexus -->
211
209
 
212
210
  <!-- CLEO-INJECTION:section=orchestration -->
@@ -228,11 +226,11 @@ silently substituting `git grep`.
228
226
  <!-- CLEO-INJECTION:section=playbooks -->
229
227
  ## Worktree-by-Default (T1140 · ADR-055)
230
228
 
231
- Every `cleo orchestrate spawn` auto-provisions a git worktree under `~/.local/share/cleo/worktrees/<projectHash>/<taskId>/`. The spawn prompt includes a `## Worktree Setup (REQUIRED)` section with path, branch name, and `FIRST ACTION: cd <path>`. Agents MUST confine all reads/writes/git ops to the worktree boundary. Integrations use `git merge --no-ff` (ADR-062), preserving commit SHAs and author identity. Skip with `--no-worktree` for meta-tasks.
229
+ `cleo orchestrate spawn` provisions a Git worktree at `~/.local/share/cleo/worktrees/<projectHash>/<taskId>/`. Its required `## Worktree Setup (REQUIRED)` section names the path, branch and `FIRST ACTION: cd <path>`. Confine reads/writes/Git operations there. Integrate with `git merge --no-ff` to preserve commit SHAs and authors (ADR-062). Use `--no-worktree` for meta-tasks.
232
230
 
233
231
  ## Playbook Domain (v2026.4.93 · T910 Orchestration Coherence v4)
234
232
 
235
- `.cantbook` playbooks encode multi-stage agent flows (research → spec → impl → review, release with HITL gate, etc.) as YAML. The playbook runtime is a deterministic state machine with HMAC-signed resume tokens for HITL gates — see `docs/architecture/orchestration-flow.md` (6-layer pipeline) and `.cleo/adrs/ADR-053-playbook-runtime.md` (state-machine decision).
233
+ `.cantbook` YAML encodes staged agent flows. Runtime: deterministic state machine, HMAC-signed HITL resume tokens. References: `docs/architecture/orchestration-flow.md` (6-layer pipeline), `.cleo/adrs/ADR-053-playbook-runtime.md` (state-machine decision).
236
234
 
237
235
  | Goal | Command |
238
236
  |------|---------|
@@ -253,11 +251,11 @@ Starter playbooks ship with `@cleocode/playbooks`: `rcasd.cantbook`, `ivtr.cantb
253
251
  | List valid doc kinds | `cleo docs list-types` |
254
252
  | Generate llms.txt summary | `cleo docs generate --for <taskId>` |
255
253
 
256
- Path policy: use repo-relative paths inside current repo/worktree — do not attach arbitrary external absolute paths from `/tmp` or another checkout. For git-tracked copies, publish via `cleo docs publish --for <ownerId> --to <repo-relative-path>`. Before batch mutations, run `cleo add-batch --dry-run` and verify `/data/insertedCount` = 0. Trust runtime help (`cleo docs list-types`) over stale enum lists for kind selection — `DocKindRegistry` is the runtime source of truth.
254
+ Use current repo-relative paths, never arbitrary external absolute paths (`/tmp`, other checkouts). Publish: `cleo docs publish --for <ownerId> --to <repo-relative-path>`. Before batch writes: `cleo add-batch --dry-run`; require `/data/insertedCount` = 0. Runtime kinds: `cleo docs list-types` / `DocKindRegistry`, not stale lists. Document storage success is separate from optional projection verification. Read `data.projection` after `cleo docs add`: retain coverage, diagnostics, captured project identity, deadline, and any job/receipt reference. Pending work can have an unresolved committed outcome; inspect it before explicit resume, never repeat the add blindly. One two-second maintenance budget covers preparation through verification; timer expiry does not preempt synchronous SQLite. Verify exact bytes with `cleo docs fetch <slug>` JSON `data.bytesBase64` and `data.metadata.sha256`; rendered content can add a newline.
257
255
  <!-- /CLEO-INJECTION:section=documents -->
258
256
  <!-- CLEO-INJECTION:section=human-render -->
259
257
  ## Human Render Contract (ADR-077)
260
- Typed `RenderableEnvelope<T>` from `@cleocode/contracts`. `envelope.data.kind` ∈ `tree | table | list | grouped-list | section | single | generic` — agents route on `kind`. Render logic in `packages/core/src/render/`, primitives in `packages/animations/render/`, icon enums in `@cleocode/contracts/render/icon.ts`. Families self-register via `registerRenderer(command, kind, fn)`. Commands: `cleo show T<id>` (typed), `cleo show T<id> --human` (force), `cleo tree T<id>` (generic walk of parent + `groups` edges).
258
+ Typed `RenderableEnvelope<T>` from `@cleocode/contracts`. `envelope.data.kind` ∈ `tree | table | list | grouped-list | section | single | generic` — agents route on `kind`. Render logic in `packages/core/src/render/`, primitives in `packages/animations/render/`, icon enums in `@cleocode/contracts/render/icon.ts`. Register with `registerRenderer(command, kind, fn)`. Commands: `cleo show T<id>` (typed), `cleo show T<id> --human` (force), `cleo tree T<id>` (generic walk of parent + `groups` edges).
261
259
  <!-- /CLEO-INJECTION:section=human-render -->
262
260
 
263
261
  <!-- CLEO-INJECTION:section=output-contract -->
@@ -268,15 +266,17 @@ Typed `RenderableEnvelope<T>` from `@cleocode/contracts`. `envelope.data.kind`
268
266
  | Need | Flag | Example |
269
267
  |------|------|---------|
270
268
  | Scalar extract | `--field <jsonpointer>` | mutate: `id=$(cleo add 'X' --acceptance "..." --field /data/created/0)` · read: `st=$(cleo show T123 --field /data/task/status)` |
271
- | ID-only pipeline | `--output id` | `cleo list --parent EPIC --output id --limit 0 \| while read c; do …; done` — **`--limit 0` means EVERY match on BOTH `list` and `find`** (gh#1302, fixed). REQUIRED on `list`, which otherwise stops at 10 silently while `--output count` reports the true total. On `find`, `--all` is the same thing with a name. |
272
- | Affected count | `--output count` | `cleo list --parent EPIC --status pending --output count` |
269
+ | ID-only pipeline | `--output id` | `cleo list --parent EPIC --output id --limit 0 \| while read c; do …; done` — **`--limit 0` means EVERY match on BOTH `list` and `find`** (gh#1302, fixed). Without it, list returns a page of 10 and find a page of 20. `--output count` counts the returned rows, agreeing with IDs/table. `data.population` separates matched/returned counts and archive scope; scalar modes disclose these facts on stderr. |
270
+ | Returned/affected count | `--output count` | `cleo list --parent EPIC --status pending --output count` |
273
271
  | TSV (no header) | `--output table` | `cleo list --parent EPIC --output table` |
274
272
  | Silent (exit-code only) | `--output silent` | `cleo update T123 --status done --output silent` |
275
273
  | 1-line per record | `--summary` | `cleo list --parent EPIC --summary` |
276
274
  | Suppress stderr | `--quiet` | `cleo add-batch --file f.json --parent T1 --quiet --output id` |
277
275
  | Force full record | `--full` | `cleo show T123 --full` |
278
276
 
279
- **READ and MUTATE envelopes NEST DIFFERENTLY — the most-guessed-wrong pointer shape.** Mutation envelopes are FLAT (`/data/created/0`); read envelopes nest the record, so `cleo show` needs `/data/task/status`, NEVER `/data/status`. `--field` resolves `description`/`acceptance`/`verification` transparently even under the default projection — no `--full` needed. An unresolvable pointer is a typed `E_FIELD_NOT_FOUND` listing every valid pointer for that op; read it rather than guessing again. `cleo verify`'s own response is SELF-CONFIRMING (it returns the full `verification` object) — do not re-read to check it; if you must, use `--field /data/verification` — `verify` is a MUTATE and its record is FLAT, so the nested `/data/task/...` spelling cannot resolve (gh#1420). Mutate ops (`add`, `add-batch`, `update`, `complete`, `delete`) return `{count, created[], updated[], deleted[], ids[]}` by default (T9931). Use contract-backed paths: `/data/created/0` for create/add-batch, `/data/updated/0` for update/complete, `/data/deleted/0` for delete, and `/data/count` for counts. `ids[]` is a deprecated compatibility alias; opt back to full record via `--full`. Anti-patterns (REJECTED): `cleo show … | tail -1 | jq …`, `cleo list … | jq -r '.data.tasks[].id'`, `cleo add 'X' 2>&1 | grep -oE 'T[0-9]+'`.
277
+ **READ/MUTATE nesting differs:** mutations are FLAT; reads nest: `cleo show` uses `/data/task/status`, NEVER `/data/status`. `--field` resolves projected `description`/`acceptance`/`verification` without `--full`. Unresolvable pointers fail with `E_FIELD_NOT_FOUND` and valid pointers; use those instead of guessing. `cleo verify` returns the full `verification` object, so no confirmation read is needed; its MUTATE extractor is `--field /data/verification`, never `/data/task/...` (gh#1420).
278
+
279
+ Mutations (`add`, `add-batch`, `update`, `complete`, `delete`) return `{count, created[], updated[], deleted[], ids[]}` (T9931). Use `/data/created/0` for create/add-batch, `/data/updated/0` for update/complete, `/data/deleted/0` for delete, `/data/count` for counts. `--output id` emits affected IDs once in created/updated/deleted order. `ids[]` is a deprecated alias; `--full` restores full records. Deletion is a soft archive: `cleo delete <id> --cascade` includes descendants; `--force` alone orphans children and permits dependents. Without either, parents with children are rejected. Receipts retain every affected ID, including cascaded children. Rejected output parsing: `cleo show … | tail -1 | jq …`, `cleo list … | jq -r '.data.tasks[].id'`, `cleo add 'X' 2>&1 | grep -oE 'T[0-9]+'`.
280
280
  <!-- /CLEO-INJECTION:section=output-contract -->
281
281
 
282
282
  <!-- CLEO-INJECTION:section=error-handling -->
@@ -297,20 +297,21 @@ Check exit code (`0` = success) and `"success"` in JSON output after every comma
297
297
  | — | `E_EVIDENCE_TOOL_FAILED` | Tool (biome/tsc/…) exited non-zero; fix source and re-run |
298
298
  | — | `E_EVIDENCE_STALE` | Files/commits changed since `verify`; re-verify with updated evidence |
299
299
  | — | `E_EVIDENCE_INVALID_DECISION` | `decision:<id>` atom — decision ID not found or not accepted/proposed in BRAIN |
300
+ | — | `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 |
300
301
  | — | `E_FLAG_REMOVED` | `cleo complete --force` removed per ADR-051. Use `--evidence` or `CLEO_OWNER_OVERRIDE=1` |
301
302
  | — | `E_IDEMPOTENCY_UNSUPPORTED` | That verb ignores `--idempotency-key`; the key was NOT applied. Query before retrying |
302
303
  | 143 / 137 | *(killed — no code)* | **A killed write carries NO information about whether it committed** |
303
304
 
304
305
  ### A killed write is not a failed write
305
306
 
306
- A 143/137 exit — or a bare exit with no output — says nothing about whether the mutation landed: the commit is fast, the teardown after it is what hangs, so the row is usually THERE. **Never retry a killed mutation blindly.** Check by id first — `cleo show <id> --full`. A HIT is conclusive even while the writer is still hung (the race can hide a committed row, never invent one); a MISS proves nothing until the writer exits. Searching instead of reading by id needs exact flags, because both read paths hide a row you just wrote (`find` excludes archived; `list` truncates at 10 and new children sort last): `cleo find "<title>" --include-archive --all` and `cleo list --parent <id> --limit 0`. `--idempotency-key` does NOT make a retry safe on `add`/`add-batch`/`update`/`docs add`/`memory observe`/`relates add` — those reject it outright.
307
+ A 143/137 exit or missing output does not establish whether a write committed; teardown may hang after commit. **Never retry a killed mutation blindly.** Read `cleo show <id> --full`: a HIT proves presence even while the writer hangs; a MISS proves nothing until it exits. For discovery use `cleo find "<title>" --include-archive --all` or `cleo list --parent <id> --limit 0`; default find hides archives and list shows only 10 rows with new children last. `add`/`add-batch`/`update`/`docs add`/`memory observe`/`relates add` reject `--idempotency-key`; it cannot make their retries safe.
307
308
 
308
309
  <!-- /CLEO-INJECTION:section=error-handling -->
309
310
 
310
311
  <!-- CLEO-INJECTION:section=pre-complete-gate -->
311
312
  ## Pre-Complete Gate Ritual (ADR-051 — evidence required)
312
313
 
313
- MANDATORY before every `cleo complete <id>`. Every gate write MUST be backed by programmatic evidence that CLEO validates against git, the filesystem, or the toolchain. `cleo verify --all` alone is REJECTED with `E_EVIDENCE_MISSING`.
314
+ Before `cleo complete <id>`, every gate requires programmatic evidence validated against git, files or tools. Bare `cleo verify --all` rejects with `E_EVIDENCE_MISSING`.
314
315
 
315
316
  ### 1. Capture evidence for each gate
316
317
 
@@ -325,7 +326,19 @@ Every gate takes `cleo verify T### --gate <gate> --evidence "<atoms>"`:
325
326
  | `securityPassed` | `tool:security-scan` |
326
327
  | `cleanupDone` | `note:removed dead branches` |
327
328
 
328
- A retroactive `pr:<number>` atom (PR MERGED + CI green) satisfies `implemented` + `testsPassed` + `qaPassed` at once — record it against each of the three.
329
+ A merged PR and green CI provide provenance. For `implemented`, pair `pr:<number>` with `files:<changed-paths>`; CLEO checks task linkage, complete changed-file coverage, and the actual merge commit's bytes. Documentation-only PRs cannot implement a code-fix task. Documentation and research tasks may use appropriate documentary artifacts.
330
+
331
+ When a task has canonical acceptance criteria, name the criteria proved by each implementation, test, or review result using existing syntax such as `satisfies:T1234#AC1`. Example: `cleo verify T1234 --gate implemented --evidence "pr:42;files:src/fix.ts;satisfies:T1234#AC1"`. Record `testsPassed` and `qaPassed` separately with actual verification results and explicit criterion links. The receipt retains criterion hashes, artifact paths, and result references; changed criteria require fresh evidence. A valid child completion leaves any parent with unproven criteria open, and a child waiver does not waive parent criteria.
332
+
333
+ ### 1b. Typed acceptance gates — observe before you attest
334
+
335
+ Typed gates (`cleo req add <id> --gate '<json>'`) EXECUTE during any `cleo verify … --gate … --evidence …` write on a task that carries them. To run them without recording anything:
336
+
337
+ ```bash
338
+ cleo verify T### --run # executes typed gates, reports results, persists nothing
339
+ ```
340
+
341
+ `--run` is read-only and cannot be combined with `--gate`/`--all`/`--reset`. A `test` gate with `minCount` needs its OWN command to emit a machine-readable report (`--reporter=json` for vitest, `--json` for jest); an exit code carries no count, and a report file from a separate invocation is not bound to this run — record that as `test-run:<path>` evidence instead.
329
342
 
330
343
  ### 2. Then complete
331
344
 
@@ -344,20 +357,20 @@ cleo memory observe "..." --title "..."
344
357
  ### Emergency override (audited)
345
358
 
346
359
  ```bash
347
- CLEO_OWNER_OVERRIDE=1 \
348
- CLEO_OWNER_OVERRIDE_REASON="incident 1234 hotfix" \
349
- cleo verify T### --all --evidence "note:owner-approved"
360
+ CLEO_OWNER_OVERRIDE=1 \ CLEO_OWNER_OVERRIDE_REASON="incident 1234 hotfix" \ cleo verify T### --gate cleanupDone --evidence "note:owner-approved"
350
361
  ```
351
362
 
352
363
  All overrides append a line to `.cleo/audit/force-bypass.jsonl`. Use sparingly.
353
364
 
354
365
  ### Tool resolution + result cache (ADR-061)
355
366
 
356
- `tool:<name>` evidence resolves via `.cleo/project-context.json` with per-`primaryType` fallbacks. Results cached under `.cleo/cache/evidence/<key>.json`, keyed on `(canonical, cmd, args, HEAD, dirty-tree fingerprint)`. Parallel verifies coalesce; cross-worktree bounded by per-tool semaphore at `~/.local/share/cleo/locks/tool-<canonical>/`. Tune with `CLEO_TOOL_CONCURRENCY_<TOOL>=<n>`. The wall-clock deadline per tool run is per-canonical: **1800000 ms (30 min) for `test` and `build`**, 300000 ms (5 min) for everything else — a suite is not a linter, and a 5 min cap below a real suite meant every run was killed and nothing was ever cached (gh#1221). Override with `CLEO_TOOL_TIMEOUT_<TOOL>=<ms>` (positive integer; invalid values are rejected with a clear error naming the default that applies to THAT tool, never silently ignored). A timed-out run caches nothing, so retrying unchanged fails identically after re-running the whole tool — raise the deadline instead.
367
+ `tool:<name>` resolves through `.cleo/project-context.json` / `primaryType` fallbacks. 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).
357
368
 
358
369
  ### `pr:<number>` retroactive atom (T9764)
359
370
 
360
- Accepts IFF PR `state=MERGED` AND required-workflow checks are `SUCCESS`/`SKIPPED`. Single atom satisfies `implemented` + `testsPassed` + `qaPassed` simultaneously (T9838). Cache under `.cleo/cache/evidence/pr-<num>.json`. **`pr:` is INERT in a repo with no required workflows (gh#1224).** If the project has no `.github/workflows/` — or branch protection lists no required checks — every `pr:` atom is refused with "required gates were not found on this PR", because the checks it looks for never ran. This is exactly the situation in which an agent reaches for `pr:`, so check before you rely on it. Either declare the real check names in `.cleo/project-context.json` → `release.prRequiredWorkflows` (an explicit empty array `[]` means "this repo requires none", and then a MERGED PR alone satisfies the atom), or use `CLEO_PR_REQUIRED_WORKFLOWS`. With neither set, CLEO falls back to a built-in list of ITS OWN gate names (`CI`, `Lockfile Check`, `Contracts Dep Lint`) which will not match your project. In a CI-less repo the honest path is `commit:<sha>;note:<why>` for `implemented` plus `tool:test` / `tool:lint` for the rest.
371
+ `pr:` proves merge provenance, not completion. CLEO checks actual `mergeCommit`, task linkage and changed files; incomplete inventories or unavailable merge artifacts remain unverified. Fetch the merge commit before `files:` evidence. Task `files` must intersect its diff; prose mentions cannot establish scope. Explicit research/spike and documentation scope retain documentary evidence.
372
+
373
+ 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.
361
374
 
362
375
  ### Anti-patterns to avoid
363
376
 
@@ -372,7 +385,7 @@ Accepts IFF PR `state=MERGED` AND required-workflow checks are `SUCCESS`/`SKIPPE
372
385
  <!-- CLEO-INJECTION:section=spawn-tiers -->
373
386
  ## Spawn Prompt Contents (what subagents receive) — T882 / v2.6.0
374
387
 
375
- `cleo orchestrate spawn <taskId>` returns a fully-resolved, self-contained prompt. Subagents never re-resolve protocol content; everything required is embedded. Three tiers control content depth:
388
+ `cleo orchestrate spawn <taskId>` embeds a resolved, self-contained prompt; subagents never re-resolve it. Content tiers:
376
389
 
377
390
  | Tier | Contents |
378
391
  |------|----------|
@@ -380,9 +393,9 @@ Accepts IFF PR `state=MERGED` AND required-workflow checks are `SUCCESS`/`SKIPPE
380
393
  | `1` | tier 0 + full **CLEO-INJECTION.md embed** (this document) — **default** |
381
394
  | `2` | tier 1 + **ct-cleo** + **ct-orchestrator** skill excerpts + **SUBAGENT-PROTOCOL-BLOCK** + anti-patterns |
382
395
 
383
- Invoke with `cleo orchestrate spawn T1234 --tier 0|1|2` — tier 0 for quick workers, tier 2 for autonomous ones; omitting `--tier` gives tier 1.
396
+ `cleo orchestrate spawn T1234 --tier 0|1|2`: tier 0 for quick workers, tier 2 for autonomous ones; default tier 1.
384
397
 
385
- Every spawn prompt contains these required sections, so an orchestrator can programmatically assert their presence before dispatching: `## Task Identity` · `## File Paths (absolute — do not guess)` · `## Session Linkage` · `## Stage-Specific Guidance` · `## Evidence-Based Gate Ritual (MANDATORY · ADR-051 · T832)` · `## Quality Gates` · `## Return Format Contract (MANDATORY)`.
398
+ Before dispatch, assert these required sections: `## Task Identity` · `## File Paths (absolute — do not guess)` · `## Session Linkage` · `## Stage-Specific Guidance` · `## Evidence-Based Gate Ritual (MANDATORY · ADR-051 · T832)` · `## Quality Gates` · `## Return Format Contract (MANDATORY)`.
386
399
  <!-- /CLEO-INJECTION:section=spawn-tiers -->
387
400
 
388
401
  <!-- CLEO-INJECTION:section=rules -->
@@ -409,18 +422,18 @@ Pull context on demand — don't pre-load everything:
409
422
 
410
423
  ### Decision Lookup (prefer BRAIN decision-store over inline ledgers)
411
424
 
412
- Architectural decisions belong in the BRAIN decision-store (`.cleo/brain.db` → `brain_decisions` table) — NOT in adrs markdown blobs or agent-outputs markdown ledgers. Decision IDs in the BRAIN are durable, queryable via `cleo memory decision-find`, and are the canonical reference format for decision citations.
425
+ Store architectural decisions in BRAIN (`.cleo/brain.db` → `brain_decisions`), not Markdown ledgers. Cite durable IDs from `cleo memory decision-find`.
413
426
 
414
427
  **Primary lookup — always try first:**
415
428
  1. `cleo memory decision-find --query <term>` — search BRAIN decision records by keyword
416
429
  2. `cleo memory find <term> --type decision` — broader memory search scoped to decisions
417
430
  3. `cleo memory fetch <id>` — retrieve full decision record by ID
418
431
 
419
- **Decision IDs (D0xx, AGT-*) are NOT globally unique** — same ID can mean different things across documents. BRAIN decisions include source provenance (`source_table`, `source_rowid`) that disambiguates. Always verify the source when citing a decision ID.
432
+ **Decision IDs (D0xx, AGT-*) are NOT globally unique.** Verify BRAIN `source_table`/`source_rowid` when citing; documents can reuse IDs.
420
433
 
421
- **Legacy fallback (last resort only):** `grep -r "D0xx" .cleo/adrs/` then `grep -r "D0xx" .cleo/agent-outputs/`. These are legacy sources being migrated to the decision-store. Prefer BRAIN decisions when available.
434
+ **Historical fallback:** use `cleo docs list` and `cleo docs fetch <slug>` to inspect canonical documents. Preserve their provenance and do not promote historical text over sourced current guidance.
422
435
 
423
- Check outcome status (pending/accepted/superseded). `decision-find` has **no epic filter** — it searches by QUERY text only, so scope it with the epic id as the query (`cleo memory decision-find "<epicId>"`) and read `source_table`/`source_rowid` to confirm provenance.
436
+ Check pending/accepted/superseded status. `decision-find` has **no epic filter**: use query text (`cleo memory decision-find "<epicId>"`) and verify `source_table`/`source_rowid`.
424
437
 
425
438
  Budget: 3 JIT calls per task phase. More = task is underspecified.
426
439
  <!-- /CLEO-INJECTION:section=memory-jit -->