@cleocode/core 2026.9.24 → 2026.9.26

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 (481) hide show
  1. package/dist/admin/import-tasks.d.ts.map +1 -1
  2. package/dist/admin/import-tasks.js +5 -2
  3. package/dist/admin/import-tasks.js.map +1 -1
  4. package/dist/admin/import.d.ts.map +1 -1
  5. package/dist/admin/import.js +7 -2
  6. package/dist/admin/import.js.map +1 -1
  7. package/dist/audit-prune.d.ts +32 -0
  8. package/dist/audit-prune.d.ts.map +1 -1
  9. package/dist/audit-prune.js +37 -3
  10. package/dist/audit-prune.js.map +1 -1
  11. package/dist/build-provenance.json +2 -2
  12. package/dist/cloud/crypto.d.ts +1 -2
  13. package/dist/cloud/crypto.d.ts.map +1 -1
  14. package/dist/cloud/crypto.js +1 -11
  15. package/dist/cloud/crypto.js.map +1 -1
  16. package/dist/cloud/index.d.ts +1 -0
  17. package/dist/cloud/index.d.ts.map +1 -1
  18. package/dist/cloud/index.js +1 -0
  19. package/dist/cloud/index.js.map +1 -1
  20. package/dist/cloud/nexus-auth.d.ts +26 -1
  21. package/dist/cloud/nexus-auth.d.ts.map +1 -1
  22. package/dist/cloud/nexus-auth.js +61 -32
  23. package/dist/cloud/nexus-auth.js.map +1 -1
  24. package/dist/cloud/nexus-credentials.js +2 -2
  25. package/dist/cloud/nexus-credentials.js.map +1 -1
  26. package/dist/cloud/nexus-device.d.ts +809 -0
  27. package/dist/cloud/nexus-device.d.ts.map +1 -0
  28. package/dist/cloud/nexus-device.js +1680 -0
  29. package/dist/cloud/nexus-device.js.map +1 -0
  30. package/dist/cloud/nexus-enrol.d.ts +210 -0
  31. package/dist/cloud/nexus-enrol.d.ts.map +1 -0
  32. package/dist/cloud/nexus-enrol.js +1023 -0
  33. package/dist/cloud/nexus-enrol.js.map +1 -0
  34. package/dist/cloud/nexus-link.d.ts +3 -0
  35. package/dist/cloud/nexus-link.d.ts.map +1 -1
  36. package/dist/cloud/nexus-link.js +38 -4
  37. package/dist/cloud/nexus-link.js.map +1 -1
  38. package/dist/cloud/signing.d.ts +20 -0
  39. package/dist/cloud/signing.d.ts.map +1 -1
  40. package/dist/cloud/signing.js +14 -0
  41. package/dist/cloud/signing.js.map +1 -1
  42. package/dist/cloud/uuidv7.d.ts +9 -0
  43. package/dist/cloud/uuidv7.d.ts.map +1 -0
  44. package/dist/cloud/uuidv7.js +19 -0
  45. package/dist/cloud/uuidv7.js.map +1 -0
  46. package/dist/crypto/credentials.d.ts +61 -0
  47. package/dist/crypto/credentials.d.ts.map +1 -1
  48. package/dist/crypto/credentials.js +154 -58
  49. package/dist/crypto/credentials.js.map +1 -1
  50. package/dist/decide/bench/index.d.ts +1 -1
  51. package/dist/decide/bench/index.d.ts.map +1 -1
  52. package/dist/decide/bench/index.js +1 -1
  53. package/dist/decide/bench/index.js.map +1 -1
  54. package/dist/decide/bench/operation.d.ts +1 -1
  55. package/dist/decide/bench/operation.d.ts.map +1 -1
  56. package/dist/decide/bench/operation.js +1 -1
  57. package/dist/decide/bench/operation.js.map +1 -1
  58. package/dist/decide/bench/profiles.d.ts +50 -22
  59. package/dist/decide/bench/profiles.d.ts.map +1 -1
  60. package/dist/decide/bench/profiles.js +103 -59
  61. package/dist/decide/bench/profiles.js.map +1 -1
  62. package/dist/decide/bench/report.d.ts.map +1 -1
  63. package/dist/decide/bench/report.js +6 -1
  64. package/dist/decide/bench/report.js.map +1 -1
  65. package/dist/decide/bench/runner.d.ts +6 -1
  66. package/dist/decide/bench/runner.d.ts.map +1 -1
  67. package/dist/decide/bench/runner.js +1 -0
  68. package/dist/decide/bench/runner.js.map +1 -1
  69. package/dist/decide/client.d.ts.map +1 -1
  70. package/dist/decide/client.js +11 -5
  71. package/dist/decide/client.js.map +1 -1
  72. package/dist/decide/jev-wire.d.ts +31 -1
  73. package/dist/decide/jev-wire.d.ts.map +1 -1
  74. package/dist/decide/jev-wire.js +61 -7
  75. package/dist/decide/jev-wire.js.map +1 -1
  76. package/dist/docs/export-document.js +12907 -10622
  77. package/dist/docs/export-document.js.map +3 -3
  78. package/dist/doctor/dependency-cycles.d.ts +41 -0
  79. package/dist/doctor/dependency-cycles.d.ts.map +1 -0
  80. package/dist/doctor/dependency-cycles.js +39 -0
  81. package/dist/doctor/dependency-cycles.js.map +1 -0
  82. package/dist/doctor/index.d.ts +2 -0
  83. package/dist/doctor/index.d.ts.map +1 -1
  84. package/dist/doctor/index.js +1 -0
  85. package/dist/doctor/index.js.map +1 -1
  86. package/dist/doctor/orphan-ac-bindings.d.ts +64 -0
  87. package/dist/doctor/orphan-ac-bindings.d.ts.map +1 -0
  88. package/dist/doctor/orphan-ac-bindings.js +59 -0
  89. package/dist/doctor/orphan-ac-bindings.js.map +1 -0
  90. package/dist/doctor/projects.d.ts.map +1 -1
  91. package/dist/doctor/projects.js +43 -29
  92. package/dist/doctor/projects.js.map +1 -1
  93. package/dist/doctor/row-identity.d.ts +42 -0
  94. package/dist/doctor/row-identity.d.ts.map +1 -0
  95. package/dist/doctor/row-identity.js +151 -0
  96. package/dist/doctor/row-identity.js.map +1 -0
  97. package/dist/doctor/twin-collapse.d.ts +58 -2
  98. package/dist/doctor/twin-collapse.d.ts.map +1 -1
  99. package/dist/doctor/twin-collapse.js +212 -14
  100. package/dist/doctor/twin-collapse.js.map +1 -1
  101. package/dist/error-catalog.d.ts.map +1 -1
  102. package/dist/error-catalog.js +4 -0
  103. package/dist/error-catalog.js.map +1 -1
  104. package/dist/error-registry.d.ts.map +1 -1
  105. package/dist/error-registry.js +8 -0
  106. package/dist/error-registry.js.map +1 -1
  107. package/dist/lifecycle/verification/satisfies-validator.d.ts.map +1 -1
  108. package/dist/lifecycle/verification/satisfies-validator.js +10 -0
  109. package/dist/lifecycle/verification/satisfies-validator.js.map +1 -1
  110. package/dist/llm/plugin-facade.js +17767 -15482
  111. package/dist/llm/plugin-facade.js.map +3 -3
  112. package/dist/memory/index.d.ts.map +1 -1
  113. package/dist/memory/index.js +19 -10
  114. package/dist/memory/index.js.map +1 -1
  115. package/dist/memory/manifest-identity.d.ts +171 -0
  116. package/dist/memory/manifest-identity.d.ts.map +1 -0
  117. package/dist/memory/manifest-identity.js +345 -0
  118. package/dist/memory/manifest-identity.js.map +1 -0
  119. package/dist/memory/mental-model-queue.d.ts +14 -4
  120. package/dist/memory/mental-model-queue.d.ts.map +1 -1
  121. package/dist/memory/mental-model-queue.js +64 -35
  122. package/dist/memory/mental-model-queue.js.map +1 -1
  123. package/dist/memory/pipeline-manifest-sqlite.d.ts +47 -5
  124. package/dist/memory/pipeline-manifest-sqlite.d.ts.map +1 -1
  125. package/dist/memory/pipeline-manifest-sqlite.js +130 -14
  126. package/dist/memory/pipeline-manifest-sqlite.js.map +1 -1
  127. package/dist/memory/retrieval/observe.d.ts.map +1 -1
  128. package/dist/memory/retrieval/observe.js +2 -0
  129. package/dist/memory/retrieval/observe.js.map +1 -1
  130. package/dist/memory/transcript-scanner.js +1 -1
  131. package/dist/nexus/deps.d.ts.map +1 -1
  132. package/dist/nexus/deps.js +7 -14
  133. package/dist/nexus/deps.js.map +1 -1
  134. package/dist/nexus/discover.d.ts.map +1 -1
  135. package/dist/nexus/discover.js +6 -9
  136. package/dist/nexus/discover.js.map +1 -1
  137. package/dist/nexus/git-state.d.ts.map +1 -1
  138. package/dist/nexus/git-state.js +10 -1
  139. package/dist/nexus/git-state.js.map +1 -1
  140. package/dist/nexus/projects-clean.d.ts.map +1 -1
  141. package/dist/nexus/projects-clean.js +22 -11
  142. package/dist/nexus/projects-clean.js.map +1 -1
  143. package/dist/nexus/projects-scan.d.ts.map +1 -1
  144. package/dist/nexus/projects-scan.js +8 -13
  145. package/dist/nexus/projects-scan.js.map +1 -1
  146. package/dist/nexus/query.d.ts.map +1 -1
  147. package/dist/nexus/query.js +4 -12
  148. package/dist/nexus/query.js.map +1 -1
  149. package/dist/nexus/registry-roots.d.ts +5 -2
  150. package/dist/nexus/registry-roots.d.ts.map +1 -1
  151. package/dist/nexus/registry-roots.js +8 -10
  152. package/dist/nexus/registry-roots.js.map +1 -1
  153. package/dist/nexus/registry.d.ts +18 -0
  154. package/dist/nexus/registry.d.ts.map +1 -1
  155. package/dist/nexus/registry.js +37 -16
  156. package/dist/nexus/registry.js.map +1 -1
  157. package/dist/nexus/workspace.d.ts.map +1 -1
  158. package/dist/nexus/workspace.js +54 -4
  159. package/dist/nexus/workspace.js.map +1 -1
  160. package/dist/orchestrate/lifecycle-ops.js +1 -1
  161. package/dist/orchestrate/lifecycle-ops.js.map +1 -1
  162. package/dist/orchestrate/pivot.d.ts.map +1 -1
  163. package/dist/orchestrate/pivot.js +4 -2
  164. package/dist/orchestrate/pivot.js.map +1 -1
  165. package/dist/orchestrate/query-ops.d.ts.map +1 -1
  166. package/dist/orchestrate/query-ops.js +3 -3
  167. package/dist/orchestrate/query-ops.js.map +1 -1
  168. package/dist/orchestrate/spawn-ops.js +1 -1
  169. package/dist/orchestrate/spawn-ops.js.map +1 -1
  170. package/dist/orchestrate/worktree-complete.d.ts.map +1 -1
  171. package/dist/orchestrate/worktree-complete.js +40 -2
  172. package/dist/orchestrate/worktree-complete.js.map +1 -1
  173. package/dist/orchestration/index.js +1 -1
  174. package/dist/orchestration/index.js.map +1 -1
  175. package/dist/orchestration/lead-rollup.d.ts.map +1 -1
  176. package/dist/orchestration/lead-rollup.js +3 -3
  177. package/dist/orchestration/lead-rollup.js.map +1 -1
  178. package/dist/orchestration/parallel.js +1 -1
  179. package/dist/orchestration/parallel.js.map +1 -1
  180. package/dist/orchestration/spawn-prompt.d.ts +26 -0
  181. package/dist/orchestration/spawn-prompt.d.ts.map +1 -1
  182. package/dist/orchestration/spawn-prompt.js +62 -91
  183. package/dist/orchestration/spawn-prompt.js.map +1 -1
  184. package/dist/orchestration/wave-topic.d.ts +4 -2
  185. package/dist/orchestration/wave-topic.d.ts.map +1 -1
  186. package/dist/orchestration/wave-topic.js +6 -4
  187. package/dist/orchestration/wave-topic.js.map +1 -1
  188. package/dist/orchestration/waves.d.ts +2 -1
  189. package/dist/orchestration/waves.d.ts.map +1 -1
  190. package/dist/orchestration/waves.js +4 -3
  191. package/dist/orchestration/waves.js.map +1 -1
  192. package/dist/phases/index.d.ts.map +1 -1
  193. package/dist/phases/index.js +4 -2
  194. package/dist/phases/index.js.map +1 -1
  195. package/dist/release/ci-evidence.d.ts +190 -0
  196. package/dist/release/ci-evidence.d.ts.map +1 -1
  197. package/dist/release/ci-evidence.js +436 -4
  198. package/dist/release/ci-evidence.js.map +1 -1
  199. package/dist/sdk/validator-ac-pull.d.ts.map +1 -1
  200. package/dist/sdk/validator-ac-pull.js +2 -1
  201. package/dist/sdk/validator-ac-pull.js.map +1 -1
  202. package/dist/selfimprove/fix-gen.js +12807 -10522
  203. package/dist/selfimprove/fix-gen.js.map +3 -3
  204. package/dist/sentient/cross-project-hygiene.d.ts +5 -0
  205. package/dist/sentient/cross-project-hygiene.d.ts.map +1 -1
  206. package/dist/sentient/cross-project-hygiene.js +7 -1
  207. package/dist/sentient/cross-project-hygiene.js.map +1 -1
  208. package/dist/sentient/propose-tick.d.ts.map +1 -1
  209. package/dist/sentient/propose-tick.js +2 -3
  210. package/dist/sentient/propose-tick.js.map +1 -1
  211. package/dist/sentient/stage-drift-tick.d.ts.map +1 -1
  212. package/dist/sentient/stage-drift-tick.js +2 -3
  213. package/dist/sentient/stage-drift-tick.js.map +1 -1
  214. package/dist/session/engine-ops.d.ts.map +1 -1
  215. package/dist/session/engine-ops.js +77 -49
  216. package/dist/session/engine-ops.js.map +1 -1
  217. package/dist/sessions/focus-state-store.d.ts +69 -23
  218. package/dist/sessions/focus-state-store.d.ts.map +1 -1
  219. package/dist/sessions/focus-state-store.js +113 -27
  220. package/dist/sessions/focus-state-store.js.map +1 -1
  221. package/dist/sessions/handoff.js +1 -1
  222. package/dist/sessions/handoff.js.map +1 -1
  223. package/dist/sessions/index.d.ts.map +1 -1
  224. package/dist/sessions/index.js +24 -13
  225. package/dist/sessions/index.js.map +1 -1
  226. package/dist/sessions/terminal-identity.d.ts +165 -17
  227. package/dist/sessions/terminal-identity.d.ts.map +1 -1
  228. package/dist/sessions/terminal-identity.js +341 -32
  229. package/dist/sessions/terminal-identity.js.map +1 -1
  230. package/dist/skills/manifests/research.js +2 -0
  231. package/dist/skills/manifests/research.js.map +1 -1
  232. package/dist/skills/orchestrator/startup.js +2 -2
  233. package/dist/skills/orchestrator/startup.js.map +1 -1
  234. package/dist/skills/orchestrator/validator.d.ts.map +1 -1
  235. package/dist/skills/orchestrator/validator.js +9 -2
  236. package/dist/skills/orchestrator/validator.js.map +1 -1
  237. package/dist/skills/validation.d.ts +4 -1
  238. package/dist/skills/validation.d.ts.map +1 -1
  239. package/dist/skills/validation.js +11 -3
  240. package/dist/skills/validation.js.map +1 -1
  241. package/dist/snapshot/index.d.ts +4 -0
  242. package/dist/snapshot/index.d.ts.map +1 -1
  243. package/dist/snapshot/index.js +50 -3
  244. package/dist/snapshot/index.js.map +1 -1
  245. package/dist/spawn/branch-lock.d.ts +111 -7
  246. package/dist/spawn/branch-lock.d.ts.map +1 -1
  247. package/dist/spawn/branch-lock.js +296 -8
  248. package/dist/spawn/branch-lock.js.map +1 -1
  249. package/dist/store/ac-binding-prune.d.ts +144 -0
  250. package/dist/store/ac-binding-prune.d.ts.map +1 -0
  251. package/dist/store/ac-binding-prune.js +293 -0
  252. package/dist/store/ac-binding-prune.js.map +1 -0
  253. package/dist/store/agent-registry-store.d.ts.map +1 -1
  254. package/dist/store/agent-registry-store.js +3 -2
  255. package/dist/store/agent-registry-store.js.map +1 -1
  256. package/dist/store/backup-sidecar.d.ts +85 -2
  257. package/dist/store/backup-sidecar.d.ts.map +1 -1
  258. package/dist/store/backup-sidecar.js +173 -1
  259. package/dist/store/backup-sidecar.js.map +1 -1
  260. package/dist/store/conduit-sqlite.d.ts.map +1 -1
  261. package/dist/store/conduit-sqlite.js +3 -2
  262. package/dist/store/conduit-sqlite.js.map +1 -1
  263. package/dist/store/credential-transfer.d.ts.map +1 -1
  264. package/dist/store/credential-transfer.js +3 -0
  265. package/dist/store/credential-transfer.js.map +1 -1
  266. package/dist/store/db-helpers.d.ts +32 -13
  267. package/dist/store/db-helpers.d.ts.map +1 -1
  268. package/dist/store/db-helpers.js +144 -40
  269. package/dist/store/db-helpers.js.map +1 -1
  270. package/dist/store/dependency-cycles.d.ts +164 -0
  271. package/dist/store/dependency-cycles.d.ts.map +1 -0
  272. package/dist/store/dependency-cycles.js +360 -0
  273. package/dist/store/dependency-cycles.js.map +1 -0
  274. package/dist/store/display-id-alias.d.ts +585 -0
  275. package/dist/store/display-id-alias.d.ts.map +1 -0
  276. package/dist/store/display-id-alias.js +1538 -0
  277. package/dist/store/display-id-alias.js.map +1 -0
  278. package/dist/store/dual-scope-db.d.ts.map +1 -1
  279. package/dist/store/dual-scope-db.js +48 -0
  280. package/dist/store/dual-scope-db.js.map +1 -1
  281. package/dist/store/exodus/migrate.d.ts.map +1 -1
  282. package/dist/store/exodus/migrate.js +8 -1
  283. package/dist/store/exodus/migrate.js.map +1 -1
  284. package/dist/store/exodus/reconcile.d.ts.map +1 -1
  285. package/dist/store/exodus/reconcile.js +7 -2
  286. package/dist/store/exodus/reconcile.js.map +1 -1
  287. package/dist/store/exodus/recovery.d.ts.map +1 -1
  288. package/dist/store/exodus/recovery.js +20 -1
  289. package/dist/store/exodus/recovery.js.map +1 -1
  290. package/dist/store/global-salt.d.ts +35 -0
  291. package/dist/store/global-salt.d.ts.map +1 -1
  292. package/dist/store/global-salt.js +136 -16
  293. package/dist/store/global-salt.js.map +1 -1
  294. package/dist/store/legacy-tasks-lineage.d.ts.map +1 -1
  295. package/dist/store/legacy-tasks-lineage.js +19 -2
  296. package/dist/store/legacy-tasks-lineage.js.map +1 -1
  297. package/dist/store/migration-sqlite.d.ts.map +1 -1
  298. package/dist/store/migration-sqlite.js +19 -11
  299. package/dist/store/migration-sqlite.js.map +1 -1
  300. package/dist/store/portable-bundle-scan.d.ts.map +1 -1
  301. package/dist/store/portable-bundle-scan.js +6 -0
  302. package/dist/store/portable-bundle-scan.js.map +1 -1
  303. package/dist/store/row-identity-flag.d.ts +26 -0
  304. package/dist/store/row-identity-flag.d.ts.map +1 -0
  305. package/dist/store/row-identity-flag.js +31 -0
  306. package/dist/store/row-identity-flag.js.map +1 -0
  307. package/dist/store/row-identity-registry.d.ts +61 -0
  308. package/dist/store/row-identity-registry.d.ts.map +1 -0
  309. package/dist/store/row-identity-registry.js +206 -0
  310. package/dist/store/row-identity-registry.js.map +1 -0
  311. package/dist/store/row-identity.d.ts +480 -0
  312. package/dist/store/row-identity.d.ts.map +1 -0
  313. package/dist/store/row-identity.js +1509 -0
  314. package/dist/store/row-identity.js.map +1 -0
  315. package/dist/store/safety-data-accessor.d.ts +5 -2
  316. package/dist/store/safety-data-accessor.d.ts.map +1 -1
  317. package/dist/store/safety-data-accessor.js +9 -2
  318. package/dist/store/safety-data-accessor.js.map +1 -1
  319. package/dist/store/schema/attachments.d.ts +1 -1
  320. package/dist/store/schema/audit.d.ts +4 -4
  321. package/dist/store/schema/background-jobs.d.ts +1 -1
  322. package/dist/store/schema/cleo-global/nexus.d.ts +1 -1
  323. package/dist/store/schema/cleo-global/skills.d.ts +2 -2
  324. package/dist/store/schema/cleo-project/audit.d.ts +4 -4
  325. package/dist/store/schema/cleo-project/docs.d.ts +1 -1
  326. package/dist/store/schema/cleo-project/lifecycle.d.ts +4 -4
  327. package/dist/store/schema/cleo-project/nexus-graph.d.ts +3 -3
  328. package/dist/store/schema/cleo-project/provenance-commits.d.ts +2 -2
  329. package/dist/store/schema/cleo-project/provenance-rest.d.ts +3 -3
  330. package/dist/store/schema/cleo-project/runtime.d.ts +3 -3
  331. package/dist/store/schema/cleo-project/tasks-core-batch2.d.ts +87 -1
  332. package/dist/store/schema/cleo-project/tasks-core-batch2.d.ts.map +1 -1
  333. package/dist/store/schema/cleo-project/tasks-core-batch2.js +35 -0
  334. package/dist/store/schema/cleo-project/tasks-core-batch2.js.map +1 -1
  335. package/dist/store/schema/cleo-project/tasks-core.d.ts +183 -7
  336. package/dist/store/schema/cleo-project/tasks-core.d.ts.map +1 -1
  337. package/dist/store/schema/cleo-project/tasks-core.js +52 -1
  338. package/dist/store/schema/cleo-project/tasks-core.js.map +1 -1
  339. package/dist/store/schema/cleo-shared/brain.d.ts +6 -6
  340. package/dist/store/schema/lifecycle.d.ts +4 -4
  341. package/dist/store/schema/manifest.d.ts +1 -1
  342. package/dist/store/schema/memory-schema.d.ts +5 -5
  343. package/dist/store/schema/nexus-schema.d.ts +3 -3
  344. package/dist/store/schema/provenance/releases.d.ts +1 -1
  345. package/dist/store/schema/skills-schema.d.ts +2 -2
  346. package/dist/store/schema/tasks.d.ts +6 -6
  347. package/dist/store/session-store.d.ts +63 -3
  348. package/dist/store/session-store.d.ts.map +1 -1
  349. package/dist/store/session-store.js +121 -8
  350. package/dist/store/session-store.js.map +1 -1
  351. package/dist/store/split-brain-import.d.ts +2 -14
  352. package/dist/store/split-brain-import.d.ts.map +1 -1
  353. package/dist/store/split-brain-import.js +40 -19
  354. package/dist/store/split-brain-import.js.map +1 -1
  355. package/dist/store/sqlite-data-accessor.d.ts +326 -2
  356. package/dist/store/sqlite-data-accessor.d.ts.map +1 -1
  357. package/dist/store/sqlite-data-accessor.js +782 -49
  358. package/dist/store/sqlite-data-accessor.js.map +1 -1
  359. package/dist/store/sync/clock-store.d.ts +67 -0
  360. package/dist/store/sync/clock-store.d.ts.map +1 -0
  361. package/dist/store/sync/clock-store.js +117 -0
  362. package/dist/store/sync/clock-store.js.map +1 -0
  363. package/dist/store/sync/flags.d.ts +51 -0
  364. package/dist/store/sync/flags.d.ts.map +1 -0
  365. package/dist/store/sync/flags.js +81 -0
  366. package/dist/store/sync/flags.js.map +1 -0
  367. package/dist/store/sync/hlc.d.ts +115 -0
  368. package/dist/store/sync/hlc.d.ts.map +1 -0
  369. package/dist/store/sync/hlc.js +172 -0
  370. package/dist/store/sync/hlc.js.map +1 -0
  371. package/dist/store/sync/index.d.ts +20 -0
  372. package/dist/store/sync/index.d.ts.map +1 -0
  373. package/dist/store/sync/index.js +20 -0
  374. package/dist/store/sync/index.js.map +1 -0
  375. package/dist/store/sync/replica-registry.d.ts +85 -0
  376. package/dist/store/sync/replica-registry.d.ts.map +1 -0
  377. package/dist/store/sync/replica-registry.js +147 -0
  378. package/dist/store/sync/replica-registry.js.map +1 -0
  379. package/dist/store/sync/replica.d.ts +181 -0
  380. package/dist/store/sync/replica.d.ts.map +1 -0
  381. package/dist/store/sync/replica.js +305 -0
  382. package/dist/store/sync/replica.js.map +1 -0
  383. package/dist/store/sync/schema.d.ts +68 -0
  384. package/dist/store/sync/schema.d.ts.map +1 -0
  385. package/dist/store/sync/schema.js +130 -0
  386. package/dist/store/sync/schema.js.map +1 -0
  387. package/dist/store/sync/skew-hold.d.ts +71 -0
  388. package/dist/store/sync/skew-hold.d.ts.map +1 -0
  389. package/dist/store/sync/skew-hold.js +89 -0
  390. package/dist/store/sync/skew-hold.js.map +1 -0
  391. package/dist/store/table-classification.d.ts +10 -8
  392. package/dist/store/table-classification.d.ts.map +1 -1
  393. package/dist/store/table-classification.js +93 -25
  394. package/dist/store/table-classification.js.map +1 -1
  395. package/dist/store/tasks-sqlite.d.ts.map +1 -1
  396. package/dist/store/tasks-sqlite.js +23 -3
  397. package/dist/store/tasks-sqlite.js.map +1 -1
  398. package/dist/store/twin-collapse.d.ts +113 -2
  399. package/dist/store/twin-collapse.d.ts.map +1 -1
  400. package/dist/store/twin-collapse.js +247 -19
  401. package/dist/store/twin-collapse.js.map +1 -1
  402. package/dist/store/umbrella-data-accessor.d.ts +5 -2
  403. package/dist/store/umbrella-data-accessor.d.ts.map +1 -1
  404. package/dist/store/umbrella-data-accessor.js +9 -2
  405. package/dist/store/umbrella-data-accessor.js.map +1 -1
  406. package/dist/store/validation-schemas.d.ts +241 -49
  407. package/dist/store/validation-schemas.d.ts.map +1 -1
  408. package/dist/system/health.d.ts +2 -0
  409. package/dist/system/health.d.ts.map +1 -1
  410. package/dist/system/health.js +57 -0
  411. package/dist/system/health.js.map +1 -1
  412. package/dist/system/project-health.d.ts +9 -2
  413. package/dist/system/project-health.d.ts.map +1 -1
  414. package/dist/system/project-health.js +8 -3
  415. package/dist/system/project-health.js.map +1 -1
  416. package/dist/task-work/index.d.ts.map +1 -1
  417. package/dist/task-work/index.js +9 -6
  418. package/dist/task-work/index.js.map +1 -1
  419. package/dist/tasks/ac-coverage-gate.d.ts.map +1 -1
  420. package/dist/tasks/ac-coverage-gate.js +3 -0
  421. package/dist/tasks/ac-coverage-gate.js.map +1 -1
  422. package/dist/tasks/ac-table.d.ts +35 -7
  423. package/dist/tasks/ac-table.d.ts.map +1 -1
  424. package/dist/tasks/ac-table.js +119 -14
  425. package/dist/tasks/ac-table.js.map +1 -1
  426. package/dist/tasks/add.d.ts.map +1 -1
  427. package/dist/tasks/add.js +48 -2
  428. package/dist/tasks/add.js.map +1 -1
  429. package/dist/tasks/analyze.d.ts.map +1 -1
  430. package/dist/tasks/analyze.js +3 -2
  431. package/dist/tasks/analyze.js.map +1 -1
  432. package/dist/tasks/backfill-child-projections.js +47 -6
  433. package/dist/tasks/backfill-child-projections.js.map +1 -1
  434. package/dist/tasks/complete.d.ts.map +1 -1
  435. package/dist/tasks/complete.js +6 -1
  436. package/dist/tasks/complete.js.map +1 -1
  437. package/dist/tasks/completion-evaluation.d.ts.map +1 -1
  438. package/dist/tasks/completion-evaluation.js +3 -0
  439. package/dist/tasks/completion-evaluation.js.map +1 -1
  440. package/dist/tasks/evidence.d.ts +19 -1
  441. package/dist/tasks/evidence.d.ts.map +1 -1
  442. package/dist/tasks/evidence.js +93 -21
  443. package/dist/tasks/evidence.js.map +1 -1
  444. package/dist/tasks/infer-add-params.js +1 -1
  445. package/dist/tasks/infer-add-params.js.map +1 -1
  446. package/dist/tasks/task-context.d.ts.map +1 -1
  447. package/dist/tasks/task-context.js +3 -1
  448. package/dist/tasks/task-context.js.map +1 -1
  449. package/dist/tasks/task-import.d.ts.map +1 -1
  450. package/dist/tasks/task-import.js +11 -3
  451. package/dist/tasks/task-import.js.map +1 -1
  452. package/dist/tasks/task-next.d.ts +5 -1
  453. package/dist/tasks/task-next.d.ts.map +1 -1
  454. package/dist/tasks/task-next.js +7 -2
  455. package/dist/tasks/task-next.js.map +1 -1
  456. package/dist/validation/compliance.d.ts +5 -1
  457. package/dist/validation/compliance.d.ts.map +1 -1
  458. package/dist/validation/compliance.js +24 -3
  459. package/dist/validation/compliance.js.map +1 -1
  460. package/dist/validation/engine-ops.d.ts.map +1 -1
  461. package/dist/validation/engine-ops.js +3 -2
  462. package/dist/validation/engine-ops.js.map +1 -1
  463. package/dist/validation/index.d.ts +1 -1
  464. package/dist/validation/index.d.ts.map +1 -1
  465. package/dist/validation/index.js +1 -1
  466. package/dist/validation/index.js.map +1 -1
  467. package/dist/validation/protocol-common.d.ts +47 -2
  468. package/dist/validation/protocol-common.d.ts.map +1 -1
  469. package/dist/validation/protocol-common.js +86 -21
  470. package/dist/validation/protocol-common.js.map +1 -1
  471. package/dist/workgraph/scaffold-apply.d.ts.map +1 -1
  472. package/dist/workgraph/scaffold-apply.js +14 -5
  473. package/dist/workgraph/scaffold-apply.js.map +1 -1
  474. package/migrations/README.md +12 -0
  475. package/migrations/drizzle-cleo-project/20260928120000_t12341-row-uids/migration.sql +169 -0
  476. package/migrations/drizzle-cleo-project/20260930160000_t12886-dependency-cycle-guard/migration.sql +76 -0
  477. package/migrations/drizzle-cleo-project/20260930160000_t12886-dependency-cycle-guard/revert.sql +7 -0
  478. package/migrations/sync-journal/20260929140000_t12342-sync-clock/migration.sql +42 -0
  479. package/package.json +13 -13
  480. package/templates/CLEO-INJECTION.md +2 -2
  481. package/templates/CLEO-REFERENCE.md +5 -1
