@cleocode/core 2026.6.12 → 2026.6.13

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 (385) hide show
  1. package/dist/conduit/local-transport.d.ts +12 -0
  2. package/dist/conduit/local-transport.d.ts.map +1 -1
  3. package/dist/conduit/local-transport.js +53 -23
  4. package/dist/conduit/local-transport.js.map +1 -1
  5. package/dist/crypto/credentials.d.ts +37 -0
  6. package/dist/crypto/credentials.d.ts.map +1 -1
  7. package/dist/crypto/credentials.js +110 -0
  8. package/dist/crypto/credentials.js.map +1 -1
  9. package/dist/dispatch/contracts/derive-output-contract.d.ts +86 -0
  10. package/dist/dispatch/contracts/derive-output-contract.d.ts.map +1 -0
  11. package/dist/dispatch/contracts/derive-output-contract.js +347 -0
  12. package/dist/dispatch/contracts/derive-output-contract.js.map +1 -0
  13. package/dist/dispatch/contracts/ensures-schema.d.ts +77 -0
  14. package/dist/dispatch/contracts/ensures-schema.d.ts.map +1 -0
  15. package/dist/dispatch/contracts/ensures-schema.js +91 -0
  16. package/dist/dispatch/contracts/ensures-schema.js.map +1 -0
  17. package/dist/dispatch/contracts/output-contracts.d.ts +27 -5
  18. package/dist/dispatch/contracts/output-contracts.d.ts.map +1 -1
  19. package/dist/dispatch/contracts/output-contracts.js +29 -6
  20. package/dist/dispatch/contracts/output-contracts.js.map +1 -1
  21. package/dist/docs/export-document.js +2294 -1250
  22. package/dist/docs/export-document.js.map +3 -3
  23. package/dist/go/driver.d.ts +132 -7
  24. package/dist/go/driver.d.ts.map +1 -1
  25. package/dist/go/driver.js +135 -10
  26. package/dist/go/driver.js.map +1 -1
  27. package/dist/go/index.d.ts +1 -1
  28. package/dist/go/index.d.ts.map +1 -1
  29. package/dist/go/index.js +1 -1
  30. package/dist/go/index.js.map +1 -1
  31. package/dist/index.d.ts +1 -0
  32. package/dist/index.d.ts.map +1 -1
  33. package/dist/index.js +5 -0
  34. package/dist/index.js.map +1 -1
  35. package/dist/internal.d.ts +13 -10
  36. package/dist/internal.d.ts.map +1 -1
  37. package/dist/internal.js +11 -11
  38. package/dist/internal.js.map +1 -1
  39. package/dist/lifecycle/engine-ops.d.ts.map +1 -1
  40. package/dist/lifecycle/engine-ops.js +7 -4
  41. package/dist/lifecycle/engine-ops.js.map +1 -1
  42. package/dist/lifecycle/ivtr-loop.d.ts +108 -183
  43. package/dist/lifecycle/ivtr-loop.d.ts.map +1 -1
  44. package/dist/lifecycle/ivtr-loop.js +207 -522
  45. package/dist/lifecycle/ivtr-loop.js.map +1 -1
  46. package/dist/llm/auxiliary-fallback.js +1 -1
  47. package/dist/llm/auxiliary-fallback.js.map +1 -1
  48. package/dist/llm/cli-ops.d.ts +14 -1
  49. package/dist/llm/cli-ops.d.ts.map +1 -1
  50. package/dist/llm/cli-ops.js +41 -12
  51. package/dist/llm/cli-ops.js.map +1 -1
  52. package/dist/llm/concrete-session.d.ts.map +1 -1
  53. package/dist/llm/concrete-session.js +4 -0
  54. package/dist/llm/concrete-session.js.map +1 -1
  55. package/dist/llm/credentials.d.ts +35 -0
  56. package/dist/llm/credentials.d.ts.map +1 -1
  57. package/dist/llm/credentials.js +49 -0
  58. package/dist/llm/credentials.js.map +1 -1
  59. package/dist/llm/index.d.ts +4 -0
  60. package/dist/llm/index.d.ts.map +1 -1
  61. package/dist/llm/index.js +4 -0
  62. package/dist/llm/index.js.map +1 -1
  63. package/dist/llm/pi/gondolin-loader.d.ts +241 -0
  64. package/dist/llm/pi/gondolin-loader.d.ts.map +1 -0
  65. package/dist/llm/pi/gondolin-loader.js +195 -0
  66. package/dist/llm/pi/gondolin-loader.js.map +1 -0
  67. package/dist/llm/pi/index.d.ts +28 -0
  68. package/dist/llm/pi/index.d.ts.map +1 -0
  69. package/dist/llm/pi/index.js +27 -0
  70. package/dist/llm/pi/index.js.map +1 -0
  71. package/dist/llm/pi/pi-agent-adapter.d.ts +135 -0
  72. package/dist/llm/pi/pi-agent-adapter.d.ts.map +1 -0
  73. package/dist/llm/pi/pi-agent-adapter.js +329 -0
  74. package/dist/llm/pi/pi-agent-adapter.js.map +1 -0
  75. package/dist/llm/pi/pi-errors.d.ts +161 -0
  76. package/dist/llm/pi/pi-errors.d.ts.map +1 -0
  77. package/dist/llm/pi/pi-errors.js +296 -0
  78. package/dist/llm/pi/pi-errors.js.map +1 -0
  79. package/dist/llm/pi/pi-execution-env.d.ts +286 -0
  80. package/dist/llm/pi/pi-execution-env.d.ts.map +1 -0
  81. package/dist/llm/pi/pi-execution-env.js +406 -0
  82. package/dist/llm/pi/pi-execution-env.js.map +1 -0
  83. package/dist/llm/pi/pi-gondolin-env.d.ts +227 -0
  84. package/dist/llm/pi/pi-gondolin-env.d.ts.map +1 -0
  85. package/dist/llm/pi/pi-gondolin-env.js +541 -0
  86. package/dist/llm/pi/pi-gondolin-env.js.map +1 -0
  87. package/dist/llm/pi/pi-session-storage.d.ts +154 -0
  88. package/dist/llm/pi/pi-session-storage.d.ts.map +1 -0
  89. package/dist/llm/pi/pi-session-storage.js +314 -0
  90. package/dist/llm/pi/pi-session-storage.js.map +1 -0
  91. package/dist/llm/pi/pi-stream-fn.d.ts +124 -0
  92. package/dist/llm/pi/pi-stream-fn.d.ts.map +1 -0
  93. package/dist/llm/pi/pi-stream-fn.js +504 -0
  94. package/dist/llm/pi/pi-stream-fn.js.map +1 -0
  95. package/dist/llm/pi/pi-tool-bridge.d.ts +99 -0
  96. package/dist/llm/pi/pi-tool-bridge.d.ts.map +1 -0
  97. package/dist/llm/pi/pi-tool-bridge.js +117 -0
  98. package/dist/llm/pi/pi-tool-bridge.js.map +1 -0
  99. package/dist/llm/pi/pi-types.d.ts +56 -0
  100. package/dist/llm/pi/pi-types.d.ts.map +1 -0
  101. package/dist/llm/pi/pi-types.js +16 -0
  102. package/dist/llm/pi/pi-types.js.map +1 -0
  103. package/dist/llm/pi/resolve-execution-env.d.ts +194 -0
  104. package/dist/llm/pi/resolve-execution-env.d.ts.map +1 -0
  105. package/dist/llm/pi/resolve-execution-env.js +132 -0
  106. package/dist/llm/pi/resolve-execution-env.js.map +1 -0
  107. package/dist/llm/plugin-facade.js +2253 -1151
  108. package/dist/llm/plugin-facade.js.map +3 -3
  109. package/dist/llm/role-executor.d.ts.map +1 -1
  110. package/dist/llm/role-executor.js +8 -5
  111. package/dist/llm/role-executor.js.map +1 -1
  112. package/dist/llm/role-resolver.d.ts +46 -14
  113. package/dist/llm/role-resolver.d.ts.map +1 -1
  114. package/dist/llm/role-resolver.js +178 -20
  115. package/dist/llm/role-resolver.js.map +1 -1
  116. package/dist/llm/sealed-credential.d.ts +125 -0
  117. package/dist/llm/sealed-credential.d.ts.map +1 -0
  118. package/dist/llm/sealed-credential.js +133 -0
  119. package/dist/llm/sealed-credential.js.map +1 -0
  120. package/dist/llm/session-factory.d.ts.map +1 -1
  121. package/dist/llm/session-factory.js +6 -2
  122. package/dist/llm/session-factory.js.map +1 -1
  123. package/dist/llm/system-key.d.ts +67 -0
  124. package/dist/llm/system-key.d.ts.map +1 -0
  125. package/dist/llm/system-key.js +87 -0
  126. package/dist/llm/system-key.js.map +1 -0
  127. package/dist/llm/system-of-use-registry.d.ts +119 -0
  128. package/dist/llm/system-of-use-registry.d.ts.map +1 -0
  129. package/dist/llm/system-of-use-registry.js +200 -0
  130. package/dist/llm/system-of-use-registry.js.map +1 -0
  131. package/dist/llm/system-resolver.d.ts +32 -10
  132. package/dist/llm/system-resolver.d.ts.map +1 -1
  133. package/dist/llm/system-resolver.js +70 -18
  134. package/dist/llm/system-resolver.js.map +1 -1
  135. package/dist/memory/brain-writer-thread.d.ts.map +1 -1
  136. package/dist/memory/brain-writer-thread.js +116 -11
  137. package/dist/memory/brain-writer-thread.js.map +1 -1
  138. package/dist/memory/claude-mem-migration.d.ts.map +1 -1
  139. package/dist/memory/claude-mem-migration.js +21 -0
  140. package/dist/memory/claude-mem-migration.js.map +1 -1
  141. package/dist/memory/graph-memory-bridge.d.ts.map +1 -1
  142. package/dist/memory/graph-memory-bridge.js +32 -25
  143. package/dist/memory/graph-memory-bridge.js.map +1 -1
  144. package/dist/memory/llm-backend-resolver.js +23 -5
  145. package/dist/memory/llm-backend-resolver.js.map +1 -1
  146. package/dist/nexus/migrations/M-split-graph.d.ts.map +1 -1
  147. package/dist/nexus/migrations/M-split-graph.js +60 -53
  148. package/dist/nexus/migrations/M-split-graph.js.map +1 -1
  149. package/dist/orchestrate/pivot.d.ts.map +1 -1
  150. package/dist/orchestrate/pivot.js +20 -2
  151. package/dist/orchestrate/pivot.js.map +1 -1
  152. package/dist/release/engine-ops.js +2 -2
  153. package/dist/release/engine-ops.js.map +1 -1
  154. package/dist/routing/capability-matrix.d.ts.map +1 -1
  155. package/dist/routing/capability-matrix.js +0 -57
  156. package/dist/routing/capability-matrix.js.map +1 -1
  157. package/dist/selfimprove/budget.d.ts +206 -0
  158. package/dist/selfimprove/budget.d.ts.map +1 -0
  159. package/dist/selfimprove/budget.js +203 -0
  160. package/dist/selfimprove/budget.js.map +1 -0
  161. package/dist/selfimprove/dhq-adapter.d.ts +105 -0
  162. package/dist/selfimprove/dhq-adapter.d.ts.map +1 -0
  163. package/dist/selfimprove/dhq-adapter.js +95 -0
  164. package/dist/selfimprove/dhq-adapter.js.map +1 -0
  165. package/dist/selfimprove/draft-pr.d.ts +129 -0
  166. package/dist/selfimprove/draft-pr.d.ts.map +1 -0
  167. package/dist/selfimprove/draft-pr.js +158 -0
  168. package/dist/selfimprove/draft-pr.js.map +1 -0
  169. package/dist/selfimprove/envelope-diff.d.ts +162 -0
  170. package/dist/selfimprove/envelope-diff.d.ts.map +1 -0
  171. package/dist/selfimprove/envelope-diff.js +321 -0
  172. package/dist/selfimprove/envelope-diff.js.map +1 -0
  173. package/dist/selfimprove/replay.d.ts +121 -0
  174. package/dist/selfimprove/replay.d.ts.map +1 -0
  175. package/dist/selfimprove/replay.js +109 -0
  176. package/dist/selfimprove/replay.js.map +1 -0
  177. package/dist/selfimprove/run-loop.d.ts +148 -0
  178. package/dist/selfimprove/run-loop.d.ts.map +1 -0
  179. package/dist/selfimprove/run-loop.js +240 -0
  180. package/dist/selfimprove/run-loop.js.map +1 -0
  181. package/dist/selfimprove/scenario.d.ts +145 -0
  182. package/dist/selfimprove/scenario.d.ts.map +1 -0
  183. package/dist/selfimprove/scenario.js +243 -0
  184. package/dist/selfimprove/scenario.js.map +1 -0
  185. package/dist/sentient/daemon-entry.js +5 -0
  186. package/dist/sentient/daemon-entry.js.map +1 -1
  187. package/dist/sentient/daemon.d.ts.map +1 -1
  188. package/dist/sentient/daemon.js +19 -0
  189. package/dist/sentient/daemon.js.map +1 -1
  190. package/dist/sentient/hygiene-scan.d.ts.map +1 -1
  191. package/dist/sentient/hygiene-scan.js +14 -6
  192. package/dist/sentient/hygiene-scan.js.map +1 -1
  193. package/dist/sessions/briefing.d.ts.map +1 -1
  194. package/dist/sessions/briefing.js +13 -9
  195. package/dist/sessions/briefing.js.map +1 -1
  196. package/dist/sessions/connection-session-handle.d.ts +161 -0
  197. package/dist/sessions/connection-session-handle.d.ts.map +1 -0
  198. package/dist/sessions/connection-session-handle.js +168 -0
  199. package/dist/sessions/connection-session-handle.js.map +1 -0
  200. package/dist/sessions/handoff.d.ts.map +1 -1
  201. package/dist/sessions/handoff.js +9 -0
  202. package/dist/sessions/handoff.js.map +1 -1
  203. package/dist/sessions/index.d.ts +4 -1
  204. package/dist/sessions/index.d.ts.map +1 -1
  205. package/dist/sessions/index.js +31 -1
  206. package/dist/sessions/index.js.map +1 -1
  207. package/dist/sessions/session-id.d.ts +34 -0
  208. package/dist/sessions/session-id.d.ts.map +1 -1
  209. package/dist/sessions/session-id.js +37 -0
  210. package/dist/sessions/session-id.js.map +1 -1
  211. package/dist/sessions/session-manifest-mirror.d.ts +115 -0
  212. package/dist/sessions/session-manifest-mirror.d.ts.map +1 -0
  213. package/dist/sessions/session-manifest-mirror.js +250 -0
  214. package/dist/sessions/session-manifest-mirror.js.map +1 -0
  215. package/dist/sessions/session-switch.d.ts.map +1 -1
  216. package/dist/sessions/session-switch.js +5 -2
  217. package/dist/sessions/session-switch.js.map +1 -1
  218. package/dist/store/converters.d.ts.map +1 -1
  219. package/dist/store/converters.js +2 -0
  220. package/dist/store/converters.js.map +1 -1
  221. package/dist/store/db-helpers.d.ts.map +1 -1
  222. package/dist/store/db-helpers.js +2 -0
  223. package/dist/store/db-helpers.js.map +1 -1
  224. package/dist/store/dual-scope-db.d.ts.map +1 -1
  225. package/dist/store/dual-scope-db.js +87 -47
  226. package/dist/store/dual-scope-db.js.map +1 -1
  227. package/dist/store/pi-session-store.d.ts +151 -0
  228. package/dist/store/pi-session-store.d.ts.map +1 -0
  229. package/dist/store/pi-session-store.js +166 -0
  230. package/dist/store/pi-session-store.js.map +1 -0
  231. package/dist/store/safety-data-accessor.d.ts +1 -0
  232. package/dist/store/safety-data-accessor.d.ts.map +1 -1
  233. package/dist/store/safety-data-accessor.js +5 -0
  234. package/dist/store/safety-data-accessor.js.map +1 -1
  235. package/dist/store/schema/cleo-global/accounts.d.ts +357 -0
  236. package/dist/store/schema/cleo-global/accounts.d.ts.map +1 -0
  237. package/dist/store/schema/cleo-global/accounts.js +136 -0
  238. package/dist/store/schema/cleo-global/accounts.js.map +1 -0
  239. package/dist/store/schema/cleo-global/index.d.ts +2 -0
  240. package/dist/store/schema/cleo-global/index.d.ts.map +1 -1
  241. package/dist/store/schema/cleo-global/index.js +2 -0
  242. package/dist/store/schema/cleo-global/index.js.map +1 -1
  243. package/dist/store/schema/cleo-global/session-manifest.d.ts +217 -0
  244. package/dist/store/schema/cleo-global/session-manifest.d.ts.map +1 -0
  245. package/dist/store/schema/cleo-global/session-manifest.js +99 -0
  246. package/dist/store/schema/cleo-global/session-manifest.js.map +1 -0
  247. package/dist/store/schema/cleo-project/tasks-core.d.ts +16 -0
  248. package/dist/store/schema/cleo-project/tasks-core.d.ts.map +1 -1
  249. package/dist/store/schema/cleo-project/tasks-core.js +14 -0
  250. package/dist/store/schema/cleo-project/tasks-core.js.map +1 -1
  251. package/dist/store/schema/tasks.d.ts +16 -0
  252. package/dist/store/schema/tasks.d.ts.map +1 -1
  253. package/dist/store/schema/tasks.js +10 -0
  254. package/dist/store/schema/tasks.js.map +1 -1
  255. package/dist/store/selfimprove-dhq-schema.d.ts +284 -0
  256. package/dist/store/selfimprove-dhq-schema.d.ts.map +1 -0
  257. package/dist/store/selfimprove-dhq-schema.js +128 -0
  258. package/dist/store/selfimprove-dhq-schema.js.map +1 -0
  259. package/dist/store/selfimprove-dhq-store.d.ts +175 -0
  260. package/dist/store/selfimprove-dhq-store.d.ts.map +1 -0
  261. package/dist/store/selfimprove-dhq-store.js +182 -0
  262. package/dist/store/selfimprove-dhq-store.js.map +1 -0
  263. package/dist/store/session-store.d.ts +52 -13
  264. package/dist/store/session-store.d.ts.map +1 -1
  265. package/dist/store/session-store.js +71 -13
  266. package/dist/store/session-store.js.map +1 -1
  267. package/dist/store/sqlite-data-accessor.d.ts.map +1 -1
  268. package/dist/store/sqlite-data-accessor.js +7 -0
  269. package/dist/store/sqlite-data-accessor.js.map +1 -1
  270. package/dist/store/umbrella-data-accessor.d.ts +1 -0
  271. package/dist/store/umbrella-data-accessor.d.ts.map +1 -1
  272. package/dist/store/umbrella-data-accessor.js +5 -0
  273. package/dist/store/umbrella-data-accessor.js.map +1 -1
  274. package/dist/store/validation-schemas.d.ts +32 -0
  275. package/dist/store/validation-schemas.d.ts.map +1 -1
  276. package/dist/store/writer-lease-schema.d.ts +392 -0
  277. package/dist/store/writer-lease-schema.d.ts.map +1 -0
  278. package/dist/store/writer-lease-schema.js +142 -0
  279. package/dist/store/writer-lease-schema.js.map +1 -0
  280. package/dist/store/writer-lease.d.ts +368 -0
  281. package/dist/store/writer-lease.d.ts.map +1 -0
  282. package/dist/store/writer-lease.js +1002 -0
  283. package/dist/store/writer-lease.js.map +1 -0
  284. package/dist/tasks/backfill-child-projections.d.ts.map +1 -1
  285. package/dist/tasks/backfill-child-projections.js +14 -9
  286. package/dist/tasks/backfill-child-projections.js.map +1 -1
  287. package/dist/tasks/complete.d.ts.map +1 -1
  288. package/dist/tasks/complete.js +7 -10
  289. package/dist/tasks/complete.js.map +1 -1
  290. package/dist/tasks/duplicate-detector.d.ts.map +1 -1
  291. package/dist/tasks/duplicate-detector.js +14 -7
  292. package/dist/tasks/duplicate-detector.js.map +1 -1
  293. package/dist/telemetry/index.d.ts.map +1 -1
  294. package/dist/telemetry/index.js +10 -4
  295. package/dist/telemetry/index.js.map +1 -1
  296. package/dist/tools/agent-registry.d.ts +250 -0
  297. package/dist/tools/agent-registry.d.ts.map +1 -0
  298. package/dist/tools/agent-registry.js +292 -0
  299. package/dist/tools/agent-registry.js.map +1 -0
  300. package/dist/tools/agent-tool-families.d.ts +107 -0
  301. package/dist/tools/agent-tool-families.d.ts.map +1 -0
  302. package/dist/tools/agent-tool-families.js +527 -0
  303. package/dist/tools/agent-tool-families.js.map +1 -0
  304. package/dist/tools/browser-driver.d.ts +183 -0
  305. package/dist/tools/browser-driver.d.ts.map +1 -0
  306. package/dist/tools/browser-driver.js +242 -0
  307. package/dist/tools/browser-driver.js.map +1 -0
  308. package/dist/tools/builtin-agent-tools.d.ts +36 -0
  309. package/dist/tools/builtin-agent-tools.d.ts.map +1 -0
  310. package/dist/tools/builtin-agent-tools.js +150 -0
  311. package/dist/tools/builtin-agent-tools.js.map +1 -0
  312. package/dist/tools/dispatch.d.ts +370 -0
  313. package/dist/tools/dispatch.d.ts.map +1 -0
  314. package/dist/tools/dispatch.js +505 -0
  315. package/dist/tools/dispatch.js.map +1 -0
  316. package/dist/tools/env-scrub.d.ts +93 -0
  317. package/dist/tools/env-scrub.d.ts.map +1 -0
  318. package/dist/tools/env-scrub.js +176 -0
  319. package/dist/tools/env-scrub.js.map +1 -0
  320. package/dist/tools/fs.d.ts +30 -0
  321. package/dist/tools/fs.d.ts.map +1 -1
  322. package/dist/tools/fs.js +55 -2
  323. package/dist/tools/fs.js.map +1 -1
  324. package/dist/tools/guard.d.ts +15 -0
  325. package/dist/tools/guard.d.ts.map +1 -1
  326. package/dist/tools/guard.js +49 -12
  327. package/dist/tools/guard.js.map +1 -1
  328. package/dist/tools/index.d.ts +10 -0
  329. package/dist/tools/index.d.ts.map +1 -1
  330. package/dist/tools/index.js +37 -0
  331. package/dist/tools/index.js.map +1 -1
  332. package/dist/tools/pty.d.ts +45 -0
  333. package/dist/tools/pty.d.ts.map +1 -0
  334. package/dist/tools/pty.js +166 -0
  335. package/dist/tools/pty.js.map +1 -0
  336. package/dist/tools/schema-gen.d.ts +57 -0
  337. package/dist/tools/schema-gen.d.ts.map +1 -0
  338. package/dist/tools/schema-gen.js +52 -0
  339. package/dist/tools/schema-gen.js.map +1 -0
  340. package/dist/tools/shell.d.ts +12 -0
  341. package/dist/tools/shell.d.ts.map +1 -1
  342. package/dist/tools/shell.js +14 -1
  343. package/dist/tools/shell.js.map +1 -1
  344. package/dist/tools/web-agent-tools.d.ts +72 -0
  345. package/dist/tools/web-agent-tools.d.ts.map +1 -0
  346. package/dist/tools/web-agent-tools.js +393 -0
  347. package/dist/tools/web-agent-tools.js.map +1 -0
  348. package/dist/tools/web-search-backends.d.ts +156 -0
  349. package/dist/tools/web-search-backends.d.ts.map +1 -0
  350. package/dist/tools/web-search-backends.js +290 -0
  351. package/dist/tools/web-search-backends.js.map +1 -0
  352. package/dist/validation/ops.d.ts +1 -15
  353. package/dist/validation/ops.d.ts.map +1 -1
  354. package/dist/validation/ops.js +0 -20
  355. package/dist/validation/ops.js.map +1 -1
  356. package/migrations/drizzle-cleo-global/20260607000000_t11891-writer-leases/migration.sql +55 -0
  357. package/migrations/drizzle-cleo-global/20260607010000_t11639-session-manifest/migration.sql +43 -0
  358. package/migrations/drizzle-cleo-global/20260608000000_t11899-pi-session-tree/migration.sql +52 -0
  359. package/migrations/drizzle-cleo-global/20260608010000_t11709-accounts-credential-pool/migration.sql +72 -0
  360. package/migrations/drizzle-cleo-global/20260608020000_t11889-selfimprove-dhq/migration.sql +64 -0
  361. package/migrations/drizzle-cleo-project/20260607000000_t11891-writer-leases/migration.sql +55 -0
  362. package/migrations/drizzle-cleo-project/20260607010000_t11639-session-parent/migration.sql +22 -0
  363. package/migrations/drizzle-cleo-project/20260608000000_t11899-pi-session-tree/migration.sql +52 -0
  364. package/migrations/drizzle-cleo-project/20260608020000_t11889-selfimprove-dhq/migration.sql +64 -0
  365. package/package.json +15 -13
  366. package/dist/lifecycle/chain-composition.d.ts +0 -30
  367. package/dist/lifecycle/chain-composition.d.ts.map +0 -1
  368. package/dist/lifecycle/chain-composition.js +0 -152
  369. package/dist/lifecycle/chain-composition.js.map +0 -1
  370. package/dist/lifecycle/chain-store.d.ts +0 -70
  371. package/dist/lifecycle/chain-store.d.ts.map +0 -1
  372. package/dist/lifecycle/chain-store.js +0 -246
  373. package/dist/lifecycle/chain-store.js.map +0 -1
  374. package/dist/lifecycle/default-chain.d.ts +0 -39
  375. package/dist/lifecycle/default-chain.d.ts.map +0 -1
  376. package/dist/lifecycle/default-chain.js +0 -176
  377. package/dist/lifecycle/default-chain.js.map +0 -1
  378. package/dist/lifecycle/tessera-engine.d.ts +0 -48
  379. package/dist/lifecycle/tessera-engine.d.ts.map +0 -1
  380. package/dist/lifecycle/tessera-engine.js +0 -249
  381. package/dist/lifecycle/tessera-engine.js.map +0 -1
  382. package/dist/validation/chain-validation.d.ts +0 -43
  383. package/dist/validation/chain-validation.d.ts.map +0 -1
  384. package/dist/validation/chain-validation.js +0 -146
  385. package/dist/validation/chain-validation.js.map +0 -1
