@cortexkit/opencode-magic-context 0.49.11 → 0.49.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 (253) hide show
  1. package/README.md +1 -1
  2. package/dist/agents/smart-notes-dreamer-gate.fixture.d.ts +28 -0
  3. package/dist/agents/smart-notes-dreamer-gate.fixture.d.ts.map +1 -0
  4. package/dist/{announcement-hdbkt8v5.js → announcement-g789dmt6.js} +2 -2
  5. package/dist/auto-search-worker.js +4 -4
  6. package/dist/chunk-embedding-write-worker.js +89 -0
  7. package/dist/{compaction-marker-candidates-xxz35vwp.js → compaction-marker-candidates-v5c6997n.js} +3 -3
  8. package/dist/compaction-marker-candidates-worker.js +1 -1
  9. package/dist/config/agent-disable.d.ts +14 -0
  10. package/dist/config/agent-disable.d.ts.map +1 -1
  11. package/dist/config/dependency-notes.d.ts +34 -0
  12. package/dist/config/dependency-notes.d.ts.map +1 -0
  13. package/dist/config/schema/agent-overrides.d.ts +12 -12
  14. package/dist/config/schema/magic-context.d.ts +88 -88
  15. package/dist/config/schema/magic-context.d.ts.map +1 -1
  16. package/dist/{conflict-warning-hook-xwkfncav.js → conflict-warning-hook-mgq17yr3.js} +8 -8
  17. package/dist/{context-twz3s0cg.js → context-azqk0vfd.js} +121 -145
  18. package/dist/{derive-budgets-3nbxsyss.js → derive-budgets-zn7yzd2d.js} +3 -3
  19. package/dist/embedding-backfill-5e1t5wha.js +22 -0
  20. package/dist/embedding-worker-process.js +2 -2
  21. package/dist/embedding-worker.js +6 -6
  22. package/dist/features/magic-context/chunk-embedding-write-worker.d.ts +2 -0
  23. package/dist/features/magic-context/chunk-embedding-write-worker.d.ts.map +1 -0
  24. package/dist/features/magic-context/chunk-embedding-writer.d.ts +48 -0
  25. package/dist/features/magic-context/chunk-embedding-writer.d.ts.map +1 -0
  26. package/dist/features/magic-context/compartment-chunk-embedding.d.ts +1 -1
  27. package/dist/features/magic-context/compartment-chunk-embedding.d.ts.map +1 -1
  28. package/dist/features/magic-context/dreamer/hidden-single-shot.d.ts +3 -2
  29. package/dist/features/magic-context/dreamer/hidden-single-shot.d.ts.map +1 -1
  30. package/dist/features/magic-context/dreamer/map-memories.d.ts +8 -1
  31. package/dist/features/magic-context/dreamer/map-memories.d.ts.map +1 -1
  32. package/dist/features/magic-context/dreamer/retrospective-raw-provider.d.ts +2 -0
  33. package/dist/features/magic-context/dreamer/retrospective-raw-provider.d.ts.map +1 -1
  34. package/dist/features/magic-context/dreamer/storage-dream-runs.d.ts +5 -0
  35. package/dist/features/magic-context/dreamer/storage-dream-runs.d.ts.map +1 -1
  36. package/dist/features/magic-context/dreamer/task-config.d.ts +22 -4
  37. package/dist/features/magic-context/dreamer/task-config.d.ts.map +1 -1
  38. package/dist/features/magic-context/dreamer/task-executor.d.ts.map +1 -1
  39. package/dist/features/magic-context/dreamer/task-registry.d.ts +22 -0
  40. package/dist/features/magic-context/dreamer/task-registry.d.ts.map +1 -1
  41. package/dist/features/magic-context/dreamer/task-scheduler.d.ts +4 -1
  42. package/dist/features/magic-context/dreamer/task-scheduler.d.ts.map +1 -1
  43. package/dist/features/magic-context/dreamer/verify-prompt.d.ts +6 -1
  44. package/dist/features/magic-context/dreamer/verify-prompt.d.ts.map +1 -1
  45. package/dist/features/magic-context/dreamer/verify.d.ts +25 -11
  46. package/dist/features/magic-context/dreamer/verify.d.ts.map +1 -1
  47. package/dist/features/magic-context/memory/embedding-openai.d.ts +32 -0
  48. package/dist/features/magic-context/memory/embedding-openai.d.ts.map +1 -1
  49. package/dist/features/magic-context/memory/project-identity.d.ts +1 -0
  50. package/dist/features/magic-context/memory/project-identity.d.ts.map +1 -1
  51. package/dist/features/magic-context/memory/unborn-head.d.ts +34 -0
  52. package/dist/features/magic-context/memory/unborn-head.d.ts.map +1 -0
  53. package/dist/features/magic-context/mural/compress-cues.d.ts +3 -0
  54. package/dist/features/magic-context/mural/compress-cues.d.ts.map +1 -1
  55. package/dist/features/magic-context/project-embedding-registry.d.ts +5 -0
  56. package/dist/features/magic-context/project-embedding-registry.d.ts.map +1 -1
  57. package/dist/features/magic-context/storage-tags.d.ts +2 -0
  58. package/dist/features/magic-context/storage-tags.d.ts.map +1 -1
  59. package/dist/{history-owner-ty29fz0f.js → history-owner-xp3pngv7.js} +3 -3
  60. package/dist/hooks/magic-context/apply-operations.d.ts.map +1 -1
  61. package/dist/hooks/magic-context/auto-embed-session.d.ts +10 -0
  62. package/dist/hooks/magic-context/auto-embed-session.d.ts.map +1 -0
  63. package/dist/hooks/magic-context/compartment-prompt.d.ts +6 -0
  64. package/dist/hooks/magic-context/compartment-prompt.d.ts.map +1 -1
  65. package/dist/hooks/magic-context/compartment-runner-incremental.d.ts.map +1 -1
  66. package/dist/hooks/magic-context/compartment-runner-types.d.ts +3 -0
  67. package/dist/hooks/magic-context/compartment-runner-types.d.ts.map +1 -1
  68. package/dist/hooks/magic-context/compartment-trigger-error.d.ts +12 -0
  69. package/dist/hooks/magic-context/compartment-trigger-error.d.ts.map +1 -0
  70. package/dist/hooks/magic-context/embed-session-state.d.ts +8 -1
  71. package/dist/hooks/magic-context/embed-session-state.d.ts.map +1 -1
  72. package/dist/hooks/magic-context/historian-prompt-fit.d.ts +2 -0
  73. package/dist/hooks/magic-context/historian-prompt-fit.d.ts.map +1 -1
  74. package/dist/hooks/magic-context/hook.d.ts +3 -1
  75. package/dist/hooks/magic-context/hook.d.ts.map +1 -1
  76. package/dist/hooks/magic-context/pending-materialization.d.ts +2 -0
  77. package/dist/hooks/magic-context/pending-materialization.d.ts.map +1 -1
  78. package/dist/hooks/magic-context/protected-tail-boundary.d.ts +12 -0
  79. package/dist/hooks/magic-context/protected-tail-boundary.d.ts.map +1 -1
  80. package/dist/hooks/magic-context/raw-exact-ordinal-read.d.ts +58 -0
  81. package/dist/hooks/magic-context/raw-exact-ordinal-read.d.ts.map +1 -0
  82. package/dist/hooks/magic-context/raw-ordinal-warmup.d.ts +7 -0
  83. package/dist/hooks/magic-context/raw-ordinal-warmup.d.ts.map +1 -1
  84. package/dist/hooks/magic-context/read-session-raw.d.ts +19 -0
  85. package/dist/hooks/magic-context/read-session-raw.d.ts.map +1 -1
  86. package/dist/hooks/magic-context/recomp-orchestrator.d.ts +2 -0
  87. package/dist/hooks/magic-context/recomp-orchestrator.d.ts.map +1 -1
  88. package/dist/hooks/magic-context/transform-compartment-phase.d.ts +2 -0
  89. package/dist/hooks/magic-context/transform-compartment-phase.d.ts.map +1 -1
  90. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
  91. package/dist/hooks/magic-context/transform.d.ts +4 -0
  92. package/dist/hooks/magic-context/transform.d.ts.map +1 -1
  93. package/dist/hooks/magic-context/wrapup-orchestrator.d.ts.map +1 -1
  94. package/dist/{index-bzp9s8z2.js → index-1d289pq2.js} +2 -2
  95. package/dist/{index-w28y7d0z.js → index-1sarmj9z.js} +15 -15
  96. package/dist/{index-z7avx6rw.js → index-2jr1smmh.js} +280 -160
  97. package/dist/{index-4ccdr7yw.js → index-3kdm78zp.js} +5 -5
  98. package/dist/{index-9159kk15.js → index-3kx0kg0f.js} +64 -7
  99. package/dist/{index-0jz47061.js → index-a8bvhwqs.js} +190 -30
  100. package/dist/{index-84j7jq8a.js → index-aw1bh90w.js} +10 -10
  101. package/dist/{index-qr1mkc2y.js → index-b16gpywn.js} +9 -9
  102. package/dist/{index-g7jkrz0x.js → index-bp5083x2.js} +1 -1
  103. package/dist/{index-yhrrx7qa.js → index-bxdg2nbt.js} +3 -3
  104. package/dist/{index-0abg88h2.js → index-dgs16axy.js} +4 -4
  105. package/dist/{index-mp2kghkv.js → index-dyvbsvga.js} +1 -1
  106. package/dist/{index-bmwfzz28.js → index-e20m7284.js} +4 -4
  107. package/dist/{index-4jkhhpn1.js → index-e4dsjj1p.js} +3 -3
  108. package/dist/{index-s178h9z8.js → index-f71thw8j.js} +1 -1
  109. package/dist/{index-kvw6xew3.js → index-fkx2qnvw.js} +2 -2
  110. package/dist/{index-f8cn4xqa.js → index-fwefky9w.js} +18 -5
  111. package/dist/{index-0sahzkwr.js → index-g2q4htwp.js} +46 -2
  112. package/dist/{index-mw7c950g.js → index-gp3kcpc4.js} +1 -1
  113. package/dist/{index-g40wgxxt.js → index-hnm8raee.js} +4 -4
  114. package/dist/{index-gjvjh960.js → index-hqkczed7.js} +1 -1
  115. package/dist/{index-mvvephtj.js → index-j75v2476.js} +1 -1
  116. package/dist/{index-150zz6fh.js → index-k29z4aqh.js} +1 -1
  117. package/dist/{index-b64n4d0h.js → index-kee4kn5j.js} +1 -1
  118. package/dist/index-ksdyrrav.js +52 -0
  119. package/dist/{index-angx1s0k.js → index-mmfa86mt.js} +16 -6
  120. package/dist/{index-9jvab89d.js → index-n6m03s3n.js} +2 -2
  121. package/dist/{index-q28hsbpg.js → index-nj7yykkx.js} +1 -1
  122. package/dist/{index-ghc9f0n7.js → index-p5y3k4g7.js} +29 -1
  123. package/dist/{index-xztdf9t7.js → index-qkd9zz0p.js} +17 -17
  124. package/dist/index-saews2s3.js +229 -0
  125. package/dist/{index-kkvxnbt8.js → index-sj89f3b0.js} +62 -33
  126. package/dist/{index-jw4gbfkv.js → index-v10f1rjv.js} +5 -5
  127. package/dist/{index-0j6crjgh.js → index-v13skev1.js} +13 -13
  128. package/dist/{index-hqnggmxn.js → index-wj6ht7nm.js} +547 -179
  129. package/dist/{index-a865mj02.js → index-wk0n1cgt.js} +4 -4
  130. package/dist/{index-q3qck7j2.js → index-wz6mzzb1.js} +6 -5
  131. package/dist/{index-se1w3v2m.js → index-y1qysm3q.js} +332 -256
  132. package/dist/{index-a4b0gbyg.js → index-y9f76s3f.js} +1 -1
  133. package/dist/index.d.ts.map +1 -1
  134. package/dist/index.js +119 -129
  135. package/dist/{logger-wn328tfg.js → logger-jm3sqqzr.js} +2 -2
  136. package/dist/{message-index-bounded-0rbbg9rd.js → message-index-bounded-vm64mqpq.js} +16 -16
  137. package/dist/{message-index-ct5x2kwa.js → message-index-seaqpb7c.js} +16 -16
  138. package/dist/{message-time-backfill-nb5hhnrt.js → message-time-backfill-qjge9044.js} +3 -3
  139. package/dist/migration-worker.js +11 -11
  140. package/dist/plugin/dream-timer.d.ts.map +1 -1
  141. package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
  142. package/dist/plugin/tool-registry.d.ts.map +1 -1
  143. package/dist/{project-embedding-registry-ft9gh2e2.js → project-embedding-registry-x45bv3qr.js} +12 -11
  144. package/dist/raw-ordinal-warmup-worker.js +12 -7
  145. package/dist/{read-session-chunk-y3hhsbzw.js → read-session-chunk-ax05f7gr.js} +11 -11
  146. package/dist/{read-session-raw-gm6xj30v.js → read-session-raw-m56hc7v2.js} +7 -3
  147. package/dist/recomp-orchestrator-dmbeadwt.js +61 -0
  148. package/dist/{safe-notification-target-jdynm677.js → safe-notification-target-1szv1k5k.js} +3 -3
  149. package/dist/{search-jd8xh721.js → search-5yd5ytzs.js} +25 -24
  150. package/dist/{send-session-notification-vzhj8bsg.js → send-session-notification-24r4esbh.js} +6 -6
  151. package/dist/shared/data-path.d.ts +4 -0
  152. package/dist/shared/data-path.d.ts.map +1 -1
  153. package/dist/shared/model-suggestion-retry.d.ts +2 -0
  154. package/dist/shared/model-suggestion-retry.d.ts.map +1 -1
  155. package/dist/shared/prompt-async-transport.d.ts.map +1 -1
  156. package/dist/{storage-tags-35m4gms2.js → storage-tags-yygfb9c8.js} +7 -5
  157. package/dist/{task-config-cgpg0nvh.js → task-config-x3qmayd2.js} +6 -2
  158. package/dist/tools/ctx-note/tools.d.ts.map +1 -1
  159. package/dist/{transform-postprocess-phase-pmqxfq4q.js → transform-postprocess-phase-72v86syx.js} +32 -31
  160. package/dist/v2/auto-search-worker.js +4 -4
  161. package/dist/v2/chunk-embedding-write-worker.js +88 -0
  162. package/dist/v2/{compaction-marker-candidates-a15w3mqh.js → compaction-marker-candidates-1vqwr3s5.js} +2 -2
  163. package/dist/v2/compaction-marker-candidates-worker.js +1 -1
  164. package/dist/v2/{context-p1zfcw41.js → context-w055w17c.js} +628 -255
  165. package/dist/v2/{derive-budgets-0rmpmxjw.js → derive-budgets-2zh4gm2c.js} +3 -3
  166. package/dist/v2/embedding-backfill-jmaf8zrr.js +21 -0
  167. package/dist/v2/embedding-worker-process.js +1 -1
  168. package/dist/v2/embedding-worker.js +5 -5
  169. package/dist/v2/{history-owner-2cr9py37.js → history-owner-42e16w0n.js} +2 -2
  170. package/dist/v2/hooks/context.d.ts.map +1 -1
  171. package/dist/v2/hooks/dream-manual.d.ts.map +1 -1
  172. package/dist/v2/hooks/dream-trigger.d.ts +1 -1
  173. package/dist/v2/hooks/dream-trigger.d.ts.map +1 -1
  174. package/dist/v2/hooks/hidden-child.d.ts.map +1 -1
  175. package/dist/v2/hooks/transform-features.d.ts +3 -2
  176. package/dist/v2/hooks/transform-features.d.ts.map +1 -1
  177. package/dist/v2/{logger-te6e1j72.js → logger-7qt02bnb.js} +1 -1
  178. package/dist/v2/{message-index-bounded-7wcbp975.js → message-index-bounded-wepg5723.js} +15 -15
  179. package/dist/v2/{message-index-cjhv92m2.js → message-index-gcmd0ng0.js} +15 -15
  180. package/dist/v2/{message-time-backfill-rz1pnpaj.js → message-time-backfill-bsteyc4d.js} +2 -2
  181. package/dist/v2/migration-worker.js +10 -10
  182. package/dist/v2/{project-embedding-registry-g34gcf74.js → project-embedding-registry-0msp56p8.js} +11 -10
  183. package/dist/v2/raw-ordinal-warmup-worker.js +12 -7
  184. package/dist/v2/{read-session-chunk-8d3v87vr.js → read-session-chunk-hr3w5bjk.js} +10 -10
  185. package/dist/v2/{read-session-raw-h4azh85b.js → read-session-raw-b3tf6ra1.js} +6 -2
  186. package/dist/v2/recomp-orchestrator-ca7qt75a.js +60 -0
  187. package/dist/v2/retrospective-raw-provider.d.ts.map +1 -1
  188. package/dist/v2/{safe-notification-target-936374xx.js → safe-notification-target-qg7n2s77.js} +2 -2
  189. package/dist/v2/{search-a1acjwf8.js → search-c86dcv14.js} +24 -23
  190. package/dist/v2/{send-session-notification-z5mcjdea.js → send-session-notification-8ghn9tnv.js} +5 -5
  191. package/dist/v2/{server-npm52h2q.js → server-05xjtq6c.js} +1 -1
  192. package/dist/v2/{server-s6jqh8bj.js → server-0ppsweh6.js} +1 -1
  193. package/dist/v2/server-0s95v3en.js +49 -0
  194. package/dist/v2/{server-hn9fb3v0.js → server-34kwfsr4.js} +2 -2
  195. package/dist/v2/server-4gn3z5an.js +229 -0
  196. package/dist/v2/{server-kn7skz9r.js → server-6cdy4rc0.js} +3 -3
  197. package/dist/v2/{server-7dv9wt9r.js → server-6pmqg9m4.js} +1 -1
  198. package/dist/v2/{server-7fvmt15t.js → server-b81w6sw3.js} +273 -107
  199. package/dist/v2/{server-kmapq3v0.js → server-bxpwy6fy.js} +18 -5
  200. package/dist/v2/{server-d6t16r89.js → server-d8tj10db.js} +1 -1
  201. package/dist/v2/{server-cxsr0ng6.js → server-da07v4xp.js} +1 -1
  202. package/dist/v2/{server-rxcq4t50.js → server-ef89gdsx.js} +5 -5
  203. package/dist/v2/{server-9e5r8y60.js → server-f2xf5gcb.js} +46 -2
  204. package/dist/v2/{server-83d71zab.js → server-g10mdym6.js} +3 -3
  205. package/dist/v2/{server-njnx39q2.js → server-gvkm8xaj.js} +189 -29
  206. package/dist/v2/{server-ckrb5rm8.js → server-h0410h0v.js} +1 -1
  207. package/dist/v2/{server-sg68np13.js → server-hek6z3w6.js} +330 -254
  208. package/dist/v2/{server-f27he3j1.js → server-k2bzedxk.js} +4 -4
  209. package/dist/v2/{server-wkhfyzpg.js → server-m97brnat.js} +9 -9
  210. package/dist/v2/{server-erfp0xb6.js → server-n8ch9683.js} +16 -16
  211. package/dist/v2/{server-bx59ezg6.js → server-prg55b7k.js} +16 -6
  212. package/dist/v2/{server-89fcbe37.js → server-pwv4ezb0.js} +1 -1
  213. package/dist/v2/{server-r5p3b1wy.js → server-qd11g795.js} +29 -1
  214. package/dist/v2/{server-ewqshbs8.js → server-qhfvvfxj.js} +64 -7
  215. package/dist/v2/{server-988cqjme.js → server-rrqpvwqd.js} +2 -2
  216. package/dist/v2/{server-d3f4g62c.js → server-t4prcjc1.js} +13 -13
  217. package/dist/v2/{server-nveratm5.js → server-tbe1femw.js} +4 -4
  218. package/dist/v2/{server-jc8v585p.js → server-th4y11y7.js} +15 -15
  219. package/dist/v2/{server-h3wc20sv.js → server-vbe4se57.js} +4 -4
  220. package/dist/v2/{server-pbpp8r8h.js → server-xh7jar6k.js} +9 -9
  221. package/dist/v2/{server-63ha7f0f.js → server-yrvqaswb.js} +1 -1
  222. package/dist/v2/{server-5x7kmyz8.js → server-zc3e54vy.js} +10 -51
  223. package/dist/v2/{server-xqf2d2mg.js → server-zs8d0s3b.js} +2 -2
  224. package/dist/v2/server.d.ts.map +1 -1
  225. package/dist/v2/server.js +18 -10
  226. package/dist/v2/{storage-tags-c4zfcxv4.js → storage-tags-a2gq6dw7.js} +6 -4
  227. package/dist/v2/store-reader.d.ts +1 -0
  228. package/dist/v2/store-reader.d.ts.map +1 -1
  229. package/dist/v2/{task-config-x0hq3qfd.js → task-config-nvz8mapa.js} +6 -2
  230. package/dist/v2/{wrapup-orchestrator-87q9d5e2.js → wrapup-orchestrator-e1a2w6jh.js} +31 -29
  231. package/dist/wrapup-orchestrator-2051r6qm.js +48 -0
  232. package/package.json +6 -5
  233. package/src/agents/smart-notes-dreamer-gate.fixture.ts +171 -0
  234. package/src/agents/smart-notes-dreamer-gate.golden.json +245 -0
  235. package/src/agents/smart-notes-dreamer-gate.test.ts +161 -0
  236. package/src/config/agent-disable.ts +13 -0
  237. package/src/config/dependency-notes.test.ts +114 -0
  238. package/src/config/dependency-notes.ts +80 -0
  239. package/src/config/schema/magic-context.ts +23 -14
  240. package/src/features/magic-context/dreamer/task-registry.ts +40 -0
  241. package/src/shared/data-path.test.ts +35 -1
  242. package/src/shared/data-path.ts +57 -1
  243. package/src/shared/model-suggestion-retry.test.ts +34 -0
  244. package/src/shared/model-suggestion-retry.ts +23 -3
  245. package/src/shared/prompt-async-transport.test.ts +1 -1
  246. package/src/shared/prompt-async-transport.ts +16 -3
  247. package/dist/embedding-backfill-fjbfh1dt.js +0 -21
  248. package/dist/recomp-orchestrator-67k45s0b.js +0 -60
  249. package/dist/v2/embedding-backfill-xcw3t6hp.js +0 -20
  250. package/dist/v2/recomp-orchestrator-n0pq36f0.js +0 -59
  251. package/dist/wrapup-orchestrator-jqapepw0.js +0 -47
  252. /package/dist/{index-e6xnpach.js → index-b7p25tm0.js} +0 -0
  253. /package/dist/v2/{index-e6xnpach.js → index-b7p25tm0.js} +0 -0