@@ -0,0 +1,345 @@
1
+ /**
2
+ * Manifest identity validation — the entry id, the linked task ids and the
3
+ * file reference of a `pipeline_manifest` entry (T12829).
4
+ *
5
+ * Before this module `cleo manifest append` stored whatever it was given: a
6
+ * `--task` of `T99999` (no such task), a 900-character JSON blob, or
7
+ * `../../x`. The shorthand builder turns `--task` into both the entry id and
8
+ * the `file` reference (`.cleo/agent-outputs/<task>-<type>-<stamp>.md`), and
9
+ * `cleo manifest show` reads `file` relative to the project root. So the blob
10
+ * became an unreadable path (ENAMETOOLONG), and a `../` task made `show` read
11
+ * a file outside the project. Nothing is written to that path; the defect is
12
+ * an unvalidated identity that later flows into a filesystem read.
13
+ *
14
+ * Every check here is pure except {@link findMissingLinkedTasks}, which reads
15
+ * the task store. Append rejects a problem before writing; show refuses a
16
+ * malformed id or unsafe file before touching the filesystem; `cleo doctor
17
+ * manifest-rows` reports rows stored before these checks existed.
18
+ *
19
+ * @module
20
+ * @task T12829
21
+ */
22
+ import { closeSync, constants as fsConstants, fstatSync, openSync, readFileSync, realpathSync, statSync, } from 'node:fs';
23
+ import { isAbsolute, join, relative, sep } from 'node:path';
24
+ import { isStorableTaskId, isTaskId } from '@cleocode/contracts';
25
+ /** Longest accepted manifest entry id. */
26
+ export const MANIFEST_ENTRY_ID_MAX_LENGTH = 200;
27
+ /**
28
+ * Accepted manifest entry id characters: an alphanumeric first character,
29
+ * then alphanumerics and `.`, `_`, `:`, `@`, `+`, `-`. No path separator,
30
+ * whitespace or control character can appear, so an id can never name a
31
+ * path outside the directory it is joined onto.
32
+ */
33
+ export const MANIFEST_ENTRY_ID_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._:@+-]*$/;
34
+ /** Longest accepted `file` reference. */
35
+ export const MANIFEST_FILE_MAX_LENGTH = 1024;
36
+ /** Longest accepted single path segment of a `file` reference (filesystem NAME_MAX). */
37
+ export const MANIFEST_FILE_SEGMENT_MAX_BYTES = 255;
38
+ /** A URI-shaped `file` reference (`cleo://docs/...`); `show` validates these itself. */
39
+ const URI_REFERENCE = /^[a-z][a-z\d+.-]*:/i;
40
+ /** A Windows drive path (`C:\x`, `C:/x`, drive-relative `C:x`), which is a path and not a URI. */
41
+ const WINDOWS_DRIVE = /^[a-z]:/i;
42
+ /** A UNC-looking reference (`\\server\share`, `//server/share`). */
43
+ const UNC_REFERENCE = /^[\\/]{2}/;
44
+ /** Control characters, which no id or path reference may contain. */
45
+ const CONTROL_CHARS = /[\x00-\x1f\x7f]/;
46
+ /**
47
+ * Structured task ids CLEO mints on purpose alongside the canonical `T<digits>`
48
+ * (`T-RECONCILE-FOLLOWUP-v2026.5.63-6`, see `isStorableTaskId`): a `T`, then
49
+ * letters, digits, `.`, `_` and `-` only.
50
+ */
51
+ const STRUCTURED_TASK_ID = /^T[A-Za-z0-9._-]+$/;
52
+ /**
53
+ * Whether `value` is acceptable as a manifest linked task id: the canonical
54
+ * `T<digits>` shape, or a structured `T…` id CLEO mints and stores
55
+ * (`isStorableTaskId`, at most 64 characters, no whitespace or separators).
56
+ * A JSON blob, a path, or an over-long value is never accepted.
57
+ *
58
+ * @param value - Candidate task id.
59
+ * @returns `true` when the value can name a task.
60
+ */
61
+ export function isManifestTaskId(value) {
62
+ if (isTaskId(value))
63
+ return true;
64
+ return typeof value === 'string' && isStorableTaskId(value) && STRUCTURED_TASK_ID.test(value);
65
+ }
66
+ /**
67
+ * Truncate a value for display in an issue so a huge input cannot flood output.
68
+ *
69
+ * @param value - Raw value.
70
+ * @returns At most 120 characters, with an ellipsis and the full length when cut.
71
+ */
72
+ function preview(value) {
73
+ return value.length <= 120 ? value : `${value.slice(0, 120)}… (${value.length} chars)`;
74
+ }
75
+ /**
76
+ * Why a manifest entry id is unacceptable, or `null` when it is fine.
77
+ *
78
+ * @param id - Candidate entry id.
79
+ * @returns A reason, or `null`.
80
+ * @example
81
+ * ```ts
82
+ * manifestEntryIdProblem('T123-implementation-20260929'); // null
83
+ * manifestEntryIdProblem('../../x'); // 'must start with ...'
84
+ * ```
85
+ */
86
+ export function manifestEntryIdProblem(id) {
87
+ if (typeof id !== 'string' || id === '')
88
+ return 'id must be a non-empty string';
89
+ if (id.length > MANIFEST_ENTRY_ID_MAX_LENGTH) {
90
+ return `id is ${id.length} characters; the maximum is ${MANIFEST_ENTRY_ID_MAX_LENGTH}`;
91
+ }
92
+ if (!MANIFEST_ENTRY_ID_PATTERN.test(id)) {
93
+ return 'id must start with a letter or digit and contain only letters, digits and . _ : @ + -';
94
+ }
95
+ return null;
96
+ }
97
+ /**
98
+ * Why a manifest `file` reference is unsafe, or `null` when it is fine.
99
+ *
100
+ * Lexical checks only: an absolute, drive, UNC or backslash path is refused,
101
+ * and the reference joined onto `root` must stay inside `root`. A symbolic
102
+ * link inside the project can still point outside it, so every reader goes
103
+ * through {@link resolveContainedFile} / {@link readContainedFile}, which
104
+ * resolve real paths. URI references are left to `show`, which accepts only
105
+ * `cleo://docs/<reference>`.
106
+ *
107
+ * @param file - Candidate `file` value.
108
+ * @param root - Directory the reference is resolved against.
109
+ * @returns A reason, or `null`.
110
+ */
111
+ export function manifestFileProblem(file, root) {
112
+ if (typeof file !== 'string' || file === '')
113
+ return 'file must be a non-empty string';
114
+ if (file.length > MANIFEST_FILE_MAX_LENGTH) {
115
+ return `file is ${file.length} characters; the maximum is ${MANIFEST_FILE_MAX_LENGTH}`;
116
+ }
117
+ if (CONTROL_CHARS.test(file))
118
+ return 'file must not contain control characters';
119
+ if (UNC_REFERENCE.test(file))
120
+ return 'file must not be a UNC path';
121
+ if (file.includes('\\'))
122
+ return 'file must not contain a backslash';
123
+ if (WINDOWS_DRIVE.test(file))
124
+ return 'file must not be a Windows drive path';
125
+ if (file.startsWith('/') || isAbsolute(file))
126
+ return 'file must be a relative path';
127
+ if (URI_REFERENCE.test(file))
128
+ return null;
129
+ const tooLong = file
130
+ .split(/[\\/]/)
131
+ .find((segment) => Buffer.byteLength(segment, 'utf8') > MANIFEST_FILE_SEGMENT_MAX_BYTES);
132
+ if (tooLong !== undefined) {
133
+ return `file has a path segment longer than ${MANIFEST_FILE_SEGMENT_MAX_BYTES} bytes`;
134
+ }
135
+ const rel = relative(root, join(root, file));
136
+ if (rel === '' || rel === '..' || rel.startsWith(`..${sep}`) || isAbsolute(rel)) {
137
+ return 'file must resolve to a path inside the project';
138
+ }
139
+ return null;
140
+ }
141
+ /**
142
+ * Format checks for a manifest entry's id, linked task ids and file reference
143
+ * (an absent `file` is not checked). Pure: no store access. Pair with {@link findMissingLinkedTasks} to check
144
+ * that the linked tasks exist.
145
+ *
146
+ * @param entry - The entry's identity fields.
147
+ * @param root - Directory `file` is resolved against (the project root).
148
+ * @returns Every problem found; empty when the entry is well formed.
149
+ */
150
+ export function manifestIdentityIssues(entry, root) {
151
+ const issues = [];
152
+ const idProblem = manifestEntryIdProblem(entry.id);
153
+ if (idProblem) {
154
+ issues.push({
155
+ field: 'id',
156
+ code: 'E_VALIDATION',
157
+ value: preview(String(entry.id ?? '')),
158
+ message: idProblem,
159
+ });
160
+ }
161
+ if (entry.linked_tasks !== undefined) {
162
+ if (!Array.isArray(entry.linked_tasks)) {
163
+ issues.push({
164
+ field: 'linked_tasks',
165
+ code: 'E_VALIDATION',
166
+ value: preview(String(entry.linked_tasks)),
167
+ message: 'linked_tasks must be an array of task ids',
168
+ });
169
+ }
170
+ else {
171
+ for (const taskId of entry.linked_tasks) {
172
+ if (!isManifestTaskId(taskId)) {
173
+ issues.push({
174
+ field: 'linked_tasks',
175
+ code: 'E_VALIDATION',
176
+ value: preview(String(taskId)),
177
+ message: 'linked task id must be a task id such as T1234',
178
+ });
179
+ }
180
+ }
181
+ }
182
+ }
183
+ // An absent file is the caller's required-field check; only a present one is resolved.
184
+ const fileProblem = entry.file === undefined ? null : manifestFileProblem(entry.file, root);
185
+ if (fileProblem) {
186
+ issues.push({
187
+ field: 'file',
188
+ code: 'E_VALIDATION',
189
+ value: preview(String(entry.file ?? '')),
190
+ message: fileProblem,
191
+ });
192
+ }
193
+ return issues;
194
+ }
195
+ /**
196
+ * The well-formed linked task ids that name no task in the project store
197
+ * (archived tasks count as existing).
198
+ *
199
+ * @param taskIds - Linked task ids; malformed ones are skipped (format checks report them).
200
+ * @param projectRoot - Project whose task store is consulted.
201
+ * @returns The ids with no task, in input order, without duplicates.
202
+ */
203
+ export async function findMissingLinkedTasks(taskIds, projectRoot) {
204
+ const wellFormed = [...new Set(taskIds.filter((id) => isManifestTaskId(id)))];
205
+ if (wellFormed.length === 0)
206
+ return [];
207
+ const { getTaskAccessor } = await import('../store/data-accessor.js');
208
+ const accessor = await getTaskAccessor(projectRoot);
209
+ const missing = [];
210
+ for (const id of wellFormed) {
211
+ if (!(await accessor.taskExists(id)))
212
+ missing.push(id);
213
+ }
214
+ return missing;
215
+ }
216
+ /**
217
+ * The error code carried by a thrown filesystem error, when it has one.
218
+ *
219
+ * @param error - Caught value.
220
+ * @returns The `code` string, or `undefined`.
221
+ */
222
+ function errnoCode(error) {
223
+ return error instanceof Error && 'code' in error && typeof error.code === 'string'
224
+ ? error.code
225
+ : undefined;
226
+ }
227
+ /** Filesystem errors that mean "nothing is there" for a manifest reference. */
228
+ const NOT_FOUND_CODES = new Set(['ENOENT', 'ENOTDIR']);
229
+ /**
230
+ * Whether `realTarget` lies strictly inside `realRoot` (separator-safe: a
231
+ * sibling `/proj-evil` is not inside `/proj`).
232
+ *
233
+ * @param realRoot - Real (symlink-free) root directory.
234
+ * @param realTarget - Real (symlink-free) candidate path.
235
+ * @returns `true` when the target is a descendant of the root.
236
+ */
237
+ function isInsideRealRoot(realRoot, realTarget) {
238
+ const prefix = realRoot.endsWith(sep) ? realRoot : `${realRoot}${sep}`;
239
+ return realTarget.startsWith(prefix);
240
+ }
241
+ /**
242
+ * Resolve a manifest `file` reference to its real path, requiring it to stay
243
+ * inside `root` after every symbolic link is followed (T12829).
244
+ *
245
+ * {@link manifestFileProblem} is lexical: `link/secret.txt` passes when
246
+ * `link` is an in-project symlink to a directory outside the project. This
247
+ * resolves both the root and the target with `realpathSync` and requires the
248
+ * real target under the real root. A missing target (or a dangling link) is
249
+ * `not-found` and must not be read; a URI reference is `unsafe` here because
250
+ * it is not a filesystem path.
251
+ *
252
+ * @param root - Directory the reference is resolved against.
253
+ * @param file - The stored `file` reference.
254
+ * @returns The resolution; only `ok` may be read, and only via `realPath`.
255
+ * @throws The underlying filesystem error for anything other than not-found or a link loop.
256
+ * @example
257
+ * ```ts
258
+ * resolveContainedFile('/proj', 'link/secret.txt'); // { status: 'unsafe', ... } when link -> ../outside
259
+ * ```
260
+ */
261
+ export function resolveContainedFile(root, file) {
262
+ const problem = manifestFileProblem(file, root);
263
+ if (problem)
264
+ return { status: 'unsafe', reason: problem };
265
+ if (typeof file !== 'string' || URI_REFERENCE.test(file)) {
266
+ return { status: 'unsafe', reason: 'file must be a filesystem path, not a URI' };
267
+ }
268
+ let realRoot;
269
+ let realTarget;
270
+ try {
271
+ realRoot = realpathSync(root);
272
+ realTarget = realpathSync(join(realRoot, file));
273
+ }
274
+ catch (error) {
275
+ const code = errnoCode(error);
276
+ if (code !== undefined && NOT_FOUND_CODES.has(code))
277
+ return { status: 'not-found' };
278
+ if (code === 'ELOOP')
279
+ return { status: 'unsafe', reason: 'file is a symbolic link loop' };
280
+ throw error;
281
+ }
282
+ if (!isInsideRealRoot(realRoot, realTarget)) {
283
+ return {
284
+ status: 'unsafe',
285
+ reason: 'file resolves (through a symbolic link) outside the project',
286
+ };
287
+ }
288
+ return { status: 'ok', realPath: realTarget };
289
+ }
290
+ /**
291
+ * Read a manifest `file` reference as UTF-8 text, only when its real path is
292
+ * inside `root` (see {@link resolveContainedFile}).
293
+ *
294
+ * The resolved real path is opened once, without following a final symbolic
295
+ * link and without blocking on a FIFO, and the content is read through that
296
+ * file descriptor. After opening, the path is re-resolved and must still name
297
+ * the same inode, so a component swapped for a link between the check and the
298
+ * open is refused rather than read.
299
+ *
300
+ * @param root - Directory the reference is resolved against.
301
+ * @param file - The stored `file` reference.
302
+ * @returns The content, or why it was not read.
303
+ * @throws The underlying filesystem error for failures other than not-found
304
+ * (a directory throws `EISDIR`).
305
+ */
306
+ export function readContainedFile(root, file) {
307
+ const resolved = resolveContainedFile(root, file);
308
+ if (resolved.status !== 'ok')
309
+ return resolved;
310
+ const flags = fsConstants.O_RDONLY | (fsConstants.O_NOFOLLOW ?? 0) | (fsConstants.O_NONBLOCK ?? 0);
311
+ let fd;
312
+ try {
313
+ fd = openSync(resolved.realPath, flags);
314
+ }
315
+ catch (error) {
316
+ const code = errnoCode(error);
317
+ if (code !== undefined && NOT_FOUND_CODES.has(code))
318
+ return { status: 'not-found' };
319
+ if (code === 'ELOOP') {
320
+ return { status: 'unsafe', reason: 'file changed into a symbolic link while being read' };
321
+ }
322
+ throw error;
323
+ }
324
+ try {
325
+ const opened = fstatSync(fd);
326
+ // A directory falls through to the read, which fails with EISDIR like any
327
+ // other read failure; a FIFO, socket or device is never read.
328
+ if (!opened.isFile() && !opened.isDirectory()) {
329
+ return { status: 'unsafe', reason: 'file is not a regular file' };
330
+ }
331
+ const again = resolveContainedFile(root, file);
332
+ if (again.status !== 'ok' || again.realPath !== resolved.realPath) {
333
+ return { status: 'unsafe', reason: 'file changed while being read' };
334
+ }
335
+ const current = statSync(again.realPath);
336
+ if (current.dev !== opened.dev || current.ino !== opened.ino) {
337
+ return { status: 'unsafe', reason: 'file changed while being read' };
338
+ }
339
+ return { status: 'ok', realPath: resolved.realPath, content: readFileSync(fd, 'utf-8') };
340
+ }
341
+ finally {
342
+ closeSync(fd);
343
+ }
344
+ }
345
+ //# sourceMappingURL=manifest-identity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest-identity.js","sourceRoot":"","sources":["../../src/memory/manifest-identity.ts"],"names":[],"mappings":"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"}
@@ -7,10 +7,20 @@
7
7
  * decouples the hot path (agent execution) from I/O latency.