@@ -0,0 +1,158 @@
1
+ /**
2
+ * Draft-PR egress for the self-improvement loop (T11889 · T11889-C).
3
+ *
4
+ * On a detected regression the loop's ONLY outbound action is to open ONE DRAFT
5
+ * PR against the cleocode repo (ADR-065 — PRs target `main` via the Merge Queue;
6
+ * NEVER a direct push to `main`, NEVER an auto-merge, NEVER a publish). This module
7
+ * is the egress primitive, modeled on `propose-patch.ts` (the closest "agent
8
+ * proposes a fix PR" exemplar) with three self-dogfooding hardenings:
9
+ *
10
+ * 1. **`--draft` is ALWAYS appended** to `gh pr create` — the PR is never
11
+ * ready-for-merge; a human reviews and undrafts it.
12
+ * 2. **Dry-run is the DEFAULT.** `openDraftPr` returns the planned `steps[]`
13
+ * WITHOUT invoking git/gh unless `execute: true` is passed. So the loop is
14
+ * side-effect-free at egress by default.
15
+ * 3. **Branch `feat/T11889-selfimprove-<scenario>-<ts>`** — a feature branch
16
+ * (ADR-065); no main mutation path exists in this module.
17
+ *
18
+ * The live path wraps the git/gh shell-out in
19
+ * {@link "../sentient/skill-provenance.js".withProvenance}`('pr-generator', …)`
20
+ * (the established legal PR-cutting origin — the `SkillWriteOrigin` union is
21
+ * closed) and returns the `gh`-emitted PR URL so the caller can record it back
22
+ * into `selfimprove_dhq.pr_url` via the leased adapter.
23
+ *
24
+ * This module is import-time side-effect-free.
25
+ *
26
+ * @module @cleocode/core/selfimprove/draft-pr
27
+ * @epic T11889
28
+ * @task T11913
29
+ */
30
+ import { execFileSync } from 'node:child_process';
31
+ import { existsSync, readFileSync } from 'node:fs';
32
+ import { resolve as resolvePath } from 'node:path';
33
+ import { cwd as processCwd } from 'node:process';
34
+ import { withProvenance } from '../sentient/skill-provenance.js';
35
+ /**
36
+ * The required Claude Code trailer every self-improvement PR body ends with.
37
+ * Matches the project PR-body convention.
38
+ */
39
+ const PR_BODY_TRAILER = '\n\n🤖 Generated with [Claude Code](https://claude.com/claude-code)';
40
+ /** Default command runner — wraps `execFileSync` with stdout-piped semantics. */
41
+ const defaultRun = (file, args) => execFileSync(file, [...args], { stdio: 'pipe' }).toString('utf8');
42
+ /**
43
+ * Compute the feature branch name for a scenario's draft PR (ADR-065 feature
44
+ * branch — `feat/T11889-selfimprove-<scenario>-<ts>`). The timestamp is
45
+ * colon/dot-sanitized so it is a valid git ref.
46
+ *
47
+ * @param scenario - The scenario name.
48
+ * @param ts - The ISO timestamp string.
49
+ * @returns The branch name.
50
+ */
51
+ export function draftPrBranchName(scenario, ts) {
52
+ const safeScenario = scenario.replace(/[^a-z0-9-]/gi, '-');
53
+ const safeTs = ts.replace(/[:.]/g, '-');
54
+ return `feat/T11889-selfimprove-${safeScenario}-${safeTs}`;
55
+ }
56
+ /**
57
+ * Open ONE DRAFT PR carrying a proposed self-improvement fix.
58
+ *
59
+ * DRY-RUN by default ({@link OpenDraftPrArgs.execute} falsey): returns the planned
60
+ * `steps[]` (the `gh pr create` step ALWAYS carries `--draft`) WITHOUT touching
61
+ * git/gh — so the loop is egress-side-effect-free unless `--execute` is threaded
62
+ * through. The live path (`execute: true`) cuts the feature branch, applies the
63
+ * diff, commits, pushes the FEATURE branch (NEVER `main`), and runs
64
+ * `gh pr create --base main --head <branch> --draft`, returning the PR URL.
65
+ *
66
+ * NEVER pushes `main`, NEVER auto-merges, NEVER publishes — the only egress is a
67
+ * draft PR against a feature branch.
68
+ *
69
+ * @param args - See {@link OpenDraftPrArgs}.
70
+ * @returns A {@link DraftPrResult} describing the outcome.
71
+ *
72
+ * @example
73
+ * ```ts
74
+ * // dry-run (default): no side effects, steps include `--draft`
75
+ * const plan = await openDraftPr({ scenario: 'x', diffPath: 'fix.patch', title, body });
76
+ * // live: cuts branch + opens draft PR
77
+ * const res = await openDraftPr({ scenario: 'x', diffPath: 'fix.patch', title, body, execute: true });
78
+ * ```
79
+ */
80
+ export async function openDraftPr(args) {
81
+ const cwd = args.cwd ?? processCwd();
82
+ const run = args.run ?? defaultRun;
83
+ const execute = args.execute === true;
84
+ const isoNow = (args.timestamp ?? (() => new Date().toISOString()))();
85
+ const base = 'main';
86
+ const body = `${args.body}${PR_BODY_TRAILER}`;
87
+ const resolvedDiff = resolvePath(cwd, args.diffPath);
88
+ if (!existsSync(resolvedDiff)) {
89
+ return {
90
+ kind: 'error',
91
+ code: 'E_NOT_FOUND',
92
+ message: `Patch file not found at '${resolvedDiff}'`,
93
+ };
94
+ }
95
+ const diffBytes = readFileSync(resolvedDiff, 'utf8');
96
+ if (diffBytes.length === 0) {
97
+ return {
98
+ kind: 'error',
99
+ code: 'E_PATCH_EMPTY',
100
+ message: `Patch file '${resolvedDiff}' is empty`,
101
+ };
102
+ }
103
+ if (execute) {
104
+ try {
105
+ run('gh', ['--version']);
106
+ }
107
+ catch {
108
+ return {
109
+ kind: 'error',
110
+ code: 'E_GH_UNAVAILABLE',
111
+ message: 'gh CLI not found or not authenticated — install gh and run `gh auth login`',
112
+ };
113
+ }
114
+ }
115
+ const branchName = draftPrBranchName(args.scenario, isoNow);
116
+ const steps = [
117
+ `git checkout -b ${branchName}`,
118
+ `git apply ${resolvedDiff}`,
119
+ 'git add -A',
120
+ `git commit -m "fix(selfimprove): ${args.scenario} regression"`,
121
+ `git push -u origin ${branchName}`,
122
+ `gh pr create --base ${base} --head ${branchName} --draft --title "${args.title}" --body <stdin>`,
123
+ ];
124
+ if (!execute) {
125
+ return { kind: 'dry-run', scenario: args.scenario, branchName, steps };
126
+ }
127
+ try {
128
+ const prUrl = await withProvenance('pr-generator', () => {
129
+ run('git', ['checkout', '-b', branchName]);
130
+ run('git', ['apply', resolvedDiff]);
131
+ run('git', ['add', '-A']);
132
+ run('git', ['commit', '-m', `fix(selfimprove): ${args.scenario} regression`]);
133
+ run('git', ['push', '-u', 'origin', branchName]);
134
+ return run('gh', [
135
+ 'pr',
136
+ 'create',
137
+ '--base',
138
+ base,
139
+ '--head',
140
+ branchName,
141
+ '--draft',
142
+ '--title',
143
+ args.title,
144
+ '--body',
145
+ body,
146
+ ]).trim();
147
+ });
148
+ return { kind: 'ok', scenario: args.scenario, branchName, prUrl };
149
+ }
150
+ catch (err) {
151
+ return {
152
+ kind: 'error',
153
+ code: 'E_DRAFT_PR_FAILED',
154
+ message: `draft-pr failed: ${err instanceof Error ? err.message : String(err)}`,
155
+ };
156
+ }
157
+ }
158
+ //# sourceMappingURL=draft-pr.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"draft-pr.js","sourceRoot":"","sources":["../../src/selfimprove/draft-pr.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,162 @@
1
+ /**
2
+ * Envelope normalization + structural diff vs a golden (T11889-B).
3
+ *
4
+ * The self-improvement loop replays a scenario (see {@link "./replay.js"}) and
5
+ * diffs each captured envelope against the golden expected envelope. This module:
6
+ *
7
+ * 1. {@link normalizeEnvelope} — strips the VOLATILE `meta` fields so only
8
+ * deterministic structure is compared. Two classes are stripped:
9
+ * timing/trace fields (`timestamp`, `requestId`, `duration_ms` /
10
+ * `durationMs`) AND the per-run session-lineage UUIDs (`sessionId`,
11
+ * `originSessionId`, `executionSessionId`). The latter are non-deterministic:
12
+ * the live `Dispatcher` defaults `executionSessionId`/`originSessionId` to a
13
+ * fresh `randomUUID()` per request
14
+ * (`ensureRequestSessionLineage`), then stamps all three onto `response.meta`
15
+ * — so a real envelope carries UUIDs the hand-authored golden cannot know.
16
+ * Stripping them prevents a permanent phantom DHQ that self-fires on every
17
+ * clean run. (The runtime field is `meta` with snake_case `duration_ms`; the
18
+ * spec wording uses `_meta`/`durationMs`, so both spellings and both
19
+ * container keys are stripped defensively.)
20
+ * 2. {@link diffEnvelopes} — structurally compares the normalized envelope set
21
+ * against the golden, producing `{ regressions: DiffEntry[] }`. Zero
22
+ * regressions on a golden match; N on injected divergence. The `meta`
23
+ * container is compared as a SUBSET (only golden-declared meta keys are
24
+ * asserted) so deterministic-but-golden-absent infra keys
25
+ * (`specVersion`, `schemaVersion`, `transport`, `mvi`, `contextVersion`,
26
+ * `strict`, `x-cleo-transport`, …) stamped by the runtime are NOT phantom
27
+ * regressions. The semantic payload (`data`/`error`) is still compared by
28
+ * full key-union — a missing or extra payload key IS a regression.
29
+ * 3. {@link computeQuestionHash} — sha256 of the normalized regression
30
+ * signature (op coordinates + diff path set) so the SAME regression maps to
31
+ * the SAME open DHQ row (the idempotency partial-UNIQUE index in T11889-A).
32
+ *
33
+ * `extractFieldFromResult` from `@cleocode/lafs` is reused for targeted-field
34
+ * asserts where a full structural compare would be too brittle.
35
+ *
36
+ * This module is PURE — no DB, no native handle, no `cleo` mutation.
37
+ * Import-time side-effect-free.
38
+ *
39
+ * @module @cleocode/core/selfimprove/envelope-diff
40
+ * @epic T11889
41
+ * @task T11912
42
+ */
43
+ import type { ReplayEnvelope } from './replay.js';
44
+ import type { GoldenEntry, ScenarioOp } from './scenario.js';
45
+ /**
46
+ * A normalized envelope: the replayed envelope with volatile `meta` fields removed.
47
+ *
48
+ * Structurally identical to {@link ReplayEnvelope} except every volatile
49
+ * meta field is absent. Stored as a plain JSON-serializable record so it can be
50
+ * compared deeply and hashed deterministically.
51
+ */
52
+ export type NormalizedEnvelope = Record<string, unknown>;
53
+ /**
54
+ * A single structural difference between a normalized envelope and its golden.
55
+ */
56
+ export interface DiffEntry {
57
+ /** Zero-based index of the op in the scenario whose envelope diverged. */
58
+ opIndex: number;
59
+ /** The op coordinate (`domain.operation`) for the diverging op. */
60
+ opCoord: string;
61
+ /** JSON-pointer-ish path to the diverging value (e.g. `data/tasks/0/id`). */
62
+ path: string;
63
+ /** The value found in the replayed (actual) normalized envelope. */
64
+ actual: unknown;
65
+ /** The value found in the golden (expected) envelope. */
66
+ expected: unknown;
67
+ }
68
+ /** The result of diffing a replayed envelope set against a golden. */
69
+ export interface EnvelopeDiffResult {
70
+ /** All structural regressions; empty ⇒ the replay matched the golden. */
71
+ regressions: DiffEntry[];
72
+ }
73
+ /**
74
+ * Strip the volatile `meta`/`_meta` fields from an envelope.
75
+ *
76
+ * Returns a NEW object; the input is not mutated. The volatile timing/trace fields
77
+ * AND the per-run session-lineage UUIDs (`sessionId`, `originSessionId`,
78
+ * `executionSessionId`) are removed — see {@link VOLATILE_META_FIELDS}. The stable
79
+ * meta remnant (`gateway`, `domain`, `operation`, `source`, …) is preserved so
80
+ * structural identity (which operation produced the envelope) still compares.
81
+ *
82
+ * Note: deterministic-but-golden-absent infra meta keys (`specVersion`,
83
+ * `transport`, …) are NOT stripped here — they are tolerated by the SUBSET compare
84
+ * in {@link diffEnvelopes} instead, so the strip set stays exactly the volatile
85
+ * fields and nothing semantic.
86
+ *
87
+ * @param envelope - The replayed envelope to normalize.
88
+ * @returns The normalized envelope with volatile meta fields removed.
89
+ *
90
+ * @example
91
+ * ```ts
92
+ * const norm = normalizeEnvelope(envelope);
93
+ * // norm.meta has no timestamp / requestId / duration_ms / *SessionId
94
+ * ```
95
+ */
96
+ export declare function normalizeEnvelope(envelope: ReplayEnvelope): NormalizedEnvelope;
97
+ /**
98
+ * Diff a set of replayed envelopes against the golden envelope set.
99
+ *
100
+ * Normalizes each replayed envelope (volatile meta stripped) and structurally
101
+ * compares it against the positionally-aligned golden entry. The op coordinate
102
+ * for each `DiffEntry` is taken from `ops[opIndex]`. Callers MUST pass aligned
103
+ * arrays (`ops.length === replayed.length === golden.length`); the function
104
+ * diffs up to the shortest length and reports an extra regression for any length
105
+ * mismatch.
106
+ *
107
+ * The `meta` container is compared as a SUBSET (only golden-declared meta keys are
108
+ * asserted) so deterministic-but-golden-absent infra keys the runtime stamps
109
+ * (`specVersion`, `transport`, …) are not phantom regressions; the semantic
110
+ * payload (`data`/`error`) keeps a full key-union compare where an extra or
111
+ * missing key IS a regression. Together with the volatile-lineage strip in
112
+ * {@link normalizeEnvelope}, a real live envelope that matches the golden body
113
+ * yields ZERO regressions.
114
+ *
115
+ * @param ops - The scenario ops (for op-coordinate labelling).
116
+ * @param replayed - The captured envelopes, one per op (replay order).
117
+ * @param golden - The golden expected entries, positionally aligned with `ops`.
118
+ * @returns `{ regressions }` — empty when the replay matches the golden.
119
+ *
120
+ * @example
121
+ * ```ts
122
+ * const { regressions } = diffEnvelopes(scenario.ops, replayed, golden.envelopes);
123
+ * if (regressions.length === 0) { /* happy path — no DHQ, no PR *\/ }
124
+ * ```
125
+ */
126
+ export declare function diffEnvelopes(ops: ScenarioOp[], replayed: ReplayEnvelope[], golden: GoldenEntry[]): EnvelopeDiffResult;
127
+ /**
128
+ * Extract a targeted field from a normalized envelope's `data` payload.
129
+ *
130
+ * Reuses the LAFS `--field` extractor (`extractFieldFromResult`) for cases where
131
+ * a full structural diff is too brittle and only a specific field's value matters
132
+ * (e.g. assert `data.tasks[0].id` without comparing the whole envelope).
133
+ *
134
+ * @param normalized - A normalized envelope (from {@link normalizeEnvelope}).
135
+ * @param field - The field name to extract from the envelope's `data` payload.
136
+ * @returns The extracted value, or `undefined` when absent.
137
+ *
138
+ * @example
139
+ * ```ts
140
+ * const id = extractTargetedField(normalizeEnvelope(env), 'id');
141
+ * ```
142
+ */
143
+ export declare function extractTargetedField(normalized: NormalizedEnvelope, field: string): unknown;
144
+ /**
145
+ * Compute the sha256 `question_hash` of a diff result's normalized signature.
146
+ *
147
+ * The hash is over the {@link regressionSignature} (op coordinates + diff path
148
+ * set), so it is stable across runs of the SAME regression and feeds the
149
+ * idempotency partial-UNIQUE index (`ux_selfimprove_dhq_open`, T11889-A): one
150
+ * open DHQ row per `question_hash`. An empty regression set hashes the empty
151
+ * signature deterministically (callers should not persist on the happy path).
152
+ *
153
+ * @param result - The diff result whose regressions are hashed.
154
+ * @returns The lowercase hex sha256 of the regression signature.
155
+ *
156
+ * @example
157
+ * ```ts
158
+ * const hash = computeQuestionHash(diffEnvelopes(ops, replayed, golden));
159
+ * ```
160
+ */
161
+ export declare function computeQuestionHash(result: EnvelopeDiffResult): string;
162
+ //# sourceMappingURL=envelope-diff.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"envelope-diff.d.ts","sourceRoot":"","sources":["../../src/selfimprove/envelope-diff.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAmD7D;;;;;;GAMG;AACH,MAAM,MAAM,kBAAkB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEzD;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,0EAA0E;IAC1E,OAAO,EAAE,MAAM,CAAC;IAChB,mEAAmE;IACnE,OAAO,EAAE,MAAM,CAAC;IAChB,6EAA6E;IAC7E,IAAI,EAAE,MAAM,CAAC;IACb,oEAAoE;IACpE,MAAM,EAAE,OAAO,CAAC;IAChB,yDAAyD;IACzD,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,sEAAsE;AACtE,MAAM,WAAW,kBAAkB;IACjC,yEAAyE;IACzE,WAAW,EAAE,SAAS,EAAE,CAAC;CAC1B;AAeD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,cAAc,GAAG,kBAAkB,CAY9E;AAkED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,aAAa,CAC3B,GAAG,EAAE,UAAU,EAAE,EACjB,QAAQ,EAAE,cAAc,EAAE,EAC1B,MAAM,EAAE,WAAW,EAAE,GACpB,kBAAkB,CAqCpB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,kBAAkB,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAO3F;AAqBD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,kBAAkB,GAAG,MAAM,CAGtE"}
@@ -0,0 +1,321 @@
1
+ /**
2
+ * Envelope normalization + structural diff vs a golden (T11889-B).
3
+ *
4
+ * The self-improvement loop replays a scenario (see {@link "./replay.js"}) and
5
+ * diffs each captured envelope against the golden expected envelope. This module:
6
+ *
7
+ * 1. {@link normalizeEnvelope} — strips the VOLATILE `meta` fields so only
8
+ * deterministic structure is compared. Two classes are stripped:
9
+ * timing/trace fields (`timestamp`, `requestId`, `duration_ms` /
10
+ * `durationMs`) AND the per-run session-lineage UUIDs (`sessionId`,
11
+ * `originSessionId`, `executionSessionId`). The latter are non-deterministic:
12
+ * the live `Dispatcher` defaults `executionSessionId`/`originSessionId` to a
13
+ * fresh `randomUUID()` per request
14
+ * (`ensureRequestSessionLineage`), then stamps all three onto `response.meta`
15
+ * — so a real envelope carries UUIDs the hand-authored golden cannot know.
16
+ * Stripping them prevents a permanent phantom DHQ that self-fires on every
17
+ * clean run. (The runtime field is `meta` with snake_case `duration_ms`; the
18
+ * spec wording uses `_meta`/`durationMs`, so both spellings and both
19
+ * container keys are stripped defensively.)
20
+ * 2. {@link diffEnvelopes} — structurally compares the normalized envelope set
21
+ * against the golden, producing `{ regressions: DiffEntry[] }`. Zero
22
+ * regressions on a golden match; N on injected divergence. The `meta`
23
+ * container is compared as a SUBSET (only golden-declared meta keys are
24
+ * asserted) so deterministic-but-golden-absent infra keys
25
+ * (`specVersion`, `schemaVersion`, `transport`, `mvi`, `contextVersion`,
26
+ * `strict`, `x-cleo-transport`, …) stamped by the runtime are NOT phantom
27
+ * regressions. The semantic payload (`data`/`error`) is still compared by
28
+ * full key-union — a missing or extra payload key IS a regression.
29
+ * 3. {@link computeQuestionHash} — sha256 of the normalized regression
30
+ * signature (op coordinates + diff path set) so the SAME regression maps to
31
+ * the SAME open DHQ row (the idempotency partial-UNIQUE index in T11889-A).
32
+ *
33
+ * `extractFieldFromResult` from `@cleocode/lafs` is reused for targeted-field
34
+ * asserts where a full structural compare would be too brittle.
35
+ *
36
+ * This module is PURE — no DB, no native handle, no `cleo` mutation.
37
+ * Import-time side-effect-free.
38
+ *
39
+ * @module @cleocode/core/selfimprove/envelope-diff
40
+ * @epic T11889
41
+ * @task T11912
42
+ */
43
+ import { createHash } from 'node:crypto';
44
+ import { extractFieldFromResult } from '@cleocode/lafs';
45
+ /**
46
+ * Volatile envelope-meta field names stripped before diffing.
47
+ *
48
+ * Two classes, both non-deterministic per run:
49
+ *
50
+ * - Timing / trace: `timestamp`, `requestId`, `duration_ms` (the runtime
51
+ * canonical, snake_case) and `durationMs` (the spec wording — stripped so a
52
+ * golden authored either way normalizes identically).
53
+ * - Session lineage: `sessionId`, `originSessionId`, `executionSessionId`. The
54
+ * live `Dispatcher` stamps these onto `response.meta`
55
+ * after defaulting `executionSessionId`/`originSessionId` to a fresh
56
+ * `randomUUID()` per request (`ensureRequestSessionLineage`). They are
57
+ * per-run UUIDs the hand-authored golden cannot encode; leaving them in would
58
+ * make every clean replay emit a phantom regression at
59
+ * `meta/executionSessionId` and `meta/originSessionId`, and because the
60
+ * regression signature hashes only `opCoord@path` (constant), the resulting
61
+ * `question_hash` would be STABLE — a permanent self-firing DHQ. Stripping
62
+ * them keeps an identical-but-for-lineage envelope a non-regression.
63
+ */
64
+ const VOLATILE_META_FIELDS = [
65
+ 'timestamp',
66
+ 'requestId',
67
+ 'duration_ms',
68
+ 'durationMs',
69
+ 'sessionId',
70
+ 'originSessionId',
71
+ 'executionSessionId',
72
+ ];
73
+ /**
74
+ * Meta container keys whose volatile fields are stripped, and whose remaining
75
+ * keys are compared as a SUBSET (see {@link diffEnvelopes}).
76
+ *
77
+ * Runtime envelopes use `meta`; `_meta` is stripped too for defensive parity with
78
+ * the gateway envelope shape.
79
+ */
80
+ const META_CONTAINER_KEYS = ['meta', '_meta'];
81
+ /**
82
+ * Top-level envelope keys whose value is a meta container.
83
+ *
84
+ * The structural diff treats these containers as a SUBSET compare (golden-declared
85
+ * keys only) so deterministic-but-golden-absent infra keys the runtime stamps
86
+ * (`specVersion`, `schemaVersion`, `transport`, `mvi`, `contextVersion`, `strict`,
87
+ * `x-cleo-transport`, …) are not phantom regressions. Everything else (`data`,
88
+ * `error`, …) keeps a full key-union compare.
89
+ */
90
+ const SUBSET_COMPARE_KEYS = new Set(META_CONTAINER_KEYS);
91
+ /**
92
+ * Deep-clone a JSON-serializable value via structured round-trip.
93
+ *
94
+ * Replay envelopes are JSON-shaped (they round-trip through transports), so a
95
+ * JSON clone is safe and avoids mutating the caller's object during normalization.
96
+ *
97
+ * @param value - The value to clone.
98
+ * @returns A deep copy.
99
+ */
100
+ function jsonClone(value) {
101
+ return JSON.parse(JSON.stringify(value));
102
+ }
103
+ /**
104
+ * Strip the volatile `meta`/`_meta` fields from an envelope.
105
+ *
106
+ * Returns a NEW object; the input is not mutated. The volatile timing/trace fields
107
+ * AND the per-run session-lineage UUIDs (`sessionId`, `originSessionId`,
108
+ * `executionSessionId`) are removed — see {@link VOLATILE_META_FIELDS}. The stable
109
+ * meta remnant (`gateway`, `domain`, `operation`, `source`, …) is preserved so
110
+ * structural identity (which operation produced the envelope) still compares.
111
+ *
112
+ * Note: deterministic-but-golden-absent infra meta keys (`specVersion`,
113
+ * `transport`, …) are NOT stripped here — they are tolerated by the SUBSET compare
114
+ * in {@link diffEnvelopes} instead, so the strip set stays exactly the volatile
115
+ * fields and nothing semantic.
116
+ *
117
+ * @param envelope - The replayed envelope to normalize.
118
+ * @returns The normalized envelope with volatile meta fields removed.
119
+ *
120
+ * @example
121
+ * ```ts
122
+ * const norm = normalizeEnvelope(envelope);
123
+ * // norm.meta has no timestamp / requestId / duration_ms / *SessionId
124
+ * ```
125
+ */
126
+ export function normalizeEnvelope(envelope) {
127
+ const cloned = jsonClone(envelope);
128
+ for (const containerKey of META_CONTAINER_KEYS) {
129
+ const container = cloned[containerKey];
130
+ if (container !== null && typeof container === 'object' && !Array.isArray(container)) {
131
+ const meta = container;
132
+ for (const field of VOLATILE_META_FIELDS) {
133
+ delete meta[field];
134
+ }
135
+ }
136
+ }
137
+ return cloned;
138
+ }
139
+ /**
140
+ * Recursively collect structural differences between two JSON values.
141
+ *
142
+ * Walks both trees in parallel, recording a `{ path, actual, expected }` for each
143
+ * leaf-level divergence. Object key sets and array lengths are compared; the path
144
+ * uses `/`-delimited segments.
145
+ *
146
+ * Key-set semantics depend on the container:
147
+ * - **Subset** (`subset === true`): only the EXPECTED (golden) object's keys are
148
+ * compared. Extra keys present in `actual` but absent from the golden are
149
+ * ignored. Applied to the `meta` container (see {@link SUBSET_COMPARE_KEYS}) so
150
+ * deterministic infra meta keys the runtime stamps but the golden omits are not
151
+ * phantom regressions.
152
+ * - **Full union** (`subset === false`, the default): keys from BOTH objects are
153
+ * compared, so an extra OR missing key is a regression. Applied to the semantic
154
+ * payload (`data`/`error`).
155
+ *
156
+ * A child whose top-level key is in {@link SUBSET_COMPARE_KEYS} (i.e. `meta`)
157
+ * switches its subtree into subset mode.
158
+ *
159
+ * @param actual - The actual (normalized replay) value.
160
+ * @param expected - The expected (golden) value.
161
+ * @param path - Accumulated path prefix.
162
+ * @param out - Mutable accumulator of `{ path, actual, expected }` tuples.
163
+ * @param subset - When `true`, compare only the golden-declared keys at this node.
164
+ */
165
+ function collectStructuralDiffs(actual, expected, path, out, subset = false) {
166
+ if (actual === expected)
167
+ return;
168
+ const bothObjects = actual !== null &&
169
+ expected !== null &&
170
+ typeof actual === 'object' &&
171
+ typeof expected === 'object' &&
172
+ Array.isArray(actual) === Array.isArray(expected);
173
+ if (!bothObjects) {
174
+ out.push({ path, actual, expected });
175
+ return;
176
+ }
177
+ const actualRec = actual;
178
+ const expectedRec = expected;
179
+ // Subset mode (meta container): compare ONLY the golden's keys, so extra
180
+ // deterministic runtime meta keys are not regressions. Full mode: union both
181
+ // key sets, so an extra OR missing payload key IS a regression.
182
+ const keys = subset
183
+ ? new Set(Object.keys(expectedRec))
184
+ : new Set([...Object.keys(actualRec), ...Object.keys(expectedRec)]);
185
+ for (const key of keys) {
186
+ const childPath = path === '' ? key : `${path}/${key}`;
187
+ // A `meta`/`_meta` container's subtree is compared as a subset; never widen
188
+ // back to full-union once inside a subset container.
189
+ const childSubset = subset || SUBSET_COMPARE_KEYS.has(key);
190
+ collectStructuralDiffs(actualRec[key], expectedRec[key], childPath, out, childSubset);
191
+ }
192
+ }
193
+ /**
194
+ * Diff a set of replayed envelopes against the golden envelope set.
195
+ *
196
+ * Normalizes each replayed envelope (volatile meta stripped) and structurally
197
+ * compares it against the positionally-aligned golden entry. The op coordinate
198
+ * for each `DiffEntry` is taken from `ops[opIndex]`. Callers MUST pass aligned
199
+ * arrays (`ops.length === replayed.length === golden.length`); the function
200
+ * diffs up to the shortest length and reports an extra regression for any length
201
+ * mismatch.
202
+ *
203
+ * The `meta` container is compared as a SUBSET (only golden-declared meta keys are
204
+ * asserted) so deterministic-but-golden-absent infra keys the runtime stamps
205
+ * (`specVersion`, `transport`, …) are not phantom regressions; the semantic
206
+ * payload (`data`/`error`) keeps a full key-union compare where an extra or
207
+ * missing key IS a regression. Together with the volatile-lineage strip in
208
+ * {@link normalizeEnvelope}, a real live envelope that matches the golden body
209
+ * yields ZERO regressions.
210
+ *
211
+ * @param ops - The scenario ops (for op-coordinate labelling).
212
+ * @param replayed - The captured envelopes, one per op (replay order).
213
+ * @param golden - The golden expected entries, positionally aligned with `ops`.
214
+ * @returns `{ regressions }` — empty when the replay matches the golden.
215
+ *
216
+ * @example
217
+ * ```ts
218
+ * const { regressions } = diffEnvelopes(scenario.ops, replayed, golden.envelopes);
219
+ * if (regressions.length === 0) { /* happy path — no DHQ, no PR *\/ }
220
+ * ```
221
+ */
222
+ export function diffEnvelopes(ops, replayed, golden) {
223
+ const regressions = [];
224
+ const n = Math.min(ops.length, replayed.length, golden.length);
225
+ for (let i = 0; i < n; i++) {
226
+ const op = ops[i];
227
+ const replayEnvelope = replayed[i];
228
+ const goldenEntry = golden[i];
229
+ if (op === undefined || replayEnvelope === undefined || goldenEntry === undefined)
230
+ continue;
231
+ const opCoord = `${op.domain}.${op.operation}`;
232
+ const normalized = normalizeEnvelope(replayEnvelope);
233
+ const leafDiffs = [];
234
+ collectStructuralDiffs(normalized, goldenEntry, '', leafDiffs);
235
+ for (const d of leafDiffs) {
236
+ regressions.push({
237
+ opIndex: i,
238
+ opCoord,
239
+ path: d.path,
240
+ actual: d.actual,
241
+ expected: d.expected,
242
+ });
243
+ }
244
+ }
245
+ if (replayed.length !== golden.length) {
246
+ regressions.push({
247
+ opIndex: -1,
248
+ opCoord: '<count>',
249
+ path: 'envelopes/length',
250
+ actual: replayed.length,
251
+ expected: golden.length,
252
+ });
253
+ }
254
+ return { regressions };
255
+ }
256
+ /**
257
+ * Extract a targeted field from a normalized envelope's `data` payload.
258
+ *
259
+ * Reuses the LAFS `--field` extractor (`extractFieldFromResult`) for cases where
260
+ * a full structural diff is too brittle and only a specific field's value matters
261
+ * (e.g. assert `data.tasks[0].id` without comparing the whole envelope).
262
+ *
263
+ * @param normalized - A normalized envelope (from {@link normalizeEnvelope}).
264
+ * @param field - The field name to extract from the envelope's `data` payload.
265
+ * @returns The extracted value, or `undefined` when absent.
266
+ *
267
+ * @example
268
+ * ```ts
269
+ * const id = extractTargetedField(normalizeEnvelope(env), 'id');
270
+ * ```
271
+ */
272
+ export function extractTargetedField(normalized, field) {
273
+ const data = normalized.data;
274
+ if (data === undefined || data === null)
275
+ return undefined;
276
+ // The LAFS extractor operates on a result value (object | array | null); the
277
+ // dispatch envelope's `data` is the equivalent payload.
278
+ if (typeof data !== 'object')
279
+ return undefined;
280
+ return extractFieldFromResult(data, field);
281
+ }
282
+ /**
283
+ * Build the deterministic regression signature for a diff result.
284
+ *
285
+ * The signature is the SORTED set of `{ opCoord, path }` pairs from the
286
+ * regressions — NOT the values. Two runs that diverge at the same op coordinates
287
+ * on the same paths produce the same signature (and thus the same
288
+ * {@link computeQuestionHash}), so a repeated regression maps to ONE open DHQ row
289
+ * rather than spamming duplicates. Actual/expected values are intentionally
290
+ * excluded so transient value noise does not fork the hash.
291
+ *
292
+ * @param regressions - The diff regressions.
293
+ * @returns A stable, sorted signature string.
294
+ */
295
+ function regressionSignature(regressions) {
296
+ const pairs = regressions.map((r) => `${r.opCoord}@${r.path}`);
297
+ pairs.sort();
298
+ return pairs.join('\n');
299
+ }
300
+ /**
301
+ * Compute the sha256 `question_hash` of a diff result's normalized signature.
302
+ *
303
+ * The hash is over the {@link regressionSignature} (op coordinates + diff path
304
+ * set), so it is stable across runs of the SAME regression and feeds the
305
+ * idempotency partial-UNIQUE index (`ux_selfimprove_dhq_open`, T11889-A): one
306
+ * open DHQ row per `question_hash`. An empty regression set hashes the empty
307
+ * signature deterministically (callers should not persist on the happy path).
308
+ *
309
+ * @param result - The diff result whose regressions are hashed.
310
+ * @returns The lowercase hex sha256 of the regression signature.
311
+ *
312
+ * @example
313
+ * ```ts
314
+ * const hash = computeQuestionHash(diffEnvelopes(ops, replayed, golden));
315
+ * ```
316
+ */
317
+ export function computeQuestionHash(result) {
318
+ const signature = regressionSignature(result.regressions);
319
+ return createHash('sha256').update(signature, 'utf-8').digest('hex');
320
+ }
321
+ //# sourceMappingURL=envelope-diff.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"envelope-diff.js","sourceRoot":"","sources":["../../src/selfimprove/envelope-diff.ts"],"names":[],"mappings":"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"}