@@ -1,15 +1,12 @@
1
1
  import {
2
2
  getMagicContextBuiltinCommands,
3
3
  readJsoncFile,
4
- COMPACTION_ENABLED_PATH,
5
- isDreamerRunnable,
6
- isCompactionEnabled,
7
4
  cortexKitUserConfigBasePath,
8
5
  cortexKitProjectConfigBasePath,
9
6
  resolveLegacyConfigSources,
10
7
  getProtectedTokensTierOverrides,
11
8
  loadPluginConfigDetailed
12
- } from "./server-5x7kmyz8.js";
9
+ } from "./server-zc3e54vy.js";
13
10
  import {
14
11
  getHarness2,
15
12
  harnessOwnsOpenCodeStore2
@@ -24,7 +21,7 @@ import {
24
21
  log2,
25
22
  sessionLog2,
26
23
  getLoggerDiagnostics2
27
- } from "./server-9e5r8y60.js";
24
+ } from "./server-f2xf5gcb.js";
28
25
  import {
29
26
  hasTrustedAbsoluteWall,
30
27
  applyProvenInputFloor,
@@ -36,7 +33,7 @@ import {
36
33
  getSdkContextLimit,
37
34
  getSdkOutputLimit,
38
35
  getModelsDevCacheState
39
- } from "./server-nveratm5.js";
36
+ } from "./server-tbe1femw.js";
40
37
  import {
41
38
  isValidLanguageCode,
42
39
  withContentLanguageDirective,
@@ -49,20 +46,31 @@ import {
49
46
  DEFAULT_HISTORIAN_TIMEOUT_MS,
50
47
  DEFAULT_LOCAL_EMBEDDING_MODEL,
51
48
  DREAM_TASK_PROMOTION_DEFAULTS
52
- } from "./server-jc8v585p.js";
49
+ } from "./server-th4y11y7.js";
50
+ import {
51
+ CANONICAL_DREAM_TASKS,
52
+ DREAM_TASK_CAPABILITIES,
53
+ toolLoopDreamTasks,
54
+ formatUnsupportedDreamTasks,
55
+ formatDreamTaskBacklogs,
56
+ processedDreamTaskItems,
57
+ PROJECT_MEMORY_DREAM_TASKS,
58
+ dreamTaskAllowedBySettings,
59
+ leaseKindFor,
60
+ leaseKeyFor,
61
+ isCanonicalDreamTask,
62
+ compareTaskOrder,
63
+ buildDreamTaskRuntimeConfigs2,
64
+ userMemoryCollectionEnabled2,
65
+ userObservationCollectionEnabled2,
66
+ userObservationsRequested2
67
+ } from "./server-qd11g795.js";
53
68
  import {
54
69
  historianRunConfig,
55
70
  dreamerRunConfig,
56
71
  pluginConfigReader,
57
72
  currentPluginConfigReader,
58
73
  withLiveDreamerOutputCap,
59
- embedPauseBySession,
60
- embedRunStateBySession,
61
- autoEmbedAttemptedBySession,
62
- autoEmbedIdentityBySession,
63
- invalidateAutoEmbedSession,
64
- getEmbedDrainUiStatus,
65
- clearEmbedSessionState,
66
74
  acquireCompartmentLease,
67
75
  releaseCompartmentLeaseBestEffort,
68
76
  isCompartmentLeaseHeld,
@@ -91,6 +99,7 @@ import {
91
99
  clearSession,
92
100
  requestPendingMaterialization,
93
101
  pendingMaterializationOrigin,
102
+ hasPendingMaterializationOrigin,
94
103
  clearPendingMaterialization,
95
104
  recordSystemPromptForRequest,
96
105
  recordHeldHeadForRequest,
@@ -198,9 +207,11 @@ import {
198
207
  toModelEntry,
199
208
  isPromptTimeoutError,
200
209
  getPromptFailureDetail,
210
+ raceWithSignal,
201
211
  promptSyncWithValidatedOutputRetry,
202
212
  normalizeSDKResponse,
203
213
  failedInvocationStatus,
214
+ sumTokensFromChildMessages,
204
215
  recordChildInvocation,
205
216
  createPromptAsyncTransport,
206
217
  CTX_NOTE_LIGHT_DESCRIPTION,
@@ -211,7 +222,6 @@ import {
211
222
  MARKER_SUMMARY_TEXT,
212
223
  markerUpdateDefinitelyDidNotCut,
213
224
  applyDeferredCompactionMarker,
214
- isProjectMemoryEnabled,
215
225
  teardownChildSession,
216
226
  runTokenLog,
217
227
  formatRunTokenLog,
@@ -266,25 +276,12 @@ import {
266
276
  getRawHistoryEligibility,
267
277
  hasRunnableCompartmentWindow,
268
278
  recordHighPressureNoEligibleHead,
279
+ noteTransformPassForExactOrdinalReads,
269
280
  getActiveCompartmentRun,
270
281
  startCompartmentAgent,
271
282
  setRecompStarting2,
272
283
  setRecompTerminal2
273
- } from "./server-7fvmt15t.js";
274
- import {
275
- CANONICAL_DREAM_TASKS,
276
- DREAM_TASK_CAPABILITIES,
277
- toolLoopDreamTasks,
278
- formatUnsupportedDreamTasks,
279
- formatDreamTaskBacklogs,
280
- processedDreamTaskItems,
281
- leaseKindFor,
282
- leaseKeyFor,
283
- isCanonicalDreamTask,
284
- compareTaskOrder,
285
- buildDreamTaskRuntimeConfigs2,
286
- userMemoryCollectionEnabled2
287
- } from "./server-r5p3b1wy.js";
284
+ } from "./server-b81w6sw3.js";
288
285
  import {
289
286
  resolveHistorianModel2
290
287
  } from "./server-8cd2j99z.js";
@@ -309,7 +306,7 @@ import {
309
306
  openDatabaseAsync,
310
307
  isDatabasePersisted,
311
308
  getDatabasePersistenceError
312
- } from "./server-erfp0xb6.js";
309
+ } from "./server-n8ch9683.js";
313
310
  import {
314
311
  setHomeProjectPermission,
315
312
  shouldSkipHomeProjectMemory,
@@ -325,7 +322,7 @@ import {
325
322
  storedPathBelongsToIdentity,
326
323
  beginBootQuietPeriod,
327
324
  scheduleAfterBootQuiet
328
- } from "./server-njnx39q2.js";
325
+ } from "./server-gvkm8xaj.js";
329
326
  import {
330
327
  detectLatestTurnThinkingMismatch,
331
328
  isPrefixBoundThinkingModel,
@@ -512,7 +509,36 @@ import {
512
509
  readRawSessionMessageById2,
513
510
  readSessionChunk2,
514
511
  readRawSessionSeedTail2
515
- } from "./server-wkhfyzpg.js";
512
+ } from "./server-m97brnat.js";
513
+ import {
514
+ embedPauseBySession,
515
+ embedRunStateBySession,
516
+ activeEmbeddingSessions,
517
+ autoEmbedAttemptedBySession,
518
+ autoEmbedIdentityBySession,
519
+ autoEmbedRetryAfterBySession,
520
+ invalidateAutoEmbedSession,
521
+ getEmbedDrainUiStatus,
522
+ clearEmbedSessionState,
523
+ describeShadowBackfillWriteRefusal2,
524
+ markProjectLoadUntrusted2,
525
+ drainProjectEmbeddingIdentityMaintenance2,
526
+ drainStaleEmbeddingIdentitiesForProject2,
527
+ registerProjectEmbedding2,
528
+ registerProjectShadowEmbedding2,
529
+ enqueueShadowEmbeddingItems2,
530
+ registerProjectInObservationMode2,
531
+ unregisterProjectShadowEmbedding2,
532
+ getProjectEmbeddingSnapshot2,
533
+ embedTextForProject2,
534
+ embedBatchForProject2,
535
+ embedUnembeddedMemoriesForProject2,
536
+ embedUnembeddedMemoriesForProjectOutcome2,
537
+ drainCommitBacklogForProject2,
538
+ embedSessionCompartmentChunks2,
539
+ getEmbeddingCoverageStatus2,
540
+ getAutoEmbeddingSessionCoverage2
541
+ } from "./server-hek6z3w6.js";
516
542
  import {
517
543
  textMentionsRecentCommit,
518
544
  hasMeaningfulUserText2,
@@ -523,7 +549,7 @@ import {
523
549
  estimateTokens,
524
550
  estimateFixedPromptTokens,
525
551
  normalizeText
526
- } from "./server-s6jqh8bj.js";
552
+ } from "./server-0ppsweh6.js";
527
553
  import {
528
554
  SubcClient,
529
555
  connectionFileExists,
@@ -531,7 +557,7 @@ import {
531
557
  toSynapseLaneDescriptor,
532
558
  formatSynapseLaneDescriptor,
533
559
  SynapseEmbeddingProvider
534
- } from "./server-988cqjme.js";
560
+ } from "./server-rrqpvwqd.js";
535
561
  import {
536
562
  inRootAsyncContext2,
537
563
  getTagIdentityWriteGeneration2,
@@ -546,17 +572,17 @@ import {
546
572
  SqliteAcquisitionBusyError2,
547
573
  withAsyncPrivilegedWriter2
548
574
  } from "./server-wafzvyhg.js";
549
- import"./server-63ha7f0f.js";
575
+ import"./server-yrvqaswb.js";
550
576
  import {
551
577
  deleteChunkEmbedBackoffForSession
552
- } from "./server-ewqshbs8.js";
578
+ } from "./server-qhfvvfxj.js";
553
579
  import {
554
580
  registerOwnRpcServerInstance,
555
581
  rpcPortDir,
556
582
  rpcPortFilePath,
557
583
  parseRpcPortFile,
558
584
  inspectProcessesAsync
559
- } from "./server-cxsr0ng6.js";
585
+ } from "./server-da07v4xp.js";
560
586
  import {
561
587
  BoundedSessionMap,
562
588
  LkgRecoveryFenceError,
@@ -575,14 +601,14 @@ import {
575
601
  isMessageIndexReconciledThrough2,
576
602
  indexMessagesAfterOrdinal2,
577
603
  sweepOrphanedOpenCodeMessageIndexes2
578
- } from "./server-d3f4g62c.js";
604
+ } from "./server-t4prcjc1.js";
579
605
  import {
580
606
  stableStringify,
581
607
  getTemporalDecisions,
582
608
  observeTemporalDecisions,
583
609
  freezeTemporalDecisions,
584
610
  tagIdentityRevisionKey
585
- } from "./server-89fcbe37.js";
611
+ } from "./server-pwv4ezb0.js";
586
612
  import {
587
613
  resolveModelCalibration,
588
614
  calibrateBuckets,
@@ -649,6 +675,7 @@ import {
649
675
  backfillTagTokenCounts2,
650
676
  insertTag2,
651
677
  updateTagStatus2,
678
+ markTagDropped2,
652
679
  markWhitespaceAssistantTagInert2,
653
680
  getInertWhitespaceAssistantTags2,
654
681
  getInertWhitespaceAssistantTagsByNumbers2,
@@ -674,14 +701,15 @@ import {
674
701
  adoptNullOwnerToolTag2,
675
702
  getCandidateToolOwners2,
676
703
  pickNearestPriorOwner2
677
- } from "./server-kmapq3v0.js";
704
+ } from "./server-bxpwy6fy.js";
678
705
  import"./server-51779zs2.js";
679
706
  import {
680
707
  isRawCompactionSummaryInfo2,
681
708
  extractInMemoryMessageViews2,
682
709
  buildInMemoryTailRawMessages2,
710
+ RawOrdinalsNotReady2,
683
711
  runSessionWarmupWorker
684
- } from "./server-bx59ezg6.js";
712
+ } from "./server-prg55b7k.js";
685
713
  import {
686
714
  resolveOpenCodeDbPath,
687
715
  assertOpenCodeStoreGeneration,
@@ -697,12 +725,12 @@ import {
697
725
  latestRealUserTurnIdFromOpenCodeDb,
698
726
  getMessageTimesFromOpenCodeDb,
699
727
  findLastAssistantModelFromOpenCodeDb
700
- } from "./server-d6t16r89.js";
728
+ } from "./server-d8tj10db.js";
701
729
  import {
702
730
  getCurrentToolSetHash,
703
731
  recordToolDefinition,
704
732
  getMeasuredToolDefinitionTokens
705
- } from "./server-xqf2d2mg.js";
733
+ } from "./server-zs8d0s3b.js";
706
734
  import {
707
735
  V2_MEMORY_CATEGORIES,
708
736
  CATEGORY_PRIORITY
@@ -715,35 +743,7 @@ import {
715
743
  resolveStoredPathWorkspaceIdentity,
716
744
  storedPathBelongsToWorkspace,
717
745
  computeWorkspaceEpochFingerprint
718
- } from "./server-f27he3j1.js";
719
- import {
720
- GIT_SWEEP_LEASE_RENEWAL_MS,
721
- acquireGitSweepLease,
722
- renewGitSweepLease,
723
- markGitSweepSuccessAndRelease,
724
- parkGitSweepNonIndexable,
725
- releaseGitSweepLease,
726
- recordSessionProjectIdentity,
727
- hasRecordedSessionProjectIdentity,
728
- describeShadowBackfillWriteRefusal2,
729
- markProjectLoadUntrusted2,
730
- drainProjectEmbeddingIdentityMaintenance2,
731
- drainStaleEmbeddingIdentitiesForProject2,
732
- registerProjectEmbedding2,
733
- registerProjectShadowEmbedding2,
734
- enqueueShadowEmbeddingItems2,
735
- registerProjectInObservationMode2,
736
- unregisterProjectShadowEmbedding2,
737
- getProjectEmbeddingSnapshot2,
738
- embedTextForProject2,
739
- embedBatchForProject2,
740
- embedUnembeddedMemoriesForProject2,
741
- embedUnembeddedMemoriesForProjectOutcome2,
742
- drainCommitBacklogForProject2,
743
- embedSessionCompartmentChunks2,
744
- getEmbeddingCoverageStatus2,
745
- getAutoEmbeddingSessionCoverage2
746
- } from "./server-sg68np13.js";
746
+ } from "./server-k2bzedxk.js";
747
747
  import {
748
748
  configureContextDatabasePragmas2
749
749
  } from "./server-fb3zxn06.js";
