@cortexkit/opencode-magic-context 0.45.0 → 0.46.1

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 (396) hide show
  1. package/README.md +26 -0
  2. package/dist/{announcement-f75t58v9.js → announcement-y35wzg2r.js} +1 -1
  3. package/dist/config/index.d.ts.map +1 -1
  4. package/dist/config/live-run-config.d.ts.map +1 -1
  5. package/dist/config/migrate-config-location.d.ts.map +1 -1
  6. package/dist/config/schema/magic-context.d.ts +13 -7
  7. package/dist/config/schema/magic-context.d.ts.map +1 -1
  8. package/dist/{conflict-warning-hook-5yrz2r24.js → conflict-warning-hook-7fj2b9jw.js} +6 -5
  9. package/dist/context-sh2m2vde.js +4525 -0
  10. package/dist/{derive-budgets-a63zsm5c.js → derive-budgets-7nj7r1rv.js} +2 -2
  11. package/dist/embedding-worker.js +4 -4
  12. package/dist/features/magic-context/checkout-claim-fake-subc.test-support.d.ts +45 -0
  13. package/dist/features/magic-context/checkout-claim-fake-subc.test-support.d.ts.map +1 -0
  14. package/dist/features/magic-context/checkout-claim.d.ts +155 -0
  15. package/dist/features/magic-context/checkout-claim.d.ts.map +1 -0
  16. package/dist/features/magic-context/compaction-marker.d.ts +20 -3
  17. package/dist/features/magic-context/compaction-marker.d.ts.map +1 -1
  18. package/dist/features/magic-context/compartment-storage.d.ts +23 -2
  19. package/dist/features/magic-context/compartment-storage.d.ts.map +1 -1
  20. package/dist/features/magic-context/dreamer/classify.d.ts.map +1 -1
  21. package/dist/features/magic-context/dreamer/evaluate-smart-notes.d.ts.map +1 -1
  22. package/dist/features/magic-context/dreamer/provider-output-failure.d.ts +6 -2
  23. package/dist/features/magic-context/dreamer/provider-output-failure.d.ts.map +1 -1
  24. package/dist/features/magic-context/dreamer/provider-output-failure.test-support.d.ts +30 -0
  25. package/dist/features/magic-context/dreamer/provider-output-failure.test-support.d.ts.map +1 -0
  26. package/dist/features/magic-context/dreamer/storage-dream-runs.d.ts.map +1 -1
  27. package/dist/features/magic-context/dreamer/task-executor.d.ts +9 -0
  28. package/dist/features/magic-context/dreamer/task-executor.d.ts.map +1 -1
  29. package/dist/features/magic-context/dreamer/task-gates.d.ts.map +1 -1
  30. package/dist/features/magic-context/dreamer/task-scheduler.d.ts.map +1 -1
  31. package/dist/features/magic-context/dreamer/verify-diff.d.ts.map +1 -1
  32. package/dist/features/magic-context/dreamer/verify-gate.d.ts.map +1 -1
  33. package/dist/features/magic-context/dreamer/verify.d.ts.map +1 -1
  34. package/dist/features/magic-context/git-commits/search-git-commits.d.ts.map +1 -1
  35. package/dist/features/magic-context/memory/embedding-local.d.ts.map +1 -1
  36. package/dist/features/magic-context/memory/project-identity-cache.d.ts.map +1 -1
  37. package/dist/features/magic-context/memory/storage-memory-verifications.d.ts.map +1 -1
  38. package/dist/features/magic-context/memory/storage-memory.d.ts +3 -0
  39. package/dist/features/magic-context/memory/storage-memory.d.ts.map +1 -1
  40. package/dist/features/magic-context/memory/verification-paths.d.ts +2 -2
  41. package/dist/features/magic-context/memory/verification-paths.d.ts.map +1 -1
  42. package/dist/features/magic-context/merged-reasoning-decisions.d.ts.map +1 -1
  43. package/dist/features/magic-context/message-index-async.d.ts +3 -3
  44. package/dist/features/magic-context/message-index-async.d.ts.map +1 -1
  45. package/dist/features/magic-context/message-index.d.ts +2 -0
  46. package/dist/features/magic-context/message-index.d.ts.map +1 -1
  47. package/dist/features/magic-context/migration-v95-perf-indexes.d.ts +12 -0
  48. package/dist/features/magic-context/migration-v95-perf-indexes.d.ts.map +1 -0
  49. package/dist/features/magic-context/migration-worker-client.d.ts +4 -4
  50. package/dist/features/magic-context/migration-worker-client.d.ts.map +1 -1
  51. package/dist/features/magic-context/migrations.d.ts +1 -0
  52. package/dist/features/magic-context/migrations.d.ts.map +1 -1
  53. package/dist/features/magic-context/mural/render-trigger.d.ts.map +1 -1
  54. package/dist/features/magic-context/mural/resolve-mural.d.ts +15 -4
  55. package/dist/features/magic-context/mural/resolve-mural.d.ts.map +1 -1
  56. package/dist/features/magic-context/mural/source-revision.d.ts +7 -0
  57. package/dist/features/magic-context/mural/source-revision.d.ts.map +1 -0
  58. package/dist/features/magic-context/mural/storage-mural-cues.d.ts.map +1 -1
  59. package/dist/features/magic-context/reclaim-protection.d.ts +15 -10
  60. package/dist/features/magic-context/reclaim-protection.d.ts.map +1 -1
  61. package/dist/features/magic-context/session-cache-ttl.d.ts +4 -2
  62. package/dist/features/magic-context/session-cache-ttl.d.ts.map +1 -1
  63. package/dist/features/magic-context/smart-notes/capabilities.d.ts +3 -0
  64. package/dist/features/magic-context/smart-notes/capabilities.d.ts.map +1 -1
  65. package/dist/features/magic-context/smart-notes/compiler.d.ts.map +1 -1
  66. package/dist/features/magic-context/smart-notes/github-token.d.ts +5 -0
  67. package/dist/features/magic-context/smart-notes/github-token.d.ts.map +1 -0
  68. package/dist/features/magic-context/smart-notes/runner.d.ts +1 -0
  69. package/dist/features/magic-context/smart-notes/runner.d.ts.map +1 -1
  70. package/dist/features/magic-context/smart-notes/sandbox-runner.d.ts +12 -0
  71. package/dist/features/magic-context/smart-notes/sandbox-runner.d.ts.map +1 -1
  72. package/dist/features/magic-context/smart-notes/ssrf-guard.d.ts +6 -0
  73. package/dist/features/magic-context/smart-notes/ssrf-guard.d.ts.map +1 -1
  74. package/dist/features/magic-context/smart-notes/storage.d.ts.map +1 -1
  75. package/dist/features/magic-context/smart-notes/types.d.ts +2 -0
  76. package/dist/features/magic-context/smart-notes/types.d.ts.map +1 -1
  77. package/dist/features/magic-context/storage-clone.d.ts.map +1 -1
  78. package/dist/features/magic-context/storage-db.d.ts +6 -9
  79. package/dist/features/magic-context/storage-db.d.ts.map +1 -1
  80. package/dist/features/magic-context/storage-meta-shared.d.ts +1 -1
  81. package/dist/features/magic-context/storage-meta-shared.d.ts.map +1 -1
  82. package/dist/features/magic-context/storage-ops.d.ts +8 -1
  83. package/dist/features/magic-context/storage-ops.d.ts.map +1 -1
  84. package/dist/features/magic-context/storage-replay-document.d.ts +7 -0
  85. package/dist/features/magic-context/storage-replay-document.d.ts.map +1 -1
  86. package/dist/features/magic-context/storage-schema-helpers.d.ts +2 -0
  87. package/dist/features/magic-context/storage-schema-helpers.d.ts.map +1 -1
  88. package/dist/features/magic-context/storage-session-tables.d.ts.map +1 -1
  89. package/dist/features/magic-context/storage-source.d.ts.map +1 -1
  90. package/dist/features/magic-context/storage-tags.d.ts +11 -3
  91. package/dist/features/magic-context/storage-tags.d.ts.map +1 -1
  92. package/dist/features/magic-context/storage.d.ts +2 -2
  93. package/dist/features/magic-context/storage.d.ts.map +1 -1
  94. package/dist/features/magic-context/temporal-decisions.d.ts +10 -0
  95. package/dist/features/magic-context/temporal-decisions.d.ts.map +1 -0
  96. package/dist/features/magic-context/tool-definition-tokens.d.ts +2 -0
  97. package/dist/features/magic-context/tool-definition-tokens.d.ts.map +1 -1
  98. package/dist/features/magic-context/transform-decision-log.d.ts.map +1 -1
  99. package/dist/features/magic-context/types.d.ts +7 -6
  100. package/dist/features/magic-context/types.d.ts.map +1 -1
  101. package/dist/features/magic-context/window-report-ledger.d.ts.map +1 -1
  102. package/dist/hooks/auto-update-checker/index.d.ts.map +1 -1
  103. package/dist/hooks/magic-context/apply-operations.d.ts +8 -0
  104. package/dist/hooks/magic-context/apply-operations.d.ts.map +1 -1
  105. package/dist/hooks/magic-context/cache-busting-signals.d.ts +6 -3
  106. package/dist/hooks/magic-context/cache-busting-signals.d.ts.map +1 -1
  107. package/dist/hooks/magic-context/channel2-cycle.d.ts +2 -0
  108. package/dist/hooks/magic-context/channel2-cycle.d.ts.map +1 -1
  109. package/dist/hooks/magic-context/compaction-marker-manager.d.ts +7 -0
  110. package/dist/hooks/magic-context/compaction-marker-manager.d.ts.map +1 -1
  111. package/dist/hooks/magic-context/compartment-prompt.d.ts +2 -2
  112. package/dist/hooks/magic-context/compartment-prompt.d.ts.map +1 -1
  113. package/dist/hooks/magic-context/compartment-render-epoch.d.ts +8 -0
  114. package/dist/hooks/magic-context/compartment-render-epoch.d.ts.map +1 -1
  115. package/dist/hooks/magic-context/compartment-runner-drop-queue.d.ts +18 -4
  116. package/dist/hooks/magic-context/compartment-runner-drop-queue.d.ts.map +1 -1
  117. package/dist/hooks/magic-context/compartment-runner-incremental.d.ts.map +1 -1
  118. package/dist/hooks/magic-context/compartment-runner-partial-recomp.d.ts.map +1 -1
  119. package/dist/hooks/magic-context/compartment-runner-recomp.d.ts.map +1 -1
  120. package/dist/hooks/magic-context/ctx-reduce-availability.d.ts +12 -0
  121. package/dist/hooks/magic-context/ctx-reduce-availability.d.ts.map +1 -1
  122. package/dist/hooks/magic-context/decision-calibration.d.ts +3 -0
  123. package/dist/hooks/magic-context/decision-calibration.d.ts.map +1 -1
  124. package/dist/hooks/magic-context/default-protection-pressure.test-support.d.ts +37 -0
  125. package/dist/hooks/magic-context/default-protection-pressure.test-support.d.ts.map +1 -0
  126. package/dist/hooks/magic-context/drop-stale-reduce-calls.d.ts +4 -0
  127. package/dist/hooks/magic-context/drop-stale-reduce-calls.d.ts.map +1 -1
  128. package/dist/hooks/magic-context/edit-marker.d.ts.map +1 -1
  129. package/dist/hooks/magic-context/emergency-drop.d.ts +2 -0
  130. package/dist/hooks/magic-context/emergency-drop.d.ts.map +1 -1
  131. package/dist/hooks/magic-context/emergency-fail-closed.d.ts +21 -1
  132. package/dist/hooks/magic-context/emergency-fail-closed.d.ts.map +1 -1
  133. package/dist/hooks/magic-context/event-handler.d.ts +5 -0
  134. package/dist/hooks/magic-context/event-handler.d.ts.map +1 -1
  135. package/dist/hooks/magic-context/final-wire-token-estimate.d.ts +30 -1
  136. package/dist/hooks/magic-context/final-wire-token-estimate.d.ts.map +1 -1
  137. package/dist/hooks/magic-context/heuristic-cleanup.d.ts +2 -0
  138. package/dist/hooks/magic-context/heuristic-cleanup.d.ts.map +1 -1
  139. package/dist/hooks/magic-context/historian-prompt-fit.d.ts +4 -2
  140. package/dist/hooks/magic-context/historian-prompt-fit.d.ts.map +1 -1
  141. package/dist/hooks/magic-context/hook.d.ts +2 -1
  142. package/dist/hooks/magic-context/hook.d.ts.map +1 -1
  143. package/dist/hooks/magic-context/inject-compartments.d.ts +9 -10
  144. package/dist/hooks/magic-context/inject-compartments.d.ts.map +1 -1
  145. package/dist/hooks/magic-context/lkg-measured-request.d.ts +69 -0
  146. package/dist/hooks/magic-context/lkg-measured-request.d.ts.map +1 -0
  147. package/dist/hooks/magic-context/lkg-persist.d.ts +2 -0
  148. package/dist/hooks/magic-context/lkg-persist.d.ts.map +1 -1
  149. package/dist/hooks/magic-context/lkg-replay-fit.d.ts +14 -0
  150. package/dist/hooks/magic-context/lkg-replay-fit.d.ts.map +1 -1
  151. package/dist/hooks/magic-context/lkg-replay.d.ts +10 -1
  152. package/dist/hooks/magic-context/lkg-replay.d.ts.map +1 -1
  153. package/dist/hooks/magic-context/lkg-slot.d.ts +4 -0
  154. package/dist/hooks/magic-context/lkg-slot.d.ts.map +1 -1
  155. package/dist/hooks/magic-context/module-state-sync.d.ts +2 -0
  156. package/dist/hooks/magic-context/module-state-sync.d.ts.map +1 -1
  157. package/dist/hooks/magic-context/module-transport.d.ts.map +1 -1
  158. package/dist/hooks/magic-context/module-wire.d.ts.map +1 -1
  159. package/dist/hooks/magic-context/note-nudger.d.ts +17 -5
  160. package/dist/hooks/magic-context/note-nudger.d.ts.map +1 -1
  161. package/dist/hooks/magic-context/read-session-chunk.d.ts +1 -1
  162. package/dist/hooks/magic-context/read-session-chunk.d.ts.map +1 -1
  163. package/dist/hooks/magic-context/read-session-db.d.ts +1 -0
  164. package/dist/hooks/magic-context/read-session-db.d.ts.map +1 -1
  165. package/dist/hooks/magic-context/read-session-formatting.d.ts +7 -0
  166. package/dist/hooks/magic-context/read-session-formatting.d.ts.map +1 -1
  167. package/dist/hooks/magic-context/read-session-raw.d.ts +4 -0
  168. package/dist/hooks/magic-context/read-session-raw.d.ts.map +1 -1
  169. package/dist/hooks/magic-context/read-session-true-raw-tokens.d.ts.map +1 -1
  170. package/dist/hooks/magic-context/recomp-orchestrator.d.ts +2 -0
  171. package/dist/hooks/magic-context/recomp-orchestrator.d.ts.map +1 -1
  172. package/dist/hooks/magic-context/reference-retrieval.d.ts +27 -17
  173. package/dist/hooks/magic-context/reference-retrieval.d.ts.map +1 -1
  174. package/dist/hooks/magic-context/request-hook-order.d.ts +56 -0
  175. package/dist/hooks/magic-context/request-hook-order.d.ts.map +1 -0
  176. package/dist/hooks/magic-context/rust-mode-transform.d.ts +22 -3
  177. package/dist/hooks/magic-context/rust-mode-transform.d.ts.map +1 -1
  178. package/dist/hooks/magic-context/strip-content.d.ts +4 -2
  179. package/dist/hooks/magic-context/strip-content.d.ts.map +1 -1
  180. package/dist/hooks/magic-context/supersession-reclaim.d.ts +4 -0
  181. package/dist/hooks/magic-context/supersession-reclaim.d.ts.map +1 -1
  182. package/dist/hooks/magic-context/system-prompt-hash.d.ts +7 -0
  183. package/dist/hooks/magic-context/system-prompt-hash.d.ts.map +1 -1
  184. package/dist/hooks/magic-context/tail-hygiene-walk.d.ts +12 -3
  185. package/dist/hooks/magic-context/tail-hygiene-walk.d.ts.map +1 -1
  186. package/dist/hooks/magic-context/temporal-awareness.d.ts +6 -3
  187. package/dist/hooks/magic-context/temporal-awareness.d.ts.map +1 -1
  188. package/dist/hooks/magic-context/temporal-served-projection.d.ts +4 -0
  189. package/dist/hooks/magic-context/temporal-served-projection.d.ts.map +1 -0
  190. package/dist/hooks/magic-context/tool-drop-target.d.ts.map +1 -1
  191. package/dist/hooks/magic-context/tool-reclaim.d.ts +2 -0
  192. package/dist/hooks/magic-context/tool-reclaim.d.ts.map +1 -1
  193. package/dist/hooks/magic-context/transform-message-helpers.d.ts +5 -0
  194. package/dist/hooks/magic-context/transform-message-helpers.d.ts.map +1 -1
  195. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts +41 -17
  196. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
  197. package/dist/hooks/magic-context/transform.d.ts +12 -0
  198. package/dist/hooks/magic-context/transform.d.ts.map +1 -1
  199. package/dist/hooks/magic-context/wrapup-orchestrator.d.ts.map +1 -1
  200. package/dist/{index-vvtfyw1z.js → index-0d3g3461.js} +5 -13
  201. package/dist/index-1bc61ans.js +154 -0
  202. package/dist/{index-n96ag4rk.js → index-1zx87sdm.js} +5 -1
  203. package/dist/{index-4krbw8z9.js → index-3h0ybwah.js} +608 -102
  204. package/dist/{index-gd5qx1j9.js → index-5eqk6z3s.js} +62 -1
  205. package/dist/index-5gq3b2ya.js +494 -0
  206. package/dist/{index-8fgkmxmy.js → index-5p8jdswx.js} +4 -3
  207. package/dist/{index-75zjgwga.js → index-7qw742ev.js} +1 -1
  208. package/dist/{index-f85teqck.js → index-8da2zjhz.js} +3 -256
  209. package/dist/{index-q7yesyk9.js → index-8x2v7gg9.js} +25 -24
  210. package/dist/{index-w9jwmntv.js → index-b35pxds2.js} +9 -1
  211. package/dist/{v2/server-a4m2b1yv.js → index-fg34g6a5.js} +55 -1
  212. package/dist/index-hpecdzec.js +28506 -0
  213. package/dist/{index-2ntg5sd4.js → index-k5bdx1bx.js} +9 -5
  214. package/dist/{index-bmzf7zxv.js → index-majxda46.js} +23 -5
  215. package/dist/{index-2aq21j41.js → index-pkbcrdqs.js} +418 -127
  216. package/dist/{index-remp7e2g.js → index-q4yp4b52.js} +16 -1
  217. package/dist/{index-fr2z4qy8.js → index-r5hmbx3t.js} +132 -169
  218. package/dist/index-sfnj6h8h.js +259 -0
  219. package/dist/{index-xgt9k6c6.js → index-sgthv3f7.js} +2 -1
  220. package/dist/index-sj29b3z2.js +30 -0
  221. package/dist/{index-16ny736w.js → index-sjthx78w.js} +20526 -19817
  222. package/dist/index.d.ts.map +1 -1
  223. package/dist/index.js +1983 -33118
  224. package/dist/{message-time-backfill-an311pmk.js → message-time-backfill-68gj6t3e.js} +2 -2
  225. package/dist/migration-worker.js +12 -7
  226. package/dist/plugin/dream-timer.d.ts +25 -1
  227. package/dist/plugin/dream-timer.d.ts.map +1 -1
  228. package/dist/plugin/hooks/create-session-hooks.d.ts +2 -1
  229. package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
  230. package/dist/plugin/messages-transform.d.ts +13 -0
  231. package/dist/plugin/messages-transform.d.ts.map +1 -1
  232. package/dist/plugin/rpc-handlers.d.ts +4 -0
  233. package/dist/plugin/rpc-handlers.d.ts.map +1 -1
  234. package/dist/plugin/subagent-tool-policy.d.ts +14 -0
  235. package/dist/plugin/subagent-tool-policy.d.ts.map +1 -0
  236. package/dist/plugin/tool-registry.d.ts +1 -0
  237. package/dist/plugin/tool-registry.d.ts.map +1 -1
  238. package/dist/{read-session-chunk-8rxs0tc9.js → read-session-chunk-egz7r68d.js} +8 -8
  239. package/dist/{recomp-orchestrator-nzamtw29.js → recomp-orchestrator-y15j0rb9.js} +15 -15
  240. package/dist/{send-session-notification-nqpv7cne.js → send-session-notification-dyw42dtr.js} +4 -4
  241. package/dist/shared/announcement.d.ts.map +1 -1
  242. package/dist/shared/cache-ttl-display.d.ts +6 -4
  243. package/dist/shared/cache-ttl-display.d.ts.map +1 -1
  244. package/dist/shared/model-cache-ttl.d.ts +1 -1
  245. package/dist/shared/model-cache-ttl.d.ts.map +1 -1
  246. package/dist/shared/model-suggestion-retry.d.ts +2 -0
  247. package/dist/shared/model-suggestion-retry.d.ts.map +1 -1
  248. package/dist/shared/models-dev-cache.d.ts.map +1 -1
  249. package/dist/shared/protected-tools-policy.d.ts +6 -0
  250. package/dist/shared/protected-tools-policy.d.ts.map +1 -0
  251. package/dist/shared/quota-diagnostic.d.ts +4 -0
  252. package/dist/shared/quota-diagnostic.d.ts.map +1 -0
  253. package/dist/shared/rpc-server.d.ts.map +1 -1
  254. package/dist/shared/sqlite-context-pragmas.d.ts +12 -0
  255. package/dist/shared/sqlite-context-pragmas.d.ts.map +1 -0
  256. package/dist/shared/sqlite-helpers.d.ts +9 -0
  257. package/dist/shared/sqlite-helpers.d.ts.map +1 -1
  258. package/dist/shared/sqlite.d.ts +10 -0
  259. package/dist/shared/sqlite.d.ts.map +1 -1
  260. package/dist/shared/status-summary.d.ts +1 -0
  261. package/dist/shared/status-summary.d.ts.map +1 -1
  262. package/dist/shared/status-view-check.d.ts.map +1 -1
  263. package/dist/shared/status-view.d.ts +4 -0
  264. package/dist/shared/status-view.d.ts.map +1 -1
  265. package/dist/shared/storage-permissions.d.ts +24 -0
  266. package/dist/shared/storage-permissions.d.ts.map +1 -1
  267. package/dist/shared/temporal-upgrade-fixture.d.ts +19 -0
  268. package/dist/shared/temporal-upgrade-fixture.d.ts.map +1 -0
  269. package/dist/shared/user-facing-codes.d.ts +5 -0
  270. package/dist/shared/user-facing-codes.d.ts.map +1 -1
  271. package/dist/shared/write-transaction-timing.d.ts +8 -1
  272. package/dist/shared/write-transaction-timing.d.ts.map +1 -1
  273. package/dist/tools/ctx-expand/render.d.ts.map +1 -1
  274. package/dist/tools/ctx-memory/tools.d.ts.map +1 -1
  275. package/dist/tools/ctx-reduce/constants.d.ts +2 -0
  276. package/dist/tools/ctx-reduce/constants.d.ts.map +1 -1
  277. package/dist/tools/ctx-reduce/tools.d.ts +4 -4
  278. package/dist/tools/ctx-reduce/tools.d.ts.map +1 -1
  279. package/dist/{transform-postprocess-phase-414phndq.js → transform-postprocess-phase-bqhz6vdr.js} +15 -15
  280. package/dist/v2/context-zecmzk5s.js +52209 -0
  281. package/dist/v2/{derive-budgets-v0krf3t7.js → derive-budgets-kdgp4s3r.js} +4 -3
  282. package/dist/v2/embedding-worker.js +6 -5
  283. package/dist/v2/fold/boundary.d.ts +2 -0
  284. package/dist/v2/fold/boundary.d.ts.map +1 -1
  285. package/dist/v2/fold/owner.d.ts.map +1 -1
  286. package/dist/v2/hidden-child-native.d.ts +7 -0
  287. package/dist/v2/hidden-child-native.d.ts.map +1 -1
  288. package/dist/v2/hidden-child-record.d.ts +8 -0
  289. package/dist/v2/hidden-child-record.d.ts.map +1 -1
  290. package/dist/v2/hidden-completion.d.ts.map +1 -1
  291. package/dist/v2/hooks/channel2.d.ts +2 -0
  292. package/dist/v2/hooks/channel2.d.ts.map +1 -1
  293. package/dist/v2/hooks/context.d.ts +2 -2
  294. package/dist/v2/hooks/context.d.ts.map +1 -1
  295. package/dist/v2/hooks/dream-timer.d.ts +39 -0
  296. package/dist/v2/hooks/dream-timer.d.ts.map +1 -0
  297. package/dist/v2/hooks/dream-trigger.d.ts +15 -1
  298. package/dist/v2/hooks/dream-trigger.d.ts.map +1 -1
  299. package/dist/v2/hooks/hidden-child.d.ts +54 -3
  300. package/dist/v2/hooks/hidden-child.d.ts.map +1 -1
  301. package/dist/v2/hooks/payload.d.ts.map +1 -1
  302. package/dist/v2/hooks/store.d.ts.map +1 -1
  303. package/dist/v2/hooks/tools.d.ts +1 -1
  304. package/dist/v2/hooks/tools.d.ts.map +1 -1
  305. package/dist/v2/hooks/types.d.ts +12 -1
  306. package/dist/v2/hooks/types.d.ts.map +1 -1
  307. package/dist/v2/hooks/update-check.d.ts.map +1 -1
  308. package/dist/v2/{message-time-backfill-0n93vrd7.js → message-time-backfill-r6qkem1x.js} +3 -3
  309. package/dist/v2/migration-worker.js +13 -8
  310. package/dist/v2/{read-session-chunk-hjza38hr.js → read-session-chunk-8vjp6581.js} +9 -9
  311. package/dist/v2/recomp-orchestrator-8ejxvrzz.js +39 -0
  312. package/dist/v2/{safe-notification-target-wtj0bbc2.js → safe-notification-target-eb1n1vfb.js} +2 -2
  313. package/dist/v2/{send-session-notification-mq9frrtm.js → send-session-notification-qs0j78v6.js} +6 -6
  314. package/dist/v2/server-14vq4kpm.js +30 -0
  315. package/dist/v2/server-1bc61ans.js +154 -0
  316. package/dist/v2/{server-n96ag4rk.js → server-1zx87sdm.js} +5 -1
  317. package/dist/v2/server-3n4q9xme.js +79 -0
  318. package/dist/v2/{server-rhdgxp1t.js → server-51dv1pr5.js} +63 -2
  319. package/dist/v2/{server-5317ykaf.js → server-6r257mf5.js} +1 -1
  320. package/dist/v2/server-84w6rvvf.js +14 -0
  321. package/dist/v2/{server-qpg6wf72.js → server-ajzeteqw.js} +9 -1
  322. package/dist/v2/server-c5gz8wph.js +3892 -0
  323. package/dist/v2/{server-v5xgft5v.js → server-e29d7p7c.js} +188 -3533
  324. package/dist/{index-a4m2b1yv.js → v2/server-fg34g6a5.js} +55 -1
  325. package/dist/v2/{server-e36nf2p1.js → server-frbm99q5.js} +1595 -1599
  326. package/dist/v2/{server-remp7e2g.js → server-g0fjrkta.js} +16 -1
  327. package/dist/v2/{server-c4g2y1z8.js → server-jc7y02q0.js} +2816 -5392
  328. package/dist/v2/{server-z19x7eqz.js → server-mcfawjgc.js} +4 -4
  329. package/dist/v2/{server-hfjfbg59.js → server-qp5hx1ad.js} +608 -105
  330. package/dist/v2/server-vs5gpnd4.js +493 -0
  331. package/dist/v2/{server-w99cyt6a.js → server-wvjvfhck.js} +14 -6
  332. package/dist/v2/server-xa4xe3rv.js +3351 -0
  333. package/dist/v2/{server-0jqw05sa.js → server-y8maxeft.js} +6 -84
  334. package/dist/v2/server.d.ts.map +1 -1
  335. package/dist/v2/server.js +104 -49288
  336. package/dist/v2/store-reader.d.ts +39 -1
  337. package/dist/v2/store-reader.d.ts.map +1 -1
  338. package/dist/v2/tool-result.d.ts +8 -0
  339. package/dist/v2/tool-result.d.ts.map +1 -0
  340. package/dist/v2/tui/index.d.ts.map +1 -1
  341. package/dist/v2/{wrapup-orchestrator-tbyx78dz.js → wrapup-orchestrator-0snhvwcv.js} +20 -16
  342. package/dist/wrapup-orchestrator-39amhv9s.js +26 -0
  343. package/package.json +26 -10
  344. package/src/config/index.ts +21 -4
  345. package/src/config/latch-permanence-guard.test.ts +6 -1
  346. package/src/config/live-run-config.ts +1 -0
  347. package/src/config/migrate-config-location.test.ts +31 -1
  348. package/src/config/migrate-config-location.ts +8 -41
  349. package/src/config/protected-tools.test.ts +70 -0
  350. package/src/config/raw-loader.test.ts +15 -0
  351. package/src/config/raw-loader.ts +1 -1
  352. package/src/config/removed-agent-source-fence.test.ts +10 -1
  353. package/src/config/schema/magic-context.test.ts +20 -1
  354. package/src/config/schema/magic-context.ts +26 -7
  355. package/src/shared/announcement.ts +6 -5
  356. package/src/shared/cache-ttl-display.test.ts +1 -1
  357. package/src/shared/cache-ttl-display.ts +17 -16
  358. package/src/shared/fold-render-lock-fence.test.ts +84 -0
  359. package/src/shared/fold-render-lock-fixtures.test.ts +276 -0
  360. package/src/shared/model-cache-ttl.test.ts +2 -2
  361. package/src/shared/model-cache-ttl.ts +8 -4
  362. package/src/shared/model-suggestion-retry.test.ts +104 -1
  363. package/src/shared/model-suggestion-retry.ts +63 -6
  364. package/src/shared/models-dev-cache.ts +3 -11
  365. package/src/shared/protected-tools-policy.ts +23 -0
  366. package/src/shared/quota-diagnostic.ts +9 -0
  367. package/src/shared/rpc-server.ts +6 -54
  368. package/src/shared/sqlite-context-pragmas.test.ts +105 -0
  369. package/src/shared/sqlite-context-pragmas.ts +24 -0
  370. package/src/shared/sqlite-helpers.ts +17 -0
  371. package/src/shared/sqlite.ts +75 -0
  372. package/src/shared/status-detail-text.test.ts +18 -1
  373. package/src/shared/status-summary.ts +11 -0
  374. package/src/shared/status-view-check.ts +5 -0
  375. package/src/shared/status-view.test.ts +11 -2
  376. package/src/shared/status-view.ts +12 -1
  377. package/src/shared/storage-permissions.test.ts +204 -0
  378. package/src/shared/storage-permissions.ts +192 -0
  379. package/src/shared/temporal-upgrade-fixture.ts +50 -0
  380. package/src/shared/user-facing-codes.ts +6 -0
  381. package/src/shared/write-transaction-timing.test.ts +39 -0
  382. package/src/shared/write-transaction-timing.ts +25 -1
  383. package/src/tui/dialogs/status-dialog-render.test.ts +1 -1
  384. package/src/tui/index.tsx +3 -1
  385. package/src/tui/startup-order.test.ts +16 -0
  386. package/src/tui-compiled/index.tsx +3 -1
  387. package/src/v2/tui/index.ts +9 -2
  388. package/dist/index-anq4nn6f.js +0 -131
  389. package/dist/index-e44zzy84.js +0 -10
  390. package/dist/index-x23gah8c.js +0 -16
  391. package/dist/v2/recomp-orchestrator-1aq7h44c.js +0 -36
  392. package/dist/v2/server-e44zzy84.js +0 -10
  393. package/dist/v2/server-fgmxwrgy.js +0 -16
  394. package/dist/v2/server-r7cmye3k.js +0 -131
  395. package/dist/wrapup-orchestrator-h28bqsy6.js +0 -26
  396. package/dist/v2/{server-ckpc8pxy.js → server-1qbnzc80.js} +8 -8