8
8
  *
9
9
  * The queue is drained to brain.db either:
10
- * 1. Periodically — every {@link FLUSH_INTERVAL_MS} milliseconds via a timer.
11
- * 2. On high watermark — when the queue exceeds {@link FLUSH_WATERMARK} entries.
12
- * 3. On process exit — SIGINT, SIGTERM, and 'exit' hooks perform a best-effort
13
- * synchronous flush so no observations are lost.
10
+ * 1. Promptly — every `enqueue` schedules a drain on the next macrotask
11
+ * (`setImmediate`, NOT unref'd), so observations enqueued in the same tick
12
+ * are written as one batch and the caller's promise always settles (T12817).
13
+ * 2. Periodically — every {@link FLUSH_INTERVAL_MS} milliseconds via a timer
14
+ * (backstop; unref'd).
15
+ * 3. On high watermark — when the queue exceeds {@link FLUSH_WATERMARK} entries.
16
+ * 4. On process exit — SIGINT, SIGTERM, and 'exit' hooks perform a best-effort
17
+ * flush.
18
+ *
19
+ * T12817: before the prompt drain existed, the ONLY drain a one-shot process
20
+ * could reach was the unref'd 5 s timer. `enqueue()` returned a promise that
21
+ * only that timer could settle, so an awaited `cleo memory observe --agent X`
22
+ * left the event loop empty: Node exited 0 with zero bytes on stdout and the
23
+ * `'exit'` hook's async drain never ran — the observation was silently lost.
14
24
  *
15
25
  * Observations without an `agent` field continue to use the existing synchronous
16
26
  * path in observeBrain() and are never routed here.
@@ -1 +1 @@
1
- {"version":3,"file":"mental-model-queue.d.ts","sourceRoot":"","sources":["../../src/memory/mental-model-queue.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AA4BnF;;;;;;;;;;GAUG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;;;;;;OAQG;IACH,OAAO,CACL,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,kBAAkB,GAAG;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,GAC7C,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAE/B;;;;;;;OAOG;IACH,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAEzB,2DAA2D;IAC3D,IAAI,IAAI,MAAM,CAAC;CAChB;AAiJD;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,EAAE,gBAyC9B,CAAC;AAMF;;;;;;;;GAQG;AACH,wBAAgB,8BAA8B,IAAI,IAAI,CAgBrD;AAED;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAI5E"}
1
+ {"version":3,"file":"mental-model-queue.d.ts","sourceRoot":"","sources":["../../src/memory/mental-model-queue.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AA4BnF;;;;;;;;;;GAUG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;;;;;;OAQG;IACH,OAAO,CACL,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,kBAAkB,GAAG;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,GAC7C,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAE/B;;;;;;;OAOG;IACH,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAEzB,2DAA2D;IAC3D,IAAI,IAAI,MAAM,CAAC;CAChB;AA8KD;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,EAAE,gBA8B9B,CAAC;AAMF;;;;;;;;GAQG;AACH,wBAAgB,8BAA8B,IAAI,IAAI,CAoBrD;AAED;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAI5E"}
@@ -7,10 +7,20 @@
7
7
  * decouples the hot path (agent execution) from I/O latency.
8
8
  *
9
9
  * The queue is drained to brain.db either:
10
- * 1. Periodically — every {@link FLUSH_INTERVAL_MS} milliseconds via a timer.
11
- * 2. On high watermark — when the queue exceeds {@link FLUSH_WATERMARK} entries.
12
- * 3. On process exit — SIGINT, SIGTERM, and 'exit' hooks perform a best-effort
13
- * synchronous flush so no observations are lost.
10
+ * 1. Promptly — every `enqueue` schedules a drain on the next macrotask
11
+ * (`setImmediate`, NOT unref'd), so observations enqueued in the same tick
12
+ * are written as one batch and the caller's promise always settles (T12817).
13
+ * 2. Periodically — every {@link FLUSH_INTERVAL_MS} milliseconds via a timer
14
+ * (backstop; unref'd).
15
+ * 3. On high watermark — when the queue exceeds {@link FLUSH_WATERMARK} entries.
16
+ * 4. On process exit — SIGINT, SIGTERM, and 'exit' hooks perform a best-effort
17
+ * flush.
18
+ *
19
+ * T12817: before the prompt drain existed, the ONLY drain a one-shot process
20
+ * could reach was the unref'd 5 s timer. `enqueue()` returned a promise that
21
+ * only that timer could settle, so an awaited `cleo memory observe --agent X`
22
+ * left the event loop empty: Node exited 0 with zero bytes on stdout and the
23
+ * `'exit'` hook's async drain never ran — the observation was silently lost.
14
24
  *
15
25
  * Observations without an `agent` field continue to use the existing synchronous
16
26
  * path in observeBrain() and are never routed here.
@@ -45,12 +55,18 @@ const MENTAL_MODEL_TYPES = new Set([
45
55
  // ---------------------------------------------------------------------------
46
56
  /** In-memory queue of pending mental-model observations. */
47
57
  const _queue = [];
48
- /** Whether a flush is currently in progress (prevents re-entrant flushes). */
49
- let _flushing = false;
50
58
  /** Whether process-exit hooks have been registered. */
51
59
  let _hooksRegistered = false;
52
60
  /** Handle for the periodic flush timer (undefined = no active timer). */
53
61
  let _timer;
62
+ /** Handle for the pending prompt drain (undefined = none scheduled). T12817 */
63
+ let _immediate;
64
+ /**
65
+ * Tail of the serialized drain chain. Every drain runs after the previous one
66
+ * settles, so entries enqueued while a drain is in flight are picked up by the
67
+ * next link instead of waiting for the unref'd timer. T12817
68
+ */
69
+ let _drainTail = Promise.resolve();
54
70
  /**
55
71
  * Drain the queue synchronously where possible, or fall back to async writes.
56
72
  * Returns when all observations in the current batch have been persisted.
@@ -76,6 +92,33 @@ async function drainQueue() {
76
92
  }
77
93
  return count;
78
94
  }
95
+ /**
96
+ * Run {@link drainQueue} after every earlier drain has settled.
97
+ *
98
+ * @returns The number of observations this drain persisted.
99
+ */
100
+ function serialDrain() {
101
+ const next = _drainTail.then(() => drainQueue());
102
+ _drainTail = next.catch(() => undefined);
103
+ return next;
104
+ }
105
+ /**
106
+ * Schedule a prompt drain on the next macrotask (T12817).
107
+ *
108
+ * The handle is deliberately NOT unref'd: an enqueued observation is pending
109
+ * I/O the process owes its caller, so it must keep the event loop alive until
110
+ * written. Entries enqueued in the same tick share one drain.
111
+ */
112
+ function schedulePromptDrain() {
113
+ if (_immediate !== undefined)
114
+ return;
115
+ _immediate = setImmediate(() => {
116
+ _immediate = undefined;
117
+ serialDrain().catch(() => {
118
+ /* per-entry errors already rejected their callers */
119
+ });
120
+ });
121
+ }
79
122
  /**
80
123
  * Best-effort synchronous exit flush.
81
124
  * Used in 'exit' event handler where async I/O is not guaranteed.
@@ -137,15 +180,8 @@ function ensureTimer() {
137
180
  _timer = setInterval(() => {
138
181
  if (_queue.length === 0)
139
182
  return;
140
- if (_flushing)
141
- return;
142
- _flushing = true;
143
- drainQueue()
144
- .catch(() => {
183
+ serialDrain().catch(() => {
145
184
  /* best-effort */
146
- })
147
- .finally(() => {
148
- _flushing = false;
149
185
  });
150
186
  }, FLUSH_INTERVAL_MS);
151
187
  // Unref so the timer doesn't prevent process exit when queue is idle
@@ -168,31 +204,20 @@ export const mentalModelQueue = {
168
204
  ensureTimer();
169
205
  return new Promise((resolve, reject) => {
170
206
  _queue.push({ projectRoot, params, resolve, reject });
171
- // High-watermark flush
172
- if (_queue.length >= FLUSH_WATERMARK && !_flushing) {
173
- _flushing = true;
174
- drainQueue()
175
- .catch(() => {
207
+ if (_queue.length >= FLUSH_WATERMARK) {
208
+ // High-watermark flush
209
+ serialDrain().catch(() => {
176
210
  /* best-effort */
177
- })
178
- .finally(() => {
179
- _flushing = false;
180
211
  });
181
212
  }
213
+ else {
214
+ // T12817: guarantee the caller's promise settles in a one-shot process.
215
+ schedulePromptDrain();
216
+ }
182
217
  });
183
218
  },
184
- async flush() {
185
- if (_flushing) {
186
- // Wait for the current flush to settle then flush again
187
- await new Promise((r) => setTimeout(r, 50));
188
- }
189
- _flushing = true;
190
- try {
191
- return await drainQueue();
192
- }
193
- finally {
194
- _flushing = false;
195
- }
219
+ flush() {
220
+ return serialDrain();
196
221
  },
197
222
  size() {
198
223
  return _queue.length;
@@ -216,13 +241,17 @@ export function _resetMentalModelQueueForTests() {
216
241
  clearInterval(_timer);
217
242
  _timer = undefined;
218
243
  }
244
+ if (_immediate !== undefined) {
245
+ clearImmediate(_immediate);
246
+ _immediate = undefined;
247
+ }
248
+ _drainTail = Promise.resolve();
219
249
  // Reject all pending observations so test assertions can proceed.
220
250
  const pending = _queue.splice(0, _queue.length);
221
251
  const cancelErr = new Error('[test teardown] mental-model queue reset');
222
252
  for (const entry of pending) {
223
253
  entry.reject(cancelErr);
224
254
  }
225
- _flushing = false;
226
255
  _hooksRegistered = false;
227
256
  }
228
257
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"mental-model-queue.js","sourceRoot":"","sources":["../../src/memory/mental-model-queue.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mental-model-queue.js","sourceRoot":"","sources":["../../src/memory/mental-model-queue.ts"],"names":[],"mappings":"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"}
@@ -16,6 +16,7 @@ import { docsPipelineManifest as pipelineManifest } from '../store/schema/cleo-p
16
16
  declare function getBinding(cwd?: string): Promise<import("../db/index.js").DomainBinding<import("drizzle-orm/node-sqlite/driver").NodeSQLiteDatabase<import("drizzle-orm").EmptyRelations>, import("../store/dual-scope-db.js").ProjectStore>>;
17
17
  import type { ContradictionDetail, ExtendedManifestEntry, ResearchFilter, SupersededDetail } from './index.js';
18
18
  import { filterManifestEntries } from './manifest-filter.js';
19
+ import { type ManifestIdentityIssue } from './manifest-identity.js';
19
20
  export type ManifestEntry = ExtendedManifestEntry;
20
21
  export type { ContradictionDetail, ResearchFilter, SupersededDetail };
21
22
  export { filterManifestEntries };
@@ -84,6 +85,26 @@ export declare function readManifestEntriesSkippingMalformed(projectRoot?: strin
84
85
  * @task T12686
85
86
  */
86
87
  export declare function listMalformedManifestRows(projectRoot?: string): Promise<MalformedManifestRow[]>;
88
+ /** A stored manifest row whose id, linked task ids or file reference fails T12829 validation. */
89
+ export interface ManifestIdentityProblemRow {
90
+ /** Manifest entry id, truncated to 120 characters for display. */
91
+ entryId: string;
92
+ /** Tables holding the row (`docs_pipeline_manifest`, legacy `pipeline_manifest`). */
93
+ tables: string[];
94
+ /** The problems: `E_VALIDATION` (malformed or unsafe) or `E_NOT_FOUND` (linked task missing). */
95
+ issues: ManifestIdentityIssue[];
96
+ }
97
+ /**
98
+ * List every stored manifest row (archived included) whose entry id, linked
99
+ * task ids or file reference would be rejected by append today, and every
100
+ * well-formed linked task id that names no task. Read-only: the rows predate
101
+ * T12829 validation and are reported, never rewritten.
102
+ *
103
+ * @param projectRoot - Project root.
104
+ * @returns The offending rows, each with its problems.
105
+ * @task T12829
106
+ */
107
+ export declare function listManifestIdentityProblems(projectRoot?: string): Promise<ManifestIdentityProblemRow[]>;
87
108
  /** One row a repair rewrote: its metadata before and after. */
88
109
  export interface ManifestRepairChange {
89
110
  entryId: string;
@@ -182,8 +203,22 @@ export declare function pipelineManifestPending(epicId?: string, projectRoot?: s
182
203
  export declare function pipelineManifestStats(epicId?: string, projectRoot?: string): Promise<EngineResult>;
183
204
  /** pipeline.manifest.read - Read manifest entries with optional filter */
184
205
  export declare function pipelineManifestRead(filter?: ResearchFilter, projectRoot?: string): Promise<EngineResult>;
185
- /** Append to canonical manifest storage after checking both histories for unresolved identities. */
186
- export declare function pipelineManifestAppend(entry: ExtendedManifestEntry, projectRoot?: string): Promise<EngineResult>;
206
+ /** Options for {@link pipelineManifestAppend}. */
207
+ export interface PipelineManifestAppendOptions {
208
+ /**
209
+ * Reject an entry whose linked task ids name no task in the project store
210
+ * (`E_NOT_FOUND`). The CLI/dispatch path sets it; direct SDK callers that
211
+ * record manifests for tasks held elsewhere may leave it off. Format checks
212
+ * on the id, linked task ids and file reference always run (T12829).
213
+ */
214
+ requireExistingTasks?: boolean;
215
+ }
216
+ /**
217
+ * Append to canonical manifest storage after checking both histories for
218
+ * unresolved identities. The entry id, linked task ids and file reference are
219
+ * validated first (T12829): no input can name a path outside the project.
220
+ */
221
+ export declare function pipelineManifestAppend(entry: ExtendedManifestEntry, projectRoot?: string, options?: PipelineManifestAppendOptions): Promise<EngineResult>;
187
222
  /** pipeline.manifest.archive - Archive old manifest entries by date */
188
223
  export declare function pipelineManifestArchive(beforeDate: string, projectRoot?: string): Promise<EngineResult>;
189
224
  /** pipeline.manifest.compact - Dedup by contentHash (keep newest by createdAt) */
@@ -245,13 +280,20 @@ export declare function filterEntries(entries: ExtendedManifestEntry[], filter:
245
280
  export declare function distillManifestEntry(_entryId: string, _projectRoot?: string): Promise<EngineResult>;
246
281
  /**
247
282
  * Migrate existing .cleo/MANIFEST.jsonl entries into the pipeline_manifest table.
248
- * Skips entries that already exist (by id). Renames MANIFEST.jsonl to
249
- * MANIFEST.jsonl.migrated when done.
283
+ * Skips entries that already exist (by id). Entries whose id, linked task ids
284
+ * or file reference fail the T12829 identity checks are skipped, not inserted,
285
+ * and listed in `invalid`. Renames MANIFEST.jsonl to MANIFEST.jsonl.migrated
286
+ * when done.
250
287
  *
251
- * @returns Count of migrated and skipped entries.
288
+ * @returns Count of migrated and skipped entries (skipped includes invalid ones),
289
+ * and every entry refused for an identity problem.
252
290
  */
253
291
  export declare function migrateManifestJsonlToSqlite(projectRoot?: string): Promise<{
254
292
  migrated: number;
255
293
  skipped: number;
294
+ invalid: Array<{
295
+ entryId: string;
296
+ issues: ManifestIdentityIssue[];
297
+ }>;
256
298
  }>;
257
299
  //# sourceMappingURL=pipeline-manifest-sqlite.d.ts.map