@@ -789,18 +789,28 @@ import {
789
789
  readGitFileChangeTimesSince,
790
790
  verificationFileExists,
791
791
  normalizeVerificationFiles
792
- } from "./server-kn7skz9r.js";
792
+ } from "./server-6cdy4rc0.js";
793
793
  import {
794
794
  deriveTriggerBudget2,
795
795
  deriveHistorianChunkTokens2,
796
796
  resolveKnownHistorianContextLimit2,
797
797
  resolveHistorianProducerLimits2,
798
798
  resolveHistorianContextLimit2
799
- } from "./server-hn9fb3v0.js";
800
- import"./server-npm52h2q.js";
799
+ } from "./server-34kwfsr4.js";
800
+ import"./server-05xjtq6c.js";
801
801
  import {
802
802
  isEmbeddingHostBusy2
803
803
  } from "./server-qt1qqasc.js";
804
+ import {
805
+ GIT_SWEEP_LEASE_RENEWAL_MS,
806
+ acquireGitSweepLease,
807
+ renewGitSweepLease,
808
+ markGitSweepSuccessAndRelease,
809
+ parkGitSweepNonIndexable,
810
+ releaseGitSweepLease,
811
+ recordSessionProjectIdentity,
812
+ hasRecordedSessionProjectIdentity
813
+ } from "./server-4gn3z5an.js";
804
814
  import {
805
815
  saveEmbeddingIfHashMatches,
806
816
  invalidateProject2,
@@ -808,10 +818,10 @@ import {
808
818
  } from "./server-4dhv7mqz.js";
809
819
  import {
810
820
  getLocalEmbeddingNativeMemoryStats
811
- } from "./server-83d71zab.js";
821
+ } from "./server-g10mdym6.js";
812
822
  import {
813
823
  cosineSimilarity
814
- } from "./server-rxcq4t50.js";
824
+ } from "./server-ef89gdsx.js";
815
825
  import {
816
826
  computeCueContentHash,
817
827
  hasMuralCueColumns,
@@ -844,11 +854,11 @@ import {
844
854
  drainNotifications2,
845
855
  isTuiConnected2
846
856
  } from "./server-x8a7jmkh.js";
847
- import"./server-ckrb5rm8.js";
857
+ import"./server-h0410h0v.js";
848
858
  import {
849
859
  flushIgnoredMessages2,
850
860
  sendStatusNotification2
851
- } from "./server-h3wc20sv.js";
861
+ } from "./server-vbe4se57.js";
852
862
  import {
853
863
  renderSingleStoreMigrationRequiredRefusal,
854
864
  SingleStoreMigrationRequiredError,
@@ -869,13 +879,19 @@ import {
869
879
  resolveMemoriesByIdsForSearch2,
870
880
  unifiedSearch2,
871
881
  formatSearchResults2
872
- } from "./server-pbpp8r8h.js";
882
+ } from "./server-xh7jar6k.js";
873
883
  import {
874
884
  resolvePromptContext2
875
885
  } from "./server-fmsr7v69.js";
876
886
  import {
877
887
  compareSemverCore
878
888
  } from "./server-84w6rvvf.js";