@@ -5,9 +5,12 @@ import {
5
5
  log,
6
6
  sessionLog
7
7
  } from "./index-hybnrwq0.js";
8
+ import {
9
+ isKnownAutocommit
10
+ } from "./index-b35pxds2.js";
8
11
  import {
9
12
  isTransientSqliteError
10
- } from "./index-a4m2b1yv.js";
13
+ } from "./index-fg34g6a5.js";
11
14
  import {
12
15
  BoundedSessionMap,
13
16
  renderUserFacingFailure,
@@ -63,9 +66,6 @@ import {
63
66
  updateSessionMeta,
64
67
  advanceToolReclaimWatermark,
65
68
  getNotes,
66
- getPendingOps,
67
- getPendingOpsCount,
68
- removePendingOp,
69
69
  getActivePrimers,
70
70
  saveSourceContent,
71
71
  replaceSourceContent,
@@ -101,36 +101,23 @@ import {
101
101
  compareOpenCodeMessagesByCanonicalOrder,
102
102
  MARKER_SUMMARY_TEXT,
103
103
  applyDeferredCompactionMarker,
104
+ injectTemporalMarkers,
104
105
  clearInjectionCache,
105
106
  getVisibleMemoryIds,
106
107
  renderCompartmentInjection,
108
+ MaterializeContentionError,
107
109
  mustMaterialize,
108
110
  hydrateCachedM0Mural,
109
111
  prepareCachedM0M1Replay,
110
112
  hasCompleteCachedM0M1,
111
113
  injectM0M1,
114
+ observeNoteNudgeServe,
112
115
  peekNoteNudgeText,
113
116
  markNoteNudgeDelivered,
114
117
  getActiveCompartmentRun
115
- } from "./index-16ny736w.js";
118
+ } from "./index-sjthx78w.js";
116
119
  import {
117
- textMentionsRecentCommit,
118
- hasMeaningfulUserText2,
119
- estimateTokens
120
- } from "./index-gd5qx1j9.js";
121
- import {
122
- isValidLanguageCode
123
- } from "./index-q7yesyk9.js";
124
- import {
125
- resolveWorkspaceShareCategories,
126
- resolveWorkspaceIdentitySet,
127
- expandWorkspaceIdentitySetWithAliases,
128
- resolveStoredPathWorkspaceIdentity,
129
- sourceNameForMemory
130
- } from "./index-fr2z4qy8.js";
131
- import {
132
- CTX_REDUCE_KEEP,
133
- newestCtxReduceTagNumbers,
120
+ protectedToolTagNumbers,
134
121
  stripWellFormedLeadingTagPrefix,
135
122
  byteSize,
136
123
  stripTagPrefix,
@@ -147,11 +134,14 @@ import {
147
134
  formatTailHygienePrefixMismatch,
148
135
  refreshTailHygieneBaseline,
149
136
  effectiveTailHygiene,
150
- assertTailHygieneContentUnchanged,
137
+ assertTailHygieneContentUnchangedIfEnabled,
151
138
  CHANNEL1_FLOOR_TOKENS,
152
139
  estimateEmergencyDropReclaimTokens,
153
140
  planEmergencyDrop,
154
141
  measureEmergencyTag,
142
+ getPendingOps,
143
+ getPendingOpsCount,
144
+ removePendingOp,
155
145
  getRecentTagOwnerMessageIds,
156
146
  AGE_RECLAIM_MIN_TOKENS,
157
147
  getOldestActiveUnprotectedToolTags,
@@ -169,9 +159,10 @@ import {
169
159
  getMaxTagNumberBySession,
170
160
  getTagNumberByMessageId,
171
161
  getAssignableTagNumberByMessageId,
172
- getTagsBySession,
173
162
  getActiveTagsBySession,
174
163
  getTailHygieneTags,
164
+ getTagsByNumbers,
165
+ getNewestToolTagNumbers,
175
166
  getDroppedTagsByNumbers,
176
167
  getTagById,
177
168
  getToolTagNumberByOwner,
@@ -199,21 +190,42 @@ import {
199
190
  extractToolCallObservation,
200
191
  ToolMutationBatch,
201
192
  createToolDropTarget
202
- } from "./index-4krbw8z9.js";
193
+ } from "./index-3h0ybwah.js";
194
+ import {
195
+ textMentionsRecentCommit,
196
+ hasMeaningfulUserText2,
197
+ estimateTokens
198
+ } from "./index-5eqk6z3s.js";
199
+ import {
200
+ isValidLanguageCode
201
+ } from "./index-8x2v7gg9.js";
202
+ import {
203
+ resolveWorkspaceShareCategories,
204
+ resolveWorkspaceIdentitySet,
205
+ expandWorkspaceIdentitySetWithAliases,
206
+ resolveStoredPathWorkspaceIdentity,
207
+ sourceNameForMemory
208
+ } from "./index-r5hmbx3t.js";
209
+ import {
210
+ getTemporalDecisions,
211
+ freezeTemporalDecisions,
212
+ stableStringify
213
+ } from "./index-5gq3b2ya.js";
214
+ import {
215
+ normalizeProtectedToolName,
216
+ mergeProtectedTools
217
+ } from "./index-q4yp4b52.js";
203
218
  import {
204
219
  openCodeDbExists,
205
220
  withReadOnlySessionDb,
206
221
  getMessageTimesFromOpenCodeDb
207
- } from "./index-bmzf7zxv.js";
208
- import {
209
- stableStringify
210
- } from "./index-anq4nn6f.js";
222
+ } from "./index-majxda46.js";
211
223
  import {
212
224
  getErrorMessage
213
225
  } from "./index-y8v6yerm.js";
214
226
  import {
215
227
  logSlowWriteTransaction
216
- } from "./index-x23gah8c.js";
228
+ } from "./index-sj29b3z2.js";
217
229
 
218
230
  // src/features/magic-context/storage-reasoning-removal.ts
219
231
  var NAMESPACE = "reasoningRemoval";
@@ -333,12 +345,14 @@ function foldChangesServedPrefix(before, after) {
333
345
  function foldBustsServedPrefix(reason, before, after) {
334
346
  return CACHE_LOSING_FOLD_REASONS.has(reason ?? "") || foldChangesServedPrefix(before, after);
335
347
  }
336
- function convertLegacyToolSkeletons(db, sessionId, targets, options = {}) {
337
- const rows = db.prepare(`SELECT tag_number AS tagNumber, drop_mode AS dropMode, message_id AS callId
348
+ function prepareLegacyToolSkeletonConversions(db, sessionId, targets, options = {}) {
349
+ const readRows = (connection) => connection.prepare(`SELECT tag_number AS tagNumber, drop_mode AS dropMode, message_id AS callId
338
350
  FROM tags
339
351
  WHERE session_id = ? AND type = 'tool' AND status = 'dropped'
340
352
  AND drop_mode IN ('truncated', 'full')
341
353
  ORDER BY tag_number`).all(sessionId);
354
+ const rows = readRows(db);
355
+ const identity = JSON.stringify(rows);
342
356
  const converted = new Map;
343
357
  for (const row of rows) {
344
358
  const target = targets.get(row.tagNumber);
@@ -355,10 +369,16 @@ function convertLegacyToolSkeletons(db, sessionId, targets, options = {}) {
355
369
  } else {
356
370
  mode = hasSmallToolInput(target) || cannotRemove ? "skeleton_real" : "full";
357
371
  }
358
- updateTagDropMode(db, sessionId, row.tagNumber, mode);
359
372
  converted.set(row.tagNumber, mode);
360
373
  }
361
- return converted;
374
+ return {
375
+ converted,
376
+ isCurrent: (connection) => JSON.stringify(readRows(connection)) === identity,
377
+ persist: (connection) => {
378
+ for (const [tagNumber, mode] of converted)
379
+ updateTagDropMode(connection, sessionId, tagNumber, mode);
380
+ }
381
+ };
362
382
  }
363
383
  function renderConvertedToolSkeletons(targets, converted) {
364
384
  let didMutate = false;
@@ -384,11 +404,16 @@ function applyPendingOperations(sessionId, db, targets, protectedTagIds, preload
384
404
  db.transaction(() => {
385
405
  admitted = true;
386
406
  startedAt = performance.now();
387
- const tags = preloadedTags ?? getTagsBySession(db, sessionId);
407
+ const pendingOps = preloadedPendingOps ?? getPendingOps(db, sessionId);
408
+ const tags = preloadedTags ?? getTagsByNumbers(db, sessionId, [
409
+ ...new Set([
410
+ ...pendingOps.map((op) => op.tagId),
411
+ ...syntheticPendingOps.map((op) => op.tagId)
412
+ ])
413
+ ]);
388
414
  const tagById = new Map(tags.map((tag) => [tag.tagNumber, tag]));
389
415
  const tagStatusById = new Map(tags.map((tag) => [tag.tagNumber, tag.status]));
390
416
  const tagTypeById = new Map(tags.map((tag) => [tag.tagNumber, tag.type]));
391
- const pendingOps = preloadedPendingOps ?? getPendingOps(db, sessionId);
392
417
  const opsToApply = [
393
418
  ...pendingOps.map((op) => ({ op, synthetic: false })),
394
419
  ...syntheticPendingOps.map((op) => ({ op, synthetic: true }))
@@ -400,7 +425,7 @@ function applyPendingOperations(sessionId, db, targets, protectedTagIds, preload
400
425
  persistedWithoutMutation: 0,
401
426
  reasons: {}
402
427
  };
403
- const skeletonWindow = new Set(tags.filter((tag) => tag.type === "tool").map((tag) => tag.tagNumber).sort((left, right) => right - left).slice(0, RECENT_TOOL_SKELETON_WINDOW));
428
+ const skeletonWindow = new Set(preloadedTags ? tags.filter((tag) => tag.type === "tool").map((tag) => tag.tagNumber).sort((left, right) => right - left).slice(0, RECENT_TOOL_SKELETON_WINDOW) : getNewestToolTagNumbers(db, sessionId, RECENT_TOOL_SKELETON_WINDOW));
404
429
  for (const { op: pendingOp, synthetic } of opsToApply) {
405
430
  let operationMutated = false;
406
431
  const tagStatus = tagStatusById.get(pendingOp.tagId);
@@ -786,6 +811,47 @@ var ftsPlainStatements = new WeakMap;
786
811
  var datedFtsPlainStatements = new WeakMap;
787
812
  var getBySHAsStatements = new WeakMap;
788
813
  var datedGetBySHAsStatements = new WeakMap;
814
+ var embeddingCache = new WeakMap;
815
+ function getSearchEmbeddings(db, projectPath, modelId) {
816
+ if (!isKnownAutocommit(db)) {
817
+ embeddingCache.delete(db);
818
+ return loadProjectCommitEmbeddings(db, projectPath, modelId);
819
+ }
820
+ let cache = embeddingCache.get(db);
821
+ if (!cache) {
822
+ cache = {
823
+ revisionStatement: db.prepare(`SELECT total_changes() AS writes,
824
+ (SELECT data_version FROM pragma_data_version) AS dataVersion,
825
+ (SELECT schema_version FROM pragma_schema_version) AS schemaVersion`),
826
+ revision: "",
827
+ entries: new Map
828
+ };
829
+ embeddingCache.set(db, cache);
830
+ }
831
+ const revision = JSON.stringify(cache.revisionStatement.get());
832
+ if (revision !== cache.revision) {
833
+ cache.entries.clear();
834
+ cache.revision = revision;
835
+ }
836
+ const key = JSON.stringify([projectPath, modelId]);
837
+ const cached = cache.entries.get(key);
838
+ if (cached) {
839
+ cache.entries.delete(key);
840
+ cache.entries.set(key, cached);
841
+ return cached;
842
+ }
843
+ const vectors = loadProjectCommitEmbeddings(db, projectPath, modelId);
844
+ const size = (entries) => [...entries.values()].reduce((sum, vector) => sum + vector.byteLength, 0);
845
+ if (size(vectors) <= 32 * 1024 * 1024)
846
+ cache.entries.set(key, vectors);
847
+ while (cache.entries.size > 16 || [...cache.entries.values()].reduce((sum, entry) => sum + size(entry), 0) > 32 * 1024 * 1024) {
848
+ const oldest = cache.entries.keys().next().value;
849
+ if (oldest === undefined)
850
+ break;
851
+ cache.entries.delete(oldest);
852
+ }
853
+ return vectors;
854
+ }
789
855
  function rowToCommit(row) {
790
856
  return {
791
857
  sha: row.sha,
@@ -882,7 +948,7 @@ function searchGitCommitsSync(db, projectPath, query, options) {
882
948
  });
883
949
  const semanticScores = new Map;
884
950
  if (options.queryEmbedding && options.queryModelId && options.queryModelId !== "off") {
885
- const embeddings = loadProjectCommitEmbeddings(db, projectPath, options.queryModelId);
951
+ const embeddings = getSearchEmbeddings(db, projectPath, options.queryModelId);
886
952
  for (const [sha, embedding] of embeddings.entries()) {
887
953
  const similarity = clamp01(cosineSimilarity(options.queryEmbedding, embedding));
888
954
  if (similarity > 0) {
@@ -3122,9 +3188,20 @@ function findLastUserMessageId(messages) {
3122
3188
  }
3123
3189
  return null;
3124
3190
  }
3191
+ function findNoteNudgeUserMessageId(messages) {
3192
+ for (let index = messages.length - 1;index >= 0; index -= 1) {
3193
+ const message = messages[index];
3194
+ if (message.info.role !== "user" || typeof message.info.id !== "string")
3195
+ continue;
3196
+ if (message.parts.some((part) => isTextPart(part) && part.ignored !== true && part.text.trim())) {
3197
+ return message.info.id;
3198
+ }
3199
+ }
3200
+ return null;
3201
+ }
3125
3202
  function appendReminderToUserMessageById(messages, messageId, reminder) {
3126
3203
  for (const message of messages) {
3127
- if (message.info.id !== messageId || !isMeaningfulUserMessage(message)) {
3204
+ if (message.info.id !== messageId || message.info.role !== "user") {
3128
3205
  continue;
3129
3206
  }
3130
3207
  appendReminderToUserMessage(message, reminder);
@@ -3374,9 +3451,15 @@ function canConsumeDeferredOnThisPass(args) {
3374
3451
  return args.schedulerDecision === "execute" || args.contextPercentage >= (args.forceMaterializationPercentage ?? escalationBands(65).forceMaterializationPercentage);
3375
3452
  }
3376
3453
  function hasReclaimRide(signals) {
3377
- return signals.hardFold || signals.force || signals.explicitFlush || signals.publishedHistory;
3378
- }
3379
- var RECLAIM_RIDE_NAMES = ["hardFold", "force", "explicitFlush", "publishedHistory"];
3454
+ return signals.hardFold || signals.force || signals.explicitFlush || signals.publishedHistory || signals.subagentExecute === true;
3455
+ }
3456
+ var RECLAIM_RIDE_NAMES = [
3457
+ "hardFold",
3458
+ "force",
3459
+ "explicitFlush",
3460
+ "publishedHistory",
3461
+ "subagentExecute"
3462
+ ];
3380
3463
  function reclaimRideLabel(signals) {
3381
3464
  const active = RECLAIM_RIDE_NAMES.filter((name) => signals[name]);
3382
3465
  return `ride=${active.length > 0 ? active.join("+") : "none"}`;
@@ -3390,6 +3473,8 @@ function rearmChannel2AfterCoverageAdvancingHardFold(input) {
3390
3473
  return casChannel2NudgeState(input.db, input.sessionId, "delivered", "");
3391
3474
  }
3392
3475
  function rearmChannel2AfterMeasuredCollapse(input) {
3476
+ if (!input.rebuilding && (!input.previous || effectiveTailHygiene(input.baseline).u >= effectiveTailHygiene(input.previous).u))
3477
+ return false;
3393
3478
  if (!input.baseline.evaluable || input.baseline.generationInvalidated)
3394
3479
  return false;
3395
3480
  if (effectiveTailHygiene(input.baseline).u >= CHANNEL1_FLOOR_TOKENS)
@@ -3656,6 +3741,29 @@ function hasLoggedCtxReducePermissionDeny(sessionId) {
3656
3741
  function markCtxReducePermissionDenyLogged(sessionId) {
3657
3742
  ctxReducePermissionDenyLogged.set(sessionId, true);
3658
3743
  }
3744
+ var ctxReducePermissionObservations = new Map;
3745
+ function observeCtxReducePermissionDeny(client, sessionId, activeAgent) {
3746
+ if (hasLoggedCtxReducePermissionDeny(sessionId))
3747
+ return;
3748
+ const inFlight = ctxReducePermissionObservations.get(sessionId);
3749
+ if (inFlight)
3750
+ return inFlight;
3751
+ const read = (async () => {
3752
+ try {
3753
+ const denied = await resolveToolPermissionDenied(client, sessionId, CTX_REDUCE_TOOL, activeAgent);
3754
+ if (denied && !hasLoggedCtxReducePermissionDeny(sessionId)) {
3755
+ markCtxReducePermissionDenyLogged(sessionId);
3756
+ sessionLog(sessionId, "ctx_reduce permission is denied by OpenCode; frozen guidance remains until session restart");
3757
+ }
3758
+ } catch (error) {
3759
+ sessionLog(sessionId, "ctx_reduce permission read failed (ignored):", error);
3760
+ } finally {
3761
+ ctxReducePermissionObservations.delete(sessionId);
3762
+ }
3763
+ })();
3764
+ ctxReducePermissionObservations.set(sessionId, read);
3765
+ return read;
3766
+ }
3659
3767
  function resolveTodowriteAvailabilityFromMessages(sessionId, messages) {
3660
3768
  return resolveToolAvailabilityFromMessages(sessionId, TODOWRITE_TOOL, messages);
3661
3769
  }
@@ -3725,18 +3833,20 @@ function messageHasReducePart(message) {
3725
3833
  }
3726
3834
  return false;
3727
3835
  }
3728
- function sentinelizeReduceParts(message) {
3836
+ function sentinelizeReduceParts(message, onFirstApplication) {
3729
3837
  let touched = false;
3730
3838
  for (let j = 0;j < message.parts.length; j++) {
3731
3839
  const part = message.parts[j];
3732
3840
  if (isSentinel(part))
3733
3841
  continue;
3734
3842
  if (isReduceToolPart(part)) {
3843
+ onFirstApplication?.(message, j);
3735
3844
  message.parts[j] = makeSentinel(part);
3736
3845
  touched = true;
3737
3846
  }
3738
3847
  }
3739
3848
  if (touched && !hasAnyMeaningfulPart(message.parts)) {
3849
+ onFirstApplication?.(message, 0);
3740
3850
  message.parts.length = 0;
3741
3851
  message.parts.push(makeSentinel(undefined));
3742
3852
  }
@@ -3752,10 +3862,15 @@ function dropStaleReduceCalls(messages, frozenIds, options = {}) {
3752
3862
  const message = messages[i];
3753
3863
  const id = typeof message.info.id === "string" ? message.info.id : undefined;
3754
3864
  const inFrozen = id !== undefined && frozenIds.has(id);
3755
- const isNewDetection = !inFrozen && detect && i < protectedStart && id !== undefined && messageHasReducePart(message) && !message.parts.some(toolPartHasUserAnswer);
3865
+ const isNewDetection = !inFrozen && detect && i < protectedStart && id !== undefined && messageHasReducePart(message) && !message.parts.some((part) => {
3866
+ if (!isRecord(part))
3867
+ return false;
3868
+ const callId = part.callID ?? part.toolCallId ?? part.id;
3869
+ return typeof callId === "string" && options.protectedCallIds?.has(callId);
3870
+ }) && !message.parts.some(toolPartHasUserAnswer);
3756
3871
  if (!inFrozen && !isNewDetection)
3757
3872
  continue;
3758
- const touched = sentinelizeReduceParts(message);
3873
+ const touched = sentinelizeReduceParts(message, isNewDetection ? options.onFirstApplication : undefined);
3759
3874
  if (touched) {
3760
3875
  didDrop = true;
3761
3876
  if (isNewDetection && id !== undefined)
@@ -3834,11 +3949,35 @@ function estimateDroppedTokensFromTagReductions(db, sessionId, reductions) {
3834
3949
 
3835
3950
  // src/hooks/magic-context/emergency-fail-closed.ts
3836
3951
  var ENGINE_RECONNECTING_USER_MESSAGE = "Magic Context's engine is reconnecting. Send your message again in a few seconds.";
3952
+ var PROTECTED_TOOL_RESULTS_OVER_LIMIT = "The tool results kept by protected_tools are larger than this model's context window, so this turn was not sent. Lower the protected_tools counts.";
3953
+ var PROTECTED_TOOL_RESULTS_OVER_LIMIT_CODE = "protected_tool_results_over_limit";
3954
+ function contextRefusalError(message) {
3955
+ return new EmergencyFailClosedError(message, {
3956
+ code: message === PROTECTED_TOOL_RESULTS_OVER_LIMIT ? PROTECTED_TOOL_RESULTS_OVER_LIMIT_CODE : undefined
3957
+ });
3958
+ }
3959
+ function protectedToolRefusal(error) {
3960
+ const seen = new Set;
3961
+ while (error && typeof error === "object" && !seen.has(error)) {
3962
+ seen.add(error);
3963
+ const current = error;
3964
+ if (current.code === PROTECTED_TOOL_RESULTS_OVER_LIMIT_CODE)
3965
+ return contextRefusalError(PROTECTED_TOOL_RESULTS_OVER_LIMIT);
3966
+ error = current.cause;
3967
+ }
3968
+ return;
3969
+ }
3970
+ function outgoingContextRefusal(estimate, limit, protectedToolTokens = 0) {
3971
+ if (estimate?.refusalGrade !== true || typeof estimate.refusalTokens !== "number" || !Number.isFinite(estimate.refusalTokens) || !limit || !Number.isFinite(limit) || limit <= 0 || estimate.refusalTokens <= limit || !Number.isFinite(protectedToolTokens) || protectedToolTokens <= limit)
3972
+ return;
3973
+ return PROTECTED_TOOL_RESULTS_OVER_LIMIT;
3974
+ }
3837
3975
 
3838
3976
  class EmergencyFailClosedError extends Error {
3839
- code = "EMERGENCY_FAIL_CLOSED";
3977
+ code;
3840
3978
  constructor(message, options) {
3841
3979
  super(message, options);
3980
+ this.code = options?.code ?? "EMERGENCY_FAIL_CLOSED";
3842
3981
  this.name = "EmergencyFailClosedError";
3843
3982
  }
3844
3983
  }
@@ -4080,6 +4219,7 @@ var DEDUP_SAFE_TOOLS = new Set([
4080
4219
  ]);
4081
4220
  function applyHeuristicCleanup(sessionId, db, targets, messageTagNumbers, config, preloadedTags) {
4082
4221
  const tags = preloadedTags ?? getActiveTagsBySession(db, sessionId);
4222
+ const protectedTools = config.protectedToolTags ?? protectedToolTagNumbers(tags, config.protectedTools);
4083
4223
  const maxTag = getMaxTagNumberBySession(db, sessionId);
4084
4224
  let droppedTools = 0;
4085
4225
  let emergencyDroppedTools = 0;
@@ -4109,7 +4249,8 @@ function applyHeuristicCleanup(sessionId, db, targets, messageTagNumbers, config
4109
4249
  usagePercentage: emergency.usagePercentage,
4110
4250
  priorInputSample,
4111
4251
  hasPriorDrop: priorInputSample > 0,
4112
- passAlreadyPriced: emergency.passAlreadyPriced === true
4252
+ passAlreadyPriced: emergency.passAlreadyPriced === true,
4253
+ protectedToolTags: protectedTools
4113
4254
  });
4114
4255
  if (plan.shouldDrop) {
4115
4256
  const toDrop = new Set(plan.tagNumbers);
@@ -4227,6 +4368,8 @@ function applyHeuristicCleanup(sessionId, db, targets, messageTagNumbers, config
4227
4368
  if (config.protectedTagNumbers.has(tag.tagNumber))
4228
4369
  continue;
4229
4370
  const target = targets.get(tag.tagNumber);
4371
+ if (protectedTools.has(tag.tagNumber))
4372
+ continue;
4230
4373
  if (target?.canDrop?.() === false)
4231
4374
  continue;
4232
4375
  const { result, mode } = applyNewToolDrop(target, { inWindow: false });
@@ -4451,7 +4594,7 @@ function isSystemInjectedText(text) {
4451
4594
  return false;
4452
4595
  return SYSTEM_INJECTION_PATTERNS.some((pattern) => pattern.test(stripped));
4453
4596
  }
4454
- function stripSystemInjectedMessages(messages, protectedTailStart, providerID) {
4597
+ function stripSystemInjectedMessages(messages, protectedTailStart, providerID, onFirstApplication) {
4455
4598
  let stripped = 0;
4456
4599
  const sentineledIds = [];
4457
4600
  for (let i = 0;i < messages.length; i++) {
@@ -4490,6 +4633,7 @@ function stripSystemInjectedMessages(messages, protectedTailStart, providerID) {
4490
4633
  break;
4491
4634
  }
4492
4635
  if (hasContentPart && allContentIsSystemInjection) {
4636
+ onFirstApplication?.(msg, 0);
4493
4637
  msg.parts.length = 0;
4494
4638
  msg.parts.push(makeWholeMessageSentinel(providerID));
4495
4639
  stripped++;
@@ -4509,7 +4653,7 @@ var METADATA_PART_TYPES = new Set([
4509
4653
  "subtask",
4510
4654
  "compaction"
4511
4655
  ]);
4512
- function stripDroppedPlaceholderMessages(messages, providerID) {
4656
+ function stripDroppedPlaceholderMessages(messages, providerID, onFirstApplication) {
4513
4657
  let stripped = 0;
4514
4658
  const sentineledIds = [];
4515
4659
  for (let i = 0;i < messages.length; i++) {
@@ -4548,6 +4692,7 @@ function stripDroppedPlaceholderMessages(messages, providerID) {
4548
4692
  break;
4549
4693
  }
4550
4694
  if (hasContentPart && !hasNonDroppedContent) {
4695
+ onFirstApplication?.(msg, 0);
4551
4696
  msg.parts.length = 0;
4552
4697
  msg.parts.push(makeWholeMessageSentinel(providerID));
4553
4698
  stripped++;
@@ -5021,6 +5166,8 @@ function stripProcessedImages(messages, frozenIds, options) {
5021
5166
  continue;
5022
5167
  }
5023
5168
  if (typeof part.url === "string" && part.url.startsWith("data:") && part.url.length > 200) {
5169
+ if (isNewDetection)
5170
+ options.onFirstApplication?.(msg, j);
5024
5171
  msg.parts[j] = makeSentinel(part);
5025
5172
  stripped++;
5026
5173
  touchedThisMsg = true;
@@ -5163,7 +5310,6 @@ function settleDroppedReasoningParts(messages, mode) {
5163
5310
  }
5164
5311
 
5165
5312
  // src/hooks/magic-context/supersession-reclaim.ts
5166
- var TODOWRITE_KEEP = 1;
5167
5313
  var SUPERSESSION_RECENT_MESSAGE_WINDOW = 20;
5168
5314
  function recentSupersessionOwnerMessageIds(db, sessionId) {
5169
5315
  return getRecentTagOwnerMessageIds(db, sessionId, SUPERSESSION_RECENT_MESSAGE_WINDOW);
@@ -5175,22 +5321,17 @@ function buildSupersessionReclaimOps(input) {
5175
5321
  const tags = getActiveTagsBySession(input.db, input.sessionId);
5176
5322
  const toolTags = tags.filter((tag) => tag.type === "tool" && tag.status === "active").sort((left, right) => right.tagNumber - left.tagNumber);
5177
5323
  const dropTagIds = [];
5178
- let todowriteSeen = 0;
5179
- let ctxReduceSeen = 0;
5324
+ const protectedTags = input.protectedToolTags ?? protectedToolTagNumbers(toolTags, input.protectedTools);
5180
5325
  for (const tag of toolTags) {
5181
5326
  if (input.protectedTagNumbers?.has(tag.tagNumber)) {
5182
5327
  continue;
5183
5328
  }
5184
- const name = tag.toolName;
5329
+ const name = normalizeProtectedToolName(tag.toolName);
5185
5330
  if (!name)
5186
5331
  continue;
5187
5332
  let isTarget = false;
5188
- if (name === "todowrite") {
5189
- todowriteSeen += 1;
5190
- isTarget = todowriteSeen > TODOWRITE_KEEP;
5191
- } else if (name === "ctx_reduce") {
5192
- ctxReduceSeen += 1;
5193
- isTarget = ctxReduceSeen > CTX_REDUCE_KEEP;
5333
+ if (name === "todowrite" || name === "ctx_reduce") {
5334
+ isTarget = true;
5194
5335
  } else if (ZERO_VALUE_META_TOOLS.has(name)) {
5195
5336
  isTarget = true;
5196
5337
  } else if (name === "ctx_note") {
@@ -5205,6 +5346,8 @@ function buildSupersessionReclaimOps(input) {
5205
5346
  for (const tagId of dropTagIds) {
5206
5347
  if (realPendingTagIds.has(tagId))
5207
5348
  continue;
5349
+ if (protectedTags.has(tagId))
5350
+ continue;
5208
5351
  if (input.targets.get(tagId)?.canDrop?.() !== true)
5209
5352
  continue;
5210
5353
  synthetic.push({
@@ -5224,6 +5367,7 @@ function buildEditSupersessionReclaim(input) {
5224
5367
  const seenFile = new Set;
5225
5368
  const ops = [];
5226
5369
  const editMarkerTagIds = new Set;
5370
+ const protectedTags = input.protectedToolTags ?? protectedToolTagNumbers(tags, input.protectedTools);
5227
5371
  for (const tag of editTags) {
5228
5372
  if (input.protectedTagNumbers?.has(tag.tagNumber)) {
5229
5373
  continue;
@@ -5240,6 +5384,8 @@ function buildEditSupersessionReclaim(input) {
5240
5384
  }
5241
5385
  if (realPendingTagIds.has(tag.tagNumber))
5242
5386
  continue;
5387
+ if (protectedTags.has(tag.tagNumber))
5388
+ continue;
5243
5389
  if (input.targets.get(tag.tagNumber)?.canDrop?.() !== true)
5244
5390
  continue;
5245
5391
  editMarkerTagIds.add(tag.tagNumber);
@@ -5273,7 +5419,7 @@ function buildSyntheticToolReclaimOps(input) {
5273
5419
  return [];
5274
5420
  const realPendingTagIds = new Set((input.pendingOps ?? []).map((op) => op.tagId));
5275
5421
  const tags = getActiveToolTagsForAgeReclaim(input.db, input.sessionId);
5276
- const newestTodowriteTag = tags.reduce((newest, tag) => tag.toolName === "todowrite" && (newest === null || tag.tagNumber > newest) ? tag.tagNumber : newest, null);
5422
+ const protectedTags = input.protectedToolTags ?? protectedToolTagNumbers(tags, input.protectedTools);
5277
5423
  const synthetic = [];
5278
5424
  for (const tag of tags) {
5279
5425
  if (tag.tagNumber > watermark)
@@ -5281,7 +5427,7 @@ function buildSyntheticToolReclaimOps(input) {
5281
5427
  if (tag.reclaimableTokens !== null && tag.reclaimableTokens < AGE_RECLAIM_MIN_TOKENS) {
5282
5428
  continue;
5283
5429
  }
5284
- if (tag.tagNumber === newestTodowriteTag)
5430
+ if (protectedTags.has(tag.tagNumber))
5285
5431
  continue;
5286
5432
  if (realPendingTagIds.has(tag.tagNumber))
5287
5433
  continue;
@@ -6350,12 +6496,14 @@ async function applyTodoSynthesis2(args) {
6350
6496
  let permissionDenied = cachedToolPermissionDenied(args.sessionId, "todowrite") ?? persistedPermissionDenied ?? false;
6351
6497
  const toolsMapUnavailable = args.todowriteAvailability.frozen && !args.todowriteAvailability.callable;
6352
6498
  if (args.isCacheBustingPass && args.client && !toolsMapUnavailable) {
6499
+ const tTodoPermission = performance.now();
6353
6500
  try {
6354
6501
  permissionDenied = await todowritePermissionDenied(args.client, args.sessionId, args.activeAgent);
6355
6502
  setPersistedTodoPermissionDenied(args.db, args.sessionId, permissionDenied);
6356
6503
  } catch (error) {
6357
6504
  sessionLog(args.sessionId, "todowrite permission read failed; retaining the last successful verdict:", error);
6358
6505
  }
6506
+ logTransformTiming(args.sessionId, "pp.todoPermissionRead", tTodoPermission);
6359
6507
  }
6360
6508
  const todowriteUnavailable = toolsMapUnavailable || permissionDenied;
6361
6509
  if (args.isCacheBustingPass && todowriteUnavailable) {
@@ -6500,7 +6648,7 @@ function replayRustModeBindingMismatchStrips2(args) {
6500
6648
  }
6501
6649
  stripReasoningFromAssistantIds(args.messages, args.resolvedProviderID, recoveryMessageIds);
6502
6650
  }
6503
- var RUST_MARKER_LOCK_SKIP_LOG2 = "rust compaction-marker: pending target write skipped on lock contention; next pass retries";
6651
+ var RUST_MARKER_LOCK_SKIP_LOG2 = "rust compaction-marker: pending target write skipped on lock contention; next cache-busting pass retries";
6504
6652
  function isSqliteLockContentionError(error) {
6505
6653
  if (!error || typeof error !== "object")
6506
6654
  return false;
@@ -6514,6 +6662,8 @@ function isSqliteLockContentionError(error) {
6514
6662
  return false;
6515
6663
  }
6516
6664
  function applyRustModeDeferredCompactionMarker2(args) {
6665
+ if (!args.cacheBustingPass)
6666
+ return;
6517
6667
  const { boundary } = args;
6518
6668
  if (boundary) {
6519
6669
  if (!Number.isSafeInteger(boundary.rowVersion) || boundary.rowVersion <= 0 || !Number.isSafeInteger(boundary.ordinal) || boundary.ordinal < 0 || boundary.endMessageId.length === 0) {
@@ -6551,12 +6701,21 @@ function applyRustModeDeferredCompactionMarker2(args) {
6551
6701
  const pending = getPendingCompactionMarkerState(args.db, args.sessionId);
6552
6702
  if (!pending)
6553
6703
  return;
6704
+ const consumed = args.consumedBoundary ?? boundary;
6705
+ if (!consumed || pending.ordinal > consumed.ordinal || pending.ordinal === consumed.ordinal && pending.endMessageId !== consumed.endMessageId) {
6706
+ sessionLog(args.sessionId, "rust compaction-marker drain: pending target not covered by served response; retaining retry state");
6707
+ return;
6708
+ }
6709
+ if (args.admissionProven === false)
6710
+ return;
6554
6711
  const trustedBoundary = boundary && pending.ordinal === boundary.ordinal && pending.endMessageId === boundary.endMessageId ? {
6555
6712
  rowVersion: boundary.rowVersion,
6556
6713
  ordinal: boundary.ordinal,
6557
6714
  endMessageId: boundary.endMessageId
6558
6715
  } : undefined;
6716
+ args.beforeApply?.();
6559
6717
  const outcome = (args.applyDeferred ?? applyDeferredCompactionMarker)(args.db, args.sessionId, pending, args.sessionDirectory, trustedBoundary);
6718
+ args.afterApply?.(outcome);
6560
6719
  switch (outcome.kind) {
6561
6720
  case "applied":
6562
6721
  case "already-current":
@@ -6651,19 +6810,26 @@ function runRustModePostprocess2(args) {
6651
6810
  getDeferredClearedCompactionMarkerState(args.db, args.sessionId)
6652
6811
  ]);
6653
6812
  const servedMarkerBefore = servedMarkerRecord();
6654
- applyRustModeDeferredCompactionMarker2({
6655
- ...args.compactionMarkerStrategy ? { applyDeferred: args.compactionMarkerStrategy.applyDeferred } : {},
6656
- db: args.db,
6657
- sessionId: args.sessionId,
6658
- boundary: args.materializedBoundary,
6659
- sessionDirectory: args.sessionDirectory
6660
- });
6813
+ if (args.cacheBustingPass) {
6814
+ applyRustModeDeferredCompactionMarker2({
6815
+ cacheBustingPass: true,
6816
+ admissionProven: args.markerAdmissionProven,
6817
+ beforeApply: args.beforeMarkerApply,
6818
+ afterApply: args.afterMarkerApply,
6819
+ ...args.compactionMarkerStrategy ? { applyDeferred: args.compactionMarkerStrategy.applyDeferred } : {},
6820
+ db: args.db,
6821
+ sessionId: args.sessionId,
6822
+ boundary: args.materializedBoundary,
6823
+ consumedBoundary: args.consumedBoundary,
6824
+ sessionDirectory: args.sessionDirectory
6825
+ });
6826
+ }
6661
6827
  (args.compactionMarkerStrategy?.reconcile ?? reconcileMarkerRepresentation2)(args.messages, getPersistedCompactionMarkerState(args.db, args.sessionId), {
6662
6828
  db: args.db,
6663
6829
  sessionId: args.sessionId,
6664
6830
  tagger: args.tagger,
6665
6831
  ctxReduceAvailability: args.ctxReduceAvailability,
6666
- isCacheBustingPass: args.materializedBoundary != null
6832
+ isCacheBustingPass: args.cacheBustingPass === true
6667
6833
  });
6668
6834
  for (const anchor of getNoteNudgeAnchors(args.db, args.sessionId)) {
6669
6835
  appendReminderToUserMessageById(args.messages, anchor.messageId, anchor.text);
@@ -6681,7 +6847,7 @@ function runRustModePostprocess2(args) {
6681
6847
  trailingBlankDecisions.set(id, decision);
6682
6848
  }
6683
6849
  const candidates = findTrailingBlankDecisionCandidates(args.messages, trailingBlankDecisions, { sourceDecisions: args.trailingBlankSourceDecisions }).filter(([id]) => id === args.trailingBlankNewestAssistantId);
6684
- if (candidates.length > 0) {
6850
+ if ((args.prefixPermissionSupported ?? args.cacheBustingPass === true) && candidates.length > 0) {
6685
6851
  const persisted = addTrailingBlankDecisions(args.db, args.sessionId, candidates, {
6686
6852
  overwriteMessageId: args.trailingBlankNewestAssistantId
6687
6853
  });
@@ -6703,14 +6869,22 @@ function runRustModePostprocess2(args) {
6703
6869
  const absorbingStripDecisions = new Map([...trailingBlankDecisions].filter(([, decision]) => decision === "strip"));
6704
6870
  applyFrozenTrailingBlankDecisions(args.messages, absorbingStripDecisions);
6705
6871
  let noteNudgeAppended = false;
6706
- const currentUserMessageId = findLastUserMessageId(args.messages);
6872
+ const currentUserMessageId = findNoteNudgeUserMessageId(args.messages);
6873
+ const eligibility = observeNoteNudgeServe({
6874
+ db: args.db,
6875
+ sessionId: args.sessionId,
6876
+ userMessageIds: args.messages.filter((m) => m.info.role === "user" && typeof m.info.id === "string").map((m) => m.info.id),
6877
+ anchorMessageId: currentUserMessageId,
6878
+ isLiveTail: args.messages.at(-1)?.info.id === currentUserMessageId,
6879
+ isCacheBustingPass: args.cacheBustingPass === true
6880
+ });
6707
6881
  const noteReadStillVisible = hasVisibleNoteReadCall(args.messages);
6708
- const deferredNoteText = peekNoteNudgeText(args.db, args.sessionId, currentUserMessageId, args.projectPath, noteReadStillVisible);
6882
+ const deferredNoteText = peekNoteNudgeText(args.db, args.sessionId, currentUserMessageId, args.projectPath, noteReadStillVisible, eligibility);
6709
6883
  if (deferredNoteText) {
6710
6884
  const instruction = `
6711
6885
 
6712
6886
  <instruction name="deferred_notes">${deferredNoteText}</instruction>`;
6713
- const anchoredMessageId = findLastUserMessageId(args.messages);
6887
+ const anchoredMessageId = currentUserMessageId;
6714
6888
  const outcome = markNoteNudgeDelivered(args.db, args.sessionId, instruction, anchoredMessageId);
6715
6889
  if (anchoredMessageId && outcome.ok) {
6716
6890
  appendReminderToUserMessageById(args.messages, anchoredMessageId, instruction);
@@ -6847,6 +7021,10 @@ async function abortSessionFailClosed2(client, sessionId) {
6847
7021
  function evaluateEmergencyFailClosed2(input) {
6848
7022
  const estimate = input.finalWireEstimate;
6849
7023
  const limit = input.providerProvenLimitTokens;
7024
+ const refusalMessage = outgoingContextRefusal(estimate, input.contextLimitTokens ?? limit, input.protectedToolTokens);
7025
+ if (refusalMessage) {
7026
+ return { shouldAbort: true, reason: "refusal-grade-final-wire-over-limit", refusalMessage };
7027
+ }
6850
7028
  if (input.emergencyRecoveryArmed && estimate?.trusted === true && Number.isFinite(estimate.tokens) && estimate.tokens > 0 && typeof limit === "number" && Number.isFinite(limit) && limit > 0 && estimate.tokens < limit * 0.8) {
6851
7029
  return {
6852
7030
  shouldAbort: false,
@@ -6992,13 +7170,23 @@ async function runPostTransformPhase2(args) {
6992
7170
  hardSignals: args.m0M1.hardSignals,
6993
7171
  muralEnabled: args.m0M1.muralEnabled,
6994
7172
  compactionOff,
6995
- onFoldCommit: (db, rendered) => {
6996
- committedFoldBustsServedPrefix = foldBustsServedPrefix(foldDueDecision.reason, servedPrefixBeforeFold, rendered);
6997
- if (!committedFoldBustsServedPrefix)
6998
- return;
6999
- for (const [tagNumber, mode] of convertLegacyToolSkeletons(db, args.sessionId, args.targets)) {
7000
- convertedToolSkeletons.set(tagNumber, mode);
7001
- }
7173
+ onFoldPrepare: () => {
7174
+ const conversions = prepareLegacyToolSkeletonConversions(args.db, args.sessionId, args.targets);
7175
+ return (db, rendered) => {
7176
+ const bustsPrefix = foldBustsServedPrefix(foldDueDecision.reason, servedPrefixBeforeFold, rendered);
7177
+ if (bustsPrefix) {
7178
+ if (!conversions.isCurrent(db)) {
7179
+ throw new MaterializeContentionError({
7180
+ reason: "fold conversion snapshot changed"
7181
+ });
7182
+ }
7183
+ conversions.persist(db);
7184
+ for (const [tagNumber, mode] of conversions.converted) {
7185
+ convertedToolSkeletons.set(tagNumber, mode);
7186
+ }
7187
+ }
7188
+ committedFoldBustsServedPrefix = bustsPrefix;
7189
+ };
7002
7190
  }
7003
7191
  });
7004
7192
  preparedPrefix = foldResult;
@@ -7033,8 +7221,10 @@ async function runPostTransformPhase2(args) {
7033
7221
  failPass("m0-m1-fold-preexecution-degradation", error);
7034
7222
  sessionLog(args.sessionId, "transform: m[0] HARD fold pre-execution failed:", getErrorMessage(error));
7035
7223
  }
7036
- sessionLog(args.sessionId, `m[0] HARD fold decision: reason=${foldDueDecision.reason ?? "unknown"} executed=${foldExecutedThisPass} bustsServedPrefix=${foldBustsServedPrefixThisPass}`);
7224
+ sessionLog(args.sessionId, `m[0] HARD fold decision: reason=${m0MaterializeReason ?? foldDueDecision.reason ?? (foldExecutedThisPass ? "drift" : "soft_refresh")} executed=${foldExecutedThisPass} bustsServedPrefix=${foldBustsServedPrefixThisPass}`);
7037
7225
  }
7226
+ logTransformTiming(args.sessionId, "pp.prefixPreflight", tPostprocessSetup, `foldExecuted=${foldExecutedThisPass} m1Refreshed=${publishedM1RefreshedThisPass}`);
7227
+ const tPassDecisions = performance.now();
7038
7228
  const shouldReadPendingOps = !compactionOff && (materializationRequested || publishedM1RefreshedThisPass || args.schedulerDecision === "execute" || forceMaterialization || foldExecutedThisPass || firstRenderBust || compartmentRunning);
7039
7229
  const pendingOps = shouldReadPendingOps ? getPendingOps(args.db, args.sessionId) : [];
7040
7230
  const hasPendingUserOps = pendingOps.length > 0;
@@ -7044,6 +7234,7 @@ async function runPostTransformPhase2(args) {
7044
7234
  };
7045
7235
  const idleExpiryRebuild = !freezeM0M1 && args.m0M1?.hardSignals?.cacheExpired === true;
7046
7236
  const rideSignals = {
7237
+ subagentExecute: !args.fullFeatureMode && args.schedulerDecision === "execute",
7047
7238
  hardFold: foldBustsServedPrefixThisPass || firstRenderBust || idleExpiryRebuild,
7048
7239
  force: emergencyDropEligible && (args.contextUsage.percentage >= 95 || getEmergencyInputSample(args.db, args.sessionId) === 0),
7049
7240
  explicitFlush: isExplicitFlush || deferredMaterialize && !prefixPreflightFailed,
@@ -7053,16 +7244,18 @@ async function runPostTransformPhase2(args) {
7053
7244
  const shouldApplyPendingOps = publishedWorkDrainAllowed;
7054
7245
  const shouldRunHeuristics = !compactionOff && hasReclaimRide(rideSignals) && (rideSignals.publishedHistory || materializationRequested || forceMaterialization || foldBustsServedPrefixThisPass || firstRenderBust || emergencyDropEligible || args.schedulerDecision === "execute" && (!alreadyRanThisTurn || !args.fullFeatureMode));
7055
7246
  const isCacheBustingPass = publishedWorkDrainAllowed;
7247
+ const previousTemporalDecisions = args.temporalCandidates && !compactionOff ? new Map([
7248
+ ...args.temporalObservedDecisions ?? [],
7249
+ ...getTemporalDecisions(args.db, args.sessionId, args.temporalReplayIds ?? args.temporalCandidates.keys())
7250
+ ]) : undefined;
7251
+ const temporalDecisions = args.temporalCandidates && !compactionOff ? isCacheBustingPass ? new Map([
7252
+ ...previousTemporalDecisions ?? [],
7253
+ ...freezeTemporalDecisions(args.db, args.sessionId, args.temporalCandidates)
7254
+ ]) : previousTemporalDecisions : undefined;
7255
+ const temporalInjected = temporalDecisions ? injectTemporalMarkers(args.messages, temporalDecisions) : 0;
7256
+ const temporalFirstApplication = temporalInjected > 0 && [...temporalDecisions ?? []].some(([id, marker]) => marker && !previousTemporalDecisions?.has(id));
7056
7257
  if (isCacheBustingPass && args.client && args.ctxReduceAvailability.callable && !hasLoggedCtxReducePermissionDeny(args.sessionId)) {
7057
- try {
7058
- const denied = await resolveToolPermissionDenied(args.client, args.sessionId, "ctx_reduce", args.activeAgent);
7059
- if (denied) {
7060
- markCtxReducePermissionDenyLogged(args.sessionId);
7061
- sessionLog(args.sessionId, "ctx_reduce permission is denied by OpenCode; frozen guidance remains until session restart");
7062
- }
7063
- } catch (error) {
7064
- sessionLog(args.sessionId, "ctx_reduce permission read failed (ignored):", error);
7065
- }
7258
+ observeCtxReducePermissionDeny(args.client, args.sessionId, args.activeAgent);
7066
7259
  }
7067
7260
  const canUseEmptySentinels = modelAcceptsEmptyContent(args.resolvedProviderID);
7068
7261
  const prefixBoundModel = args.thinkingBindingRecoveryEnabledForModel === true;
@@ -7103,6 +7296,19 @@ async function runPostTransformPhase2(args) {
7103
7296
  let explicitMaterializedSuccessfully = false;
7104
7297
  let deferredMaterializedSuccessfully = false;
7105
7298
  let pendingOpsDidMutate = false;
7299
+ const protectedToolTags = protectedToolTagNumbers(args.tags, args.protectedTools);
7300
+ const firstApplicationEdits = { any: false, beforeNewerThinking: false };
7301
+ const recordFirstApplicationWireEdit = (beforeNewerThinking) => {
7302
+ firstApplicationEdits.any = true;
7303
+ firstApplicationEdits.beforeNewerThinking ||= beforeNewerThinking;
7304
+ };
7305
+ if (temporalFirstApplication)
7306
+ recordFirstApplicationWireEdit(true);
7307
+ const firstApplicationLocations = new Map;
7308
+ const recordFirstApplicationAt = (message, partIndex) => {
7309
+ recordFirstApplicationWireEdit(false);
7310
+ firstApplicationLocations.set(message, Math.min(firstApplicationLocations.get(message) ?? Infinity, partIndex));
7311
+ };
7106
7312
  let heuristicOrReasoningDidMutate = false;
7107
7313
  let heuristicOrReasoningEditBesidesTrim = false;
7108
7314
  let droppedCount = 0;
@@ -7133,12 +7339,16 @@ async function runPostTransformPhase2(args) {
7133
7339
  }
7134
7340
  }
7135
7341
  let autoReclaimDidMutateThisPass = false;
7342
+ logTransformTiming(args.sessionId, "pp.passDecisions", tPassDecisions, `pendingOps=${pendingOps.length}`);
7136
7343
  try {
7137
7344
  if (shouldApplyPendingOps) {
7138
7345
  const applyReason = isExplicitFlush ? "explicit_flush" : deferredMaterialize ? "deferred_materialization" : foldBustsServedPrefixThisPass && args.schedulerDecision !== "execute" ? `m0_hard_fold (drain folded into executed m[0] bust, scheduler=${args.schedulerDecision})` : `${reclaimRideLabel(rideSignals)} (scheduler=${args.schedulerDecision})`;
7139
7346
  sessionLog(args.sessionId, `pending ops WILL APPLY — reason=${applyReason}, pendingOps=${formatPendingOpsDepth()}, context=${args.contextUsage.percentage.toFixed(1)}%`);
7140
7347
  const tApply = performance.now();
7141
- pendingOpsDidMutate = applyPendingOperations(args.sessionId, args.db, args.targets, args.contextUsage.percentage >= 95 ? newestCtxReduceTagNumbers(getTagsBySession(args.db, args.sessionId)) : args.protectedTagIds, undefined, pendingOps, [], new Set, (reduction) => droppedTokenReductions.push(reduction));
7348
+ pendingOpsDidMutate = applyPendingOperations(args.sessionId, args.db, args.targets, new Set([
7349
+ ...args.contextUsage.percentage >= 95 ? [] : args.protectedTagIds,
7350
+ ...protectedToolTags
7351
+ ]), undefined, pendingOps, [], new Set, (reduction) => droppedTokenReductions.push(reduction));
7142
7352
  if (pendingOpsDidMutate) {
7143
7353
  droppedCount += pendingOps.length;
7144
7354
  for (const pendingOp of pendingOps) {
@@ -7167,6 +7377,7 @@ async function runPostTransformPhase2(args) {
7167
7377
  let cleanup = applyHeuristicCleanup(args.sessionId, args.db, args.targets, args.messageTagNumbers, {
7168
7378
  protectedTagNumbers: args.protectedTagNumbers,
7169
7379
  protectedCutoff: args.protectedCutoff,
7380
+ protectedToolTags,
7170
7381
  emergency: emergencyDropEligible && args.emergencyCeilingTokens !== undefined && args.emergencyCeilingTokens > 0 ? {
7171
7382
  currentTotalInputTokens: args.contextUsage.inputTokens,
7172
7383
  ceilingTokens: args.emergencyCeilingTokens,
@@ -7180,6 +7391,7 @@ async function runPostTransformPhase2(args) {
7180
7391
  const ridingCleanup = applyHeuristicCleanup(args.sessionId, args.db, args.targets, args.messageTagNumbers, {
7181
7392
  protectedTagNumbers: args.protectedTagNumbers,
7182
7393
  protectedCutoff: args.protectedCutoff,
7394
+ protectedToolTags,
7183
7395
  routine: true,
7184
7396
  caveman: cavemanConfig
7185
7397
  }, getActiveTagsBySession(args.db, args.sessionId));
@@ -7301,15 +7513,17 @@ async function runPostTransformPhase2(args) {
7301
7513
  let autoReclaimTargetCount = 0;
7302
7514
  let autoReclaimDidMutate = false;
7303
7515
  if (toolReclaimApplicationOpportunity && !emergencyDropEligible) {
7516
+ const tReclaimSelect = performance.now();
7304
7517
  const syntheticPendingOps = buildSyntheticToolReclaimOps({
7305
7518
  db: args.db,
7306
7519
  sessionId: args.sessionId,
7307
7520
  targets: args.targets,
7308
7521
  watermark: args.sessionMeta.toolReclaimWatermark ?? 0,
7522
+ protectedToolTags,
7309
7523
  pendingOps
7310
7524
  });
7311
7525
  const editMarkerTagIds = new Set;
7312
- if (args.smartDrops) {
7526
+ {
7313
7527
  const recentMessageIds = recentSupersessionOwnerMessageIds(args.db, args.sessionId);
7314
7528
  const selectedIds = new Set(syntheticPendingOps.map((op) => op.tagId));
7315
7529
  const supersessionOps = buildSupersessionReclaimOps({
@@ -7318,7 +7532,8 @@ async function runPostTransformPhase2(args) {
7318
7532
  targets: args.targets,
7319
7533
  pendingOps,
7320
7534
  recentMessageIds,
7321
- protectedTagNumbers: args.protectedTagNumbers
7535
+ protectedTagNumbers: args.protectedTagNumbers,
7536
+ protectedToolTags
7322
7537
  });
7323
7538
  for (const op of supersessionOps) {
7324
7539
  if (!selectedIds.has(op.tagId)) {
@@ -7332,7 +7547,8 @@ async function runPostTransformPhase2(args) {
7332
7547
  targets: args.targets,
7333
7548
  pendingOps,
7334
7549
  recentMessageIds,
7335
- protectedTagNumbers: args.protectedTagNumbers
7550
+ protectedTagNumbers: args.protectedTagNumbers,
7551
+ protectedToolTags
7336
7552
  });
7337
7553
  for (const op of editReclaim.ops) {
7338
7554
  if (!selectedIds.has(op.tagId)) {
@@ -7343,8 +7559,11 @@ async function runPostTransformPhase2(args) {
7343
7559
  }
7344
7560
  }
7345
7561
  autoReclaimTargetCount = syntheticPendingOps.length;
7562
+ logTransformTiming(args.sessionId, "toolReclaim.select", tReclaimSelect, `targets=${autoReclaimTargetCount}`);
7346
7563
  if (syntheticPendingOps.length > 0) {
7564
+ const tReclaimApply = performance.now();
7347
7565
  autoReclaimDidMutate = applyPendingOperations(args.sessionId, args.db, args.targets, args.protectedTagIds, undefined, [], syntheticPendingOps, editMarkerTagIds, (reduction) => droppedTokenReductions.push(reduction));
7566
+ logTransformTiming(args.sessionId, "toolReclaim.apply", tReclaimApply);
7348
7567
  if (autoReclaimDidMutate) {
7349
7568
  droppedCount += syntheticPendingOps.length;
7350
7569
  autoReclaimDidMutateThisPass = true;
@@ -7358,6 +7577,7 @@ async function runPostTransformPhase2(args) {
7358
7577
  }
7359
7578
  }
7360
7579
  }
7580
+ const tBatchFinalize = performance.now();
7361
7581
  args.batch?.finalize();
7362
7582
  if (toolReclaimApplicationOpportunity) {
7363
7583
  const maxTagNumber = advanceToolReclaimWatermarkToCurrentMax(args.db, args.sessionId);
@@ -7366,7 +7586,7 @@ async function runPostTransformPhase2(args) {
7366
7586
  if (autoReclaimTargetCount > 0) {
7367
7587
  sessionLog(args.sessionId, `tool reclaim auto-drop: targets=${autoReclaimTargetCount} mutated=${autoReclaimDidMutate}`);
7368
7588
  }
7369
- logTransformTiming(args.sessionId, "batchFinalize:heuristics", performance.now());
7589
+ logTransformTiming(args.sessionId, "batchFinalize:heuristics", tBatchFinalize);
7370
7590
  if (args.sessionMeta.lastTransformError !== null) {
7371
7591
  updateSessionMeta(args.db, args.sessionId, { lastTransformError: null });
7372
7592
  }
@@ -7382,7 +7602,9 @@ async function runPostTransformPhase2(args) {
7382
7602
  updateSessionMeta(args.db, args.sessionId, { lastTransformError: getErrorMessage(error) });
7383
7603
  }
7384
7604
  if (isCacheBustingPass) {
7605
+ const tDroppedEstimate = performance.now();
7385
7606
  droppedTokens = estimateDroppedTokensFromTagReductions(args.db, args.sessionId, droppedTokenReductions);
7607
+ logTransformTiming(args.sessionId, "pp.droppedTokenEstimate", tDroppedEstimate);
7386
7608
  }
7387
7609
  logTransformTiming(args.sessionId, "pp.setupAndOperations", tPostprocessSetup);
7388
7610
  const tReplaySnapshot = performance.now();
@@ -7394,7 +7616,9 @@ async function runPostTransformPhase2(args) {
7394
7616
  const frozenStaleReduceIds = replaySnapshot.staleReduceStrippedIds;
7395
7617
  const staleReduceResult = dropStaleReduceCalls(args.messages, frozenStaleReduceIds, {
7396
7618
  detect: isCacheBustingPass,
7397
- protectedCount: args.protectedCount
7619
+ protectedCount: args.protectedCount,
7620
+ protectedCallIds: new Set(args.tags.filter((tag) => protectedToolTags.has(tag.tagNumber)).map((tag) => tag.messageId)),
7621
+ onFirstApplication: recordFirstApplicationAt
7398
7622
  });
7399
7623
  if (isCacheBustingPass && staleReduceResult.newlyStrippedIds.length > 0) {
7400
7624
  addStaleReduceStrippedIds(args.db, args.sessionId, staleReduceResult.newlyStrippedIds);
@@ -7412,7 +7636,8 @@ async function runPostTransformPhase2(args) {
7412
7636
  const imageResult = stripProcessedImages(args.messages, frozenImageIds, {
7413
7637
  detect: isCacheBustingPass && args.watermark > 0,
7414
7638
  watermark: args.watermark,
7415
- messageTagNumbers: args.messageTagNumbers
7639
+ messageTagNumbers: args.messageTagNumbers,
7640
+ onFirstApplication: recordFirstApplicationAt
7416
7641
  });
7417
7642
  if (isCacheBustingPass && imageResult.newlyStrippedIds.length > 0) {
7418
7643
  addProcessedImageStrippedIds(args.db, args.sessionId, imageResult.newlyStrippedIds);
@@ -7430,6 +7655,7 @@ async function runPostTransformPhase2(args) {
7430
7655
  }
7431
7656
  const tInjectM0M1 = performance.now();
7432
7657
  try {
7658
+ const messagesBeforeInjection = args.messages.slice();
7433
7659
  const result = injectM0M1({
7434
7660
  db: args.db,
7435
7661
  sessionId: args.sessionId,
@@ -7452,6 +7678,14 @@ async function runPostTransformPhase2(args) {
7452
7678
  compactionOff
7453
7679
  });
7454
7680
  deliveredPrefix = result;
7681
+ if (result.prefixTrimStatus === "applied") {
7682
+ const retainedMessages = new Set(args.messages);
7683
+ const trimmedMessageIds = messagesBeforeInjection.filter((message) => !retainedMessages.has(message)).map((message) => message.info.id).filter((id) => typeof id === "string");
7684
+ const currentPolicy = mergeProtectedTools(args.protectedTools);
7685
+ const previousPolicy = args.channel1StateBySession?.get(args.sessionId)?.protectedToolsPolicy;
7686
+ const eligibleTagNumbers = new Set(args.tags.filter((tag) => tag.type === "tool" && ((currentPolicy[normalizeProtectedToolName(tag.toolName)] ?? 0) > 0 || (previousPolicy?.[normalizeProtectedToolName(tag.toolName)] ?? 0) > 0)).map((tag) => tag.tagNumber));
7687
+ markTagsCompactedByMessageIds(args.db, args.sessionId, trimmedMessageIds, eligibleTagNumbers);
7688
+ }
7455
7689
  if (result.injected) {
7456
7690
  m0M1InjectedThisPass = true;
7457
7691
  prependedMessageCount += result.prependedMessageCount;
@@ -7500,9 +7734,9 @@ async function runPostTransformPhase2(args) {
7500
7734
  }
7501
7735
  }
7502
7736
  if (isCacheBustingPass) {
7503
- const droppedResult = stripDroppedPlaceholderMessages(args.messages, args.resolvedProviderID);
7737
+ const droppedResult = stripDroppedPlaceholderMessages(args.messages, args.resolvedProviderID, recordFirstApplicationAt);
7504
7738
  const protectedTailStart = Math.max(0, args.messages.length - SYSTEM_INJECTION_ACTIONABLE_TAIL_MESSAGES);
7505
- const systemInjectedResult = stripSystemInjectedMessages(args.messages, protectedTailStart, args.resolvedProviderID);
7739
+ const systemInjectedResult = stripSystemInjectedMessages(args.messages, protectedTailStart, args.resolvedProviderID, recordFirstApplicationAt);
7506
7740
  const hiddenMessages = args.hiddenMessagesAtCompactionSeam ?? [];
7507
7741
  const hiddenDroppedResult = stripDroppedPlaceholderMessages(hiddenMessages, args.resolvedProviderID);
7508
7742
  const hiddenSystemInjectedResult = stripSystemInjectedMessages(hiddenMessages, hiddenMessages.length, args.resolvedProviderID);
@@ -7562,7 +7796,9 @@ async function runPostTransformPhase2(args) {
7562
7796
  suppressV12HistoryDrain = true;
7563
7797
  sessionLog(args.sessionId, `compaction-marker drain: refusing ordinal ${pending.ordinal} because prefix trim through ${args.pendingCompartmentInjection?.compartmentEndMessageId ?? "<none>"} was not proven; preserving deferred history refresh signal`);
7564
7798
  } else {
7799
+ const tMarkerDrain = performance.now();
7565
7800
  const outcome = (args.compactionMarkerStrategy ?? defaultCompactionMarkerStrategy2).applyDeferred(args.db, args.sessionId, pending, args.sessionDirectory);
7801
+ logTransformTiming(args.sessionId, "pp.markerDrain", tMarkerDrain, `outcome=${outcome.kind}`);
7566
7802
  switch (outcome.kind) {
7567
7803
  case "applied":
7568
7804
  case "already-current":
@@ -7588,6 +7824,7 @@ async function runPostTransformPhase2(args) {
7588
7824
  }
7589
7825
  const deferredClearedMarkerRetires = !compactionOff && isCacheBustingPass && persistedCompactionMarkerState === null && getDeferredClearedCompactionMarkerState(args.db, args.sessionId) !== null;
7590
7826
  if (!compactionOff) {
7827
+ const tMarkerWire = performance.now();
7591
7828
  (args.compactionMarkerStrategy ?? defaultCompactionMarkerStrategy2).reconcile(args.messages, persistedCompactionMarkerState, {
7592
7829
  db: args.db,
7593
7830
  sessionId: args.sessionId,
@@ -7595,6 +7832,7 @@ async function runPostTransformPhase2(args) {
7595
7832
  ctxReduceAvailability: args.ctxReduceAvailability,
7596
7833
  isCacheBustingPass
7597
7834
  });
7835
+ logTransformTiming(args.sessionId, "pp.markerWireReconcile", tMarkerWire);
7598
7836
  }
7599
7837
  const deferredHistoryDrainEligible = historyWasConsumedThisPass && args.deferredHistoryWasPendingAtPassStart && !suppressV12HistoryDrain;
7600
7838
  if (deferredHistoryDrainEligible) {
@@ -7607,12 +7845,21 @@ async function runPostTransformPhase2(args) {
7607
7845
  const tNoteAndTodo = performance.now();
7608
7846
  const noteReadStillVisible = args.fullFeatureMode ? hasVisibleNoteReadCall(args.messages) : false;
7609
7847
  let noteNudgeAppendedThisPass = false;
7610
- const deferredNoteText = args.fullFeatureMode ? peekNoteNudgeText(args.db, args.sessionId, args.currentTurnId, args.projectPath, noteReadStillVisible) : null;
7848
+ const noteNudgeUserMessageId = findNoteNudgeUserMessageId(args.messages);
7849
+ const noteNudgeEligibility = args.fullFeatureMode ? observeNoteNudgeServe({
7850
+ db: args.db,
7851
+ sessionId: args.sessionId,
7852
+ userMessageIds: args.messages.filter((m) => m.info.role === "user" && typeof m.info.id === "string").map((m) => m.info.id),
7853
+ anchorMessageId: noteNudgeUserMessageId,
7854
+ isLiveTail: args.messages.at(-1)?.info.id === noteNudgeUserMessageId,
7855
+ isCacheBustingPass
7856
+ }) : undefined;
7857
+ const deferredNoteText = args.fullFeatureMode ? peekNoteNudgeText(args.db, args.sessionId, noteNudgeUserMessageId, args.projectPath, noteReadStillVisible, noteNudgeEligibility) : null;
7611
7858
  if (deferredNoteText) {
7612
7859
  const noteInstruction = `
7613
7860
 
7614
7861
  <instruction name="deferred_notes">${deferredNoteText}</instruction>`;
7615
- const anchoredMessageId = findLastUserMessageId(args.messages);
7862
+ const anchoredMessageId = noteNudgeUserMessageId;
7616
7863
  const outcome = markNoteNudgeDelivered(args.db, args.sessionId, noteInstruction, anchoredMessageId);
7617
7864
  if (anchoredMessageId && outcome.ok) {
7618
7865
  appendReminderToUserMessageById(args.messages, anchoredMessageId, noteInstruction);
@@ -7711,7 +7958,7 @@ async function runPostTransformPhase2(args) {
7711
7958
  }
7712
7959
  const materializeReason = m0MaterializeReason ?? (explicitMaterializedSuccessfully ? "explicit_flush" : null);
7713
7960
  const materialized = m0RematerializedThisPass || explicitMaterializedSuccessfully || deferredMaterializedSuccessfully;
7714
- let bustedThisPass = firstRenderBust || pendingOpsDidMutate || heuristicOrReasoningDidMutate || autoReclaimDidMutateThisPass || convertedToolSkeletonsDidMutate || m0RematerializedThisPass || m0M1InjectedThisPass && historyWasConsumedThisPass || historyWasConsumedThisPass;
7961
+ let bustedThisPass = firstApplicationEdits.any || firstRenderBust || pendingOpsDidMutate || heuristicOrReasoningDidMutate || autoReclaimDidMutateThisPass || convertedToolSkeletonsDidMutate || m0RematerializedThisPass || m0M1InjectedThisPass && historyWasConsumedThisPass || historyWasConsumedThisPass;
7715
7962
  const proactiveThinkingStripPermitted = isCacheBustingPass;
7716
7963
  const tFrozenDecisions = performance.now();
7717
7964
  if (reasoningMutationTargetUnknown) {
@@ -7730,7 +7977,6 @@ async function runPostTransformPhase2(args) {
7730
7977
  }
7731
7978
  }
7732
7979
  const mergedReasoningStrippedIds = new Set(replaySnapshot?.mergedReasoningStrippedIds ?? []);
7733
- let lateEditBeforeNewestThinking = false;
7734
7980
  const thinkingBindingRecoveryMessageIds = new Set;
7735
7981
  let thinkingBindingRecovery = null;
7736
7982
  if (!compactionOff) {
@@ -7756,8 +8002,7 @@ async function runPostTransformPhase2(args) {
7756
8002
  mergedReasoningStrippedIds.add(thinkingBindingRecoveryFrozenId(messageId));
7757
8003
  }
7758
8004
  if (thinkingBindingRecovery.messageIds.length > 0) {
7759
- bustedThisPass = true;
7760
- lateEditBeforeNewestThinking = true;
8005
+ recordFirstApplicationWireEdit(true);
7761
8006
  }
7762
8007
  } else {
7763
8008
  failPass("thinking-binding-recovery-persistence-failure");
@@ -7774,8 +8019,7 @@ async function runPostTransformPhase2(args) {
7774
8019
  for (const id of getMergedReasoningStrippedIds(args.db, args.sessionId)) {
7775
8020
  mergedReasoningStrippedIds.add(id);
7776
8021
  }
7777
- bustedThisPass = true;
7778
- lateEditBeforeNewestThinking = true;
8022
+ recordFirstApplicationWireEdit(true);
7779
8023
  } else {
7780
8024
  failPass("merged-reasoning-strip-persistence-failure");
7781
8025
  sessionLog(args.sessionId, "merged reasoning strip: persistence failed; leaving newly detected assistants intact");
@@ -7789,6 +8033,25 @@ async function runPostTransformPhase2(args) {
7789
8033
  }
7790
8034
  const trailingBlankDecisions = new Map(replaySnapshot?.trailingBlankDecisions ?? []);
7791
8035
  const newestAssistantId = typeof trailingBlankNewestAssistant?.info.id === "string" ? trailingBlankNewestAssistant.info.id : undefined;
8036
+ let trailingDecisionMessages;
8037
+ const recordTrailingBlankWireEdit = (id, next) => {
8038
+ trailingDecisionMessages ??= new Map(args.messages.flatMap((message) => typeof message.info.id === "string" ? [[message.info.id, message]] : []));
8039
+ const message = trailingDecisionMessages.get(id);
8040
+ if (!message)
8041
+ return;
8042
+ const before = [{ ...message, parts: [...message.parts] }];
8043
+ const after = [{ ...message, parts: [...message.parts] }];
8044
+ const previous = trailingBlankDecisions.get(id);
8045
+ if (previous)
8046
+ applyFrozenTrailingBlankDecisions(before, new Map([[id, previous]]));
8047
+ applyFrozenTrailingBlankDecisions(after, new Map([[id, next]]));
8048
+ if (JSON.stringify(before[0].parts) !== JSON.stringify(after[0].parts)) {
8049
+ let partIndex = 0;
8050
+ while (partIndex < before[0].parts.length && JSON.stringify(before[0].parts[partIndex]) === JSON.stringify(after[0].parts[partIndex]))
8051
+ partIndex++;
8052
+ recordFirstApplicationAt(message, partIndex);
8053
+ }
8054
+ };
7792
8055
  if (isCacheBustingPass && trailingBlankDecisions.size > 0) {
7793
8056
  const visibleMessageIds = new Set(args.messages.flatMap((message) => typeof message.info.id === "string" ? [message.info.id] : []));
7794
8057
  const poisonedKeepIds = [];
@@ -7808,9 +8071,8 @@ async function runPostTransformPhase2(args) {
7808
8071
  sessionLog(args.sessionId, "trailing blank heal: persistence failed; retaining frozen keep decisions");
7809
8072
  } else {
7810
8073
  for (const id of demotedIds) {
8074
+ recordTrailingBlankWireEdit(id, "strip");
7811
8075
  trailingBlankDecisions.set(id, "strip");
7812
- bustedThisPass = true;
7813
- lateEditBeforeNewestThinking = true;
7814
8076
  sessionLog(args.sessionId, `trailing blank heal: demoted message ${id} from keep to strip because its source has no trailing blank`);
7815
8077
  }
7816
8078
  }
@@ -7835,13 +8097,11 @@ async function runPostTransformPhase2(args) {
7835
8097
  const committed = getTrailingBlankDecisions(args.db, args.sessionId, candidates.map(([id]) => id));
7836
8098
  for (const [id] of candidates) {
7837
8099
  const decision = committed.get(id);
7838
- if (decision)
8100
+ if (decision) {
8101
+ if (isCacheBustingPass)
8102
+ recordTrailingBlankWireEdit(id, decision);
7839
8103
  trailingBlankDecisions.set(id, decision);
7840
- }
7841
- if (isCacheBustingPass)
7842
- bustedThisPass = true;
7843
- if (isCacheBustingPass && candidates.some(([id]) => id !== newestAssistantId)) {
7844
- lateEditBeforeNewestThinking = true;
8104
+ }
7845
8105
  }
7846
8106
  } else {
7847
8107
  failPass("trailing-blank-decision-persistence-failure");
@@ -7854,6 +8114,7 @@ async function runPostTransformPhase2(args) {
7854
8114
  }
7855
8115
  }
7856
8116
  logTransformTiming(args.sessionId, "pp.frozenDecisions", tFrozenDecisions);
8117
+ bustedThisPass ||= firstApplicationEdits.any;
7857
8118
  const finalizeOptions = {
7858
8119
  prependedMessageCount,
7859
8120
  reasoningMutatedMessages,
@@ -7865,7 +8126,33 @@ async function runPostTransformPhase2(args) {
7865
8126
  skipTrailingWhitespaceStrip: compactionOff
7866
8127
  };
7867
8128
  const dropModeSwitchesThisPass = !canUseEmptySentinels && !dropLeavesReasoning && typeof args.resolvedProviderID === "string" && isCacheBustingPass && reasoningRemovalReadable && args.messages.some((message) => message.info.role === "assistant" && message.parts.some((part) => isNeutralizedReasoningPart(part)));
7868
- const prefixEditBesidesReasoningTrim = firstRenderBust || materializationRequested || explicitMaterializedSuccessfully || deferredMaterializedSuccessfully || foldBustsServedPrefixThisPass || publishedM1RefreshedThisPass || m0RematerializedThisPass || m0M1InjectedThisPass && historyWasConsumedThisPass || historyWasConsumedThisPass || pendingOpsDidMutate || heuristicOrReasoningEditBesidesTrim || emergency || autoReclaimDidMutateThisPass || convertedToolSkeletonsDidMutate || deferredClearedMarkerRetires || noteNudgeAppendedThisPass || todoAnchorMovedThisPass || autoSearchHintAppendedThisPass || dropModeSwitchesThisPass || lateEditBeforeNewestThinking;
8129
+ if (prefixBoundModel && firstApplicationLocations.size > 0 && !firstApplicationEdits.beforeNewerThinking) {
8130
+ const remaining = args.messages.map((message) => ({
8131
+ ...message,
8132
+ parts: [...message.parts]
8133
+ }));
8134
+ stripClearedReasoning(remaining);
8135
+ stripReasoningFromAssistantIds(remaining, args.resolvedProviderID, thinkingBindingRecoveryMessageIds);
8136
+ stripReasoningFromMergedAssistants(remaining, args.resolvedProviderID, {
8137
+ frozenMessageIds: mergedReasoningStrippedIds,
8138
+ mutationExemptMessage: remaining[args.messages.indexOf(reasoningMutationExemptMessage)]
8139
+ });
8140
+ let newerThinking = false;
8141
+ for (let index = remaining.length - 1;index >= 0; index--) {
8142
+ const message = remaining[index];
8143
+ const editIndex = firstApplicationLocations.get(args.messages[index]);
8144
+ if (editIndex !== undefined && editIndex >= message.parts.length && newerThinking)
8145
+ firstApplicationEdits.beforeNewerThinking = true;
8146
+ for (let partIndex = message.parts.length - 1;partIndex >= 0; partIndex--) {
8147
+ const part = message.parts[partIndex];
8148
+ if (message.info.role === "assistant" && isRecord(part) && part.ignored !== true && (part.type === "reasoning" || part.type === "thinking" || part.type === "redacted_thinking"))
8149
+ newerThinking = true;
8150
+ if (editIndex !== undefined && partIndex === editIndex && newerThinking)
8151
+ firstApplicationEdits.beforeNewerThinking = true;
8152
+ }
8153
+ }
8154
+ }
8155
+ const prefixEditBesidesReasoningTrim = firstRenderBust || materializationRequested || explicitMaterializedSuccessfully || deferredMaterializedSuccessfully || foldBustsServedPrefixThisPass || publishedM1RefreshedThisPass || m0RematerializedThisPass || m0M1InjectedThisPass && historyWasConsumedThisPass || historyWasConsumedThisPass || pendingOpsDidMutate || heuristicOrReasoningEditBesidesTrim || emergency || autoReclaimDidMutateThisPass || convertedToolSkeletonsDidMutate || deferredClearedMarkerRetires || noteNudgeAppendedThisPass || todoAnchorMovedThisPass || autoSearchHintAppendedThisPass || dropModeSwitchesThisPass || firstApplicationEdits.beforeNewerThinking;
7869
8156
  let proactiveThinkingStrip = null;
7870
8157
  if (!compactionOff && args.thinkingBindingRecoveryEnabledForModel === true && proactiveThinkingStripPermitted && prefixEditBesidesReasoningTrim) {
7871
8158
  const outcome = freezeReasoningOnBustingPass2({
@@ -7905,6 +8192,8 @@ async function runPostTransformPhase2(args) {
7905
8192
  settledDroppedReasoning = settleDroppedReasoningParts(args.messages, mode);
7906
8193
  }
7907
8194
  const tFinalRepresentation = performance.now();
8195
+ if (temporalDecisions)
8196
+ injectTemporalMarkers(args.messages, temporalDecisions);
7908
8197
  const finalRepresentation = finalizeMessageRepresentation2(args.messages, args.resolvedProviderID, finalizeOptions);
7909
8198
  const removedReasoningParts = reasoningRemovalEnabled ? removeReasoningParts(args.messages, removedReasoningIds, args.resolvedProviderID) : 0;
7910
8199
  sessionLog(args.sessionId, `final representation: clearedParts=${finalRepresentation.clearedParts} mergedReasoningParts=${finalRepresentation.mergedReasoningParts} removedReasoningParts=${removedReasoningParts} settledDroppedReasoning=${settledDroppedReasoning}`);
@@ -7926,6 +8215,8 @@ async function runPostTransformPhase2(args) {
7926
8215
  messages: args.messages,
7927
8216
  tags,
7928
8217
  protectedTagNumbers: args.protectedTagNumbers,
8218
+ protectedToolTags,
8219
+ protectedTools: args.protectedTools,
7929
8220
  pendingDropTagNumbers,
7930
8221
  cacheBusting: bustedThisPass,
7931
8222
  previous,
@@ -7957,7 +8248,9 @@ async function runPostTransformPhase2(args) {
7957
8248
  rearmChannel2AfterMeasuredCollapse({
7958
8249
  db: args.db,
7959
8250
  sessionId: args.sessionId,
7960
- baseline
8251
+ baseline,
8252
+ rebuilding: bustedThisPass,
8253
+ previous
7961
8254
  });
7962
8255
  } catch (error) {
7963
8256
  sessionLog(args.sessionId, "channel2 U-collapse reset failed (ignored):", error);
@@ -7992,14 +8285,12 @@ async function runPostTransformPhase2(args) {
7992
8285
  } catch (error) {
7993
8286
  sessionLog(args.sessionId, "ERROR [tail-hygiene-last-writer-check-failed]: structural production guard failed open:", error);
7994
8287
  }
7995
- if (true) {
7996
- assertTailHygieneContentUnchanged({
7997
- messages: args.messages,
7998
- tags: assertedBaseline.tags,
7999
- protectedTagNumbers: assertedBaseline.protectedTagNumbers,
8000
- expectedSignature: assertedBaseline.contentSignature
8001
- });
8002
- }
8288
+ assertTailHygieneContentUnchangedIfEnabled({
8289
+ messages: args.messages,
8290
+ tags: assertedBaseline.tags,
8291
+ protectedTagNumbers: assertedBaseline.protectedTagNumbers,
8292
+ expectedSignature: assertedBaseline.contentSignature
8293
+ });
8003
8294
  }
8004
8295
  logTransformTiming(args.sessionId, "pp.tailGuard", tTailGuard);
8005
8296
  return {
@@ -8036,4 +8327,4 @@ function checkM0MutationDriftAndSignal2(args) {
8036
8327
  return false;
8037
8328
  }
8038
8329
 
8039
- export { indexCommitsForProject, embedUnembeddedCommits, createTagger, createUnifiedSearchDiagnostics, parseIdShapedQuery, resolveMemoriesByIdsForSearch, unifiedSearch, formatSearchResults, cavemanWordRulesForLanguage, findSessionId, findLastUserMessageId, clearAutoSearchForSession, setCtxReduceRegisteredGlobally, resolveCtxReduceAvailabilityFromMessages, resolveCtxReduceAvailability, primeCtxReduceSpawnPermission, ctxReduceSpawnPermissionReadNeeded, spawnAgentFromMessages, spawnAgentFromOpenCodeDb, todowritePermissionDenied, cachedToolPermissionDenied, clearToolPermissionDenied, resolveTodowriteAvailabilityFromMessages, resolveTodowriteAvailability, canConsumeDeferredOnThisPass, hasReclaimRide, reclaimRideLabel, replayCavemanCompression, DegradedPassRefusalError, degradedPassError, ENGINE_RECONNECTING_USER_MESSAGE, EmergencyFailClosedError, replayClearedReasoning, replayStrippedInlineThinking, stripClearedReasoning, snapshotTrailingBlankSourceDecisions, applyFlushedStatuses, stripStructuralNoise, logTransformTiming, hasRecentAssistantCommit, tagMessages, resetDegradedCacheCount2, isSyntheticHeadMessage2, applyTodoSynthesis2, freezeReasoningOnBustingPass2, firstServedDivergenceIndex2, rustModeServedKeyAfterPersistedStrips2, replayRustModeBindingMismatchStrips2, RUST_MARKER_LOCK_SKIP_LOG2, applyRustModeDeferredCompactionMarker2, clearRustModeBoundaryRecord2, runRustModePostprocess2, reconcileMarkerRepresentation2, clearPendingCompactionMarkerAfterSuccessfulDrain2, defaultCompactionMarkerStrategy2, abortSessionFailClosed2, evaluateEmergencyFailClosed2, finalizeMessageRepresentation2, runPostTransformPhase2, checkM0MutationDriftAndSignal2 };
8330
+ export { indexCommitsForProject, embedUnembeddedCommits, createTagger, createUnifiedSearchDiagnostics, parseIdShapedQuery, resolveMemoriesByIdsForSearch, unifiedSearch, formatSearchResults, cavemanWordRulesForLanguage, findSessionId, findLastUserMessageId, clearAutoSearchForSession, setCtxReduceRegisteredGlobally, resolveCtxReduceAvailabilityFromMessages, resolveCtxReduceAvailability, primeCtxReduceSpawnPermission, ctxReduceSpawnPermissionReadNeeded, spawnAgentFromMessages, spawnAgentFromOpenCodeDb, todowritePermissionDenied, cachedToolPermissionDenied, clearToolPermissionDenied, resolveTodowriteAvailabilityFromMessages, resolveTodowriteAvailability, canConsumeDeferredOnThisPass, hasReclaimRide, reclaimRideLabel, replayCavemanCompression, DegradedPassRefusalError, degradedPassError, ENGINE_RECONNECTING_USER_MESSAGE, contextRefusalError, protectedToolRefusal, outgoingContextRefusal, EmergencyFailClosedError, replayClearedReasoning, replayStrippedInlineThinking, stripClearedReasoning, snapshotTrailingBlankSourceDecisions, applyFlushedStatuses, stripStructuralNoise, logTransformTiming, hasRecentAssistantCommit, tagMessages, resetDegradedCacheCount2, isSyntheticHeadMessage2, applyTodoSynthesis2, freezeReasoningOnBustingPass2, firstServedDivergenceIndex2, rustModeServedKeyAfterPersistedStrips2, replayRustModeBindingMismatchStrips2, RUST_MARKER_LOCK_SKIP_LOG2, applyRustModeDeferredCompactionMarker2, clearRustModeBoundaryRecord2, runRustModePostprocess2, reconcileMarkerRepresentation2, clearPendingCompactionMarkerAfterSuccessfulDrain2, defaultCompactionMarkerStrategy2, abortSessionFailClosed2, evaluateEmergencyFailClosed2, finalizeMessageRepresentation2, runPostTransformPhase2, checkM0MutationDriftAndSignal2 };