889
+ import {
890
+ COMPACTION_ENABLED_PATH,
891
+ isDreamerRunnable,
892
+ isSmartNoteSurfaceAvailable,
893
+ isCompactionEnabled
894
+ } from "./server-0s95v3en.js";
879
895
  import {
880
896
  __toESM,
881
897
  __export
@@ -883,21 +899,6 @@ import {
883
899
  import {
884
900
  computeNormalizedHash
885
901
  } from "./server-2bvekkfy.js";
886
- import {
887
- sameProjectDirectory,
888
- canonicalProjectDirectory
889
- } from "./server-knvkbfvh.js";
890
- import {
891
- getErrorMessage,
892
- describeError
893
- } from "./server-y8v6yerm.js";
894
- import {
895
- shouldEnforcePrivateStoragePermissions,
896
- ensureStorageDirectorySync,
897
- writeStorageFileAtomicSync,
898
- writeStorageFileAsync,
899
- createStorageWriteStream
900
- } from "./server-fvnzcnww.js";
901
902
  import {
902
903
  normalizeProtectedToolName,
903
904
  mergeProtectedTools
@@ -907,13 +908,28 @@ import {
907
908
  piModelRefToCanonical,
908
909
  modelRefLookupOrder
909
910
  } from "./server-avwt563y.js";
911
+ import {
912
+ sameProjectDirectory,
913
+ canonicalProjectDirectory
914
+ } from "./server-knvkbfvh.js";
915
+ import {
916
+ getErrorMessage,
917
+ describeError
918
+ } from "./server-y8v6yerm.js";
910
919
  import {
911
920
  closeQuietly,
912
921
  isKnownAutocommit
913
922
  } from "./server-8ajstryz.js";
914
923
  import {
915
924
  logSlowWriteTransaction
916
- } from "./server-7dv9wt9r.js";
925
+ } from "./server-6pmqg9m4.js";
926
+ import {
927
+ shouldEnforcePrivateStoragePermissions,
928
+ ensureStorageDirectorySync,
929
+ writeStorageFileAtomicSync,
930
+ writeStorageFileAsync,
931
+ createStorageWriteStream
932
+ } from "./server-fvnzcnww.js";
917
933
 
918
934
  // ../../node_modules/.bun/zod@4.1.8/node_modules/zod/v4/classic/external.js
919
935
  var exports_external = {};
@@ -1613,6 +1629,39 @@ __export(exports_coerce, {
1613
1629
  string: () => string3
1614
1630
  });
1615
1631
 
1632
+ // src/config/dependency-notes.ts
1633
+ function scheduledTasks(config) {
1634
+ const tasks = config.dreamer?.tasks ?? {};
1635
+ return Object.entries(tasks).filter(([, task]) => typeof task?.schedule === "string" && task.schedule.trim() !== "").map(([name]) => name);
1636
+ }
1637
+ function configDependencyNotes(config) {
1638
+ const notes = [];
1639
+ const dreamerRunnable = isDreamerRunnable(config);
1640
+ const dreamerDisabled = config.dreamer?.disable === true;
1641
+ const memoryOff = config.memory?.enabled === false;
1642
+ const memoryTasks = scheduledTasks(config).filter((task) => PROJECT_MEMORY_DREAM_TASKS.includes(task));
1643
+ if (dreamerRunnable && memoryOff && memoryTasks.length > 0) {
1644
+ notes.push(`memory.enabled is false, so these scheduled dreamer tasks do not run for this project, on schedule or through /ctx-dream: ${memoryTasks.join(", ")}. maintain-docs, evaluate-smart-notes and review-user-memories still run.`);
1645
+ }
1646
+ if (dreamerDisabled && config.smart_notes?.enabled !== false) {
1647
+ notes.push("dreamer.disable is true, so smart_notes.enabled has no effect: ctx_note does not offer surface_condition and pending smart notes are not evaluated.");
1648
+ }
1649
+ const reviewSchedule = config.dreamer?.tasks?.["review-user-memories"]?.schedule;
1650
+ if (dreamerDisabled && typeof reviewSchedule === "string" && reviewSchedule.trim() !== "") {
1651
+ notes.push("dreamer.disable is true, so dreamer.tasks.review-user-memories.schedule has no effect: the historian does not collect user observations and the <user-profile> block gets no new entries.");
1652
+ }
1653
+ return notes;
1654
+ }
1655
+ var loggedNotes = new Set;
1656
+ function logConfigDependencyNotesOnce(config, log) {
1657
+ const fresh = configDependencyNotes(config).filter((note) => !loggedNotes.has(note));
1658
+ for (const note of fresh) {
1659
+ loggedNotes.add(note);
1660
+ log(`[magic-context] config note: ${note}`);
1661
+ }
1662
+ return fresh;
1663
+ }
1664
+
1616
1665
  // src/features/magic-context/dreamer/manual-summary.ts
1617
1666
  function summarizeManualDream(summary) {
1618
1667
  const lines = ["## /ctx-dream", ""];
@@ -6874,13 +6923,20 @@ function foldBustsServedPrefix(reason, before, after) {
6874
6923
  return CACHE_LOSING_FOLD_REASONS.has(reason ?? "") || foldChangesServedPrefix(before, after);
6875
6924
  }
6876
6925
  function prepareLegacyToolSkeletonConversions(db, sessionId, targets, options = {}) {
6877
- const readRows = (connection) => connection.prepare(`SELECT tag_number AS tagNumber, drop_mode AS dropMode, message_id AS callId
6878
- FROM tags
6879
- WHERE session_id = ? AND type = 'tool' AND status = 'dropped'
6880
- AND drop_mode IN ('truncated', 'full')
6881
- ORDER BY tag_number`).all(sessionId);
6926
+ const candidates = [...targets.keys()].sort((a, b) => a - b);
6927
+ const readRows = (connection) => {
6928
+ if (candidates.length === 0)
6929
+ return [];
6930
+ const statement = connection.prepare(`SELECT tag_number AS tagNumber, drop_mode AS dropMode, message_id AS callId
6931
+ FROM tags WHERE session_id = ? AND tag_number = ?
6932
+ AND type = 'tool' AND status = 'dropped'
6933
+ AND drop_mode IN ('truncated', 'full')`);
6934
+ return candidates.flatMap((tagNumber) => {
6935
+ const row = statement.get(sessionId, tagNumber);
6936
+ return row ? [row] : [];
6937
+ });
6938
+ };
6882
6939
  const rows = readRows(db);
6883
- const identity = JSON.stringify(rows);
6884
6940
  const converted = new Map;
6885
6941
  for (const row of rows) {
6886
6942
  const target = targets.get(row.tagNumber);
@@ -6901,7 +6957,10 @@ function prepareLegacyToolSkeletonConversions(db, sessionId, targets, options =
6901
6957
  }
6902
6958
  return {
6903
6959
  converted,
6904
- isCurrent: (connection) => JSON.stringify(readRows(connection)) === identity,
6960
+ isCurrent: (connection) => {
6961
+ const current = readRows(connection);
6962
+ return current.length === rows.length && current.every((row, index) => row.tagNumber === rows[index].tagNumber && row.dropMode === rows[index].dropMode && row.callId === rows[index].callId);
6963
+ },
6905
6964
  persist: (connection) => {
6906
6965
  for (const [tagNumber, mode] of converted)
6907
6966
  updateTagDropMode2(connection, sessionId, tagNumber, mode);
@@ -6988,9 +7047,7 @@ function applyPendingOperations(sessionId, db, targets, protectedTagIds, preload
6988
7047
  try {
6989
7048
  db.transaction(() => {
6990
7049
  startedAt = performance.now();
6991
- if (mode)
6992
- updateTagDropMode2(db, sessionId, pendingOp.tagId, mode);
6993
- updateTagStatus2(db, sessionId, pendingOp.tagId, "dropped");
7050
+ markTagDropped2(db, sessionId, pendingOp.tagId, mode);
6994
7051
  if (!synthetic)
6995
7052
  removePendingOp(db, sessionId, pendingOp.tagId);
6996
7053
  }).immediate();
@@ -9529,6 +9586,25 @@ function finalizeMessageRepresentation(messages, resolvedProviderID, options) {
9529
9586
  }
9530
9587
  return { clearedParts, mergedReasoningParts };
9531
9588
  }
9589
+ function legacyPublishedHeadChanged(args) {
9590
+ if (!args.pendingCompartmentInjection || !args.readLastServedMessages)
9591
+ return false;
9592
+ const served = args.readLastServedMessages();
9593
+ if (served === null)
9594
+ return true;
9595
+ const previous = served[0];
9596
+ if (!Array.isArray(previous?.parts) || !args.pendingCompartmentInjection)
9597
+ return false;
9598
+ const text = previous.parts.find((part) => typeof part === "object" && part !== null && ("type" in part) && part.type === "text" && ("text" in part))?.text;
9599
+ if (typeof text !== "string")
9600
+ return false;
9601
+ const block = `<session-history>
9602
+ ${args.pendingCompartmentInjection.block}
9603
+ </session-history>`;
9604
+ return text !== block && !text.startsWith(`${block}
9605
+
9606
+ `);
9607
+ }
9532
9608
  async function runPostTransformPhase(args) {
9533
9609
  const tPostprocessSetup = performance.now();
9534
9610
  const compactionOff = args.compactionOff === true;
@@ -9739,11 +9815,6 @@ async function runPostTransformPhase(args) {
9739
9815
  }
9740
9816
  sessionLog2(args.sessionId, `m[0] HARD fold decision: reason=${m0MaterializeReason ?? foldDueDecision.reason ?? (foldExecutedThisPass ? "drift" : "soft_refresh")} executed=${foldExecutedThisPass} bustsServedPrefix=${foldBustsServedPrefixThisPass}`);
9741
9817
  }
9742
- if (args.normalizeRecoveryTail && (foldBustsServedPrefixThisPass || firstRenderBust)) {
9743
- args.normalizeRecoveryTail();
9744
- args.tags = getTagsBySession2(args.db, args.sessionId);
9745
- newTargets = protectNewTagMutations(args.messages, args.targets, retainedThinking, args.thinkingBindingRecoveryEnabledForModel === true);
9746
- }
9747
9818
  logTransformTiming(args.sessionId, "pp.prefixPreflight", tPostprocessSetup, `foldExecuted=${foldExecutedThisPass} m1Refreshed=${publishedM1RefreshedThisPass}`);
9748
9819
  const tPassDecisions = performance.now();
9749
9820
  const frontToolCandidates = args.tags.filter((tag) => tag.type === "tool" && tag.status === "active" && args.targets.get(tag.tagNumber)?.canDrop?.());
@@ -9770,13 +9841,18 @@ async function runPostTransformPhase(args) {
9770
9841
  subagentExecute: !args.fullFeatureMode && args.schedulerDecision === "execute",
9771
9842
  hardFold: foldBustsServedPrefixThisPass || firstRenderBust || idleExpiryRebuild,
9772
9843
  force: emergencyDropEligible && (args.contextUsage.percentage >= 95 || getEmergencyInputSample(args.db, args.sessionId) === 0),
9773
- explicitFlush: isExplicitFlush || deferredMaterialize && !prefixPreflightFailed,
9774
- publishedHistory: publishedM1RefreshedThisPass || !m0M1EnabledForFold && (args.pendingCompartmentInjection?.compartmentCount ?? 0) > 0 && (args.historyRebuiltThisPass || args.rebuiltHistoryFromInitialPrepare || args.canConsumeDeferredLate && args.deferredHistoryWasPendingAtPassStart)
9844
+ explicitFlush: isExplicitFlush && hasPendingMaterializationOrigin(args.pendingMaterializationSessions, args.sessionId, "user_flush"),
9845
+ publishedHistory: !prefixPreflightFailed && (publishedM1RefreshedThisPass || !m0M1EnabledForFold && (args.pendingCompartmentInjection?.compartmentCount ?? 0) > 0 && legacyPublishedHeadChanged(args))
9775
9846
  };
9776
9847
  const publishedWorkDrainAllowed = !compactionOff && (!activeThinkingPrefixHold || firstRenderBust || idleExpiryRebuild || emergencyDropEligible) && hasReclaimRide(rideSignals);
9777
9848
  const shouldApplyPendingOps = publishedWorkDrainAllowed;
9778
9849
  const shouldRunHeuristics = publishedWorkDrainAllowed && (rideSignals.publishedHistory || materializationRequested || forceMaterialization || foldBustsServedPrefixThisPass || firstRenderBust || heldIdleExpiryRebuild || emergencyDropEligible || args.schedulerDecision === "execute" && (!alreadyRanThisTurn || !args.fullFeatureMode));
9779
9850
  const isCacheBustingPass = publishedWorkDrainAllowed;
9851
+ if (args.normalizeRecoveryTail && isCacheBustingPass) {
9852
+ args.normalizeRecoveryTail();
9853
+ args.tags = getTagsBySession2(args.db, args.sessionId);
9854
+ newTargets = protectNewTagMutations(args.messages, args.targets, retainedThinking, args.thinkingBindingRecoveryEnabledForModel === true);
9855
+ }
9780
9856
  const reclaimDistance = isCacheBustingPass ? toolReclaimDistanceEntries(args.messages, args.targets) : [];
9781
9857
  const canEditWholePrefix = isCacheBustingPass && !activeThinkingPrefixHold;
9782
9858
  const previousTemporalDecisions = args.temporalCandidates && !compactionOff ? new Map([
@@ -11512,6 +11588,16 @@ function commitCompactionModeRecord(db, sessionId, record) {
11512
11588
  setCompactionModeRecord(db, sessionId, record);
11513
11589
  }
11514
11590
 
11591
+ // src/hooks/magic-context/compartment-trigger-error.ts
11592
+ function recordCompartmentTriggerError(passOutcome, sessionId, error, log = sessionLog2) {
11593
+ passOutcome.record("compartment-trigger-failure");
11594
+ if (error instanceof RawOrdinalsNotReady2) {
11595
+ log(sessionId, "compartment trigger deferred: raw ordinals not ready; the next pass evaluates it again");
11596
+ return;
11597
+ }
11598
+ log(sessionId, "compartment trigger failed (non-fatal):", error);
11599
+ }
11600
+
11515
11601
  // src/hooks/magic-context/pass-outcome.ts
11516
11602
  var PASS_DEGRADATION_EFFECTS = {
11517
11603
  "store-generation-rebase-failure": "changes-request",
@@ -17738,6 +17824,7 @@ async function runCompartmentPhaseImpl(args) {
17738
17824
  ensureProjectRegistered: args.ensureProjectRegistered,
17739
17825
  getNotificationParams: args.getNotificationParams,
17740
17826
  experimentalUserMemories: args.experimentalUserMemories,
17827
+ userObservationsRequested: args.userObservationsRequested,
17741
17828
  historianTwoPass: args.historianTwoPass,
17742
17829
  historianExpandTools: args.historianExpandTools,
17743
17830
  memoryEnabled: args.memoryEnabled,
@@ -17779,6 +17866,7 @@ async function runCompartmentPhaseImpl(args) {
17779
17866
  ensureProjectRegistered: args.ensureProjectRegistered,
17780
17867
  getNotificationParams: args.getNotificationParams,
17781
17868
  experimentalUserMemories: args.experimentalUserMemories,
17869
+ userObservationsRequested: args.userObservationsRequested,
17782
17870
  historianTwoPass: args.historianTwoPass,
17783
17871
  historianExpandTools: args.historianExpandTools,
17784
17872
  memoryEnabled: args.memoryEnabled,
@@ -18474,6 +18562,7 @@ function createTransform(deps) {
18474
18562
  fallbackModelId,
18475
18563
  getNotificationParams: () => notificationParams,
18476
18564
  experimentalUserMemories: historianRun?.userMemoriesEnabled ?? deps.experimentalUserMemories,
18565
+ userObservationsRequested: historianRun?.userObservationsRequested ?? deps.userObservationsRequested,
18477
18566
  experimentalTemporalAwareness: deps.experimentalTemporalAwareness,
18478
18567
  historianTwoPass: historianRun?.twoPass ?? deps.historianTwoPass,
18479
18568
  historianExpandTools: historianRun?.expandTools ?? deps.historianExpandTools,
@@ -18529,6 +18618,7 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
18529
18618
  sessionLog2(sessionId, `tag floor: 0 (full-scan fallback) — no leading wire message resolved a tag across ${messages.length} msgs`);
18530
18619
  }
18531
18620
  const ownerRatio = sessionDecisionCalibration(db, sessionId).proseRatio;
18621
+ noteTransformPassForExactOrdinalReads(sessionId);
18532
18622
  prewarmTagOwners(db, sessionId, ownerRatio);
18533
18623
  const tagOwnersReady = isTagOwnerSummaryReady2(db, sessionId, ownerRatio);
18534
18624
  let triggerBoundarySnapshot;
@@ -18552,8 +18642,7 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
18552
18642
  triggerBoundarySnapshot = triggerResult.boundarySnapshot;
18553
18643
  }
18554
18644
  } catch (error) {
18555
- passOutcome.record("compartment-trigger-failure");
18556
- sessionLog2(sessionId, "compartment trigger failed (non-fatal):", error);
18645
+ recordCompartmentTriggerError(passOutcome, sessionId, error);
18557
18646
  }
18558
18647
  logTransformTiming(sessionId, "compartmentTrigger", tTrigger);
18559
18648
  }
@@ -18744,6 +18833,7 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
18744
18833
  safeForBackgroundCompression: historianRunnable && (isCacheBusting || schedulerDecision === "execute"),
18745
18834
  deferredHistoryRefreshSessions,
18746
18835
  experimentalUserMemories: historianRun?.userMemoriesEnabled ?? deps.experimentalUserMemories,
18836
+ userObservationsRequested: historianRun?.userObservationsRequested ?? deps.userObservationsRequested,
18747
18837
  experimentalTemporalAwareness: deps.experimentalTemporalAwareness,
18748
18838
  historianTwoPass: historianRun?.twoPass ?? deps.historianTwoPass,
18749
18839
  historianExpandTools: historianRun?.expandTools ?? deps.historianExpandTools,
@@ -20449,7 +20539,7 @@ function getAsyncModule() {
20449
20539
  await beforeModuleLoad();
20450
20540
  const [{ default: singlefileAsyncifyVariant }, { newQuickJSAsyncWASMModuleFromVariant }] = await importPluginModule(() => Promise.all([
20451
20541
  import("./index-6e4mwffh.js").then((m)=>__toESM(m.default,1)),
20452
- import("./index-e6xnpach.js")
20542
+ import("./index-b7p25tm0.js")
20453
20543
  ]));
20454
20544
  const module = await newQuickJSAsyncWASMModuleFromVariant(singlefileAsyncifyVariant);
20455
20545
  return module;
@@ -22475,9 +22565,9 @@ function registerRpcHandlers(rpcServer, args) {
22475
22565
  return { count: buildCompartmentCount(db, sessionId, moduleStatus) };
22476
22566
  });
22477
22567
  const buildManagedCtx = async (db) => {
22478
- const { deriveHistorianChunkTokens, resolveHistorianContextLimit } = await importPluginModule(() => import("./derive-budgets-0rmpmxjw.js"));
22568
+ const { deriveHistorianChunkTokens, resolveHistorianContextLimit } = await importPluginModule(() => import("./derive-budgets-2zh4gm2c.js"));
22479
22569
  const { resolveHistorianModel } = await importPluginModule(() => import("./model-resolution-nx97z3x7.js"));
22480
- const { userMemoryCollectionEnabled } = await importPluginModule(() => import("./task-config-x0hq3qfd.js"));
22570
+ const { userObservationCollectionEnabled, userObservationsRequested } = await importPluginModule(() => import("./task-config-nvz8mapa.js"));
22481
22571
  const DEFAULT_HISTORIAN_TIMEOUT_MS = 10 * 60 * 1000;
22482
22572
  const runConfig = historianRunConfig(config, currentPluginConfigReader(directory)?.poll().effective ?? config);
22483
22573
  const historianModel = resolveHistorianModel(runConfig, "opencode");
@@ -22495,7 +22585,8 @@ function registerRpcHandlers(rpcServer, args) {
22495
22585
  autoPromote: runConfig.memory?.auto_promote ?? true,
22496
22586
  historianModel: historianModel.primary,
22497
22587
  fallbackModels: historianModel.fallbacks,
22498
- userMemoriesEnabled: userMemoryCollectionEnabled(runConfig.dreamer),
22588
+ userMemoriesEnabled: userObservationCollectionEnabled(runConfig.dreamer),
22589
+ userObservationsRequested: userObservationsRequested(runConfig.dreamer),
22499
22590
  historianTwoPass: runConfig.historian?.two_pass === true,
22500
22591
  historianExpandTools: runConfig.historian?.expand_tools,
22501
22592
  getNotificationParams: (sessionId) => getLiveNotificationParams(sessionId, liveSessionState.liveModelBySession, liveSessionState.variantBySession, liveSessionState.agentBySession, runConfig.toast_duration_ms)
@@ -22507,7 +22598,7 @@ function registerRpcHandlers(rpcServer, args) {
22507
22598
  return { ok: false, error: "no session" };
22508
22599
  const readDirectory = args.readSessionDirectory;
22509
22600
  if (readDirectory) {
22510
- const { handoffHistoryWork } = await import("./history-owner-2cr9py37.js");
22601
+ const { handoffHistoryWork } = await import("./history-owner-42e16w0n.js");
22511
22602
  const handed = await handoffHistoryWork({
22512
22603
  storageDir: args.storageDir ?? getMagicContextStorageDir(),
22513
22604
  directory,
@@ -22526,8 +22617,8 @@ function registerRpcHandlers(rpcServer, args) {
22526
22617
  const db = readDatabase();
22527
22618
  if (!db)
22528
22619
  return { ok: false, error: "db unavailable" };
22529
- const { runManagedRecomp } = await importPluginModule(() => import("./recomp-orchestrator-n0pq36f0.js"));
22530
- const { sendIgnoredMessage } = await importPluginModule(() => import("./send-session-notification-z5mcjdea.js"));
22620
+ const { runManagedRecomp } = await importPluginModule(() => import("./recomp-orchestrator-ca7qt75a.js"));
22621
+ const { sendIgnoredMessage } = await importPluginModule(() => import("./send-session-notification-8ghn9tnv.js"));
22531
22622
  log2(`[rpc] recomp requested for session ${sessionId}`);
22532
22623
  if (!args.client && !args.hiddenCompletionExecutor) {
22533
22624
  return {
@@ -22585,7 +22676,7 @@ function registerRpcHandlers(rpcServer, args) {
22585
22676
  rpcServer.handle("wrapup", async (params) => {
22586
22677
  const readDirectory = args.readSessionDirectory;
22587
22678
  if (readDirectory && params.sessionId) {
22588
- const { handoffHistoryWork } = await import("./history-owner-2cr9py37.js");
22679
+ const { handoffHistoryWork } = await import("./history-owner-42e16w0n.js");
22589
22680
  const sessionId = String(params.sessionId);
22590
22681
  const handed = await handoffHistoryWork({
22591
22682
  storageDir: args.storageDir ?? getMagicContextStorageDir(),
@@ -22611,7 +22702,7 @@ function registerRpcHandlers(rpcServer, args) {
22611
22702
  const db = readDatabase();
22612
22703
  if (!db)
22613
22704
  return { ok: false, error: "db unavailable" };
22614
- const { runManagedWrapup } = await importPluginModule(() => import("./wrapup-orchestrator-87q9d5e2.js"));
22705
+ const { runManagedWrapup } = await importPluginModule(() => import("./wrapup-orchestrator-e1a2w6jh.js"));
22615
22706
  const model = liveSessionState.liveModelBySession.get(sessionId);
22616
22707
  const contextLimit = model ? resolveContextLimit(model.providerID, model.modelID, { db, sessionID: sessionId }) : 128000;
22617
22708
  const ctx = {
@@ -26719,9 +26810,12 @@ async function runCompressCues(args) {
26719
26810
  let timeoutStreakElapsedMs = [];
26720
26811
  for (let i = 0;i < chunks.length; i += 1) {
26721
26812
  const remainingMs = Math.max(0, args.deadline - Date.now());
26722
- if (remainingMs <= 0)
26813
+ if (remainingMs <= 0) {
26814
+ result.stopReason = "deadline";
26723
26815
  break;
26816
+ }
26724
26817
  if (remainingMs < CHUNK_TIMEOUT_FLOOR_MS) {
26818
+ result.stopReason = "deadline";
26725
26819
  log2(`[dreamer] compress-cues: stopping before chunk ${i + 1}/${chunks.length} — remaining budget ${remainingMs}ms is below the ${CHUNK_TIMEOUT_FLOOR_MS}ms chunk floor; banking ${result.compressed} compressed cue(s)`);
26726
26820
  break;
26727
26821
  }
@@ -26730,6 +26824,10 @@ async function runCompressCues(args) {
26730
26824
  if (!chunk)
26731
26825
  break;
26732
26826
  const outcome = await compressOneChunk(args, chunk, sliceMs, abortController.signal);
26827
+ if (outcome.failure) {
26828
+ result.failure = outcome.failure.error;
26829
+ result.failureStage = outcome.failure.stage;
26830
+ }
26733
26831
  result.compressed += outcome.compressed;
26734
26832
  result.skipped += outcome.skipped;
26735
26833
  result.remaining -= outcome.compressed;
@@ -26739,6 +26837,7 @@ async function runCompressCues(args) {
26739
26837
  consecutiveTimeouts += 1;
26740
26838
  timeoutStreakElapsedMs.push(outcome.failure.elapsedMs);
26741
26839
  if (consecutiveTimeouts >= CONSECUTIVE_TIMEOUT_LIMIT) {
26840
+ result.stopReason = "timeout-circuit-breaker";
26742
26841
  log2(`[dreamer] compress-cues: circuit breaker tripped — ${consecutiveTimeouts} consecutive chunk timeouts (model too slow for its time slice); per-chunk elapsed [${timeoutStreakElapsedMs.join("ms, ")}ms] vs ${sliceMs}ms slice; stopping run incomplete with ${chunks.length - i - 1} chunk(s) unattempted`);
26743
26842
  break;
26744
26843
  }
@@ -26755,7 +26854,7 @@ async function runCompressCues(args) {
26755
26854
  }
26756
26855
  }
26757
26856
  function isTimeoutClassError(error) {
26758
- return error instanceof Error && /^prompt timed out after \d+ms$/.test(error.message);
26857
+ return isPromptTimeoutError(error) || getPromptFailureDetail(error)?.failureClass === "provider_timeout";
26759
26858
  }
26760
26859
  async function compressOneChunk(args, chunk, sliceMs, signal) {
26761
26860
  let agentSessionId = null;
@@ -26763,6 +26862,7 @@ async function compressOneChunk(args, chunk, sliceMs, signal) {
26763
26862
  const executor = resolveHiddenCompletionExecutor(args.hiddenCompletionExecutor, args.client, args.db, args.sessionDirectory, "compress-cues");
26764
26863
  let promptSettled = false;
26765
26864
  const startedAt = Date.now();
26865
+ let stage = "child-start";
26766
26866
  try {
26767
26867
  const prompt = buildCompressCuesPrompt({
26768
26868
  projectPath: args.projectIdentity,
@@ -26783,6 +26883,7 @@ async function compressOneChunk(args, chunk, sliceMs, signal) {
26783
26883
  agentSessionId = handle.id || null;
26784
26884
  if (!agentSessionId)
26785
26885
  throw new Error("Could not create compress-cues session.");
26886
+ stage = "prompt";
26786
26887
  const opened = handle;
26787
26888
  const run = await promptSyncWithValidatedOutputRetry(args.client, {
26788
26889
  path: { id: agentSessionId },
@@ -26834,16 +26935,19 @@ async function compressOneChunk(args, chunk, sliceMs, signal) {
26834
26935
  modelId: run.output.modelId
26835
26936
  });
26836
26937
  }
26938
+ stage = "apply";
26837
26939
  return args.moduleRoute ? await applyCuesThroughModule(args, chunk, run.validated, signal) : applyCues(args, chunk, run.validated);
26838
26940
  } catch (error) {
26839
26941
  const desc = describeError(error);
26840
26942
  log2(`[dreamer] compress-cues chunk failed: ${desc.brief}`, desc.stackHead ? { stackHead: desc.stackHead } : undefined);
26841
- if (signal.aborted || error instanceof HiddenCompletionRefusal || error instanceof DreamerProviderOutputFailureError)
26943
+ if (signal.aborted || error instanceof DreamerModuleFailureError || error instanceof HiddenCompletionRefusal || error instanceof DreamerProviderOutputFailureError)
26842
26944
  throw error;
26843
26945
  return {
26844
26946
  compressed: 0,
26845
26947
  skipped: 0,
26846
26948
  failure: {
26949
+ error,
26950
+ stage,
26847
26951
  class: isTimeoutClassError(error) ? "timeout" : "other",
26848
26952
  brief: desc.brief,
26849
26953
  elapsedMs: Date.now() - startedAt
@@ -26997,7 +27101,7 @@ async function applyCuesThroughModule(args, chunk, manifestText, signal) {
26997
27101
  // src/features/magic-context/dreamer/hidden-single-shot.ts
26998
27102
  async function runHiddenSingleShotPrompt(args) {
26999
27103
  const system = withContentLanguageDirective(args.system, args.language);
27000
- const handle = await args.executor.open({
27104
+ const opening = args.executor.open({
27001
27105
  parentSessionId: args.parentSessionId,
27002
27106
  agent: args.agent,
27003
27107
  kind: "dreamer-task",
@@ -27009,6 +27113,17 @@ async function runHiddenSingleShotPrompt(args) {
27009
27113
  directory: args.sessionDirectory,
27010
27114
  ...args.metadata ? { metadata: args.metadata } : {}
27011
27115
  });
27116
+ opening.then((handle) => {
27117
+ if (args.signal?.aborted)
27118
+ return args.executor.close(handle, {
27119
+ promptSettled: false,
27120
+ privacySensitive: args.privacySensitive ?? true,
27121
+ context: `[dreamer] ${args.callContext}`,
27122
+ log: log2
27123
+ });
27124
+ }).catch(() => {});
27125
+ const handle = await raceWithSignal(opening, args.signal);
27126
+ args.onOpened?.(handle.id);
27012
27127
  let promptSettled = false;
27013
27128
  try {
27014
27129
  if (!handle.id)
@@ -27063,12 +27178,16 @@ async function runHiddenSingleShotPrompt(args) {
27063
27178
  }
27064
27179
  throw error;
27065
27180
  } finally {
27066
- await args.executor.close(handle, {
27181
+ const close = args.executor.close(handle, {
27067
27182
  promptSettled,
27068
27183
  privacySensitive: args.privacySensitive ?? true,
27069
27184
  context: `[dreamer] ${args.callContext}`,
27070
27185
  log: log2
27071
27186
  });
27187
+ if (args.signal?.aborted)
27188
+ close.catch(() => {});
27189
+ else
27190
+ await raceWithSignal(close, args.signal);
27072
27191
  }
27073
27192
  }
27074
27193
 
@@ -30143,14 +30262,28 @@ function isDeferred(memory, retries) {
30143
30262
  return !!retry && retry.content === contentKey2(memory) && retry.deferUntil > Date.now();
30144
30263
  }
30145
30264
  function assistantText2(messages) {
30146
- return messages.filter((message) => isRecord(message) && (message.role === "assistant" || isRecord(message.info) && message.info.role === "assistant")).map((message) => extractLatestAssistantText([message]) ?? (isRecord(message) && Array.isArray(message.content) ? message.content.filter(isRecord).filter((part) => part.type === "text" && typeof part.text === "string").map((part) => part.text).join(`
30265
+ const joined = messages.filter((message) => isRecord(message) && (message.role === "assistant" || isRecord(message.info) && message.info.role === "assistant")).map((message) => extractLatestAssistantText([message]) ?? (isRecord(message) && Array.isArray(message.content) ? message.content.filter(isRecord).filter((part) => part.type === "text" && typeof part.text === "string").map((part) => part.text).join(`
30147
30266
  `) : "")).join(`
30148
30267
  `);
30268
+ return joined.trim() ? joined : null;
30149
30269
  }
30150
30270
  function currentManifest(text) {
30151
30271
  const start = text.lastIndexOf("<mappings>");
30152
30272
  return start < 0 ? text : text.slice(start);
30153
30273
  }
30274
+ function parseMapMemoriesCompletion(text, completion, expectedIds) {
30275
+ return validateMapMemoriesManifest(currentManifest(assistantText2(completion.messages ?? []) || text), expectedIds);
30276
+ }
30277
+ function validateClientMapMemories(messages, expectedIds) {
30278
+ if (hasLengthCappedOutput(messages)) {
30279
+ throw new Error("map-memories returned length-capped output");
30280
+ }
30281
+ const raw = assistantText2(messages);
30282
+ if (raw == null) {
30283
+ throw new Error("map-memories returned no output");
30284
+ }
30285
+ return validateMapMemoriesManifest(currentManifest(raw), expectedIds);
30286
+ }
30154
30287
  function logBatchUsage(messages, committed, startedAt) {
30155
30288
  const steps = messages.filter((message) => isRecord(message) && (message.role === "assistant" || isRecord(message.info) && message.info.role === "assistant")).length;
30156
30289
  log2(`[dreamer] map-memories batch: steps=${steps} committed=${committed} steps_per_memory=${committed ? (steps / committed).toFixed(2) : "n/a"} elapsed_ms=${Date.now() - startedAt}`);
@@ -30215,8 +30348,11 @@ async function mapMemories(args) {
30215
30348
  const inputs = allInputs.filter((memory) => !isDeferred(memory, retries));
30216
30349
  result.remaining = allInputs.length;
30217
30350
  result.complete = result.remaining === 0;
30218
- if (inputs.length === 0)
30351
+ if (inputs.length === 0) {
30352
+ if (allInputs.length > 0)
30353
+ result.deferred = true;
30219
30354
  return result;
30355
+ }
30220
30356
  const batches = [];
30221
30357
  for (let i = 0;i < inputs.length; i += MAP_BATCH_SIZE) {
30222
30358
  batches.push({ inputs: inputs.slice(i, i + MAP_BATCH_SIZE), isOmissionRetry: false });
@@ -30242,6 +30378,10 @@ async function mapMemories(args) {
30242
30378
  if (!batch)
30243
30379
  break;
30244
30380
  const outcome = await mapOneBatch(args, batch.inputs, sliceMs, abortController.signal);
30381
+ if (outcome.failure) {
30382
+ result.failure = outcome.failure.error;
30383
+ result.failureStage = outcome.failure.stage;
30384
+ }
30245
30385
  const committed = outcome.mapped + outcome.independent;
30246
30386
  runLeaseGuardedWrite(args.db, args.holderId, args.leaseKey, () => {
30247
30387
  const committedIds = new Set(outcome.committedIds);
@@ -30305,6 +30445,7 @@ async function mapOneBatch(args, batch, sliceMs, signal) {
30305
30445
  const startedAt = Date.now();
30306
30446
  let budgetFinalized = false;
30307
30447
  let failedCompletion;
30448
+ let stage = "child-start";
30308
30449
  const onBudgetUpdate = (state) => {
30309
30450
  budgetFinalized ||= state.finalizeFired;
30310
30451
  args.onBudgetUpdate?.(state);
@@ -30326,15 +30467,19 @@ async function mapOneBatch(args, batch, sliceMs, signal) {
30326
30467
  fallbackModels: args.fallbackModels,
30327
30468
  timeoutMs: sliceMs,
30328
30469
  signal,
30470
+ onOpened: () => {
30471
+ stage = "prompt";
30472
+ },
30329
30473
  onFailureOutput: (completion) => {
30330
30474
  failedCompletion = completion;
30331
30475
  },
30332
- parse: (text, completion) => validateMapMemoriesManifest(currentManifest(assistantText2(completion.messages ?? []) || text), new Set(batch.map((memory) => memory.id)))
30476
+ parse: (text, completion) => parseMapMemoriesCompletion(text, completion, new Set(batch.map((memory) => memory.id)))
30333
30477
  });
30334
30478
  recordInvocation2(args, startedAt, {
30335
30479
  status: "completed",
30336
30480
  messages: run.completion.messages ?? []
30337
30481
  });
30482
+ stage = "apply";
30338
30483
  const outcome = await applyParsedBatchMappings(args, batch, run.validated, budgetFinalized, true);
30339
30484
  logBatchUsage(run.completion.messages ?? [], outcome.mapped + outcome.independent, startedAt);
30340
30485
  const returnedIds = new Set(outcome.committedIds);
@@ -30359,6 +30504,7 @@ async function mapOneBatch(args, batch, sliceMs, signal) {
30359
30504
  agentSessionId = typeof created?.id === "string" ? created.id : null;
30360
30505
  if (!agentSessionId)
30361
30506
  throw new Error("Could not create map-memories session.");
30507
+ stage = "prompt";
30362
30508
  const run = await promptSyncWithValidatedOutputRetry(client, {
30363
30509
  path: { id: agentSessionId },
30364
30510
  query: { directory: args.sessionDirectory },
@@ -30386,18 +30532,11 @@ async function mapOneBatch(args, batch, sliceMs, signal) {
30386
30532
  preferResponseOnMissingData: true
30387
30533
  });
30388
30534
  },
30389
- validateOutput: (messages) => {
30390
- if (hasLengthCappedOutput(messages)) {
30391
- throw new Error("map-memories returned length-capped output");
30392
- }
30393
- const text = currentManifest(assistantText2(messages));
30394
- if (!text)
30395
- throw new Error("map-memories returned no output");
30396
- return validateMapMemoriesManifest(text, new Set(batch.map((memory) => memory.id)));
30397
- }
30535
+ validateOutput: (messages) => validateClientMapMemories(messages, new Set(batch.map((memory) => memory.id)))
30398
30536
  });
30399
30537
  promptSettled = true;
30400
30538
  recordInvocation2(args, startedAt, { status: "completed", messages: run.output });
30539
+ stage = "apply";
30401
30540
  const outcome = await applyParsedBatchMappings(args, batch, run.validated, budgetFinalized, true);
30402
30541
  logBatchUsage(run.output, outcome.mapped + outcome.independent, startedAt);
30403
30542
  const returnedIds = new Set(outcome.committedIds);
@@ -30426,6 +30565,8 @@ async function mapOneBatch(args, batch, sliceMs, signal) {
30426
30565
  return {
30427
30566
  ...outcome,
30428
30567
  failure: {
30568
+ error,
30569
+ stage,
30429
30570
  class: isTimeoutClassError2(error) ? "timeout" : "other",
30430
30571
  elapsedMs: Date.now() - startedAt
30431
30572
  }
@@ -31582,10 +31723,28 @@ async function readRetrospectiveScanWindow(provider, projectIdentity, watermarkM
31582
31723
  }
31583
31724
  function readOpenCodeMessagesSince(db, sessionId, sinceMs, capPerSession) {
31584
31725
  const limit = Math.max(1, Math.floor(capPerSession));
31585
- const rows = db.prepare(`SELECT id, data, time_created
31586
- FROM message
31587
- WHERE session_id = ? AND time_created > ?
31588
- ORDER BY time_created ASC, id ASC
31726
+ const rows = db.prepare(`SELECT current.id, current.data, current.time_created,
31727
+ EXISTS (
31728
+ SELECT 1 FROM message assistant_reply
31729
+ WHERE assistant_reply.session_id = current.session_id
31730
+ AND json_valid(assistant_reply.data)
31731
+ AND json_extract(assistant_reply.data, '$.role') = 'assistant'
31732
+ AND (assistant_reply.time_created < current.time_created
31733
+ OR (assistant_reply.time_created = current.time_created
31734
+ AND assistant_reply.id < current.id))
31735
+ AND EXISTS (
31736
+ SELECT 1 FROM message prior_user
31737
+ WHERE prior_user.session_id = current.session_id
31738
+ AND json_valid(prior_user.data)
31739
+ AND json_extract(prior_user.data, '$.role') = 'user'
31740
+ AND (prior_user.time_created < assistant_reply.time_created
31741
+ OR (prior_user.time_created = assistant_reply.time_created
31742
+ AND prior_user.id < assistant_reply.id))
31743
+ )
31744
+ ) AS has_prior_assistant_reply
31745
+ FROM message current
31746
+ WHERE current.session_id = ? AND current.time_created > ?
31747
+ ORDER BY current.time_created ASC, current.id ASC
31589
31748
  LIMIT ?`).all(sessionId, sinceMs, limit + 1);
31590
31749
  const truncated = rows.length > limit;
31591
31750
  const kept = truncated ? rows.slice(0, limit) : rows;
@@ -31689,7 +31848,8 @@ function normalizeOpenCodeRows(db, sessionId, rows) {
31689
31848
  ordinal,
31690
31849
  role,
31691
31850
  parts,
31692
- ts: row.time_created
31851
+ ts: row.time_created,
31852
+ followsAssistantReply: row.has_prior_assistant_reply === 1
31693
31853
  });
31694
31854
  });
31695
31855
  }
@@ -31703,7 +31863,8 @@ function normalizeOpenCodeMessage(args) {
31703
31863
  ordinal: args.ordinal,
31704
31864
  role: "user",
31705
31865
  text,
31706
- ts: args.ts
31866
+ ts: args.ts,
31867
+ ...args.followsAssistantReply ? { followsAssistantReply: true } : {}
31707
31868
  });
31708
31869
  }
31709
31870
  }
@@ -32069,7 +32230,7 @@ var VERIFY_SYSTEM_PROMPT = `You are a memory verifier for the magic-context syst
32069
32230
 
32070
32231
  Each memory below comes with its backing file(s) — the code it makes a claim about. For EACH memory: use the provided git diff as evidence when present. If no diff is supplied, read its backing files (you may read more if needed) and decide whether the memory is still accurate.
32071
32232
 
32072
- Tools (read-only): read, grep, glob. Request line ranges and keep reads short. You read code only when the evidence requires it; you change nothing.
32233
+ Tools (read-only): read, grep, glob, plus any available AFT navigation tools. Use at most 3 tool calls per memory, including searches and reads. Start with the backing files and likely identifier matches. Never read the same file twice in a batch; reuse evidence. Request short useful line ranges unless the claim concerns the file as a whole. If evidence is insufficient when the call budget runs out, SKIP that memory; uncertainty never justifies archival. You change nothing.
32073
32234
 
32074
32235
  Decide ONE of four outcomes per memory:
32075
32236
  - VERIFIED — still accurate. Keep it as-is.
@@ -32081,7 +32242,7 @@ UPDATE and ARCHIVE are ONLY for claims a repository file can falsify, such as an
32081
32242
 
32082
32243
  BE CONSERVATIVE ABOUT ARCHIVING. Wrong archival of a TRUE memory is the worst possible outcome — far worse than leaving a slightly-stale memory. If you cannot find the code, or you are unsure, or it might still be true somewhere you didn't look: mark it VERIFIED or SKIPPED, never archived. Archive ONLY when you have positive evidence the code contradicts a code fact.
32083
32244
 
32084
- Output ONE XML manifest at the very end and NOTHING else — no narration, no per-memory commentary, no reasoning:
32245
+ Output ONE XML manifest and NOTHING else — no narration or reasoning. Open <verify> before investigating and emit each complete verdict immediately before investigating the next memory, so interruption preserves finished work. Close </verify> when done:
32085
32246
  <verify>
32086
32247
  <verified id="N" files="path/a.ts,path/b.ts"/>
32087
32248
  <update id="M" files="path/c.ts">corrected present-tense content</update>
@@ -32094,17 +32255,24 @@ Rules:
32094
32255
  - Every input memory id MUST appear exactly once, in exactly one of verified/update/archive/skip.
32095
32256
  - files = the COMPLETE current backing set (repo-relative, comma-separated). It may differ from the given mapping if a file moved — record what you actually verified against.
32096
32257
  - Default to VERIFIED. skip when code cannot decide the claim. update and archive are the exceptions, not the norm.`;
32258
+ async function seedVerifyCandidates(memories, directory) {
32259
+ const seeded = await seedIdentifierCandidates(memories.map((m) => ({ ...m, candidates: [] })), directory);
32260
+ return memories.map((m, i) => ({ ...m, candidates: seeded[i].candidates }));
32261
+ }
32097
32262
  function buildVerifyPrompt(projectPath, memories, evidence) {
32098
32263
  const list = memories.map((m) => `[${m.id}] ${m.category}
32099
32264
  Content: ${m.content}
32100
- Backing files: ${m.mappedFiles.join(", ")}`).join(`
32265
+ Backing files: ${m.mappedFiles.join(", ")}${m.candidates?.length ? `
32266
+ Likely files (identifier matches, confirm before using): ${m.candidates.join(", ")}` : ""}`).join(`
32101
32267
 
32102
32268
  `);
32103
32269
  return `## Verify these memories against the code
32104
32270
 
32105
32271
  Project: ${projectPath}
32106
32272
 
32107
- ${evidence ? "The git diff below is the evidence. If changed hunks do not touch a claim, mark it verified without opening files. Open files only when a diff suggests the claim may have changed. A rename or deletion requires an update or archive when positively supported; do not archive on uncertainty." : "Read each memory's backing files to check its claims."} Decide verified / update / archive / skip (default verified; behavioral directives only permit verified or skip), then output ONE <verify> manifest covering every id.
32273
+ When available in this session, use aft_outline to outline the backing file and aft_zoom on the claimed symbol (or aft_search to locate it), instead of paging through whole files. Read a whole file only when the claim is about the file as a whole. Otherwise use the available read-only tools.
32274
+
32275
+ ${evidence ? "The git diff below is the evidence. If changed hunks do not touch a claim, mark it verified without opening files. Open files only when a diff suggests the claim may have changed. A rename or deletion requires an update or archive when positively supported; do not archive on uncertainty." : "Check each memory's claim against its backing files."} Decide verified / update / archive / skip (default verified; behavioral directives only permit verified or skip), then output ONE <verify> manifest covering every id.
32108
32276
 
32109
32277
  <memories>
32110
32278
  ${list}
@@ -32181,13 +32349,57 @@ function validateVerifyManifest(text, expectedIds) {
32181
32349
  assertNoDuplicateManifestIds(ids.filter((id) => expectedIds.has(id)), "verify");
32182
32350
  return parsed;
32183
32351
  }
32352
+ function parsePartialVerifyManifest(text, expectedIds) {
32353
+ const out = { verified: [], updated: [], archived: [], skipped: [] };
32354
+ const start = text.lastIndexOf("<verify>");
32355
+ if (start < 0)
32356
+ return out;
32357
+ const entries = new Map;
32358
+ const conflicts = new Set;
32359
+ for (const match of text.slice(start).matchAll(/<(?:verified|archive|skip)\b[^<>]*\/>|<update\b[^<>]*>[\s\S]*?<\/update>/g)) {
32360
+ try {
32361
+ const parsed = parseVerifyManifest(`<verify>${match[0]}</verify>`);
32362
+ const id = verifyIds(parsed)[0];
32363
+ if (!expectedIds.has(id) || conflicts.has(id))
32364
+ continue;
32365
+ const previous = entries.get(id);
32366
+ if (previous && JSON.stringify(previous) !== JSON.stringify(parsed)) {
32367
+ entries.delete(id);
32368
+ conflicts.add(id);
32369
+ } else
32370
+ entries.set(id, parsed);
32371
+ } catch {}
32372
+ }
32373
+ for (const parsed of entries.values()) {
32374
+ out.verified.push(...parsed.verified);
32375
+ out.updated.push(...parsed.updated);
32376
+ out.archived.push(...parsed.archived);
32377
+ out.skipped.push(...parsed.skipped);
32378
+ }
32379
+ return out;
32380
+ }
32184
32381
 
32185
32382
  // src/features/magic-context/dreamer/verify.ts
32186
- var VERIFY_BATCH_SIZE = 20;
32383
+ var VERIFY_BATCH_SIZE = 5;
32384
+ var VERIFY_TOKENS_PER_MEMORY = 1e5;
32385
+ var VERIFY_RUN_TOKEN_BUDGET = 2500000;
32386
+ var VERIFY_RUN_SLICE_MS = 240000;
32387
+ function verifyBatchTokenBudget(size, configured) {
32388
+ return Math.min(configured ?? Number.MAX_SAFE_INTEGER, size * VERIFY_TOKENS_PER_MEMORY);
32389
+ }
32390
+ function verifyAssistantText(messages) {
32391
+ const text = messages.filter((m) => isRecord(m) && (m.role === "assistant" || isRecord(m.info) && m.info.role === "assistant")).map((m) => extractLatestAssistantText([m]) || (isRecord(m) && Array.isArray(m.content) ? m.content.filter(isRecord).filter((p) => p.type === "text").map((p) => p.text).join(`
32392
+ `) : "")).join(`
32393
+ `);
32394
+ if (!text.trim())
32395
+ return null;
32396
+ const start = text.lastIndexOf("<verify>");
32397
+ return start >= 0 ? text.slice(start) : text;
32398
+ }
32187
32399
  var IDENTICAL_PROVIDER_FAILURE_BATCH_LIMIT = 2;
32188
- var VERIFY_BATCH_FLOOR_MS = 240000;
32189
- function computeVerifyBatchSliceMs(remainingMs, batchesRemaining) {
32190
- return Math.min(remainingMs, Math.max(VERIFY_BATCH_FLOOR_MS, Math.floor(remainingMs / batchesRemaining)));
32400
+ var VERIFY_BATCH_FLOOR_MS = 30000;
32401
+ function computeVerifyBatchSliceMs(remainingMs, _batchesRemaining) {
32402
+ return Math.min(remainingMs, VERIFY_RUN_SLICE_MS);
32191
32403
  }
32192
32404
  function closeBroadCycle(args, cycleStartAt) {
32193
32405
  if (!args.forceBroad || cycleStartAt === undefined)
@@ -32211,6 +32423,7 @@ async function runVerify(args) {
32211
32423
  }
32212
32424
  async function runVerifyWithCooldown(args) {
32213
32425
  const runStartedAt = Date.now();
32426
+ const sliceDeadline = runStartedAt + VERIFY_RUN_SLICE_MS;
32214
32427
  const result = {
32215
32428
  verified: 0,
32216
32429
  updated: 0,
@@ -32253,16 +32466,31 @@ async function runVerifyWithCooldown(args) {
32253
32466
  let consecutiveProviderFailures = 0;
32254
32467
  let priorProviderFailureFingerprint = null;
32255
32468
  let lastProviderFailure = null;
32469
+ let runSpent = 0;
32470
+ const runTokenBudget = Math.min(args.tokenBudget ?? VERIFY_RUN_TOKEN_BUDGET, VERIFY_RUN_TOKEN_BUDGET);
32256
32471
  try {
32257
32472
  for (let i = 0;i < batches.length; i += 1) {
32258
- const remainingMs = Math.max(0, args.deadline - Date.now());
32473
+ const remainingMs = Math.max(0, Math.min(args.deadline, sliceDeadline) - Date.now());
32259
32474
  if (remainingMs < VERIFY_BATCH_FLOOR_MS) {
32260
32475
  result.stopReason = "deadline";
32261
32476
  log2(`[dreamer] ${args.forceBroad ? "verify-broad" : "verify"}: stopping before batch ${i + 1}/${batches.length} — remaining budget ${remainingMs}ms is below the ${VERIFY_BATCH_FLOOR_MS}ms batch floor`);
32262
32477
  break;
32263
32478
  }
32264
32479
  const sliceMs = computeVerifyBatchSliceMs(remainingMs, batches.length - i);
32265
- const counts = await verifyOneBatch(args, batches[i], sliceMs, abortController.signal);
32480
+ if (runSpent >= runTokenBudget) {
32481
+ result.stopReason = "token-budget";
32482
+ break;
32483
+ }
32484
+ let batchSpent = 0;
32485
+ const counts = await verifyOneBatch({
32486
+ ...args,
32487
+ tokenBudget: runTokenBudget - runSpent,
32488
+ onBudgetUpdate: (state) => {
32489
+ runSpent += Math.max(0, state.spent - batchSpent);
32490
+ batchSpent = Math.max(batchSpent, state.spent);
32491
+ args.onBudgetUpdate?.(state);
32492
+ }
32493
+ }, batches[i], sliceMs, abortController.signal);
32266
32494
  result.verified += counts.verified;
32267
32495
  result.updated += counts.updated;
32268
32496
  result.archived += counts.archived;
@@ -32272,6 +32500,10 @@ async function runVerifyWithCooldown(args) {
32272
32500
  result.remaining -= batchProcessed;
32273
32501
  result.batches += 1;
32274
32502
  args.onProgress?.(result.verified + result.updated + result.archived + result.skipped + result.refused, result.refused);
32503
+ if (counts.tokenLimited) {
32504
+ result.stopReason = "token-budget";
32505
+ break;
32506
+ }
32275
32507
  if (counts.timedOut) {
32276
32508
  result.stopReason = "batch-timeout";
32277
32509
  log2(`[dreamer] ${args.forceBroad ? "verify-broad" : "verify"}: batch ${i + 1}/${batches.length} timed out after its ${sliceMs}ms slice; stopping with ${result.remaining} remaining`);
@@ -32306,18 +32538,41 @@ async function runVerifyWithCooldown(args) {
32306
32538
  }
32307
32539
  }
32308
32540
  async function verifyOneBatch(args, batch, sliceMs, signal) {
32541
+ const batchController = new AbortController;
32542
+ const abort = () => batchController.abort(signal.reason);
32543
+ signal.addEventListener("abort", abort, { once: true });
32544
+ if (signal.aborted)
32545
+ abort();
32546
+ const timer = setTimeout(() => batchController.abort(new Error(`verify slice timed out after ${sliceMs}ms`)), sliceMs);
32547
+ const batchSignal = batchController.signal;
32548
+ const tokenBudget = verifyBatchTokenBudget(batch.length, args.tokenBudget);
32309
32549
  let agentSessionId = null;
32550
+ let hiddenSessionId = null;
32310
32551
  let promptSettled = false;
32311
32552
  const startedAt = Date.now();
32312
32553
  let budgetFinalized = false;
32554
+ let failedCompletion;
32555
+ let headAtPrompt = null;
32313
32556
  const onBudgetUpdate = (state) => {
32314
32557
  budgetFinalized ||= state.finalizeFired;
32315
- args.onBudgetUpdate?.(state);
32558
+ args.onBudgetUpdate?.({
32559
+ ...state,
32560
+ ...hiddenSessionId ? { sessionId: hiddenSessionId } : {}
32561
+ });
32562
+ };
32563
+ const reportUsage = (messages, sessionId, fallbackSpent = 0) => {
32564
+ const usage = sumTokensFromChildMessages(messages);
32565
+ onBudgetUpdate({
32566
+ spent: Math.max(fallbackSpent, usage.input + usage.cacheRead + usage.cacheWrite),
32567
+ finalizeFired: budgetFinalized,
32568
+ ...sessionId ? { sessionId } : {}
32569
+ });
32316
32570
  };
32317
32571
  try {
32318
- const headAtPrompt = await readGitHead(args.sessionDirectory);
32319
- const evidence = !args.forceBroad && batch.every((m) => m.verifiedAt) ? await buildVerifyDiffEvidence(args.sessionDirectory, batch) : null;
32320
- const prompt = buildVerifyPrompt(args.projectIdentity, batch, evidence);
32572
+ headAtPrompt = await raceWithSignal(readGitHead(args.sessionDirectory), batchSignal);
32573
+ const evidence = !args.forceBroad && batch.every((m) => m.verifiedAt) ? await raceWithSignal(buildVerifyDiffEvidence(args.sessionDirectory, batch), batchSignal) : null;
32574
+ const prompt = buildVerifyPrompt(args.projectIdentity, await raceWithSignal(seedVerifyCandidates(batch, args.sessionDirectory), batchSignal), evidence);
32575
+ batchSignal.throwIfAborted();
32321
32576
  if (args.hiddenCompletionExecutor) {
32322
32577
  const run = await runHiddenSingleShotPrompt({
32323
32578
  executor: args.hiddenCompletionExecutor,
@@ -32328,41 +32583,53 @@ async function verifyOneBatch(args, batch, sliceMs, signal) {
32328
32583
  prompt,
32329
32584
  title: "magic-context-dream-verify",
32330
32585
  callContext: "dreamer:verify",
32331
- metadata: { tokenBudget: args.tokenBudget, onBudgetUpdate },
32586
+ metadata: { tokenBudget, onBudgetUpdate },
32332
32587
  model: args.model,
32333
32588
  fallbackModels: args.fallbackModels,
32334
32589
  language: args.language,
32335
32590
  timeoutMs: sliceMs,
32336
- signal,
32591
+ signal: batchSignal,
32592
+ onFailureOutput: (completion) => {
32593
+ failedCompletion = completion;
32594
+ },
32595
+ onOpened: (sessionId) => {
32596
+ hiddenSessionId = sessionId;
32597
+ onBudgetUpdate({ spent: 0, finalizeFired: false, sessionId });
32598
+ },
32337
32599
  parse: (text, completion) => {
32338
32600
  const providerFailure = providerOutputFailureFromInvalidManifest(completion.messages ?? [], text);
32339
32601
  if (providerFailure)
32340
32602
  throw providerFailure;
32341
- return validateVerifyManifest(text, new Set(batch.map((memory) => memory.id)));
32603
+ const manifest = verifyAssistantText(completion.messages ?? []) ?? (text.trim() ? text : null);
32604
+ if (!manifest)
32605
+ throw new Error("verify returned no output");
32606
+ return validateVerifyManifest(manifest, new Set(batch.map((memory) => memory.id)));
32342
32607
  }
32343
32608
  });
32344
32609
  recordInvocation4(args, startedAt, {
32345
32610
  status: "completed",
32346
32611
  messages: run.completion.messages ?? []
32347
32612
  });
32348
- return applyParsedVerifyManifest(args, batch, run.validated, evidence?.head ?? headAtPrompt, budgetFinalized);
32613
+ reportUsage(run.completion.messages ?? [], run.childSessionId, run.completion.usage.input + (run.completion.usage.cacheRead ?? 0) + (run.completion.usage.cacheWrite ?? 0));
32614
+ return await applyParsedVerifyManifest(args, batch, run.validated, evidence?.head ?? headAtPrompt, budgetFinalized);
32349
32615
  }
32350
32616
  const client = args.client;
32351
32617
  if (!client)
32352
32618
  throw new Error("verify requires a client or hidden completion executor");
32353
- const createResponse = await createChildSessionWithFence({
32619
+ const createResponse = await raceWithSignal(createChildSessionWithFence({
32354
32620
  client,
32355
32621
  db: args.db,
32356
32622
  parentSessionId: args.parentSessionId,
32357
32623
  title: args.forceBroad ? "magic-context-dream-verify-broad" : "magic-context-dream-verify",
32358
32624
  directory: args.sessionDirectory
32359
- });
32625
+ }), batchSignal);
32360
32626
  const created = normalizeSDKResponse(createResponse, null, {
32361
32627
  preferResponseOnMissingData: true
32362
32628
  });
32363
32629
  agentSessionId = typeof created?.id === "string" ? created.id : null;
32364
32630
  if (!agentSessionId)
32365
32631
  throw new Error("Could not create verify session.");
32632
+ onBudgetUpdate({ spent: 0, finalizeFired: false, sessionId: agentSessionId });
32366
32633
  const run = await promptSyncWithValidatedOutputRetry(client, {
32367
32634
  path: { id: agentSessionId },
32368
32635
  query: { directory: args.sessionDirectory },
@@ -32374,11 +32641,11 @@ async function verifyOneBatch(args, batch, sliceMs, signal) {
32374
32641
  }
32375
32642
  }, {
32376
32643
  transport: createPromptAsyncTransport(client, agentSessionId, {
32377
- tokenBudget: args.tokenBudget,
32644
+ tokenBudget,
32378
32645
  onBudgetUpdate
32379
32646
  }),
32380
32647
  timeoutMs: sliceMs,
32381
- signal,
32648
+ signal: batchSignal,
32382
32649
  fallbackModels: args.fallbackModels,
32383
32650
  callContext: "dreamer:verify",
32384
32651
  fetchOutput: async () => {
@@ -32394,7 +32661,7 @@ async function verifyOneBatch(args, batch, sliceMs, signal) {
32394
32661
  if (hasLengthCappedOutput(messages)) {
32395
32662
  throw new Error("verify returned length-capped output");
32396
32663
  }
32397
- const text = extractLatestAssistantText(messages);
32664
+ const text = verifyAssistantText(messages);
32398
32665
  if (!text)
32399
32666
  throw new Error("verify returned no output");
32400
32667
  const providerFailure = providerOutputFailureFromInvalidManifest(messages, text);
@@ -32405,27 +32672,31 @@ async function verifyOneBatch(args, batch, sliceMs, signal) {
32405
32672
  });
32406
32673
  promptSettled = true;
32407
32674
  recordInvocation4(args, startedAt, { status: "completed", messages: run.output });
32675
+ reportUsage(run.output, agentSessionId);
32408
32676
  return await applyParsedVerifyManifest(args, batch, run.validated, evidence?.head ?? headAtPrompt, budgetFinalized);
32409
32677
  } catch (error) {
32410
32678
  const desc = describeError(error);
32411
32679
  const providerFailure = error instanceof DreamerProviderOutputFailureError ? error : undefined;
32412
32680
  const promptFailure = getPromptFailureDetail(error);
32413
32681
  log2(`[dreamer] verify batch ${providerFailure ? "provider failure" : "failed"}: ${desc.brief}`, desc.stackHead ? { stackHead: desc.stackHead } : undefined);
32682
+ const messages = failedCompletion?.messages ?? await readFailedChildMessages(args.client, agentSessionId, args.sessionDirectory) ?? [];
32683
+ reportUsage(messages, hiddenSessionId ?? agentSessionId, failedCompletion?.usage.input ?? 0);
32414
32684
  recordInvocation4(args, startedAt, {
32415
32685
  status: failedInvocationStatus(error),
32416
32686
  error,
32417
- messages: await readFailedChildMessages(args.client, agentSessionId, args.sessionDirectory)
32687
+ messages
32418
32688
  });
32419
- if (error instanceof DreamerModuleFailureError || error instanceof DreamTokenBudgetExceeded || signal.aborted)
32689
+ if (error instanceof DreamerModuleFailureError || signal.aborted)
32420
32690
  throw error;
32421
- if (promptFailure?.failureClass === "provider_timeout" || isPromptTimeoutError(error)) {
32691
+ const interrupted = batchSignal.aborted || error instanceof DreamTokenBudgetExceeded || promptFailure?.failureClass === "provider_timeout" || isPromptTimeoutError(error);
32692
+ if (interrupted) {
32693
+ const text = verifyAssistantText(messages) ?? failedCompletion?.text ?? "";
32694
+ const recovered = parsePartialVerifyManifest(text, new Set(batch.map((m) => m.id)));
32695
+ const counts = await applyParsedVerifyManifest(args, batch, recovered, headAtPrompt, true);
32422
32696
  return {
32423
- verified: 0,
32424
- updated: 0,
32425
- archived: 0,
32426
- skipped: 0,
32427
- refused: 0,
32428
- timedOut: true
32697
+ ...counts,
32698
+ timedOut: !(error instanceof DreamTokenBudgetExceeded),
32699
+ tokenLimited: error instanceof DreamTokenBudgetExceeded
32429
32700
  };
32430
32701
  }
32431
32702
  if (promptFailure !== null && promptFailure.failureClass !== "parse_failed" && !providerFailure)
@@ -32440,7 +32711,7 @@ async function verifyOneBatch(args, batch, sliceMs, signal) {
32440
32711
  };
32441
32712
  } finally {
32442
32713
  if (agentSessionId && args.client)
32443
- await teardownChildSession({
32714
+ await raceWithSignal(teardownChildSession({
32444
32715
  client: args.client,
32445
32716
  sessionId: agentSessionId,
32446
32717
  sessionDirectory: args.sessionDirectory,
@@ -32448,7 +32719,9 @@ async function verifyOneBatch(args, batch, sliceMs, signal) {
32448
32719
  privacySensitive: true,
32449
32720
  context: "[dreamer] verify",
32450
32721
  log: log2
32451
- });
32722
+ }), batchSignal).catch(() => {});
32723
+ clearTimeout(timer);
32724
+ signal.removeEventListener("abort", abort);
32452
32725
  }
32453
32726
  }
32454
32727
  async function applyParsedVerifyManifest(args, batch, parsed, headAtPrompt, budgetFinalized = false) {
@@ -32475,7 +32748,7 @@ async function applyParsedVerifyManifest(args, batch, parsed, headAtPrompt, budg
32475
32748
  throw new Error(`verify manifest covers ${validIds.length}/${batch.length} batch ids after filtering unknown entries; rejecting mostly-wrong manifest`);
32476
32749
  }
32477
32750
  if (budgetFinalized && validIds.length < batch.length) {
32478
- log2(`[dreamer] verify: accepted partial manifest after token budget: ${validIds.length}/${batch.length}`);
32751
+ log2(`[dreamer] verify: accepted partial manifest after investigation stop: ${validIds.length}/${batch.length}`);
32479
32752
  }
32480
32753
  if (validIds.length === 0) {
32481
32754
  return { verified: 0, updated: 0, archived: 0, skipped: 0, refused: 0 };
@@ -32710,10 +32983,10 @@ function dreamRunFailureDetail(error) {
32710
32983
  child_session_id: null
32711
32984
  };
32712
32985
  }
32713
- const localRefusal = error instanceof HiddenCompletionRefusal;
32986
+ const localRefusal = error instanceof HiddenCompletionRefusal || error instanceof DreamerModuleFailureError;
32714
32987
  const providerFailure = error instanceof Error && error.name === "DreamerProviderOutputFailureError";
32715
32988
  return {
32716
- failure_class: localRefusal ? "local_refusal" : providerFailure ? "provider_error" : /no models?|model chain is empty/i.test(message) ? "no_models" : "unknown",
32989
+ failure_class: localRefusal ? "local_refusal" : providerFailure ? "provider_error" : /lease_(?:lost|expired)|Dream lease (?:lost|unavailable)/i.test(message) ? "child_aborted" : /no models?|model chain is empty/i.test(message) ? "no_models" : "unknown",
32717
32990
  model_attempted: null,
32718
32991
  models_tried: [],
32719
32992
  provider_error: providerFailure ? sanitizeDiagnosticText(message).slice(0, 500) : null,
@@ -32724,6 +32997,10 @@ function dreamRunFailureDetail(error) {
32724
32997
  } : {}
32725
32998
  };
32726
32999
  }
33000
+ function incompleteFailure(error, fallback = "parse_failed") {
33001
+ const detail = dreamRunFailureDetail(error);
33002
+ return detail.failure_class === "unknown" ? { ...detail, failure_class: fallback } : detail;
33003
+ }
32727
33004
  function classifyFailure(error) {
32728
33005
  const described = describeError(error);
32729
33006
  const brief = described.brief;
@@ -32883,6 +33160,7 @@ function createDreamTaskExecutor(deps) {
32883
33160
  const { db, projectIdentity, holderId, leaseKey } = ctx;
32884
33161
  deps.client?.resetDreamTokenBudget?.(config.task);
32885
33162
  const startedAt = Date.now();
33163
+ const effectiveTokenBudget = config.task === "verify" || config.task === "verify-broad" ? Math.min(config.tokenBudget ?? VERIFY_RUN_TOKEN_BUDGET, VERIFY_RUN_TOKEN_BUDGET) : config.tokenBudget;
32886
33164
  const leaseAcquisition = ctx.leaseAcquisition ?? acquireLeaseWithAcquisition(db, holderId, leaseKey) ?? (() => {
32887
33165
  throw new Error("Dream lease unavailable during executor setup");
32888
33166
  })();
@@ -32930,7 +33208,7 @@ function createDreamTaskExecutor(deps) {
32930
33208
  if (state.sessionId) {
32931
33209
  const previous = childSpending.get(state.sessionId) ?? 0;
32932
33210
  budgetSpent += Math.max(0, state.spent - previous);
32933
- childSpending.set(state.sessionId, state.spent);
33211
+ childSpending.set(state.sessionId, Math.max(previous, state.spent));
32934
33212
  } else
32935
33213
  budgetSpent = Math.max(budgetSpent, state.spent);
32936
33214
  budgetFinalized ||= state.finalizeFired;
@@ -32957,9 +33235,15 @@ function createDreamTaskExecutor(deps) {
32957
33235
  failure: extra?.failure ?? dreamRunFailureDetail(error ?? "unknown dreamer failure")
32958
33236
  } : {},
32959
33237
  ...extra?.progress ? { progress: extra.progress } : {},
32960
- ...config.tokenBudget ? {
33238
+ ...childSpending.size ? {
33239
+ children: [...childSpending].map(([sessionId, promptTokens]) => ({
33240
+ sessionId,
33241
+ promptTokens
33242
+ }))
33243
+ } : {},
33244
+ ...effectiveTokenBudget ? {
32961
33245
  tokenBudget: {
32962
- budget: config.tokenBudget,
33246
+ budget: effectiveTokenBudget,
32963
33247
  spent: budgetSpent,
32964
33248
  finalizeFired: budgetFinalized,
32965
33249
  banked: extra?.banked ?? processedDreamTaskItems(backlogAtStart.pending, (extra?.backlogAfter ?? getDreamTaskBacklog(db, projectIdentity, config.task)).pending)
@@ -33048,8 +33332,13 @@ function createDreamTaskExecutor(deps) {
33048
33332
  });
33049
33333
  log2(`[dreamer] compress-cues: compressed=${result.compressed} skipped=${result.skipped} chunks=${result.chunks} remaining=${result.remaining}`);
33050
33334
  if (!result.complete) {
33051
- const error = incompleteMessage(result.remaining);
33052
- recordRun("failed", error);
33335
+ if (result.stopReason === "deadline" && result.chunks === 0)
33336
+ return skip("compress-cues: insufficient time to start a chunk");
33337
+ const error = `${incompleteMessage(result.remaining)}; ${result.failureStage ? `${result.failureStage}: ` : ""}${result.failure ? describeError(result.failure).brief : `${result.skipped} cues rejected by validation`}`;
33338
+ recordRun("failed", error, {
33339
+ banked: result.compressed,
33340
+ failure: incompleteFailure(result.failure, result.failureStage === "child-start" ? "local_refusal" : result.stopReason === "timeout-circuit-breaker" ? "provider_timeout" : "parse_failed")
33341
+ });
33053
33342
  return { status: "failed", transient: true, error };
33054
33343
  }
33055
33344
  recordRun("completed", null);
@@ -33095,9 +33384,15 @@ function createDreamTaskExecutor(deps) {
33095
33384
  });
33096
33385
  log2(`[dreamer] map-memories: committed=${result.mapped + result.independent} mapped=${result.mapped} independent=${result.independent} batches=${result.batches} remaining=${result.remaining} complete=${result.complete}${result.stopReason ? ` stop_reason=${result.stopReason}` : ""}`);
33097
33386
  if (!result.complete) {
33387
+ if (result.deferred)
33388
+ return skip("map-memories: all pending mappings are in content-keyed retry backoff; no child started");
33389
+ if (result.stopReason === "deadline" && result.batches === 0 && !result.failure)
33390
+ return skip("map-memories: insufficient time to start a batch");
33098
33391
  if (result.stopReason === "timeout-circuit-breaker") {
33099
33392
  const error = `map-memories starvation: timeout circuit breaker stopped the run with ${result.remaining} remain`;
33100
- recordRun("failed", error);
33393
+ recordRun("failed", error, {
33394
+ failure: incompleteFailure(result.failure, "provider_timeout")
33395
+ });
33101
33396
  return { status: "failed", transient: true, error };
33102
33397
  }
33103
33398
  const processed = result.mapped + result.independent;
@@ -33106,8 +33401,10 @@ function createDreamTaskExecutor(deps) {
33106
33401
  recordRun("completed", null, { progress });
33107
33402
  return { status: "completed" };
33108
33403
  }
33109
- const error = incompleteMessage(result.remaining);
33110
- recordRun("failed", error);
33404
+ const error = `${incompleteMessage(result.remaining)}; ${result.failureStage ? `${result.failureStage}: ` : ""}${result.failure ? describeError(result.failure).brief : "manifest returned no accepted mapping decisions"}`;
33405
+ recordRun("failed", error, {
33406
+ failure: incompleteFailure(result.failure, result.failureStage === "child-start" ? "local_refusal" : "parse_failed")
33407
+ });
33111
33408
  return { status: "failed", transient: true, error };
33112
33409
  }
33113
33410
  recordRun("completed", null);
@@ -33137,25 +33434,27 @@ function createDreamTaskExecutor(deps) {
33137
33434
  });
33138
33435
  const processed = result.verified + result.updated + result.archived + result.skipped + result.refused;
33139
33436
  const verificationProgress = `${config.task}${config.task === "verify-broad" ? ` cycle ${result.broadCycleStartAt ?? "open"}` : ""}: processed ${processed} (verified ${result.verified}, updated ${result.updated}, archived ${result.archived}, skipped ${result.skipped}, refused ${result.refused}); ${result.remaining} remain`;
33140
- const broadProgress = config.task === "verify-broad" ? verificationProgress : null;
33141
33437
  const backlogAfter = config.task === "verify-broad" ? { pending: result.remaining, total: backlogAtStart.total } : undefined;
33142
33438
  if (!result.complete) {
33143
- if (broadProgress && processed > 0) {
33439
+ if (processed > 0) {
33144
33440
  recordRun("completed", null, {
33145
- progress: broadProgress,
33441
+ progress: verificationProgress,
33146
33442
  memoryChanges: computeMemoryDelta(memoryBefore),
33147
33443
  backlogAfter,
33148
33444
  banked: result.verified + result.updated + result.archived
33149
33445
  });
33150
33446
  return { status: "completed" };
33151
33447
  }
33448
+ if (result.stopReason === "deadline")
33449
+ return skip(`${config.task}: insufficient time to start a batch`);
33152
33450
  const batchTimedOut = result.stopReason === "batch-timeout";
33153
33451
  const error = batchTimedOut ? `${config.task}: a batch timed out within its time slice; ${result.remaining} remain` : incompleteMessage(result.remaining);
33154
33452
  recordRun("failed", error, {
33155
33453
  progress: verificationProgress,
33156
33454
  memoryChanges: computeMemoryDelta(memoryBefore),
33157
33455
  backlogAfter,
33158
- banked: result.verified + result.updated + result.archived
33456
+ banked: result.verified + result.updated + result.archived,
33457
+ failure: incompleteFailure(error, batchTimedOut ? "provider_timeout" : result.stopReason === "token-budget" ? "token_budget" : "parse_failed")
33159
33458
  });
33160
33459
  return { status: "failed", transient: !batchTimedOut, error };
33161
33460
  }
@@ -33279,6 +33578,7 @@ function createDreamTaskExecutor(deps) {
33279
33578
  if (retro.skipReason)
33280
33579
  return skip(retro.skipReason);
33281
33580
  recordRun("completed", null, {
33581
+ progress: retro.noOpReason,
33282
33582
  memoryChanges: computeMemoryDelta(memoryBefore),
33283
33583
  backlogAfter: retro.retrospectiveWatermarkMs == null ? undefined : getDreamTaskBacklog(db, projectIdentity, "retrospective", {
33284
33584
  retrospectiveWatermarkMs: retro.retrospectiveWatermarkMs
@@ -33286,6 +33586,7 @@ function createDreamTaskExecutor(deps) {
33286
33586
  });
33287
33587
  return {
33288
33588
  status: "completed",
33589
+ ...retro.noOpReason ? { detail: retro.noOpReason } : {},
33289
33590
  schedulePatch: retro.retrospectiveWatermarkMs != null || retro.taskStateJson !== undefined ? {
33290
33591
  ...retro.retrospectiveWatermarkMs != null ? {
33291
33592
  retrospectiveWatermarkMs: retro.retrospectiveWatermarkMs
@@ -33485,20 +33786,28 @@ async function runRetrospectiveTask(config, ctx, helpers) {
33485
33786
  const recencyCutoffMs = helpers.invocationStartedAt - recencyDays * RETROSPECTIVE_DAY_MS;
33486
33787
  const scan = await readRetrospectiveScanWindow(provider, projectIdentity, watermarkMs, RETROSPECTIVE_OVERLAP_USER_LINES, { usableInputTokens, recencyCutoffMs });
33487
33788
  const clearedTaskStateJson = activeOverflow ? writeRetrospectiveOverflowState(taskState.root, null) : undefined;
33488
- const completedWindow = (retrospectiveWatermarkMs) => ({
33789
+ const completedWindow = (retrospectiveWatermarkMs, noOpReason) => ({
33489
33790
  retrospectiveWatermarkMs,
33490
- ...clearedTaskStateJson ? { taskStateJson: clearedTaskStateJson } : {}
33791
+ ...clearedTaskStateJson ? { taskStateJson: clearedTaskStateJson } : {},
33792
+ ...noOpReason ? { noOpReason } : {}
33491
33793
  });
33492
33794
  const messages = withGlobalOrdinals(scan.messages);
33493
33795
  const userMessages = messages.filter((message) => message.role === "user" && message.text.trim().length > 0);
33494
33796
  if (userMessages.length === 0) {
33495
- log2("[dreamer] retrospective: no user messages in window");
33496
- return completedWindow(scan.maxScannedTs);
33797
+ const noOpReason = "no reply-following user lines";
33798
+ log2(`[dreamer] retrospective: ${noOpReason}`);
33799
+ return completedWindow(scan.maxScannedTs, noOpReason);
33497
33800
  }
33498
- const postWatermarkOrdinals = new Set(userMessages.filter((message) => message.ts > watermarkMs).map((message) => message.ordinal));
33499
- if (postWatermarkOrdinals.size === 0) {
33801
+ const newUserOrdinals = new Set(userMessages.filter((message) => message.ts > watermarkMs).map((message) => message.ordinal));
33802
+ if (newUserOrdinals.size === 0) {
33500
33803
  log2("[dreamer] retrospective: only overlap lines, nothing new");
33501
- return completedWindow(scan.maxScannedTs);
33804
+ return completedWindow(scan.maxScannedTs, "only overlap lines, nothing new");
33805
+ }
33806
+ const postWatermarkOrdinals = new Set(userMessages.filter((message) => message.ts > watermarkMs && message.followsAssistantReply === true).map((message) => message.ordinal));
33807
+ if (postWatermarkOrdinals.size === 0) {
33808
+ const noOpReason = "no reply-following user lines";
33809
+ log2(`[dreamer] retrospective: ${noOpReason}`);
33810
+ return completedWindow(scan.maxScannedTs, noOpReason);
33502
33811
  }
33503
33812
  const abortController = new AbortController;
33504
33813
  let leaseLost = false;
@@ -34079,6 +34388,12 @@ function pruneIdleScheduleIdentities(db, now) {
34079
34388
 
34080
34389
  // src/features/magic-context/dreamer/task-scheduler.ts
34081
34390
  var MAX_TASK_RETRIES = 3;
34391
+ function tasksAllowedBySettings(deps) {
34392
+ return deps.tasks.filter((config) => dreamTaskAllowedBySettings(config.task, {
34393
+ projectMemoryEnabled: deps.projectMemoryEnabled,
34394
+ smartNotesEnabled: deps.smartNotesEnabled
34395
+ }));
34396
+ }
34082
34397
  function ensureSeeded(db, projectIdentity, config, now) {
34083
34398
  if (getTaskScheduleState(db, projectIdentity, config.task))
34084
34399
  return;
@@ -34297,19 +34612,18 @@ async function runManualDream(deps) {
34297
34612
  };
34298
34613
  if (!isUsableProjectIdentity(deps.projectIdentity))
34299
34614
  return result;
34615
+ const allowed = tasksAllowedBySettings(deps);
34300
34616
  let selected;
34301
34617
  let forceGate = false;
34302
34618
  if (deps.task) {
34303
- const cfg = deps.tasks.find((t) => t.task === deps.task);
34619
+ const cfg = allowed.find((t) => t.task === deps.task);
34304
34620
  if (!cfg)
34305
34621
  return result;
34306
34622
  selected = [cfg];
34307
34623
  forceGate = true;
34308
34624
  } else {
34309
- selected = deps.tasks.filter((t) => t.schedule.trim() !== "");
34625
+ selected = allowed.filter((t) => t.schedule.trim() !== "");
34310
34626
  }
34311
- if (!isProjectMemoryEnabled(deps.projectMemoryEnabled))
34312
- selected = selected.filter((config) => config.task === "evaluate-smart-notes");
34313
34627
  if (selected.length === 0)
34314
34628
  return result;
34315
34629
  const selectedTaskNames = selected.map((config) => config.task);
@@ -34375,10 +34689,11 @@ async function runManualDream(deps) {
34375
34689
  async function runDueTasksForProject(deps) {
34376
34690
  if (!isUsableProjectIdentity(deps.projectIdentity))
34377
34691
  return 0;
34378
- if (!isProjectMemoryEnabled(deps.projectMemoryEnabled))
34692
+ const tasks = tasksAllowedBySettings(deps);
34693
+ if (tasks.length === 0)
34379
34694
  return 0;
34380
34695
  const now = deps.now ?? Date.now();
34381
- const due = planDueTasks(deps.db, deps.projectIdentity, deps.tasks, now);
34696
+ const due = planDueTasks(deps.db, deps.projectIdentity, tasks, now);
34382
34697
  if (due.length === 0)
34383
34698
  return 0;
34384
34699
  const gated = [];
@@ -34446,7 +34761,8 @@ class V2RetrospectiveRawProvider {
34446
34761
  ordinal: row.seq,
34447
34762
  role: "user",
34448
34763
  text: cleanUserText2(row.text),
34449
- ts: row.time_created
34764
+ ts: row.time_created,
34765
+ ...row.follows_assistant_reply === 1 ? { followsAssistantReply: true } : {}
34450
34766
  }));
34451
34767
  }
34452
34768
  readUserMessagesSince(sessionId, sinceMs, capPerSession) {
@@ -34515,6 +34831,7 @@ async function runManualDreamNow(args) {
34515
34831
  db: args.db,
34516
34832
  projectIdentity: args.projectIdentity,
34517
34833
  projectMemoryEnabled: args.memoryEnabled,
34834
+ smartNotesEnabled: args.smartNotesEnabled,
34518
34835
  tasks: selection.runnable,
34519
34836
  executor,
34520
34837
  ...args.task !== undefined ? { task: args.task } : {}
@@ -34992,7 +35309,8 @@ async function sweepProject(reg, origin, db, gitCommitEnabled) {
34992
35309
  projectIdentity: reg.projectIdentity,
34993
35310
  tasks: runtimeConfigs,
34994
35311
  executor,
34995
- projectMemoryEnabled: reg.memoryEnabled !== false
35312
+ projectMemoryEnabled: reg.memoryEnabled !== false,
35313
+ smartNotesEnabled: reg.smartNotesEnabled
34996
35314
  });
34997
35315
  if (ran > 0) {
34998
35316
  log2(`[dreamer] timer tick (${origin}) ${reg.projectIdentity} — ran ${ran} task(s)`);
@@ -35230,6 +35548,7 @@ function startDreamTrigger(context, args) {
35230
35548
  db,
35231
35549
  projectIdentity: args.projectIdentity(),
35232
35550
  projectMemoryEnabled: args.projectMemoryEnabled,
35551
+ smartNotesEnabled: args.smartNotesEnabled,
35233
35552
  tasks: runnable,
35234
35553
  executor: createDreamTaskExecutor({
35235
35554
  hiddenCompletionExecutor: args.executor,
@@ -49777,12 +50096,13 @@ function parseNoteIds(action, value) {
49777
50096
  }
49778
50097
  function createCtxNoteTool(deps) {
49779
50098
  const { surface_condition: _condition, ...plainArgs } = ctxNoteArgsShape;
50099
+ const smartNoteSurface = deps.smartNotesEnabled !== false && deps.dreamerEnabled !== false;
49780
50100
  return tool({
49781
- description: deps.smartNotesEnabled === false ? withoutSmartNoteText(CTX_NOTE_DESCRIPTION) : CTX_NOTE_DESCRIPTION,
49782
- args: deps.smartNotesEnabled === false ? {
50101
+ description: smartNoteSurface ? CTX_NOTE_DESCRIPTION : withoutSmartNoteText(CTX_NOTE_DESCRIPTION),
50102
+ args: smartNoteSurface ? ctxNoteArgsShape : {
49783
50103
  ...plainArgs,
49784
50104
  filter: ctxNoteArgsShape.filter.describe(NOTES_FILTER_DESCRIPTION)
49785
- } : ctxNoteArgsShape,
50105
+ },
49786
50106
  async execute(rawArgs, toolContext) {
49787
50107
  const parsedArgs = ctxNoteArgsSchema.safeParse(rawArgs);
49788
50108
  let args = parsedArgs.success ? parsedArgs.data : rawArgs;
@@ -50438,6 +50758,85 @@ function bindV2TransformDecision(args) {
50438
50758
  }
50439
50759
  }
50440
50760
 
50761
+ // src/hooks/magic-context/auto-embed-session.ts
50762
+ function embeddingIdentity(projectIdentity) {
50763
+ const snapshot = getProjectEmbeddingSnapshot2(projectIdentity);
50764
+ return JSON.stringify([
50765
+ projectIdentity,
50766
+ snapshot?.providerIdentity,
50767
+ snapshot?.chunkModelId,
50768
+ snapshot?.runtimeFingerprint
50769
+ ]);
50770
+ }
50771
+ function maybeAutoEmbedSessionBackfill(deps, sessionId) {
50772
+ const markActive = () => activeEmbeddingSessions.set(sessionId, {
50773
+ project: deps.projectIdentity,
50774
+ model: getProjectEmbeddingSnapshot2(deps.projectIdentity)?.chunkModelId ?? "off"
50775
+ });
50776
+ markActive();
50777
+ const identity = embeddingIdentity(deps.projectIdentity);
50778
+ if (autoEmbedIdentityBySession.get(sessionId) !== identity) {
50779
+ invalidateAutoEmbedSession(sessionId);
50780
+ autoEmbedIdentityBySession.set(sessionId, identity);
50781
+ }
50782
+ if (autoEmbedAttemptedBySession.has(sessionId) || embedPauseBySession.has(sessionId) || embedRunStateBySession.has(sessionId) || Date.now() < (autoEmbedRetryAfterBySession.get(sessionId) ?? 0))
50783
+ return;
50784
+ const controller = new AbortController;
50785
+ embedRunStateBySession.set(sessionId, controller);
50786
+ (async () => {
50787
+ let complete = false;
50788
+ let retryDelay = 1000;
50789
+ let started = false;
50790
+ let reason = "error";
50791
+ let registeredIdentity = identity;
50792
+ try {
50793
+ await new Promise((resolve) => setTimeout(resolve, 0));
50794
+ if (controller.signal.aborted)
50795
+ return;
50796
+ await deps.ensureRegistered();
50797
+ if (controller.signal.aborted)
50798
+ return;
50799
+ markActive();
50800
+ registeredIdentity = embeddingIdentity(deps.projectIdentity);
50801
+ autoEmbedIdentityBySession.set(sessionId, registeredIdentity);
50802
+ const coverage = await getAutoEmbeddingSessionCoverage2(deps.db, deps.projectIdentity, sessionId);
50803
+ if (controller.signal.aborted || !coverage.enabled)
50804
+ return;
50805
+ if (coverage.embedded === coverage.total) {
50806
+ complete = true;
50807
+ return;
50808
+ }
50809
+ const model = getProjectEmbeddingSnapshot2(deps.projectIdentity)?.model;
50810
+ log2(`[magic-context] session backfill start session=${sessionId} missing=${coverage.total - coverage.embedded} model=${model}`);
50811
+ started = true;
50812
+ const outcome = await embedSessionCompartmentChunks2(deps.db, deps.projectIdentity, sessionId, { signal: controller.signal, automatic: true });
50813
+ reason = outcome.status;
50814
+ const after = await getAutoEmbeddingSessionCoverage2(deps.db, deps.projectIdentity, sessionId);
50815
+ complete = after.enabled && after.embedded === after.total;
50816
+ if (!complete && outcome.status !== "busy" && outcome.status !== "aborted") {
50817
+ retryDelay = 60000;
50818
+ if (outcome.status === "nothing" || outcome.status === "done")
50819
+ reason = "deferred";
50820
+ }
50821
+ } catch (error) {
50822
+ log2("[magic-context] auto-embed drain failed:", error);
50823
+ retryDelay = 60000;
50824
+ } finally {
50825
+ if (started)
50826
+ log2(`[magic-context] session backfill ${complete ? "complete" : "stop"} session=${sessionId} reason=${reason}`);
50827
+ if (embedRunStateBySession.get(sessionId) === controller) {
50828
+ embedRunStateBySession.delete(sessionId);
50829
+ }
50830
+ if (!controller.signal.aborted && autoEmbedIdentityBySession.get(sessionId) === registeredIdentity && embeddingIdentity(deps.projectIdentity) === registeredIdentity) {
50831
+ if (complete)
50832
+ autoEmbedAttemptedBySession.add(sessionId);
50833
+ else
50834
+ autoEmbedRetryAfterBySession.set(sessionId, Date.now() + retryDelay);
50835
+ }
50836
+ }
50837
+ })();
50838
+ }
50839
+
50441
50840
  // src/v2/hooks/transform-features.ts
50442
50841
  function createV2TransformFeatureDeps(config, compactionOff, directory) {
50443
50842
  return {
@@ -50452,7 +50851,8 @@ function createV2TransformFeatureDeps(config, compactionOff, directory) {
50452
50851
  },
50453
50852
  ensureProjectRegistered: ensureProjectRegisteredFromOpenCodeDirectory,
50454
50853
  historyBudgetPercentage: config.history_budget_percentage,
50455
- experimentalUserMemories: userMemoryCollectionEnabled2(config.dreamer),
50854
+ experimentalUserMemories: userObservationCollectionEnabled2(config.dreamer),
50855
+ userObservationsRequested: userObservationsRequested2(config.dreamer),
50456
50856
  experimentalTemporalAwareness: config.temporal_awareness === true,
50457
50857
  muralEnabled: config.mural?.enabled === true,
50458
50858
  autoSearch: {
@@ -50472,47 +50872,18 @@ function createV2TransformFeatureDeps(config, compactionOff, directory) {
50472
50872
  }
50473
50873
  function createV2AutoEmbedSession(deps) {
50474
50874
  return (sessionId) => {
50475
- if (isEmbeddingHostBusy2())
50476
- return;
50477
50875
  const directory = deps.resolveDirectory(sessionId);
50478
- const identity = resolveProjectIdentityForSession(directory, deps.allowHomeProject);
50479
- const snapshot = identity ? getProjectEmbeddingSnapshot2(identity) : undefined;
50480
- const embedIdentity = snapshot ? JSON.stringify([
50481
- snapshot.providerIdentity,
50482
- snapshot.chunkModelId,
50483
- snapshot.runtimeFingerprint
50484
- ]) : "off";
50485
- if (autoEmbedIdentityBySession.get(sessionId) !== embedIdentity)
50486
- invalidateAutoEmbedSession(sessionId);
50487
- if (autoEmbedAttemptedBySession.has(sessionId) || embedPauseBySession.has(sessionId))
50876
+ const projectIdentity = resolveProjectIdentityForSession(directory, deps.allowHomeProject);
50877
+ if (!projectIdentity)
50488
50878
  return;
50489
- autoEmbedAttemptedBySession.add(sessionId);
50490
- autoEmbedIdentityBySession.set(sessionId, embedIdentity);
50491
- (async () => {
50492
- try {
50493
- await new Promise((resolve) => setTimeout(resolve, 0));
50494
- if (isEmbeddingHostBusy2()) {
50495
- invalidateAutoEmbedSession(sessionId);
50496
- return;
50497
- }
50879
+ maybeAutoEmbedSessionBackfill({
50880
+ db: deps.db,
50881
+ projectIdentity,
50882
+ ensureRegistered: async () => {
50498
50883
  await ensureProjectRegisteredFromOpenCodeDirectory(directory, deps.db);
50499
- const project = resolveProjectIdentityForSession(directory, deps.allowHomeProject);
50500
- if (!project) {
50501
- invalidateAutoEmbedSession(sessionId);
50502
- return;
50503
- }
50504
- const coverage = await getAutoEmbeddingSessionCoverage2(deps.db, project, sessionId);
50505
- if (!coverage.enabled) {
50506
- invalidateAutoEmbedSession(sessionId);
50507
- return;
50508
- }
50509
- if (coverage.total <= coverage.embedded)
50510
- return;
50511
- await runEmbedHistoryDrain(deps, sessionId, { silent: true });
50512
- } catch (error) {
50513
- log2("[magic-context] auto-embed drain failed:", error);
50884
+ deps.onDirectoryResolved?.(sessionId, directory);
50514
50885
  }
50515
- })();
50886
+ }, sessionId);
50516
50887
  };
50517
50888
  }
50518
50889
 
@@ -50830,6 +51201,7 @@ async function registerContext(context) {
50830
51201
  directory,
50831
51202
  warn: (message) => log2(`[magic-context] config warning: ${message}`)
50832
51203
  });
51204
+ logConfigDependencyNotesOnce(config, log2);
50833
51205
  const storage = createV2StorageGate({
50834
51206
  onUnavailable: (reason) => {
50835
51207
  const message = formatFailClosedBlockingMessage(reason);
@@ -51019,7 +51391,8 @@ async function registerContext(context) {
51019
51391
  twoPass: fresh.historian?.two_pass === true,
51020
51392
  expandTools: fresh.historian?.expand_tools,
51021
51393
  autoPromote: fresh.memory?.auto_promote ?? true,
51022
- userMemoriesEnabled: userMemoryCollectionEnabled2(fresh.dreamer),
51394
+ userMemoriesEnabled: userObservationCollectionEnabled2(fresh.dreamer),
51395
+ userObservationsRequested: userObservationsRequested2(fresh.dreamer),
51023
51396
  commitClusterTrigger: fresh.commit_cluster_trigger,
51024
51397
  chunkTokens: deriveHistorianChunkTokens2(resolveHistorianContextLimit2(models.primary?.model))
51025
51398
  };
@@ -51436,7 +51809,7 @@ async function registerContext(context) {
51436
51809
  if (!modelLimitCacheWarm())
51437
51810
  withoutSqliteTransformPass2(() => warmModelLimitCacheFromCatalog(context));
51438
51811
  agents.set(draft.sessionID, draft.agent);
51439
- applyV2PromptSurfaceTools(draft, promptSurfaceRuntime, config.prompt_surface, config.smart_notes.enabled);
51812
+ applyV2PromptSurfaceTools(draft, promptSurfaceRuntime, config.prompt_surface, isSmartNoteSurfaceAvailable(config));
51440
51813
  const admissionDb = db ?? storage.current();
51441
51814
  const replayFits = (messages) => {
51442
51815
  const system = structuredClone(draft.system);