@cortexkit/opencode-magic-context 0.49.33 → 0.49.35

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 (229) hide show
  1. package/dist/auto-search-worker.js +11 -6
  2. package/dist/chunk-embedding-write-worker.js +16 -14
  3. package/dist/{compaction-marker-candidates-31h86ph0.js → compaction-marker-candidates-g0p67ced.js} +3 -2
  4. package/dist/compaction-marker-candidates-worker.js +1 -1
  5. package/dist/{compartment-chunk-embedding-5q5gj67r.js → compartment-chunk-embedding-y4136are.js} +8 -7
  6. package/dist/{conflict-warning-hook-xgskea1v.js → conflict-warning-hook-hhw8z5ak.js} +9 -8
  7. package/dist/{context-jyzkstnr.js → context-fk8e3h9p.js} +1400 -701
  8. package/dist/{derive-budgets-pqybnx09.js → derive-budgets-htj16n4x.js} +3 -2
  9. package/dist/embedding-backfill-q6n72sy0.js +27 -0
  10. package/dist/embedding-worker-process.js +2 -1
  11. package/dist/embedding-worker.js +5 -4
  12. package/dist/expand-attachments-h33jbgyz.js +21 -0
  13. package/dist/features/magic-context/auto-search-diagnostics.d.ts +21 -0
  14. package/dist/features/magic-context/auto-search-diagnostics.d.ts.map +1 -0
  15. package/dist/features/magic-context/compaction-marker.d.ts +22 -6
  16. package/dist/features/magic-context/compaction-marker.d.ts.map +1 -1
  17. package/dist/features/magic-context/compartment-chunk-embedding.d.ts +1 -1
  18. package/dist/features/magic-context/compartment-chunk-embedding.d.ts.map +1 -1
  19. package/dist/features/magic-context/search.d.ts +4 -0
  20. package/dist/features/magic-context/search.d.ts.map +1 -1
  21. package/dist/features/magic-context/storage-meta-persisted.d.ts +7 -0
  22. package/dist/features/magic-context/storage-meta-persisted.d.ts.map +1 -1
  23. package/dist/features/magic-context/store-generation-rebase-labels.d.ts +6 -0
  24. package/dist/features/magic-context/store-generation-rebase-labels.d.ts.map +1 -0
  25. package/dist/features/magic-context/store-generation-rebase.d.ts.map +1 -1
  26. package/dist/{history-owner-36wp3mkb.js → history-owner-0z620wgz.js} +3 -2
  27. package/dist/hooks/magic-context/apply-operations.d.ts +20 -3
  28. package/dist/hooks/magic-context/apply-operations.d.ts.map +1 -1
  29. package/dist/hooks/magic-context/auto-search-observation.d.ts +13 -0
  30. package/dist/hooks/magic-context/auto-search-observation.d.ts.map +1 -0
  31. package/dist/hooks/magic-context/auto-search-runner.d.ts.map +1 -1
  32. package/dist/hooks/magic-context/auto-search-worker-client.d.ts +5 -1
  33. package/dist/hooks/magic-context/auto-search-worker-client.d.ts.map +1 -1
  34. package/dist/hooks/magic-context/compaction-marker-manager.d.ts +5 -5
  35. package/dist/hooks/magic-context/compaction-marker-manager.d.ts.map +1 -1
  36. package/dist/hooks/magic-context/compaction-marker-publication.d.ts +9 -0
  37. package/dist/hooks/magic-context/compaction-marker-publication.d.ts.map +1 -0
  38. package/dist/hooks/magic-context/compartment-commit-hashes.d.ts +4 -0
  39. package/dist/hooks/magic-context/compartment-commit-hashes.d.ts.map +1 -0
  40. package/dist/hooks/magic-context/compartment-runner-validation.d.ts +1 -0
  41. package/dist/hooks/magic-context/compartment-runner-validation.d.ts.map +1 -1
  42. package/dist/hooks/magic-context/event-resolvers.d.ts.map +1 -1
  43. package/dist/hooks/magic-context/final-wire-completeness.d.ts +15 -0
  44. package/dist/hooks/magic-context/final-wire-completeness.d.ts.map +1 -0
  45. package/dist/hooks/magic-context/final-wire-token-estimate.d.ts.map +1 -1
  46. package/dist/hooks/magic-context/inject-compartments.d.ts.map +1 -1
  47. package/dist/hooks/magic-context/raw-ordinal-warmup.d.ts +1 -0
  48. package/dist/hooks/magic-context/raw-ordinal-warmup.d.ts.map +1 -1
  49. package/dist/hooks/magic-context/read-session-chunk.d.ts +11 -0
  50. package/dist/hooks/magic-context/read-session-chunk.d.ts.map +1 -1
  51. package/dist/hooks/magic-context/read-session-formatting.d.ts +2 -0
  52. package/dist/hooks/magic-context/read-session-formatting.d.ts.map +1 -1
  53. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
  54. package/dist/hooks/magic-context/transform.d.ts.map +1 -1
  55. package/dist/{index-as2amvn3.js → index-0c7p8mq5.js} +6 -531
  56. package/dist/{index-51rdvtkz.js → index-1rhgxqs8.js} +2 -2
  57. package/dist/index-2amn2s73.js +123 -0
  58. package/dist/{index-c7phnbvk.js → index-2p37txes.js} +1 -1
  59. package/dist/index-2qbtqg1w.js +529 -0
  60. package/dist/{index-waktfbjy.js → index-2v6nvy3k.js} +4 -4
  61. package/dist/{index-dq5xzeb9.js → index-3d3872c6.js} +7 -5
  62. package/dist/{index-qr2mb02j.js → index-3j9t1v4n.js} +55 -21
  63. package/dist/{index-2xh37qn5.js → index-4bgk5ztz.js} +576 -5524
  64. package/dist/{index-b88dwwrh.js → index-4xyjr62e.js} +1 -1
  65. package/dist/index-66a50f3e.js +777 -0
  66. package/dist/{index-94ef0qe2.js → index-87ctnzz9.js} +33 -5
  67. package/dist/{index-xrnsygfq.js → index-9wnbnx8f.js} +1 -1
  68. package/dist/{index-3fkk2gwj.js → index-b6xz3qbe.js} +246 -420
  69. package/dist/{index-0fe4q77z.js → index-brg2w6qc.js} +146 -134
  70. package/dist/{index-spwjbkc7.js → index-dnqqqc5f.js} +1 -1
  71. package/dist/index-dy7w6wm4.js +194 -0
  72. package/dist/{index-3jmx3fae.js → index-ezv6dz3y.js} +37 -7
  73. package/dist/index-f297z1n8.js +4557 -0
  74. package/dist/{index-qgh1qwjj.js → index-f9b3vtt1.js} +1 -1
  75. package/dist/{index-v15ne3a3.js → index-faxb7mck.js} +2 -2
  76. package/dist/{index-rrv26qjz.js → index-fw42ms3m.js} +1 -1
  77. package/dist/{index-t5pck3ss.js → index-fxbk7gk3.js} +1 -1
  78. package/dist/{index-wfybj1dw.js → index-g4t7850m.js} +2 -2
  79. package/dist/{index-hbt0sbv2.js → index-gyaa159j.js} +18 -276
  80. package/dist/{index-4pnsgvfk.js → index-hacf2tyx.js} +1 -1
  81. package/dist/{index-s1n8dd2n.js → index-jkanybgq.js} +2 -2
  82. package/dist/{index-2743x98y.js → index-jn0ddrhp.js} +29 -138
  83. package/dist/{index-h7tgn49j.js → index-jrfre9ah.js} +5 -222
  84. package/dist/{index-kfyb3k6n.js → index-jz5bk7xd.js} +2 -2
  85. package/dist/{index-np3rgfw4.js → index-ksv0a31x.js} +3 -3
  86. package/dist/{index-7kkphb6c.js → index-nj360hcs.js} +4 -4
  87. package/dist/{index-gkee6p4g.js → index-p56dszfp.js} +3 -3
  88. package/dist/{index-4s4zq97n.js → index-pq0dpwrc.js} +4 -4
  89. package/dist/{index-rfxzazzy.js → index-pswsyf1w.js} +4 -4
  90. package/dist/{index-y1qwzvxn.js → index-pztqab6k.js} +2 -2
  91. package/dist/{index-rverk2vz.js → index-qncw9hey.js} +1 -1
  92. package/dist/index-qx8j6kds.js +270 -0
  93. package/dist/{index-kq5w68dp.js → index-txs8tce6.js} +1 -1
  94. package/dist/index-vzhhr1ht.js +532 -0
  95. package/dist/index-wh9fxds5.js +265 -0
  96. package/dist/{index-b7w46fp2.js → index-x2mrq5xv.js} +170 -48
  97. package/dist/{index-43vqx0za.js → index-xwwsbsd3.js} +15 -13
  98. package/dist/index-z4p0ry94.js +222 -0
  99. package/dist/index-z9zygwse.js +89 -0
  100. package/dist/{index-v7287tzq.js → index-zhqwda72.js} +19 -8
  101. package/dist/index.js +83 -72
  102. package/dist/{logger-94kew5wm.js → logger-qwnbcfj9.js} +2 -1
  103. package/dist/{message-fts-rowid-map-va36knh4.js → message-fts-rowid-map-xg7hr0mk.js} +5 -4
  104. package/dist/{message-index-bounded-zq7a5nm6.js → message-index-bounded-narw7bnz.js} +12 -11
  105. package/dist/{message-time-backfill-4qva0b4f.js → message-time-backfill-39bm498k.js} +3 -2
  106. package/dist/migration-worker.js +13 -11
  107. package/dist/{project-embedding-registry-6yex0r9f.js → project-embedding-registry-tdz7985n.js} +13 -11
  108. package/dist/raw-ordinal-warmup-worker.js +12 -7
  109. package/dist/{read-session-chunk-1ndphmb8.js → read-session-chunk-vmg1zjg0.js} +15 -10
  110. package/dist/{read-session-raw-b2sd67v4.js → read-session-raw-mncmzbm9.js} +3 -2
  111. package/dist/recomp-orchestrator-qyyhnc9b.js +68 -0
  112. package/dist/render-c5p0k846.js +43 -0
  113. package/dist/{safe-notification-target-mkr9yzvr.js → safe-notification-target-wztd7bgk.js} +3 -2
  114. package/dist/{search-archive-sr07c6aj.js → search-archive-0ny7p3bw.js} +13 -11
  115. package/dist/{search-040pac3a.js → search-f6hwvcxk.js} +26 -23
  116. package/dist/{send-session-notification-vz86nt79.js → send-session-notification-0gwcz3fw.js} +7 -6
  117. package/dist/{storage-tags-6hvkk01c.js → storage-tags-zx1023km.js} +5 -4
  118. package/dist/store-620rjzt9.js +21 -0
  119. package/dist/store-reader-yh19h38c.js +14 -0
  120. package/dist/tools/ctx-expand/render.d.ts +5 -3
  121. package/dist/tools/ctx-expand/render.d.ts.map +1 -1
  122. package/dist/tools/ctx-expand/search-archive.d.ts.map +1 -1
  123. package/dist/tools/ctx-expand/tools.d.ts +2 -0
  124. package/dist/tools/ctx-expand/tools.d.ts.map +1 -1
  125. package/dist/tools/ctx-expand/v2-archive-reader.d.ts +33 -0
  126. package/dist/tools/ctx-expand/v2-archive-reader.d.ts.map +1 -0
  127. package/dist/{transform-postprocess-phase-zx1peqma.js → transform-postprocess-phase-807ff6t2.js} +36 -30
  128. package/dist/v2/auto-search-worker.js +11 -6
  129. package/dist/v2/chunk-embedding-write-worker.js +16 -14
  130. package/dist/v2/{compaction-marker-candidates-m4vmye3w.js → compaction-marker-candidates-t1aq6gsj.js} +3 -2
  131. package/dist/v2/compaction-marker-candidates-worker.js +1 -1
  132. package/dist/v2/{compartment-chunk-embedding-rc31e6md.js → compartment-chunk-embedding-ncsk0r9e.js} +8 -7
  133. package/dist/v2/{context-3c4z2wj5.js → context-znqfkap4.js} +1725 -1095
  134. package/dist/v2/{derive-budgets-knf763tt.js → derive-budgets-sa0v7bz0.js} +4 -3
  135. package/dist/v2/embedding-backfill-11j425e0.js +26 -0
  136. package/dist/v2/embedding-worker-process.js +2 -1
  137. package/dist/v2/embedding-worker.js +5 -4
  138. package/dist/v2/expand-attachments-h33jbgyz.js +21 -0
  139. package/dist/v2/fold/idle.d.ts +15 -0
  140. package/dist/v2/fold/idle.d.ts.map +1 -0
  141. package/dist/v2/fold/native-replay-v3.d.ts +68 -0
  142. package/dist/v2/fold/native-replay-v3.d.ts.map +1 -0
  143. package/dist/v2/fold/native-replay.d.ts +58 -2
  144. package/dist/v2/fold/native-replay.d.ts.map +1 -1
  145. package/dist/v2/fold/policy.d.ts +2 -1
  146. package/dist/v2/fold/policy.d.ts.map +1 -1
  147. package/dist/v2/{history-owner-ad0crnrn.js → history-owner-fpka43cn.js} +3 -2
  148. package/dist/v2/hooks/context.d.ts.map +1 -1
  149. package/dist/v2/hooks/expand-attachments.d.ts +8 -0
  150. package/dist/v2/hooks/expand-attachments.d.ts.map +1 -0
  151. package/dist/v2/hooks/overflow-recovery.d.ts +45 -0
  152. package/dist/v2/hooks/overflow-recovery.d.ts.map +1 -0
  153. package/dist/v2/hooks/store.d.ts +7 -2
  154. package/dist/v2/hooks/store.d.ts.map +1 -1
  155. package/dist/v2/{logger-p34mjtja.js → logger-4cj6d03m.js} +2 -1
  156. package/dist/v2/{message-fts-rowid-map-78awh03v.js → message-fts-rowid-map-rmk571mb.js} +5 -4
  157. package/dist/v2/{message-index-bounded-jvgz7vk9.js → message-index-bounded-620bppw7.js} +12 -11
  158. package/dist/v2/{message-time-backfill-zvthw6xb.js → message-time-backfill-0c4h7sg6.js} +3 -2
  159. package/dist/v2/migration-worker.js +13 -11
  160. package/dist/v2/ordinal-range.fixture.d.ts +7 -0
  161. package/dist/v2/ordinal-range.fixture.d.ts.map +1 -0
  162. package/dist/v2/{project-embedding-registry-1x5qe2fy.js → project-embedding-registry-bm5fe1a8.js} +13 -11
  163. package/dist/v2/raw-ordinal-warmup-worker.js +12 -7
  164. package/dist/v2/{read-session-chunk-djzgm4jg.js → read-session-chunk-qfwv1k71.js} +15 -10
  165. package/dist/v2/{read-session-raw-5x088amc.js → read-session-raw-q294t8xs.js} +3 -2
  166. package/dist/v2/recomp-orchestrator-fcnjref7.js +67 -0
  167. package/dist/v2/render-98a1qv0b.js +42 -0
  168. package/dist/v2/{safe-notification-target-khnzg57c.js → safe-notification-target-gphhast7.js} +3 -2
  169. package/dist/v2/{search-archive-n3dhns4r.js → search-archive-r0y1bafr.js} +13 -11
  170. package/dist/v2/{search-q3wkpe8t.js → search-z1zqzsmh.js} +25 -22
  171. package/dist/v2/{send-session-notification-x5nzy34v.js → send-session-notification-fst6hkg7.js} +7 -6
  172. package/dist/v2/{server-rb8m4vry.js → server-1xesqm5h.js} +146 -134
  173. package/dist/v2/server-2amn2s73.js +123 -0
  174. package/dist/v2/{server-6g98c227.js → server-3schkz95.js} +4 -4
  175. package/dist/v2/server-468mya5v.js +209 -0
  176. package/dist/v2/server-55v5hpth.js +270 -0
  177. package/dist/v2/server-5jp38p98.js +532 -0
  178. package/dist/v2/{server-qjvk4a9t.js → server-69m30b21.js} +1 -1
  179. package/dist/v2/{server-d01pe8q5.js → server-7ccxt4nq.js} +14 -216
  180. package/dist/v2/{server-3mz2qh5a.js → server-969cdpmg.js} +1 -1
  181. package/dist/v2/{server-835q39kd.js → server-9k0mjef7.js} +2 -2
  182. package/dist/v2/{server-qc915kw2.js → server-bez34e60.js} +4 -4
  183. package/dist/v2/{server-nxas8v1d.js → server-bpvsvtph.js} +3 -3
  184. package/dist/v2/{server-ab8017gw.js → server-bxpz2dcn.js} +29 -138
  185. package/dist/v2/{server-bsgd4dk1.js → server-dcws5831.js} +2 -2
  186. package/dist/v2/server-ef1mskas.js +777 -0
  187. package/dist/v2/{server-1bw1wcbp.js → server-f0j864ma.js} +1 -1
  188. package/dist/v2/{server-aqbm9c8d.js → server-fqj6ddpr.js} +632 -5540
  189. package/dist/v2/{server-rr4cbkr0.js → server-hnknwaz8.js} +37 -7
  190. package/dist/v2/{server-h1byrhwx.js → server-hsf0qsn5.js} +19 -8
  191. package/dist/v2/{server-6495nmn9.js → server-jb6tjyeb.js} +5 -222
  192. package/dist/v2/{server-2aasmpsp.js → server-kkxzwa6w.js} +4 -4
  193. package/dist/v2/{server-a7x00tw8.js → server-mfn1yf9d.js} +1 -1
  194. package/dist/v2/{server-tkdabx8q.js → server-q0z2q2dx.js} +5 -530
  195. package/dist/v2/{server-n14edf07.js → server-qa74bj91.js} +77 -17
  196. package/dist/v2/server-qf2kzsh2.js +4513 -0
  197. package/dist/v2/{server-gyy4k6mf.js → server-qmmkhz2z.js} +1 -1
  198. package/dist/v2/{server-29qp8nz4.js → server-qxzbmtqt.js} +1 -1
  199. package/dist/v2/{server-hwag0khr.js → server-r3chnxs5.js} +4 -4
  200. package/dist/v2/{server-vr4szghm.js → server-rktnzs89.js} +2 -2
  201. package/dist/v2/{server-6vd2n183.js → server-s9xgyyj9.js} +1 -1
  202. package/dist/v2/{server-53eh1r8r.js → server-sd8hvzte.js} +2 -2
  203. package/dist/v2/{server-k3t06fxr.js → server-sefxj8k1.js} +1 -1
  204. package/dist/v2/{server-v77xa5wj.js → server-tpt7bwq8.js} +1 -1
  205. package/dist/v2/{server-awr8qa4c.js → server-ws5exe6q.js} +2 -2
  206. package/dist/v2/server-x4m6xcn4.js +194 -0
  207. package/dist/v2/{server-806rzhs6.js → server-xbtw0p9t.js} +1 -1
  208. package/dist/v2/{server-cqjvxyrp.js → server-xy7w7hrd.js} +2 -2
  209. package/dist/v2/server-ypf1ap0v.js +529 -0
  210. package/dist/v2/server-z4p0ry94.js +222 -0
  211. package/dist/v2/server-z9zygwse.js +89 -0
  212. package/dist/v2/{server-ab1g0wn9.js → server-zzgtgqmd.js} +2 -2
  213. package/dist/v2/server.js +6 -5
  214. package/dist/v2/{storage-tags-18nbaanf.js → storage-tags-19s0ebf0.js} +5 -4
  215. package/dist/v2/store-reader-cgx47zkp.js +14 -0
  216. package/dist/v2/store-reader.d.ts +9 -2
  217. package/dist/v2/store-reader.d.ts.map +1 -1
  218. package/dist/v2/store-vdm8v3jd.js +21 -0
  219. package/dist/v2/v2-archive-reader-t2c0eypn.js +11 -0
  220. package/dist/v2/{wrapup-orchestrator-ga5vfmwr.js → wrapup-orchestrator-aqpqsveg.js} +46 -39
  221. package/dist/v2-archive-reader-tm2eayp2.js +11 -0
  222. package/dist/wrapup-orchestrator-k5yp19a6.js +55 -0
  223. package/package.json +1 -1
  224. package/src/shared/sqlite-transaction-mode-guard.test.ts +4 -0
  225. package/dist/embedding-backfill-0jgtqxen.js +0 -25
  226. package/dist/recomp-orchestrator-skqzzvby.js +0 -62
  227. package/dist/v2/embedding-backfill-f43hd8y6.js +0 -24
  228. package/dist/v2/recomp-orchestrator-qfqdvbta.js +0 -61
  229. package/dist/wrapup-orchestrator-dy8r3gp8.js +0 -49
@@ -7,7 +7,7 @@ import {
7
7
  resolveLegacyConfigSources,
8
8
  getProtectedTokensTierOverrides,
9
9
  loadPluginConfigDetailed
10
- } from "./server-835q39kd.js";
10
+ } from "./server-9k0mjef7.js";
11
11
  import {
12
12
  getHarness2,
13
13
  harnessOwnsOpenCodeStore2
@@ -15,14 +15,16 @@ import {
15
15
  import {
16
16
  getDataDir,
17
17
  getMagicContextStorageDir,
18
- sanitizeDiagnosticText,
19
- hasShareabilitySensitiveText,
20
18
  classifyStalePluginBuild,
21
19
  importPluginModule,
22
20
  log2,
23
21
  sessionLog2,
24
22
  getLoggerDiagnostics2
25
- } from "./server-6495nmn9.js";
23
+ } from "./server-jb6tjyeb.js";
24
+ import {
25
+ sanitizeDiagnosticText,
26
+ hasShareabilitySensitiveText
27
+ } from "./server-z4p0ry94.js";
26
28
  import {
27
29
  hasTrustedAbsoluteWall,
28
30
  applyProvenInputFloor,
@@ -34,7 +36,7 @@ import {
34
36
  getSdkContextLimit,
35
37
  getSdkOutputLimit,
36
38
  getModelsDevCacheState
37
- } from "./server-29qp8nz4.js";
39
+ } from "./server-qxzbmtqt.js";
38
40
  import {
39
41
  isValidLanguageCode,
40
42
  withContentLanguageDirective,
@@ -73,111 +75,6 @@ import {
73
75
  currentPluginConfigReader,
74
76
  withLiveDreamerOutputCap,
75
77
  v2ToolDefinitionsHash,
76
- acquireCompartmentLease,
77
- releaseCompartmentLeaseBestEffort,
78
- isCompartmentLeaseHeld,
79
- queueM0Mutation,
80
- getMaxM0MutationId,
81
- getLastCompartmentEndMessage,
82
- getLastCompartmentEndMessageId,
83
- getUncoveredCompartmentEndsThrough,
84
- providerResponseFailed,
85
- isSuccessfulProviderCompletion,
86
- LkgRecoveryFenceError,
87
- lkgServedArrayDigest,
88
- hasCleanLkgRecoveryFence,
89
- dirtyLkgRecoveryRevision,
90
- ownsLkgDirtyFence,
91
- invalidateCleanLkgRecoveryFence,
92
- prepareLkgCaptureFence,
93
- certifyCommittedLkgCapture,
94
- markLkgRecoveryDirty,
95
- rememberUnpublishedAutoSearchNoHint,
96
- getUnpublishedAutoSearchNoHint,
97
- forgetUnpublishedAutoSearchNoHint,
98
- registerAutoSearchWork,
99
- gaDatabasePath,
100
- RAW_MESSAGE_TYPES,
101
- V2StoreReaderPool,
102
- V2StoreReader,
103
- advanceSessionActivity,
104
- backfillSessionActivity,
105
- getOrCreateSessionMeta,
106
- updateSessionMeta,
107
- advanceToolReclaimWatermark,
108
- markSessionCleanupPending,
109
- retryPendingSessionCleanups,
110
- retryPendingRustSessionCleanupsForProject,
111
- clearSession,
112
- requestPendingMaterialization,
113
- pendingMaterializationOrigin,
114
- hasPendingMaterializationOrigin,
115
- clearPendingMaterialization,
116
- recordSystemPromptForRequest,
117
- recordHeldHeadForRequest,
118
- bindSystemPromptResponse,
119
- isHeldHeadForRequest,
120
- deferDeliveredSystemRefresh,
121
- retirePendingSystemPromptDelivery,
122
- lkgProviderInputTotal,
123
- beginV2LkgRequest,
124
- claimLkgRequestIdentity,
125
- currentLkgRequestIdentity,
126
- noteCapturedLkgRequest,
127
- noteLkgProviderResponse,
128
- measuredLkgPrefix,
129
- clearLkgMeasuredRequest,
130
- saveLkgSlotToDb,
131
- clearPersistedLkgSlotStrict,
132
- loadPersistedLkgSlot,
133
- drainStaleLkgSlots,
134
- resolveLkgModelKeys,
135
- createLkgEntryProjector,
136
- captureLkgSlot,
137
- validateAnthropicReasoningRuns,
138
- validateLkgSeam,
139
- replayLkg,
140
- coldStartRawServedIndex,
141
- coldStartUncapturedReplay,
142
- noteUncertifiedNormalLkg,
143
- hasProcessLocalLkgProof,
144
- lkgDirtyRevision,
145
- rememberLkgDirtyRevision,
146
- readPersistedLkgUntaggedInputIds,
147
- persistLkgUntaggedInputIds,
148
- noteLkgRecoveryPrefix,
149
- readLkgRecoveryPrefix,
150
- noteLkgHealthyPrefix,
151
- lkgRecoveryReplayUnproven,
152
- lkgRecoveryEntryUnproven,
153
- lkgInputIdentity,
154
- beginLkgPass,
155
- visitMessageContentFields,
156
- contentSnapshotValue,
157
- messageContentFields,
158
- signatureForFields,
159
- exactReusablePrefix,
160
- incrementalLkgContentDigests,
161
- lkgSlotRejection,
162
- captureSlot,
163
- getInMemorySlot,
164
- getSlot,
165
- forgetInMemorySlot,
166
- dropSlot,
167
- noteEntry,
168
- getLkgSlotHeapStats,
169
- TOOL_SWEEP_SCOPED_MARKER,
170
- useScopedToolSweep,
171
- createPreAdoptionToolSweepResolver,
172
- copySessionStateForClone,
173
- queueMemoryMutation,
174
- getMaxMemoryMutationIdForProjects,
175
- GLOBAL_USER_PROFILE_PROJECT_PATH,
176
- getProjectState,
177
- bumpProjectUserProfileVersion,
178
- saveSourceContent,
179
- replaceSourceContent,
180
- getSourceContents,
181
78
  readCoordinateGeneration,
182
79
  rebaseSessionCoordinatesAsync,
183
80
  HiddenCompletionRefusal,
@@ -305,7 +202,7 @@ import {
305
202
  startCompartmentAgent,
306
203
  setRecompStarting2,
307
204
  setRecompTerminal2
308
- } from "./server-aqbm9c8d.js";
205
+ } from "./server-fqj6ddpr.js";
309
206
  import {
310
207
  resolveHistorianModel2
311
208
  } from "./server-5kym00ag.js";
@@ -315,22 +212,8 @@ import {
315
212
  createFailClosedBlockingError,
316
213
  isFailClosedBlockingError,
317
214
  shouldBypassFailClosedBlock,
318
- resolveAgentNameFromMessages,
319
- startBootDeadline,
320
- getUnconfirmedMigrationHolders,
321
- getSchemaFenceRejection,
322
- getMigrationOnOpenRefusal,
323
- LATEST_SUPPORTED_VERSION,
324
- BOOT_SQLITE_BUSY_TIMEOUT_MS,
325
- getDatabasePath,
326
- getPersistedSchemaVersion,
327
- runSqliteOptimize,
328
- openDatabase,
329
- openCurrentDatabase,
330
- openDatabaseAsync,
331
- isDatabasePersisted,
332
- getDatabasePersistenceError
333
- } from "./server-d01pe8q5.js";
215
+ resolveAgentNameFromMessages
216
+ } from "./server-468mya5v.js";
334
217
  import {
335
218
  pruneMissingProjectIdentities,
336
219
  setHomeProjectPermission,
@@ -347,7 +230,7 @@ import {
347
230
  storedPathBelongsToIdentity,
348
231
  beginBootQuietPeriod,
349
232
  scheduleAfterBootQuiet
350
- } from "./server-qjvk4a9t.js";
233
+ } from "./server-69m30b21.js";
351
234
  import"./server-51779zs2.js";
352
235
  import {
353
236
  inRootAsyncContext2,
@@ -373,7 +256,7 @@ import {
373
256
  buildInMemoryTailRawMessages2,
374
257
  RawOrdinalsNotReady2,
375
258
  runSessionWarmupWorker
376
- } from "./server-6vd2n183.js";
259
+ } from "./server-s9xgyyj9.js";
377
260
  import {
378
261
  resolveModelCalibration,
379
262
  calibrateBuckets,
@@ -468,7 +351,7 @@ import {
468
351
  adoptNullOwnerToolTag2,
469
352
  getCandidateToolOwners2,
470
353
  pickNearestPriorOwner2
471
- } from "./server-nxas8v1d.js";
354
+ } from "./server-bpvsvtph.js";
472
355
  import {
473
356
  textMentionsRecentCommit,
474
357
  hasMeaningfulUserText2,
@@ -479,7 +362,7 @@ import {
479
362
  estimateTokens,
480
363
  estimateFixedPromptTokens,
481
364
  normalizeText
482
- } from "./server-3mz2qh5a.js";
365
+ } from "./server-969cdpmg.js";
483
366
  import {
484
367
  stableStringify,
485
368
  getTableColumnNames,
@@ -488,7 +371,7 @@ import {
488
371
  freezeTemporalDecisions,
489
372
  tagRevisionKey,
490
373
  tagIdentityRevisionKey
491
- } from "./server-v77xa5wj.js";
374
+ } from "./server-tpt7bwq8.js";
492
375
  import {
493
376
  resolveOpenCodeDbPath,
494
377
  assertOpenCodeStoreGeneration,
@@ -504,15 +387,9 @@ import {
504
387
  latestRealUserTurnIdFromOpenCodeDb,
505
388
  getMessageTimesFromOpenCodeDb,
506
389
  findLastAssistantModelFromOpenCodeDb
507
- } from "./server-a7x00tw8.js";
390
+ } from "./server-mfn1yf9d.js";
508
391
  import {
509
- expandToolPart,
510
392
  askAnswerLines,
511
- markHostUnservedRow,
512
- markCoveredInstructionRow,
513
- isCoveredInstructionRow,
514
- takeCoveredInstructionRows,
515
- cloneKeepingCoveredInstructionMarks,
516
393
  estimateTrueRawMessageTokens,
517
394
  stripSystemInjection,
518
395
  isTextPart,
@@ -526,6 +403,7 @@ import {
526
403
  createDroppedInputGuard,
527
404
  assertExecutableToolInput,
528
405
  isEditTool,
406
+ createFinalWireIncompleteLogger,
529
407
  decodeMergedReasoningParts,
530
408
  MAX_EXECUTE_THRESHOLD,
531
409
  escalationBands,
@@ -683,6 +561,7 @@ import {
683
561
  ToolMutationBatch,
684
562
  createToolDropTarget,
685
563
  hasRawMessageProvider2,
564
+ rawMessageWorkerSource2,
686
565
  setRawMessageProvider2,
687
566
  setBoundedRawMessageProvider2,
688
567
  cleanUserText2,
@@ -700,28 +579,28 @@ import {
700
579
  readRawSessionBoundaryEndpoints2,
701
580
  hasRawSessionMessageById2,
702
581
  readRawSessionMessageOrdinalById2,
703
- readRawSessionMessageById2,
704
582
  readSessionChunk2,
705
583
  readRawSessionSeedTail2
706
- } from "./server-rb8m4vry.js";
584
+ } from "./server-1xesqm5h.js";
707
585
  import {
708
586
  BoundedSessionMap,
709
587
  recordToolDefinitionSet,
710
588
  getCurrentToolSetHash,
711
589
  getMeasuredToolDefinitionTokens
712
- } from "./server-cqjvxyrp.js";
590
+ } from "./server-xy7w7hrd.js";
713
591
  import {
714
592
  cleanSearchText,
715
593
  matchedSearchSnippet,
716
594
  getLastIndexedOrdinal
717
- } from "./server-hwag0khr.js";
718
- import"./server-awr8qa4c.js";
595
+ } from "./server-r3chnxs5.js";
596
+ import"./server-ws5exe6q.js";
719
597
  import {
720
598
  getMessageIndexEpoch,
721
599
  isMessageIndexSearchable,
722
600
  scheduleReconciliation,
723
601
  scheduleClearAndReindex,
724
602
  getMessageIndexQueueHeapStats,
603
+ createAutoSearchDiagnostics,
725
604
  renderSingleStoreMigrationRequiredRefusal,
726
605
  SingleStoreMigrationRequiredError,
727
606
  singleStoreMigrationRequiredFailure,
@@ -740,7 +619,7 @@ import {
740
619
  resolveMemoriesByIdsForSearch2,
741
620
  unifiedSearch2,
742
621
  formatSearchResults2
743
- } from "./server-n14edf07.js";
622
+ } from "./server-qa74bj91.js";
744
623
  import {
745
624
  embedPauseBySession,
746
625
  embedRunStateBySession,
@@ -750,27 +629,8 @@ import {
750
629
  autoEmbedRetryAfterBySession,
751
630
  invalidateAutoEmbedSession,
752
631
  getEmbedDrainUiStatus,
753
- clearEmbedSessionState,
754
- describeShadowBackfillWriteRefusal2,
755
- retainProjectEmbedding2,
756
- markProjectLoadUntrusted2,
757
- drainProjectEmbeddingIdentityMaintenance2,
758
- drainStaleEmbeddingIdentitiesForProject2,
759
- registerProjectEmbedding2,
760
- registerProjectShadowEmbedding2,
761
- enqueueShadowEmbeddingItems2,
762
- registerProjectInObservationMode2,
763
- unregisterProjectShadowEmbedding2,
764
- getProjectEmbeddingSnapshot2,
765
- embedTextForProject2,
766
- embedBatchForProject2,
767
- embedUnembeddedMemoriesForProject2,
768
- embedUnembeddedMemoriesForProjectOutcome2,
769
- drainCommitBacklogForProject2,
770
- embedSessionCompartmentChunks2,
771
- getEmbeddingCoverageStatus2,
772
- getAutoEmbeddingSessionCoverage2
773
- } from "./server-ab8017gw.js";
632
+ clearEmbedSessionState
633
+ } from "./server-2amn2s73.js";
774
634
  import {
775
635
  SubcClient,
776
636
  connectionFileExists,
@@ -778,17 +638,137 @@ import {
778
638
  toSynapseLaneDescriptor,
779
639
  formatSynapseLaneDescriptor,
780
640
  SynapseEmbeddingProvider
781
- } from "./server-ab1g0wn9.js";
641
+ } from "./server-zzgtgqmd.js";
782
642
  import {
783
643
  deleteChunkEmbedBackoffForSession2
784
- } from "./server-h1byrhwx.js";
644
+ } from "./server-hsf0qsn5.js";
785
645
  import {
786
646
  registerOwnRpcServerInstance,
787
647
  rpcPortDir,
788
648
  rpcPortFilePath,
789
649
  parseRpcPortFile,
790
650
  inspectProcessesAsync
791
- } from "./server-k3t06fxr.js";
651
+ } from "./server-sefxj8k1.js";
652
+ import {
653
+ acquireCompartmentLease,
654
+ releaseCompartmentLeaseBestEffort,
655
+ isCompartmentLeaseHeld,
656
+ queueM0Mutation,
657
+ getMaxM0MutationId,
658
+ getLastCompartmentEndMessage,
659
+ getLastCompartmentEndMessageId,
660
+ getUncoveredCompartmentEndsThrough,
661
+ providerResponseFailed,
662
+ isSuccessfulProviderCompletion,
663
+ LkgRecoveryFenceError,
664
+ lkgServedArrayDigest,
665
+ hasCleanLkgRecoveryFence,
666
+ dirtyLkgRecoveryRevision,
667
+ ownsLkgDirtyFence,
668
+ invalidateCleanLkgRecoveryFence,
669
+ prepareLkgCaptureFence,
670
+ certifyCommittedLkgCapture,
671
+ markLkgRecoveryDirty,
672
+ rememberUnpublishedAutoSearchNoHint,
673
+ getUnpublishedAutoSearchNoHint,
674
+ forgetUnpublishedAutoSearchNoHint,
675
+ registerAutoSearchWork,
676
+ advanceSessionActivity,
677
+ backfillSessionActivity,
678
+ readSessionMeta,
679
+ getOrCreateSessionMeta,
680
+ updateSessionMeta,
681
+ advanceToolReclaimWatermark,
682
+ markSessionCleanupPending,
683
+ retryPendingSessionCleanups,
684
+ retryPendingRustSessionCleanupsForProject,
685
+ clearSession,
686
+ requestPendingMaterialization,
687
+ pendingMaterializationOrigin,
688
+ hasPendingMaterializationOrigin,
689
+ clearPendingMaterialization,
690
+ recordSystemPromptForRequest,
691
+ recordHeldHeadForRequest,
692
+ bindSystemPromptResponse,
693
+ isHeldHeadForRequest,
694
+ deferDeliveredSystemRefresh,
695
+ retirePendingSystemPromptDelivery,
696
+ lkgProviderInputTotal,
697
+ beginV2LkgRequest,
698
+ claimLkgRequestIdentity,
699
+ currentLkgRequestIdentity,
700
+ noteCapturedLkgRequest,
701
+ noteLkgProviderResponse,
702
+ measuredLkgPrefix,
703
+ clearLkgMeasuredRequest,
704
+ saveLkgSlotToDb,
705
+ clearPersistedLkgSlotStrict,
706
+ loadPersistedLkgSlot,
707
+ drainStaleLkgSlots,
708
+ resolveLkgModelKeys,
709
+ createLkgEntryProjector,
710
+ captureLkgSlot,
711
+ validateAnthropicReasoningRuns,
712
+ validateLkgSeam,
713
+ replayLkg,
714
+ coldStartRawServedIndex,
715
+ coldStartUncapturedReplay,
716
+ noteUncertifiedNormalLkg,
717
+ hasProcessLocalLkgProof,
718
+ lkgDirtyRevision,
719
+ rememberLkgDirtyRevision,
720
+ readPersistedLkgUntaggedInputIds,
721
+ persistLkgUntaggedInputIds,
722
+ noteLkgRecoveryPrefix,
723
+ readLkgRecoveryPrefix,
724
+ noteLkgHealthyPrefix,
725
+ lkgRecoveryReplayUnproven,
726
+ lkgRecoveryEntryUnproven,
727
+ lkgInputIdentity,
728
+ beginLkgPass,
729
+ visitMessageContentFields,
730
+ contentSnapshotValue,
731
+ messageContentFields,
732
+ signatureForFields,
733
+ exactReusablePrefix,
734
+ incrementalLkgContentDigests,
735
+ lkgSlotRejection,
736
+ captureSlot,
737
+ getInMemorySlot,
738
+ getSlot,
739
+ forgetInMemorySlot,
740
+ dropSlot,
741
+ noteEntry,
742
+ getLkgSlotHeapStats,
743
+ TOOL_SWEEP_SCOPED_MARKER,
744
+ useScopedToolSweep,
745
+ createPreAdoptionToolSweepResolver,
746
+ copySessionStateForClone,
747
+ queueMemoryMutation,
748
+ getMaxMemoryMutationIdForProjects,
749
+ GLOBAL_USER_PROFILE_PROJECT_PATH,
750
+ getProjectState,
751
+ bumpProjectUserProfileVersion,
752
+ saveSourceContent,
753
+ replaceSourceContent,
754
+ getSourceContents
755
+ } from "./server-qf2kzsh2.js";
756
+ import {
757
+ startBootDeadline,
758
+ getUnconfirmedMigrationHolders,
759
+ getSchemaFenceRejection,
760
+ getMigrationOnOpenRefusal,
761
+ LATEST_SUPPORTED_VERSION,
762
+ BOOT_SQLITE_BUSY_TIMEOUT_MS,
763
+ getDatabasePath,
764
+ getPersistedSchemaVersion,
765
+ runSqliteOptimize,
766
+ openDatabase,
767
+ openCurrentDatabase,
768
+ openDatabaseAsync,
769
+ isDatabasePersisted,
770
+ getDatabasePersistenceError
771
+ } from "./server-7ccxt4nq.js";
792
772
  import {
793
773
  V2_MEMORY_CATEGORIES,
794
774
  CATEGORY_PRIORITY
@@ -801,7 +781,13 @@ import {
801
781
  resolveStoredPathWorkspaceIdentity,
802
782
  storedPathBelongsToWorkspace,
803
783
  computeWorkspaceEpochFingerprint
804
- } from "./server-6g98c227.js";
784
+ } from "./server-3schkz95.js";
785
+ import {
786
+ gaDatabasePath2,
787
+ RAW_MESSAGE_TYPES2,
788
+ V2StoreReaderPool2,
789
+ V2StoreReader2
790
+ } from "./server-ef1mskas.js";
805
791
  import {
806
792
  configureContextDatabasePragmas2
807
793
  } from "./server-fb3zxn06.js";
@@ -829,36 +815,40 @@ import {
829
815
  getActivePrimers,
830
816
  createPrimer,
831
817
  updatePrimerSupport,
832
- updatePrimerAnswer,
833
- renderUserFacingFailure,
834
- userFacingFailureCode,
835
- renderCapabilityRefusal,
836
- renderDreamFailure,
837
- dreamFailureCode,
838
- renderEmbeddingFailure,
839
- recordMemoryMapping,
840
- recordMemoryVerifications,
841
- getUnmappedMemoryIds,
842
- clearMemoryVerifications,
843
- getMemoryVerifications,
844
- resolveGitTopLevel,
845
- readGitHead,
846
- readGitChangedFilesSince,
847
- readGitFileChangeTimesSince,
848
- verificationFileExists,
849
- normalizeVerificationFiles
850
- } from "./server-tkdabx8q.js";
818
+ updatePrimerAnswer
819
+ } from "./server-ypf1ap0v.js";
851
820
  import {
852
821
  deriveTriggerBudget2,
853
822
  deriveHistorianChunkTokens2,
854
823
  resolveKnownHistorianContextLimit2,
855
824
  resolveHistorianProducerLimits2,
856
825
  resolveHistorianContextLimit2
857
- } from "./server-53eh1r8r.js";
858
- import"./server-806rzhs6.js";
826
+ } from "./server-sd8hvzte.js";
827
+ import"./server-xbtw0p9t.js";
859
828
  import {
860
829
  isEmbeddingHostBusy2
861
830
  } from "./server-qt1qqasc.js";
831
+ import {
832
+ describeShadowBackfillWriteRefusal2,
833
+ retainProjectEmbedding2,
834
+ markProjectLoadUntrusted2,
835
+ drainProjectEmbeddingIdentityMaintenance2,
836
+ drainStaleEmbeddingIdentitiesForProject2,
837
+ registerProjectEmbedding2,
838
+ registerProjectShadowEmbedding2,
839
+ enqueueShadowEmbeddingItems2,
840
+ registerProjectInObservationMode2,
841
+ unregisterProjectShadowEmbedding2,
842
+ getProjectEmbeddingSnapshot2,
843
+ embedTextForProject2,
844
+ embedBatchForProject2,
845
+ embedUnembeddedMemoriesForProject2,
846
+ embedUnembeddedMemoriesForProjectOutcome2,
847
+ drainCommitBacklogForProject2,
848
+ embedSessionCompartmentChunks2,
849
+ getEmbeddingCoverageStatus2,
850
+ getAutoEmbeddingSessionCoverage2
851
+ } from "./server-bxpz2dcn.js";
862
852
  import {
863
853
  GIT_SWEEP_LEASE_RENEWAL_MS,
864
854
  acquireGitSweepLease,
@@ -868,7 +858,7 @@ import {
868
858
  releaseGitSweepLease,
869
859
  recordSessionProjectIdentity,
870
860
  hasRecordedSessionProjectIdentity
871
- } from "./server-bsgd4dk1.js";
861
+ } from "./server-dcws5831.js";
872
862
  import {
873
863
  saveEmbeddingIfHashMatches,
874
864
  invalidateProject2,
@@ -878,10 +868,10 @@ import {
878
868
  getCachedLocalEmbeddingPooling,
879
869
  preflightLocalEmbeddingPooling,
880
870
  getLocalEmbeddingNativeMemoryStats
881
- } from "./server-vr4szghm.js";
871
+ } from "./server-rktnzs89.js";
882
872
  import {
883
873
  cosineSimilarity
884
- } from "./server-2aasmpsp.js";
874
+ } from "./server-kkxzwa6w.js";
885
875
  import {
886
876
  computeCueContentHash,
887
877
  hasMuralCueColumns,
@@ -907,6 +897,25 @@ import {
907
897
  archiveMemory2,
908
898
  getMemoryCountsByStatus2
909
899
  } from "./server-jjvbk92s.js";
900
+ import {
901
+ renderUserFacingFailure,
902
+ userFacingFailureCode,
903
+ renderCapabilityRefusal,
904
+ renderDreamFailure,
905
+ dreamFailureCode,
906
+ renderEmbeddingFailure,
907
+ recordMemoryMapping,
908
+ recordMemoryVerifications,
909
+ getUnmappedMemoryIds,
910
+ clearMemoryVerifications,
911
+ getMemoryVerifications,
912
+ resolveGitTopLevel,
913
+ readGitHead,
914
+ readGitChangedFilesSince,
915
+ readGitFileChangeTimesSince,
916
+ verificationFileExists,
917
+ normalizeVerificationFiles
918
+ } from "./server-q0z2q2dx.js";
910
919
  import {
911
920
  registerNotificationSink2,
912
921
  pushNotification2,
@@ -914,18 +923,49 @@ import {
914
923
  drainNotifications2,
915
924
  isTuiConnected2
916
925
  } from "./server-x8a7jmkh.js";
917
- import"./server-1bw1wcbp.js";
926
+ import"./server-f0j864ma.js";
918
927
  import {
919
928
  flushIgnoredMessages2,
920
929
  sendStatusNotification2
921
- } from "./server-qc915kw2.js";
930
+ } from "./server-bez34e60.js";
931
+ import {
932
+ isToolError,
933
+ toolErrorText,
934
+ toolStateContent,
935
+ STORAGE_NOTICE_PREFIX,
936
+ formatStorageRefusalNotice,
937
+ formatStorageRecoveryNotice,
938
+ hasStorageNoticeShape,
939
+ dropStorageNotices,
940
+ restoreRow,
941
+ servedBoundaryRow2,
942
+ resolveV2BoundaryUserMessage2,
943
+ readAllV2RawMessagesForConversion2,
944
+ readV2RawMessagePagesForConversion2,
945
+ createV2RawMessageReader2,
946
+ createV2RawMessageProvider2
947
+ } from "./server-5jp38p98.js";
922
948
  import {
923
949
  resolvePromptContext2
924
950
  } from "./server-fmsr7v69.js";
951
+ import {
952
+ renderMessageByOrdinal2,
953
+ renderVerboseRangeForTool2,
954
+ renderItemByTag2
955
+ } from "./server-55v5hpth.js";
925
956
  import"./server-kaqs6h31.js";
957
+ import {
958
+ readV2ArchiveOffThread2
959
+ } from "./server-x4m6xcn4.js";
926
960
  import {
927
961
  renderSearchArchiveOffThread2
928
- } from "./server-rr4cbkr0.js";
962
+ } from "./server-hnknwaz8.js";
963
+ import {
964
+ markCoveredInstructionRow,
965
+ isCoveredInstructionRow,
966
+ takeCoveredInstructionRows,
967
+ cloneKeepingCoveredInstructionMarks
968
+ } from "./server-z9zygwse.js";
929
969
  import {
930
970
  compareSemverCore
931
971
  } from "./server-84w6rvvf.js";
@@ -965,7 +1005,7 @@ import {
965
1005
  } from "./server-8ajstryz.js";
966
1006
  import {
967
1007
  logSlowWriteTransaction
968
- } from "./server-gyy4k6mf.js";
1008
+ } from "./server-qmmkhz2z.js";
969
1009
  import {
970
1010
  shouldEnforcePrivateStoragePermissions,
971
1011
  ensureStorageDirectorySync,
@@ -1143,7 +1183,7 @@ __export(exports_external, {
1143
1183
  nullable: () => nullable,
1144
1184
  nullish: () => nullish2,
1145
1185
  number: () => number2,
1146
- object: () => object,
1186
+ object: () => object2,
1147
1187
  optional: () => optional,
1148
1188
  overwrite: () => _overwrite,
1149
1189
  parse: () => parse3,
@@ -1846,13 +1886,19 @@ function modelMatchedPersistedUsage(db, sessionID, modelKey) {
1846
1886
  return;
1847
1887
  }
1848
1888
  function modelMatchedProvenContextLimit(db, sessionID, modelKey) {
1849
- const persisted = modelMatchedPersistedUsage(db, sessionID, modelKey);
1850
- return isSaneLimit(persisted?.observedSafeInputTokens) ? persisted.observedSafeInputTokens : undefined;
1889
+ if (!db || !sessionID || !modelKey)
1890
+ return;
1891
+ try {
1892
+ const provenLimit = resolveOpenCodeProvenInputFloor(db, sessionID, modelKey);
1893
+ return isSaneLimit(provenLimit) ? provenLimit : undefined;
1894
+ } catch {
1895
+ return;
1896
+ }
1851
1897
  }
1852
- function applySessionProvenFloor(geometry, persisted, ctx) {
1853
- const provenLimit = isSaneLimit(persisted?.observedSafeInputTokens) ? persisted.observedSafeInputTokens : undefined;
1898
+ function applySessionProvenFloor(geometry, provenLimit, ctx) {
1854
1899
  const result = applyProvenInputFloor(geometry, provenLimit);
1855
1900
  if (result.refused && ctx?.db && ctx.sessionID) {
1901
+ const persisted = loadPersistedUsage(ctx.db, ctx.sessionID);
1856
1902
  const impossiblePressure = persisted?.usage.inputTokens ? persisted.usage.inputTokens > result.refused.absoluteWall : false;
1857
1903
  updateSessionMeta(ctx.db, ctx.sessionID, {
1858
1904
  observedSafeInputTokens: 0,
@@ -1886,7 +1932,7 @@ function resolveContextWindowGeometry(providerID, modelID, ctx) {
1886
1932
  });
1887
1933
  if (!geometry || detected !== undefined)
1888
1934
  return geometry;
1889
- return applySessionProvenFloor(geometry, modelMatchedPersistedUsage(ctx?.db, ctx?.sessionID, modelKey), ctx);
1935
+ return applySessionProvenFloor(geometry, modelMatchedProvenContextLimit(ctx?.db, ctx?.sessionID, modelKey), ctx);
1890
1936
  }
1891
1937
  function resolveContextLimit(providerID, modelID, ctx) {
1892
1938
  const modelKey = resolveModelKey(providerID, modelID);
@@ -4004,6 +4050,32 @@ function selectAutoSearchResults(results, threshold) {
4004
4050
  return results.filter((result) => relevance(result) >= threshold).sort((left, right) => relevance(right) - relevance(left));
4005
4051
  }
4006
4052
 
4053
+ // src/hooks/magic-context/auto-search-observation.ts
4054
+ var disabledTurns = new WeakMap;
4055
+ function logDisabledAutoSearch(db, sessionId, messageId, threshold, startedAt) {
4056
+ const sessions = disabledTurns.get(db) ?? new Map;
4057
+ disabledTurns.set(db, sessions);
4058
+ if (sessions.get(sessionId) === messageId)
4059
+ return;
4060
+ sessions.set(sessionId, messageId);
4061
+ observeAutoSearch(sessionId, threshold, startedAt).finish("disabled");
4062
+ }
4063
+ function observeAutoSearch(sessionId, threshold, startedAt) {
4064
+ const diagnostics = createAutoSearchDiagnostics(threshold);
4065
+ let logged = false;
4066
+ return {
4067
+ diagnostics,
4068
+ finish(outcome, reason) {
4069
+ if (logged)
4070
+ return;
4071
+ logged = true;
4072
+ const lanes = Object.entries(diagnostics.lanes).map(([lane, value]) => `${lane}:${value.top?.toFixed(3) ?? "none"}`).join(",");
4073
+ const nearMisses = Object.values(diagnostics.lanes).reduce((sum, lane) => sum + lane.nearMisses, 0);
4074
+ sessionLog2(sessionId, `auto-search: decision outcome=${outcome}${reason ? ` reason=${reason}` : ""} lanes=${lanes || "none"} nearMisses=${nearMisses} threshold=${threshold} pool=${diagnostics.pool} rows=${diagnostics.poolRows ?? "unknown"} workerStarted=${diagnostics.workerStarted ?? "unknown"} peek=${diagnostics.peek} elapsedMs=${Math.round(performance.now() - startedAt)}`);
4075
+ }
4076
+ };
4077
+ }
4078
+
4007
4079
  // src/hooks/magic-context/auto-search-worker-client.ts
4008
4080
  import { Worker } from "node:worker_threads";
4009
4081
  var pendingRegistrations = new WeakMap;
@@ -4241,6 +4313,7 @@ async function executeAutoSearchWorker(db, sessionId, projectPath, query, option
4241
4313
  readMessages: _readMessages,
4242
4314
  searchMessageHistory: _searchMessageHistory,
4243
4315
  stepTimings: _stepTimings,
4316
+ onAutoSearchDiagnostics: _onAutoSearchDiagnostics,
4244
4317
  ...serializable
4245
4318
  } = options;
4246
4319
  const lifecycle = registerAutoSearchWork(sessionId);
@@ -4282,6 +4355,11 @@ async function executeAutoSearchWorker(db, sessionId, projectPath, query, option
4282
4355
  throw new AutoSearchBusyError;
4283
4356
  }
4284
4357
  const { slot, fresh } = lease;
4358
+ if (options.autoSearchDiagnostics) {
4359
+ options.autoSearchDiagnostics.workerStarted = fresh;
4360
+ if (fresh)
4361
+ options.autoSearchDiagnostics.pool = "cold";
4362
+ }
4285
4363
  const worker = slot.worker;
4286
4364
  const detachable = job === "search" && entry.href === defaultAutoSearchWorkerEntry().href;
4287
4365
  const startedAt = performance.now();
@@ -4361,6 +4439,15 @@ async function executeAutoSearchWorker(db, sessionId, projectPath, query, option
4361
4439
  const onMessage = async (reply) => {
4362
4440
  if (released)
4363
4441
  return;
4442
+ if (reply.kind === "diagnostics") {
4443
+ if (!settled && options.autoSearchDiagnostics) {
4444
+ const workerStarted = options.autoSearchDiagnostics.workerStarted;
4445
+ Object.assign(options.autoSearchDiagnostics, reply.diagnostics, {
4446
+ workerStarted
4447
+ });
4448
+ }
4449
+ return;
4450
+ }
4364
4451
  if (reply.kind === "result" || reply.kind === "error") {
4365
4452
  if (detachedAt !== undefined) {
4366
4453
  logLateSearch(sessionId, performance.now() - detachedAt, detachedAt - startedAt, ownerVectorMs, reply.kind === "result" ? reply.timings : undefined, reply.kind === "error");
@@ -4696,8 +4783,12 @@ function findLatestMeaningfulUserMessage(messages) {
4696
4783
  async function runAutoSearchHint(args) {
4697
4784
  const startedAt = performance.now();
4698
4785
  const { sessionId, db, messages, options } = args;
4699
- if (!options.enabled)
4786
+ if (!options.enabled) {
4787
+ const tail = findLatestMeaningfulUserMessage(messages);
4788
+ if (tail && typeof tail.info.id === "string" && messages.at(-1) === tail)
4789
+ logDisabledAutoSearch(db, sessionId, tail.info.id, options.scoreThreshold, startedAt);
4700
4790
  return AUTO_SEARCH_OK;
4791
+ }
4701
4792
  const userMsg = findLatestMeaningfulUserMessage(messages);
4702
4793
  if (!userMsg || typeof userMsg.info.id !== "string")
4703
4794
  return AUTO_SEARCH_OK;
@@ -4721,10 +4812,12 @@ async function runAutoSearchHint(args) {
4721
4812
  if (messages.length === 0 || messages[messages.length - 1].info.id !== userMsgId) {
4722
4813
  return AUTO_SEARCH_OK;
4723
4814
  }
4815
+ const observation = observeAutoSearch(sessionId, options.scoreThreshold, startedAt);
4724
4816
  const embeddingSnapshot = getProjectEmbeddingSnapshot2(options.projectPath);
4725
4817
  if (!embeddingSnapshot) {
4726
4818
  queueAutoSearchRegistration(db, options.projectPath, options.directory && options.ensureProjectRegistered ? () => options.ensureProjectRegistered?.(options.directory, db) ?? Promise.resolve() : undefined);
4727
4819
  persistAutoSearchSkip(db, sessionId, userMsgId, "empty");
4820
+ observation.finish("no-candidates", "unregistered");
4728
4821
  return AUTO_SEARCH_OK;
4729
4822
  }
4730
4823
  const writeNoHintAndReconcile = async (reason) => {
@@ -4735,21 +4828,24 @@ async function runAutoSearchHint(args) {
4735
4828
  }, startedAt);
4736
4829
  if (outcome === null) {
4737
4830
  persistAutoSearchSkip(db, sessionId, userMsgId);
4831
+ observation.finish("timeout");
4738
4832
  return { ok: false, kind: "timeout" };
4739
4833
  }
4740
- if (!outcome.ok)
4834
+ if (!outcome.ok) {
4835
+ observation.finish("error", outcome.kind);
4741
4836
  return {
4742
4837
  ok: false,
4743
4838
  kind: outcome.kind === "storage-busy" ? "storage-busy" : "cas-exhaustion"
4744
4839
  };
4840
+ }
4745
4841
  if (outcome.kind === "already-present" && outcome.decision.decision === "hint") {
4746
4842
  appendReminderToUserMessageById(messages, userMsgId, outcome.decision.text);
4747
4843
  }
4844
+ observation.finish(outcome.decision.decision === "hint" ? "attached" : reason === "below-threshold" ? "below-threshold" : reason === "error" ? "error" : "no-candidates", reason);
4748
4845
  return AUTO_SEARCH_OK;
4749
4846
  };
4750
4847
  const rawPartsText = collectUserPromptParts(userMsg);
4751
4848
  if (hasStackedAugmentation(rawPartsText)) {
4752
- sessionLog2(sessionId, "auto-search: skipping — user message already carries augmentation/hint");
4753
4849
  return writeNoHintAndReconcile("stacked");
4754
4850
  }
4755
4851
  const rawPrompt = extractUserPromptText(userMsg);
@@ -4765,6 +4861,7 @@ async function runAutoSearchHint(args) {
4765
4861
  const embeddingEnabled = embeddingSnapshot ? embeddingSnapshot.historyEnabled : options.embeddingEnabled;
4766
4862
  const gitCommitsEnabled = embeddingSnapshot?.gitCommitEnabled ?? options.gitCommitsEnabled ?? false;
4767
4863
  const searchOptions = {
4864
+ autoSearchDiagnostics: observation.diagnostics,
4768
4865
  limit: 10,
4769
4866
  maxMessageOrdinal: Math.max(0, getLastCompartmentEndMessage(db, sessionId)),
4770
4867
  excludeMessageId: userMsgId,
@@ -4791,11 +4888,10 @@ async function runAutoSearchHint(args) {
4791
4888
  if (lifecycleSignal.aborted)
4792
4889
  return AUTO_SEARCH_OK;
4793
4890
  if (error instanceof AutoSearchBusyError) {
4794
- sessionLog2(sessionId, "auto-search: an earlier search of this session is still running, skipping hint for this turn");
4891
+ observation.finish("timeout", "worker-busy");
4795
4892
  persistAutoSearchSkip(db, sessionId, userMsgId);
4796
4893
  return { ok: false, kind: "timeout" };
4797
4894
  }
4798
- log2(`[auto-search] unified search failed for session ${sessionId} (no-hint frozen for this turn): ${error instanceof Error ? error.message : String(error)}`);
4799
4895
  const outcome = await writeNoHintAndReconcile("error");
4800
4896
  return outcome.ok ? { ok: false, kind: "search-failure" } : outcome;
4801
4897
  }
@@ -4803,9 +4899,8 @@ async function runAutoSearchHint(args) {
4803
4899
  return AUTO_SEARCH_OK;
4804
4900
  try {
4805
4901
  if (results === null) {
4806
- sessionLog2(sessionId, `auto-search: timed out after ${AUTO_SEARCH_TIMEOUT_MS}ms, skipping hint for this turn`);
4902
+ observation.finish("timeout");
4807
4903
  persistAutoSearchSkip(db, sessionId, userMsgId);
4808
- sessionLog2(sessionId, "auto-search: skip frozen; retries for this turn are replay-only");
4809
4904
  return { ok: false, kind: "timeout" };
4810
4905
  }
4811
4906
  if (results.length === 0) {
@@ -4813,7 +4908,6 @@ async function runAutoSearchHint(args) {
4813
4908
  }
4814
4909
  results = selectAutoSearchResults(results, options.scoreThreshold);
4815
4910
  if (results.length === 0) {
4816
- sessionLog2(sessionId, `auto-search: no fragment meets relevance threshold ${options.scoreThreshold}`);
4817
4911
  return writeNoHintAndReconcile("below-threshold");
4818
4912
  }
4819
4913
  const hintText = buildAutoSearchHint(results, {
@@ -4833,18 +4927,19 @@ ${hintText}`;
4833
4927
  }, startedAt);
4834
4928
  if (outcome === null) {
4835
4929
  persistAutoSearchSkip(db, sessionId, userMsgId);
4930
+ observation.finish("timeout");
4836
4931
  return { ok: false, kind: "timeout" };
4837
4932
  }
4838
4933
  if (!outcome.ok) {
4934
+ observation.finish("error", outcome.kind);
4839
4935
  if (outcome.kind === "storage-busy")
4840
4936
  return { ok: false, kind: "storage-busy" };
4841
- sessionLog2(sessionId, `auto-search: CAS exhausted for ${userMsgId}; skipping wire append`);
4842
4937
  return { ok: false, kind: "cas-exhaustion" };
4843
4938
  }
4844
4939
  if (outcome.decision.decision === "hint") {
4845
4940
  appendReminderToUserMessageById(messages, userMsgId, outcome.decision.text);
4846
4941
  }
4847
- sessionLog2(sessionId, `auto-search: attached hint to ${userMsgId} (${results.length} fragments, top relevance ${(results[0].relevanceScore ?? results[0].score).toFixed(3)})`);
4942
+ observation.finish(outcome.decision.decision === "hint" ? "attached" : "no-candidates");
4848
4943
  return AUTO_SEARCH_OK;
4849
4944
  } finally {
4850
4945
  if (!lifecycleSignal.aborted && results !== null)
@@ -7490,6 +7585,50 @@ function renderConvertedToolSkeletons(targets, converted) {
7490
7585
  }
7491
7586
  return didMutate;
7492
7587
  }
7588
+ function prepareAgedToolSkeletonConversions(db, sessionId, targets, options = {}) {
7589
+ const candidates = [...targets.keys()].sort((a, b) => a - b);
7590
+ const readRows = (connection) => {
7591
+ const window = getNewestToolTagNumbers2(connection, sessionId, RECENT_TOOL_SKELETON_WINDOW);
7592
+ const recent = new Set(window);
7593
+ const statement = connection.prepare(`SELECT tag_number AS tagNumber, drop_mode AS dropMode, message_id AS callId
7594
+ FROM tags WHERE session_id = ? AND tag_number = ?
7595
+ AND type = 'tool' AND status = 'dropped'
7596
+ AND drop_mode IN ('truncated', 'skeleton_real', 'skeleton_stripped')`);
7597
+ const rows = candidates.filter((id) => !recent.has(id)).flatMap((id) => {
7598
+ const row = statement.get(sessionId, id);
7599
+ return row ? [row] : [];
7600
+ });
7601
+ return { window, rows };
7602
+ };
7603
+ const snapshot = readRows(db);
7604
+ options.prepareRemovals?.(snapshot.rows);
7605
+ const converted = new Map;
7606
+ const plannedRemovals = new Set;
7607
+ for (const row of snapshot.rows) {
7608
+ const target = targets.get(row.tagNumber);
7609
+ if (target?.thinkingDropProtected || target?.thinkingRewriteProtected || target?.identityRepairProtected)
7610
+ continue;
7611
+ if (target?.canDrop?.() !== true || target.prepareDrop?.() === false)
7612
+ continue;
7613
+ if (target.requiresToolArcSkeleton) {
7614
+ const owners = target.mutationParts ? target.mutationParts.map(({ message }) => message).filter((message) => message.info.role === "assistant") : target.message ? [target.message] : [];
7615
+ if (owners.length === 0 || owners.some((message) => !options.thinkingStrippedIds?.has(message.info.id ?? "")))
7616
+ continue;
7617
+ }
7618
+ if (target.cannotRemove?.() === true || target.wouldStrandConversationEnd?.(plannedRemovals) === true)
7619
+ continue;
7620
+ converted.set(row.tagNumber, "full");
7621
+ target.notePlannedRemoval?.(plannedRemovals);
7622
+ }
7623
+ return {
7624
+ converted,
7625
+ isCurrent: (connection) => JSON.stringify(readRows(connection)) === JSON.stringify(snapshot),
7626
+ persist: (connection) => {
7627
+ for (const tagNumber of converted.keys())
7628
+ updateTagDropMode2(connection, sessionId, tagNumber, "full");
7629
+ }
7630
+ };
7631
+ }
7493
7632
  var PENDING_OPERATION_CHUNK_SIZE = 64;
7494
7633
  function applyPendingOperations(sessionId, db, targets, protectedTagIds, preloadedTags, preloadedPendingOps, syntheticPendingOps = [], editMarkerTagIds = new Set, onTagReduced, onBatchComplete, onEligibilitySnapshot) {
7495
7634
  let didMutateMessage = false;
@@ -10994,6 +11133,20 @@ async function runPostTransformPhase(args) {
10994
11133
  }
10995
11134
  }
10996
11135
  }
11136
+ if (!args.fullFeatureMode && canEditWholePrefix && !compactionOff) {
11137
+ const thinkingStrippedIds = new Set([...bindingThinking, ...removedReasoningIds]);
11138
+ for (const id of getMergedReasoningStrippedIds(args.db, args.sessionId)) {
11139
+ if (id.startsWith(THINKING_BINDING_RECOVERY_FROZEN_PREFIX))
11140
+ thinkingStrippedIds.add(id.slice(THINKING_BINDING_RECOVERY_FROZEN_PREFIX.length));
11141
+ }
11142
+ const conversions = prepareAgedToolSkeletonConversions(args.db, args.sessionId, newTargets, { thinkingStrippedIds });
11143
+ args.db.transaction(() => {
11144
+ if (!conversions.isCurrent(args.db))
11145
+ throw new Error("Subagent skeleton candidates changed before commit");
11146
+ conversions.persist(args.db);
11147
+ }).immediate();
11148
+ convertedToolSkeletonsDidMutate = renderConvertedToolSkeletons(newTargets, conversions.converted) || convertedToolSkeletonsDidMutate;
11149
+ }
10997
11150
  const tBatchFinalize = performance.now();
10998
11151
  args.batch?.finalize();
10999
11152
  if (toolReclaimApplicationOpportunity) {
@@ -11404,6 +11557,18 @@ async function runPostTransformPhase(args) {
11404
11557
  }
11405
11558
  autoSearchHintAppendedThisPass = autoSearchCompletedThisPass && countAutoSearchHints(args.db, args.sessionId) !== autoSearchHintsBefore;
11406
11559
  logTransformTiming(args.sessionId, "pp.autoSearchHint", tAutoSearch);
11560
+ } else if (args.fullFeatureMode && args.autoSearch && !args.autoSearch.enabled && args.projectPath) {
11561
+ await runAutoSearchHint({
11562
+ sessionId: args.sessionId,
11563
+ db: args.db,
11564
+ messages: args.messages,
11565
+ options: {
11566
+ enabled: false,
11567
+ scoreThreshold: args.autoSearch.scoreThreshold,
11568
+ minPromptChars: args.autoSearch.minPromptChars,
11569
+ projectPath: args.projectPath
11570
+ }
11571
+ });
11407
11572
  }
11408
11573
  if (args.fullFeatureMode && canEditWholePrefix) {
11409
11574
  const visibleIds = new Set;
@@ -18926,7 +19091,7 @@ async function runCompartmentPhaseImpl(args) {
18926
19091
  awaitedCompartmentRun = true;
18927
19092
  compartmentInProgress = false;
18928
19093
  } else {
18929
- sessionLog2(args.sessionId, "transform: proceeding after 95% timeout — historian still running in background");
19094
+ sessionLog2(args.sessionId, "transform: historian join timed out — reclaim and final fit checks continue; historian keeps running in the background");
18930
19095
  }
18931
19096
  }
18932
19097
  }
@@ -20205,6 +20370,7 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
20205
20370
  postTransformResult.bustedThisPass = true;
20206
20371
  passOutcome.markFinalized();
20207
20372
  const finalWireTail = describeFinalWireTail(messages);
20373
+ const logIncompleteFinalWire = createFinalWireIncompleteLogger(sessionId);
20208
20374
  const signedFitPreviouslyRefused = !compactionOff && activeThinkingPrefixHold && getMergedReasoningStrippedIds(db, sessionId).has(SIGNED_FIT_REFUSED_MARKER);
20209
20375
  let finalWireEstimate;
20210
20376
  if (postTransformResult.bustedThisPass) {
@@ -20234,6 +20400,7 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
20234
20400
  systemPromptHash: sessionMeta.systemPromptHash
20235
20401
  }, boundaryContextLimit) : undefined);
20236
20402
  if (finalWireEstimate) {
20403
+ logIncompleteFinalWire(finalWireEstimate, messages);
20237
20404
  sessionLog2(sessionId, `transform: final-wire telemetry estimate=${finalWireEstimate.tokens} trusted=${finalWireEstimate.trusted} conversation=${finalWireEstimate.messageTokens.conversation} tools=${finalWireEstimate.messageTokens.toolCall} system=${finalWireEstimate.systemTokens} toolDefinitions=${finalWireEstimate.toolDefinitionTokens ?? "unknown"} tail=${finalWireTail}`);
20238
20405
  }
20239
20406
  if ((finalWireEstimate?.refusalGrade || finalWireEstimate?.refusalBasis === "byte-bound" && finalWireEstimate.refusalTokens !== undefined) && boundaryContextLimit > 0 && (finalWireEstimate.refusalTokens ?? finalWireEstimate.tokens) > boundaryContextLimit) {
@@ -20372,6 +20539,7 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
20372
20539
  }
20373
20540
  }
20374
20541
  }
20542
+ logIncompleteFinalWire(finalWireEstimate, messages);
20375
20543
  if (!finalWireEstimate) {
20376
20544
  sessionLog2(sessionId, `transform: final-wire telemetry estimate=unavailable trusted=false conversation=unknown tools=unknown system=unknown toolDefinitions=unknown tail=${finalWireTail}`);
20377
20545
  }
@@ -23784,7 +23952,7 @@ function registerRpcHandlers(rpcServer, args) {
23784
23952
  return { count: buildCompartmentCount(db, sessionId, moduleStatus) };
23785
23953
  });
23786
23954
  const buildManagedCtx = async (db) => {
23787
- const { deriveHistorianChunkTokens, resolveHistorianContextLimit } = await importPluginModule(() => import("./derive-budgets-knf763tt.js"));
23955
+ const { deriveHistorianChunkTokens, resolveHistorianContextLimit } = await importPluginModule(() => import("./derive-budgets-sa0v7bz0.js"));
23788
23956
  const { resolveHistorianModel } = await importPluginModule(() => import("./model-resolution-280gmqvd.js"));
23789
23957
  const { userObservationCollectionEnabled, userObservationsRequested } = await importPluginModule(() => import("./task-config-7md27rx8.js"));
23790
23958
  const DEFAULT_HISTORIAN_TIMEOUT_MS = 10 * 60 * 1000;
@@ -23817,7 +23985,7 @@ function registerRpcHandlers(rpcServer, args) {
23817
23985
  return { ok: false, error: "no session" };
23818
23986
  const readDirectory = args.readSessionDirectory;
23819
23987
  if (readDirectory) {
23820
- const { handoffHistoryWork } = await import("./history-owner-ad0crnrn.js");
23988
+ const { handoffHistoryWork } = await import("./history-owner-fpka43cn.js");
23821
23989
  const handed = await handoffHistoryWork({
23822
23990
  storageDir: args.storageDir ?? getMagicContextStorageDir(),
23823
23991
  directory,
@@ -23836,8 +24004,8 @@ function registerRpcHandlers(rpcServer, args) {
23836
24004
  const db = readDatabase();
23837
24005
  if (!db)
23838
24006
  return { ok: false, error: "db unavailable" };
23839
- const { runManagedRecomp } = await importPluginModule(() => import("./recomp-orchestrator-qfqdvbta.js"));
23840
- const { sendIgnoredMessage } = await importPluginModule(() => import("./send-session-notification-x5nzy34v.js"));
24007
+ const { runManagedRecomp } = await importPluginModule(() => import("./recomp-orchestrator-fcnjref7.js"));
24008
+ const { sendIgnoredMessage } = await importPluginModule(() => import("./send-session-notification-fst6hkg7.js"));
23841
24009
  log2(`[rpc] recomp requested for session ${sessionId}`);
23842
24010
  if (!args.client && !args.hiddenCompletionExecutor) {
23843
24011
  return {
@@ -23895,7 +24063,7 @@ function registerRpcHandlers(rpcServer, args) {
23895
24063
  rpcServer.handle("wrapup", async (params) => {
23896
24064
  const readDirectory = args.readSessionDirectory;
23897
24065
  if (readDirectory && params.sessionId) {
23898
- const { handoffHistoryWork } = await import("./history-owner-ad0crnrn.js");
24066
+ const { handoffHistoryWork } = await import("./history-owner-fpka43cn.js");
23899
24067
  const sessionId = String(params.sessionId);
23900
24068
  const handed = await handoffHistoryWork({
23901
24069
  storageDir: args.storageDir ?? getMagicContextStorageDir(),
@@ -23921,7 +24089,7 @@ function registerRpcHandlers(rpcServer, args) {
23921
24089
  const db = readDatabase();
23922
24090
  if (!db)
23923
24091
  return { ok: false, error: "db unavailable" };
23924
- const { runManagedWrapup } = await importPluginModule(() => import("./wrapup-orchestrator-ga5vfmwr.js"));
24092
+ const { runManagedWrapup } = await importPluginModule(() => import("./wrapup-orchestrator-aqpqsveg.js"));
23925
24093
  const model = liveSessionState.liveModelBySession.get(sessionId);
23926
24094
  const contextLimit = model ? resolveContextLimit(model.providerID, model.modelID, { db, sessionID: sessionId }) : 128000;
23927
24095
  const ctx = {
@@ -24984,6 +25152,60 @@ function hostMediaFromEncoded(value) {
24984
25152
  return `${first}; ${second}`;
24985
25153
  }
24986
25154
 
25155
+ // src/v2/fold/idle.ts
25156
+ class HostFoldIdle {
25157
+ fold;
25158
+ now;
25159
+ timers;
25160
+ windows = new Map;
25161
+ constructor(fold, now = Date.now, timers = { setTimeout, clearTimeout }) {
25162
+ this.fold = fold;
25163
+ this.now = now;
25164
+ this.timers = timers;
25165
+ }
25166
+ active(sessionID) {
25167
+ const window = this.windows.get(sessionID);
25168
+ if (window?.timer)
25169
+ this.timers.clearTimeout(window.timer);
25170
+ this.windows.delete(sessionID);
25171
+ }
25172
+ idle(sessionID, cacheTtl, lastResponseTime) {
25173
+ this.active(sessionID);
25174
+ let ttl;
25175
+ try {
25176
+ ttl = parseCacheTtl(cacheTtl);
25177
+ } catch {
25178
+ ttl = 5 * 60 * 1000;
25179
+ }
25180
+ if (!Number.isFinite(ttl) || lastResponseTime <= 0)
25181
+ return;
25182
+ const window = { cacheTtl, lastResponseTime };
25183
+ this.windows.set(sessionID, window);
25184
+ const eligible = () => this.windows.get(sessionID) === window && computeHardCacheExpired(window.cacheTtl, window.lastResponseTime, this.now());
25185
+ const wake = () => {
25186
+ if (this.windows.get(sessionID) !== window)
25187
+ return;
25188
+ if (eligible()) {
25189
+ window.timer = undefined;
25190
+ const release = () => {
25191
+ if (this.windows.get(sessionID) === window)
25192
+ this.windows.delete(sessionID);
25193
+ };
25194
+ this.fold(sessionID, eligible).then(release, release);
25195
+ return;
25196
+ }
25197
+ const remaining = Math.max(1, lastResponseTime + ttl - this.now() + 1);
25198
+ window.timer = this.timers.setTimeout(wake, Math.min(remaining, 2147483647));
25199
+ window.timer.unref?.();
25200
+ };
25201
+ wake();
25202
+ }
25203
+ dispose() {
25204
+ for (const sessionID of this.windows.keys())
25205
+ this.active(sessionID);
25206
+ }
25207
+ }
25208
+
24987
25209
  // src/v2/fold/memory-cache.ts
24988
25210
  import { randomUUID as randomUUID4 } from "node:crypto";
24989
25211
 
@@ -25313,39 +25535,6 @@ function nativeFoldCache(db, budget) {
25313
25535
  return new NativeFoldCache(typeof db === "function" ? db : () => db, budget);
25314
25536
  }
25315
25537
 
25316
- // src/v2/tool-result.ts
25317
- function isToolError(part) {
25318
- const result = part.result;
25319
- return part.resultType === "error" || result?.type === "error" || result !== null && typeof result === "object" && "error" in result;
25320
- }
25321
- function toolErrorText(result) {
25322
- const value = result.value === undefined ? result : result.value;
25323
- return typeof value === "string" ? value : JSON.stringify(value);
25324
- }
25325
- function toolStateContent(state) {
25326
- if (typeof state.output === "string")
25327
- return state.output;
25328
- if (state.status === "error")
25329
- return toolErrorText({ error: state.error, content: state.content ?? [] });
25330
- if (typeof state.content === "string")
25331
- return state.content;
25332
- if (!Array.isArray(state.content))
25333
- return "";
25334
- return state.content.map((part) => {
25335
- if (typeof part === "string")
25336
- return part;
25337
- if (!part || typeof part !== "object")
25338
- return "";
25339
- const value = part;
25340
- if (typeof value.text === "string")
25341
- return value.text;
25342
- if (typeof value.value === "string")
25343
- return value.value;
25344
- return "";
25345
- }).filter(Boolean).join(`
25346
- `);
25347
- }
25348
-
25349
25538
  // src/v2/hooks/copied-tag-notation.ts
25350
25539
  function stripCopiedTagNotation(text, acceptsEmpty = true) {
25351
25540
  return text.includes("§") ? stripPersistedAssistantText(text, acceptsEmpty) : text;
@@ -25844,239 +26033,177 @@ function reviveNative(messages) {
25844
26033
  return result;
25845
26034
  }
25846
26035
 
25847
- // src/v2/fold/restore.ts
25848
- import { fileURLToPath as fileURLToPath2 } from "node:url";
26036
+ // src/v2/fold/native-replay-v3.ts
26037
+ var IMPORTED_MC_SUMMARY = "[Compacted by magic-context — session history is managed by the plugin]";
26038
+ var MAX_CONTROL_BYTES = 128 * 1024;
26039
+ var efforts = new Set(["none", "minimal", "low", "medium", "high", "xhigh", "max"]);
25849
26040
 
25850
- // src/v2/hooks/storage-notice.ts
25851
- var STORAGE_NOTICE_PREFIX = "[Magic Context storage notice] ";
25852
- function formatStorageRefusalNotice(reason) {
25853
- return `${STORAGE_NOTICE_PREFIX}This turn was not sent to the model. ${formatFailClosedBlockingSummary(reason)}`;
26041
+ class ControlMetadataUnavailable extends Error {
25854
26042
  }
25855
- function formatStorageRecoveryNotice(hiddenWorkRecovered) {
25856
- return hiddenWorkRecovered ? `${STORAGE_NOTICE_PREFIX}Magic Context storage is available again and turns are sent to the model. The historian and dreamer are running again. Restart OpenCode to enable Magic Context's tools.` : `${STORAGE_NOTICE_PREFIX}Magic Context storage is available again and turns are sent to the model. Restart OpenCode to enable Magic Context's tools, historian and dreamer.`;
25857
- }
25858
- function isStorageNoticeText(text) {
25859
- return typeof text === "string" && text.startsWith(STORAGE_NOTICE_PREFIX);
26043
+ var object = (value) => !!value && typeof value === "object" && !Array.isArray(value);
26044
+ var keys = (value, allowed) => Object.keys(value).every((key) => allowed.includes(key));
26045
+ var identity = (value) => typeof value === "string" && value.length > 0 && Buffer.byteLength(value) <= 1024;
26046
+ var digest = (value) => typeof value === "string" && /^[a-f0-9]{64}$/.test(value);
26047
+ function validReplayState(value) {
26048
+ if (!object(value) || !keys(value, ["floor", "controls", "blocked", "upgrade", "withoutRecentContext"]))
26049
+ return false;
26050
+ const floor = value.floor;
26051
+ const upgrade = value.upgrade;
26052
+ return object(floor) && keys(floor, ["kind", "id", "seq", "after", "digest"]) && ["start", "summary", "checkpoint", "host-checkpoint"].includes(floor.kind) && identity(floor.id) && typeof floor.seq === "number" && typeof floor.after === "number" && Number.isSafeInteger(floor.seq) && Number.isSafeInteger(floor.after) && floor.after === (floor.kind === "start" || floor.kind === "host-checkpoint" ? floor.seq - 1 : floor.seq) && digest(floor.digest) && validControls(value.controls) && (value.blocked === undefined || typeof value.blocked === "boolean") && (value.withoutRecentContext === undefined || typeof value.withoutRecentContext === "boolean") && (upgrade === undefined || object(upgrade) && keys(upgrade, ["admissionID", "mode"]) && identity(upgrade.admissionID) && ["bounded", "host-checkpoint", "source-repair"].includes(upgrade.mode));
25860
26053
  }
25861
- function hasStorageNoticeShape(message) {
25862
- if (message.role !== "user" || typeof message.id !== "string")
26054
+ function validAdmissionV3(value) {
26055
+ if (!object(value) || !keys(value, ["version", "proof", "replay"]) || value.version !== 3 || !object(value.proof))
25863
26056
  return false;
25864
- if (message.content.length !== 1)
26057
+ const proof = value.proof;
26058
+ return keys(proof, [
26059
+ "sourceDigest",
26060
+ "sessionID",
26061
+ "admissionID",
26062
+ "summaryDigest",
26063
+ "historyDigest"
26064
+ ]) && identity(proof.sessionID) && identity(proof.admissionID) && digest(proof.sourceDigest) && digest(proof.summaryDigest) && digest(proof.historyDigest) && validReplayState(value.replay);
26065
+ }
26066
+ function encodeAdmissionV3(value) {
26067
+ if (!validAdmissionV3(value))
26068
+ throw new Error("Unsupported native fold admission metadata");
26069
+ return JSON.stringify(value);
26070
+ }
26071
+ function validCapturedReplayV3(value) {
26072
+ return object(value) && keys(value, ["version", "sessionID", "sourceDigest", "through", "replay"]) && value.version === 3 && identity(value.sessionID) && digest(value.sourceDigest) && Number.isSafeInteger(value.through) && validReplayState(value.replay);
26073
+ }
26074
+ function floorFor(row, kind) {
26075
+ return {
26076
+ kind,
26077
+ id: row.id,
26078
+ seq: row.seq,
26079
+ after: inclusiveFloor(kind) ? row.seq - 1 : row.seq,
26080
+ digest: foldDigest(JSON.stringify(row))
26081
+ };
26082
+ }
26083
+ function validFloor(reader, sessionID, value) {
26084
+ if (!value || !["checkpoint", "summary", "start", "host-checkpoint"].includes(value.kind) || !Number.isSafeInteger(value.seq) || !Number.isSafeInteger(value.after) || value.after !== (inclusiveFloor(value.kind) ? value.seq - 1 : value.seq))
25865
26085
  return false;
25866
- const part = message.content[0];
25867
- return part?.type === "text" && isStorageNoticeText(part.text);
26086
+ const row = reader.range(sessionID, value.seq - 1, value.seq).find((candidate) => candidate.id === value.id && candidate.seq === value.seq);
26087
+ return !!row && row.session_id === sessionID && foldDigest(JSON.stringify(row)) === value.digest;
25868
26088
  }
25869
- async function dropStorageNotices(messages, isAdmittedSynthetic) {
25870
- const drop = new Set;
25871
- for (const message of messages) {
25872
- if (!hasStorageNoticeShape(message))
25873
- continue;
25874
- if (await isAdmittedSynthetic(message.id))
25875
- drop.add(message);
25876
- }
25877
- if (drop.size === 0)
25878
- return 0;
25879
- const kept = messages.filter((message) => !drop.has(message));
25880
- messages.splice(0, messages.length, ...kept);
25881
- return drop.size;
25882
- }
25883
-
25884
- // src/v2/fold/restore.ts
25885
- function unavailableAttachmentNote(name, mediaType) {
25886
- return `[Attachment ${name ? `"${name}" ` : ""}(${mediaType}) is not available in this restored history]`;
25887
- }
25888
- var imageMimes = new Set(["image/png", "image/jpeg", "image/gif", "image/webp"]);
25889
- function attachmentParts(files, rowID, media) {
25890
- const seen = new Map;
25891
- return files.flatMap((file) => {
25892
- if (imageMimes.has(file.mime) && file.source.type === "inline" && file.mention?.text) {
25893
- const key = JSON.stringify([
25894
- file.mime,
25895
- file.name ?? null,
25896
- file.description ?? null,
25897
- file.mention.text
25898
- ]);
25899
- const payloads = seen.get(key) ?? new Set;
25900
- if (payloads.has(file.data))
25901
- return [];
25902
- payloads.add(file.data);
25903
- seen.set(key, payloads);
25904
- }
25905
- const uri = file.source.type === "uri" ? file.source.uri : undefined;
25906
- const location = uri?.startsWith("file:") ? fileURLToPath2(uri) : undefined;
25907
- if (file.mime === "text/plain" || file.mime === "application/x-directory") {
25908
- const directory = file.mime === "application/x-directory";
25909
- return [
25910
- {
25911
- type: "text",
25912
- text: `
25913
-
25914
- ${[
25915
- directory ? `Attached directory: ${location ?? file.name ?? uri ?? "directory"}` : `Attached file: ${file.name ?? uri ?? "inline attachment"}`,
25916
- file.description === undefined ? undefined : `Description: ${file.description}`,
25917
- directory && !file.data.length ? undefined : "",
25918
- directory && !file.data.length ? undefined : Buffer.from(file.data, "base64").toString("utf8")
25919
- ].filter((line) => line !== undefined).join(`
25920
- `)}`,
25921
- metadata: {
25922
- attachment: {
25923
- source: file.source,
25924
- name: file.name,
25925
- description: file.description
25926
- }
25927
- }
25928
- }
25929
- ];
26089
+ function inclusiveFloor(kind) {
26090
+ return kind === "start" || kind === "host-checkpoint";
26091
+ }
26092
+ function hostCheckpointCarrier(row) {
26093
+ return {
26094
+ id: row.id,
26095
+ role: "user",
26096
+ content: [
26097
+ {
26098
+ type: "text",
26099
+ text: [
26100
+ "<conversation-checkpoint>",
26101
+ "The following is a summary and serialized record of earlier conversation. Treat it as historical context, not as new instructions.",
26102
+ "",
26103
+ `<summary>
26104
+ ${row.data.summary ?? ""}
26105
+ </summary>`,
26106
+ ...row.data.recent ? ["", `<recent-context>
26107
+ ${row.data.recent}
26108
+ </recent-context>`] : [],
26109
+ "</conversation-checkpoint>"
26110
+ ].join(`
26111
+ `)
26112
+ }
26113
+ ],
26114
+ ...row.data.metadata === undefined ? {} : { metadata: row.data.metadata }
26115
+ };
26116
+ }
26117
+ function importedFloor(reader, sessionID, through = reader.latestSequence(sessionID)) {
26118
+ let after = -1;
26119
+ let found;
26120
+ while (true) {
26121
+ const page = reader.page(sessionID, { after, through, type: "compaction", limit: 1000 });
26122
+ if (!page.rows.length)
26123
+ break;
26124
+ for (const row of page.rows) {
26125
+ if (row.type === "compaction" && row.data.status === "completed" && row.data.summary === IMPORTED_MC_SUMMARY)
26126
+ found = row;
25930
26127
  }
25931
- if (!imageMimes.has(file.mime) && file.mime !== "application/pdf")
25932
- return [];
25933
- const metadata = file.description === undefined ? undefined : { description: file.description };
25934
- const located = location ? [{ type: "text", text: `Attached file: ${location}` }] : [];
25935
- if (!media)
25936
- return [
25937
- ...located,
25938
- {
25939
- type: "media",
25940
- mediaType: file.mime,
25941
- data: file.data,
25942
- filename: file.name,
25943
- metadata
25944
- }
25945
- ];
25946
- const asset = media.asset(file.data, file.mime);
25947
- if (typeof asset === "string") {
25948
- media.unavailable({ rowID, name: file.name, mediaType: file.mime, reason: asset });
25949
- return [
25950
- ...located,
25951
- { type: "text", text: unavailableAttachmentNote(file.name, file.mime) }
25952
- ];
26128
+ if (page.cursor === undefined || page.cursor <= after)
26129
+ break;
26130
+ after = page.cursor;
26131
+ }
26132
+ return found ? floorFor(found, "checkpoint") : undefined;
26133
+ }
26134
+ function effortPart(message) {
26135
+ return message.role === "system" && message.content.length === 1 && message.content[0]?.type === "effort" ? message.content[0] : undefined;
26136
+ }
26137
+ function validControls(value) {
26138
+ return Array.isArray(value) && Buffer.byteLength(JSON.stringify(value)) <= MAX_CONTROL_BYTES && value.every((control) => control && typeof control === "object" && !Array.isArray(control) && Object.keys(control).every((key) => ["after", "effort", "previous"].includes(key)) && (control.after === undefined || identity(control.after)) && (control.effort === undefined || efforts.has(control.effort)) && (control.previous === undefined || efforts.has(control.previous)));
26139
+ }
26140
+ function captureControls(draft, coordinate, visibleIDs) {
26141
+ let after;
26142
+ const controls = [];
26143
+ for (const message of draft.messages) {
26144
+ const part = effortPart(message);
26145
+ if (part) {
26146
+ const control = {
26147
+ after,
26148
+ effort: part.effort,
26149
+ previous: part.previous
26150
+ };
26151
+ if (!validControls([control]))
26152
+ throw new ControlMetadataUnavailable("unsupported host effort control");
26153
+ controls.push(control);
26154
+ } else {
26155
+ const id = coordinate(message);
26156
+ if (id && visibleIDs.has(id))
26157
+ after = id;
25953
26158
  }
25954
- return [...located, { type: "media", media: asset, filename: file.name, metadata }];
26159
+ }
26160
+ if (!validControls(controls))
26161
+ throw new ControlMetadataUnavailable("host effort controls exceed replay metadata budget");
26162
+ return controls;
26163
+ }
26164
+ var controlCoordinates = new WeakMap;
26165
+ function controlKey(control) {
26166
+ return JSON.stringify({
26167
+ after: control.after,
26168
+ effort: control.effort,
26169
+ previous: control.previous
25955
26170
  });
25956
26171
  }
25957
- function restoreRow(row, model, media) {
25958
- const data = row.data;
25959
- const make = (role, content, metadata = data.metadata) => ({
25960
- id: row.id,
25961
- role,
25962
- content,
25963
- ...metadata === undefined ? {} : { metadata }
25964
- });
25965
- if (row.type === "user") {
25966
- const skills = data.skills ?? [];
25967
- const content = [
25968
- ...skills.flatMap((skill) => skill.text === undefined ? [] : [{ type: "text", text: skill.text }]),
25969
- ...data.text ? [{ type: "text", text: data.text }] : [],
25970
- ...attachmentParts(data.files ?? [], row.id, media)
25971
- ];
25972
- return content.length ? [
25973
- make("user", content, {
25974
- ...data.metadata ?? {},
25975
- ...data.agents?.length ? { agents: data.agents } : {}
25976
- })
25977
- ] : [];
25978
- }
25979
- if (row.type === "system")
25980
- return [{ role: "system", content: [{ type: "text", text: data.text ?? "" }] }];
25981
- if (row.type === "synthetic" && isStorageNoticeText(data.text))
25982
- return [];
25983
- if (["synthetic", "skill"].includes(row.type))
25984
- return [make("user", [{ type: "text", text: data.text ?? "" }])];
25985
- if (row.type === "location-switched")
25986
- return [
25987
- make("user", [
26172
+ function rememberedControlKey(message) {
26173
+ return controlCoordinates.get(message);
26174
+ }
26175
+ function insertControls(messages, controls, coordinate) {
26176
+ const remaining = new Set(controls);
26177
+ const emit = (control) => {
26178
+ remaining.delete(control);
26179
+ const message = {
26180
+ role: "system",
26181
+ content: [
25988
26182
  {
25989
- type: "text",
25990
- text: `The working directory has been changed to ${data.location.directory}.`
26183
+ type: "effort",
26184
+ ...control.effort === undefined ? {} : { effort: control.effort },
26185
+ ...control.previous === undefined ? {} : { previous: control.previous }
25991
26186
  }
25992
- ])
25993
- ];
25994
- if (row.type === "shell")
25995
- return data.metadata?.background === true ? [] : [
25996
- make("user", [
25997
- {
25998
- type: "text",
25999
- text: `The following shell command was executed by the user:
26000
-
26001
- Command:
26002
- ${data.command}
26003
-
26004
- Output:
26005
- ${data.output?.output ?? ""}`
26006
- }
26007
- ])
26008
- ];
26009
- if (row.type !== "assistant")
26010
- return [];
26011
- const previousModel = data.model;
26012
- const sameProvider = previousModel?.providerID === model.providerID;
26013
- const sameModel = sameProvider && previousModel?.id === model.id;
26014
- const reuse = sameModel && data.error === undefined;
26015
- const metadata = (state) => state === undefined ? undefined : { [model.providerID]: state };
26016
- const reasoningInterrupted = data.content?.some((part) => part.type === "reasoning" && part.time !== undefined && part.time.completed === undefined);
26017
- const content = [];
26018
- const results = [];
26019
- for (const part of data.content ?? []) {
26020
- let native = "native" in part ? part.native : part.type === "tool" ? part.providerState : part.state;
26021
- if (part.type === "tool" && part.providerResultState !== null && typeof part.providerResultState === "object" && !Array.isArray(part.providerResultState))
26022
- native = {
26023
- ...native !== null && typeof native === "object" && !Array.isArray(native) ? native : {},
26024
- ...part.providerResultState
26025
- };
26026
- if (part.type === "text") {
26027
- if (part.text !== "")
26028
- content.push({
26029
- type: "text",
26030
- text: part.text,
26031
- providerMetadata: reuse ? metadata(native) : undefined
26032
- });
26033
- continue;
26034
- }
26035
- if (part.type === "reasoning") {
26036
- if (part.text !== "" || reuse && !reasoningInterrupted && native !== undefined)
26037
- content.push({
26038
- type: data.error === undefined && !reasoningInterrupted ? "reasoning" : "text",
26039
- text: part.text,
26040
- providerMetadata: reuse && !reasoningInterrupted ? metadata(native) : undefined
26041
- });
26042
- continue;
26043
- }
26044
- const state = part.state;
26045
- const completed = state.status === "completed" || state.status === "error";
26046
- const toolReuse = reuse || sameModel && part.executed === true && completed;
26047
- let input = state.input;
26048
- if (state.status === "streaming" && typeof input === "string") {
26049
- try {
26050
- input = JSON.parse(input);
26051
- } catch {}
26052
- }
26053
- content.push({
26054
- type: "tool-call",
26055
- id: part.id,
26056
- name: part.name,
26057
- input,
26058
- providerExecuted: part.executed,
26059
- providerMetadata: toolReuse ? metadata(native) : undefined
26060
- });
26061
- if (!completed)
26062
- continue;
26063
- const toolContent = state.content ?? [];
26064
- const single = toolContent.length === 1 ? toolContent[0] : undefined;
26065
- const result = {
26066
- type: "tool-result",
26067
- id: part.id,
26068
- name: part.name,
26069
- providerExecuted: part.executed,
26070
- providerMetadata: (part.executed === true ? sameProvider : reuse) ? metadata(native) : undefined,
26071
- result: state.status === "error" ? { error: state.error, content: toolContent } : single?.type === "text" ? { type: "text", value: single.text } : { type: "content", value: toolContent },
26072
- ...state.status === "error" ? { resultType: "error" } : {}
26187
+ ]
26073
26188
  };
26074
- if (part.executed === true)
26075
- content.push(result);
26076
- else
26077
- results.push({ role: "tool", content: [result] });
26189
+ controlCoordinates.set(message, controlKey(control));
26190
+ return message;
26191
+ };
26192
+ const ids = new Set(messages.flatMap((message) => coordinate(message) ?? []));
26193
+ const output = controls.filter((control) => !control.after || !ids.has(control.after)).map(emit);
26194
+ for (const message of messages) {
26195
+ output.push(message);
26196
+ const id = coordinate(message);
26197
+ if (id) {
26198
+ for (const control of remaining)
26199
+ if (control.after === id)
26200
+ output.push(emit(control));
26201
+ }
26078
26202
  }
26079
- return [...content.length ? [make("assistant", content)] : [], ...results];
26203
+ return output;
26204
+ }
26205
+ function controlsThrough(controls, reader, sessionID, through) {
26206
+ return controls.filter((control) => !control.after || (reader.sequenceForId(sessionID, control.after) ?? Infinity) <= through);
26080
26207
  }
26081
26208
 
26082
26209
  // src/v2/fold/native-replay.ts
@@ -26084,6 +26211,9 @@ var coordinates = new WeakMap;
26084
26211
  function nativeRowID(message) {
26085
26212
  return coordinates.get(message) ?? message.id;
26086
26213
  }
26214
+ function bindNativeRowID(message, id) {
26215
+ coordinates.set(message, id);
26216
+ }
26087
26217
  function copyNativeInput(messages) {
26088
26218
  const copies = reviveNative(encodeNative(messages));
26089
26219
  copies.forEach((copy, i) => {
@@ -26110,9 +26240,10 @@ function isAdmittedLocalCheckpoint(storage, sessionID, cut) {
26110
26240
  return false;
26111
26241
  }
26112
26242
  }
26113
- var conversational = (row) => RAW_MESSAGE_TYPES.includes(row.type) || row.type === "location-switched";
26114
- var historyDigest = (reader, sessionID, through) => foldDigest(JSON.stringify(reader.range(sessionID, -1, through).filter(conversational)));
26243
+ var conversational = (row) => RAW_MESSAGE_TYPES2.includes(row.type) || row.type === "location-switched";
26244
+ var historyDigest = (reader, sessionID, through, after = -1) => foldDigest(JSON.stringify(reader.range(sessionID, after, through).filter(conversational)));
26115
26245
  var admissionKey = (sessionID) => `native-fold/v2/${encodeURIComponent(sessionID)}`;
26246
+ var capturedReplayKey = (sessionID) => `native-fold-state/v3/${encodeURIComponent(sessionID)}`;
26116
26247
  async function forgetNativeFoldProvenance(storage, sessionID, legacyOnly = false) {
26117
26248
  const remove = async (key) => {
26118
26249
  if (storage.remove)
@@ -26120,8 +26251,11 @@ async function forgetNativeFoldProvenance(storage, sessionID, legacyOnly = false
26120
26251
  else
26121
26252
  await storage.set(key, null);
26122
26253
  };
26123
- if (!legacyOnly)
26254
+ if (!legacyOnly) {
26124
26255
  await remove(admissionKey(sessionID));
26256
+ await remove(`native-fold/v3/${encodeURIComponent(sessionID)}`);
26257
+ await remove(capturedReplayKey(sessionID));
26258
+ }
26125
26259
  if (!storage.scan)
26126
26260
  return;
26127
26261
  let after;
@@ -26139,18 +26273,25 @@ class NativeFoldReplay {
26139
26273
  storage;
26140
26274
  openReader;
26141
26275
  admissions;
26276
+ options;
26142
26277
  changed = new Set;
26143
26278
  dirty = new Set;
26144
26279
  unavailable = new Set;
26145
26280
  metadata = new Map;
26146
26281
  metadataThrough = new Map;
26282
+ metadataAfter = new Map;
26283
+ stampMRU;
26147
26284
  loaded = new Map;
26148
26285
  sources = new Map;
26149
26286
  staleHeads = new Set;
26150
- constructor(storage, openReader, admissions) {
26287
+ unprovenControls = new Set;
26288
+ editedAdmissions = new Map;
26289
+ legacyUpgrades = new Map;
26290
+ constructor(storage, openReader, admissions, options = {}) {
26151
26291
  this.storage = storage;
26152
26292
  this.openReader = openReader;
26153
26293
  this.admissions = admissions;
26294
+ this.options = options;
26154
26295
  storage.onEvict((sessionID) => this.clear(sessionID));
26155
26296
  }
26156
26297
  account(sessionID) {
@@ -26174,6 +26315,8 @@ class NativeFoldReplay {
26174
26315
  this.invalidate(sessionID);
26175
26316
  }
26176
26317
  invalidate(sessionID, suppressNomination = false) {
26318
+ if (this.stampMRU?.sessionID === sessionID)
26319
+ this.stampMRU = undefined;
26177
26320
  if (suppressNomination)
26178
26321
  this.unavailable.add(sessionID);
26179
26322
  this.dirty.add(sessionID);
@@ -26190,7 +26333,290 @@ class NativeFoldReplay {
26190
26333
  return this.tail(sessionID)?.baseline;
26191
26334
  }
26192
26335
  admissionKey(sessionID) {
26193
- return admissionKey(sessionID);
26336
+ return this.options.protocol === 3 ? `native-fold/v3/${encodeURIComponent(sessionID)}` : admissionKey(sessionID);
26337
+ }
26338
+ report(sessionID, reason) {
26339
+ try {
26340
+ this.options.log?.(sessionID, `v3 host fold: ${reason}`);
26341
+ } catch {}
26342
+ }
26343
+ async floorState(sessionID, reader, boundary, served, preferCapture = false) {
26344
+ const retained = this.tail(sessionID)?.replay;
26345
+ const controlsKnown = (replay) => replay.controls.every((control) => !control.after || reader.sequenceForId(sessionID, control.after) !== undefined);
26346
+ const memory = retained && validReplayState(retained) && controlsKnown(retained) && validFloor(reader, sessionID, retained.floor) ? retained : undefined;
26347
+ const cut = reader.latestCompaction(sessionID);
26348
+ const saved = await this.readV3(sessionID);
26349
+ const durable = saved && saved.proof.sourceDigest === foldDigest(reader.hostIdentity()) && (!cut || saved.proof.admissionID === cut.id) && controlsKnown(saved.replay) && validFloor(reader, sessionID, saved.replay.floor) ? saved.replay : undefined;
26350
+ const imported = importedFloor(reader, sessionID, cut?.seq);
26351
+ const captured = await this.readCapturedReplay(sessionID, reader);
26352
+ const existing = preferCapture ? captured ?? memory ?? durable : memory ?? durable ?? captured;
26353
+ if (preferCapture && !existing && !served)
26354
+ return;
26355
+ let floor = existing?.floor ?? imported;
26356
+ if (imported && (!floor || imported.after > floor.after))
26357
+ floor = imported;
26358
+ if (cut) {
26359
+ const meta = readSessionMeta(this.storage.db, sessionID);
26360
+ const max = this.storage.db.prepare("SELECT COALESCE(MAX(id),0) AS id FROM m0_mutation_log WHERE session_id=?").get(sessionID);
26361
+ const bound = this.storage.db.prepare("SELECT cached_m0_last_baseline_end_message_id AS id FROM session_meta WHERE session_id=?").get(sessionID);
26362
+ const seq = bound?.id ? reader.sequenceForId(sessionID, bound.id) : undefined;
26363
+ if (meta.cachedM0Bytes && max.id <= (meta.cachedM0MaxMutationId ?? 0) && seq !== undefined && (!floor || seq > floor.after)) {
26364
+ const row = reader.range(sessionID, seq - 1, seq).find((row) => row.id === bound?.id);
26365
+ if (row)
26366
+ floor = floorFor(row, "summary");
26367
+ }
26368
+ }
26369
+ const baseline = served ? this.servedBaseline(served) : undefined;
26370
+ if (boundary && baseline === boundary.summary) {
26371
+ const seq = reader.sequenceForId(sessionID, boundary.id);
26372
+ if (seq !== undefined && (!floor || seq > floor.after)) {
26373
+ const row = reader.range(sessionID, seq - 1, seq).find((row) => row.id === boundary.id);
26374
+ if (row)
26375
+ floor = floorFor(row, "summary");
26376
+ }
26377
+ }
26378
+ if (!floor && !cut) {
26379
+ const row = reader.page(sessionID, { limit: 1 }).rows[0];
26380
+ if (row)
26381
+ floor = floorFor(row, "start");
26382
+ }
26383
+ return floor ? { ...existing, floor, controls: existing?.controls ?? [], blocked: existing?.blocked } : undefined;
26384
+ }
26385
+ async readV3(sessionID) {
26386
+ const saved = await this.admissions?.get(this.admissionKey(sessionID));
26387
+ if (typeof saved?.payload !== "string" || saved.digest !== foldDigest(saved.payload))
26388
+ return;
26389
+ try {
26390
+ const value = JSON.parse(saved.payload);
26391
+ return validAdmissionV3(value) && value.proof.sessionID === sessionID ? value : undefined;
26392
+ } catch {
26393
+ return;
26394
+ }
26395
+ }
26396
+ async readCapturedReplay(sessionID, reader) {
26397
+ const saved = await this.admissions?.get(capturedReplayKey(sessionID));
26398
+ if (typeof saved?.payload !== "string" || saved.digest !== foldDigest(saved.payload))
26399
+ return;
26400
+ try {
26401
+ const value = JSON.parse(saved.payload);
26402
+ return validCapturedReplayV3(value) && value.sessionID === sessionID && value.sourceDigest === foldDigest(reader.hostIdentity()) && value.through <= reader.latestSequence(sessionID) && validFloor(reader, sessionID, value.replay.floor) && value.replay.controls.every((control) => !control.after || reader.sequenceForId(sessionID, control.after) !== undefined) ? value.replay : undefined;
26403
+ } catch {
26404
+ return;
26405
+ }
26406
+ }
26407
+ async saveCapturedReplay(sessionID, replay, reader) {
26408
+ const value = {
26409
+ version: 3,
26410
+ sessionID,
26411
+ sourceDigest: foldDigest(reader.hostIdentity()),
26412
+ through: reader.latestSequence(sessionID),
26413
+ replay
26414
+ };
26415
+ if (!validCapturedReplayV3(value))
26416
+ throw new Error("Unsupported captured native replay metadata");
26417
+ const payload = JSON.stringify(value);
26418
+ try {
26419
+ await this.admissions?.set(capturedReplayKey(sessionID), {
26420
+ payload,
26421
+ digest: foldDigest(payload)
26422
+ });
26423
+ this.unprovenControls.delete(sessionID);
26424
+ } catch (error) {
26425
+ this.unprovenControls.add(sessionID);
26426
+ throw error;
26427
+ }
26428
+ }
26429
+ servedBaseline(draft) {
26430
+ const identified = draft.messages.find((message) => message.id === HEAD_IDS[0])?.content.find((part) => part.type === "text")?.text;
26431
+ if (typeof identified === "string")
26432
+ return identified;
26433
+ if (this.options.protocol !== 3)
26434
+ return;
26435
+ const cached = readSessionMeta(this.storage.db, draft.sessionID).cachedM0Bytes?.toString("utf8");
26436
+ const checkpointID = this.tail(draft.sessionID)?.replay?.floor.kind === "host-checkpoint" ? this.tail(draft.sessionID)?.replay?.floor.id : undefined;
26437
+ return cached && draft.messages.some((message) => message.content.some((part) => part.type === "text" && (part.text === cached || message.id === checkpointID && typeof part.text === "string" && part.text.includes(`<summary>
26438
+ ${cached}
26439
+ </summary>`)))) ? cached : undefined;
26440
+ }
26441
+ async retainReplay(sessionID, replay, model, sourceSeq) {
26442
+ const tail = this.tail(sessionID) ?? { model, sourceSeq };
26443
+ await this.storage.saveTail(sessionID, JSON.stringify({ ...tail, replay }), []);
26444
+ if (!this.storage.tail(sessionID))
26445
+ await this.storage.saveTail(sessionID, JSON.stringify({ model, sourceSeq, replay }), []);
26446
+ }
26447
+ async canFold(sessionID, reader) {
26448
+ if (this.options.protocol !== 3) {
26449
+ const future = await this.admissions?.get(`native-fold/v3/${encodeURIComponent(sessionID)}`);
26450
+ if (future) {
26451
+ this.report(sessionID, "refused: unsupported admission version");
26452
+ return false;
26453
+ }
26454
+ return true;
26455
+ }
26456
+ if (await this.admissions?.get(admissionKey(sessionID)) && !await this.readV3(sessionID)) {
26457
+ this.report(sessionID, "fold refused: V2 upgrade has not completed a rebuilding pass");
26458
+ return false;
26459
+ }
26460
+ if (this.unprovenControls.has(sessionID)) {
26461
+ this.report(sessionID, "fold refused: capture controls have not been persisted");
26462
+ return false;
26463
+ }
26464
+ const replay = await this.floorState(sessionID, reader, undefined, undefined, true);
26465
+ if (!replay || replay.blocked) {
26466
+ this.report(sessionID, "refused: no usable host replay boundary; waiting for a permitted rebuild");
26467
+ return false;
26468
+ }
26469
+ return true;
26470
+ }
26471
+ async restorationFloor(sessionID, _cut, reader) {
26472
+ if (this.options.protocol !== 3)
26473
+ return;
26474
+ const replay = await this.floorState(sessionID, reader);
26475
+ if (replay)
26476
+ return replay.floor.after;
26477
+ const current = await this.admissions?.get(this.admissionKey(sessionID));
26478
+ const legacy = await this.admissions?.get(admissionKey(sessionID));
26479
+ if (current || legacy?.payload) {
26480
+ this.report(sessionID, "replay refused: no usable host checkpoint boundary");
26481
+ throw new NativeReplayUnavailable("Host checkpoint replay boundary is unavailable");
26482
+ }
26483
+ return;
26484
+ }
26485
+ async prepareLegacyUpgrade(args) {
26486
+ const { draft, cut, reader } = args;
26487
+ const admissions = this.admissions;
26488
+ if (this.options.protocol !== 3 || !admissions || !isLocalCheckpoint(cut))
26489
+ return false;
26490
+ if (await this.readV3(draft.sessionID))
26491
+ return false;
26492
+ this.legacyUpgrades.delete(draft.sessionID);
26493
+ const started = performance.now();
26494
+ const receipt = await this.admissions?.get(admissionKey(draft.sessionID));
26495
+ if (!receipt?.payload || receipt.digest !== foldDigest(receipt.payload))
26496
+ return false;
26497
+ let legacy;
26498
+ try {
26499
+ legacy = JSON.parse(receipt.payload);
26500
+ } catch {
26501
+ return false;
26502
+ }
26503
+ if (legacy.sourceDigest !== foldDigest(reader.hostIdentity()) || legacy.sessionID !== draft.sessionID || legacy.admissionID !== cut.id || legacy.summaryDigest !== foldDigest(cut.data.summary ?? "") || !/^[a-f0-9]{64}$/.test(legacy.historyDigest))
26504
+ return false;
26505
+ const rows = reader.range(draft.sessionID, -1, cut.seq - 1).filter(conversational);
26506
+ if (foldDigest(JSON.stringify(rows)) !== legacy.historyDigest)
26507
+ return false;
26508
+ let floor;
26509
+ if (!floor) {
26510
+ const candidate = await this.floorState(draft.sessionID, reader);
26511
+ const cached = readSessionMeta(this.storage.db, draft.sessionID).cachedM0Bytes?.toString("utf8");
26512
+ if (candidate && (candidate.floor.kind === "checkpoint" || candidate.floor.kind === "summary" && cached === cut.data.summary))
26513
+ floor = candidate.floor;
26514
+ }
26515
+ const mode = floor ? "bounded" : "source-repair";
26516
+ floor ??= rows[0] ? floorFor(rows[0], "start") : floorFor(cut, "checkpoint");
26517
+ let controls = [];
26518
+ let blocked = false;
26519
+ try {
26520
+ controls = captureControls(draft, nativeRowID, new Set(draft.messages.flatMap((message) => nativeRowID(message) ?? [])));
26521
+ } catch (error) {
26522
+ if (!(error instanceof ControlMetadataUnavailable))
26523
+ throw error;
26524
+ blocked = true;
26525
+ }
26526
+ const replay = {
26527
+ floor,
26528
+ controls,
26529
+ ...blocked ? { blocked } : {},
26530
+ upgrade: { admissionID: cut.id, mode }
26531
+ };
26532
+ const value = {
26533
+ version: 3,
26534
+ replay,
26535
+ proof: {
26536
+ sourceDigest: legacy.sourceDigest,
26537
+ sessionID: draft.sessionID,
26538
+ admissionID: cut.id,
26539
+ summaryDigest: legacy.summaryDigest,
26540
+ historyDigest: foldDigest(JSON.stringify(rows.filter((row) => row.seq > floor.after)))
26541
+ }
26542
+ };
26543
+ this.legacyUpgrades.set(draft.sessionID, { value, rows, started });
26544
+ await this.retainReplay(draft.sessionID, replay, `${draft.model.providerID}/${draft.model.id}`, cut.seq - 1);
26545
+ return true;
26546
+ }
26547
+ legacyUpgradeInput(sessionID, model) {
26548
+ const pending = this.legacyUpgrades.get(sessionID);
26549
+ if (!pending)
26550
+ return;
26551
+ return pending.rows.filter((row) => row.seq > pending.value.replay.floor.after).flatMap((row) => {
26552
+ const messages = this.rendered(structuredClone(row), model);
26553
+ for (const message of messages)
26554
+ coordinates.set(message, row.id);
26555
+ return messages;
26556
+ });
26557
+ }
26558
+ async commitLegacyUpgrade(sessionID, prefixMutationPermitted) {
26559
+ if (!prefixMutationPermitted)
26560
+ return false;
26561
+ const pending = this.legacyUpgrades.get(sessionID);
26562
+ const admissions = this.admissions;
26563
+ if (!pending || !admissions)
26564
+ return false;
26565
+ const replay = this.tail(sessionID)?.replay ?? pending.value.replay;
26566
+ if (replay.blocked)
26567
+ return false;
26568
+ const value = {
26569
+ ...pending.value,
26570
+ replay,
26571
+ proof: {
26572
+ ...pending.value.proof,
26573
+ historyDigest: foldDigest(JSON.stringify(pending.rows.filter((row) => row.seq > replay.floor.after)))
26574
+ }
26575
+ };
26576
+ const payload = encodeAdmissionV3(value);
26577
+ await admissions.set(this.admissionKey(sessionID), {
26578
+ payload,
26579
+ digest: foldDigest(payload)
26580
+ });
26581
+ this.legacyUpgrades.delete(sessionID);
26582
+ this.report(sessionID, `V2 upgrade-state HARD mode=${replay.upgrade?.mode} rows_read=${pending.rows.length} duration_ms=${Math.round(performance.now() - pending.started)} floor=${replay.floor.id}:${replay.floor.after}`);
26583
+ return true;
26584
+ }
26585
+ cancelLegacyUpgrade(sessionID) {
26586
+ this.legacyUpgrades.delete(sessionID);
26587
+ }
26588
+ async checkpointForReplay(sessionID, reader) {
26589
+ if (this.options.protocol !== 3)
26590
+ return;
26591
+ const replay = await this.floorState(sessionID, reader);
26592
+ if (replay?.floor.kind !== "host-checkpoint")
26593
+ return;
26594
+ const row = reader.range(sessionID, replay.floor.seq - 1, replay.floor.seq).find((row) => row.id === replay.floor.id && row.type === "compaction");
26595
+ if (!row || !isLocalCheckpoint(row))
26596
+ return;
26597
+ const rendered = hostCheckpointCarrier(row);
26598
+ if (replay.withoutRecentContext)
26599
+ stripCheckpointRecentContext(rendered, row.data.summary ?? "");
26600
+ return { row, rendered, submitted: row.data.summary ?? "" };
26601
+ }
26602
+ async checkpointCovered(sessionID, checkpointID) {
26603
+ const admissions = this.admissions;
26604
+ if (!admissions)
26605
+ return;
26606
+ const pending = this.legacyUpgrades.get(sessionID);
26607
+ const value = await this.readV3(sessionID) ?? pending?.value;
26608
+ if (value?.replay.floor.kind !== "host-checkpoint" || value.replay.floor.id !== checkpointID || value.replay.withoutRecentContext)
26609
+ return;
26610
+ value.replay.withoutRecentContext = true;
26611
+ const payload = encodeAdmissionV3(value);
26612
+ if (!pending)
26613
+ await admissions.set(this.admissionKey(sessionID), {
26614
+ payload,
26615
+ digest: foldDigest(payload)
26616
+ });
26617
+ const tail = this.tail(sessionID);
26618
+ if (tail)
26619
+ await this.retainReplay(sessionID, value.replay, tail.model, tail.sourceSeq);
26194
26620
  }
26195
26621
  async removeAdmission(key) {
26196
26622
  if (this.admissions?.remove)
@@ -26203,6 +26629,46 @@ class NativeFoldReplay {
26203
26629
  await forgetNativeFoldProvenance(this.admissions, sessionID, true);
26204
26630
  }
26205
26631
  async admits(sessionID, cut, reader) {
26632
+ if (this.options.protocol === 3) {
26633
+ const saved = await this.readV3(sessionID);
26634
+ if (!saved || !isLocalCheckpoint(cut) || cut.session_id !== sessionID)
26635
+ return false;
26636
+ const proof = saved.proof;
26637
+ if (proof.sourceDigest !== foldDigest(reader.hostIdentity()) || proof.admissionID !== cut.id || proof.summaryDigest !== foldDigest(cut.data.summary ?? "")) {
26638
+ this.report(sessionID, "replay refused: invalid checkpoint floor or provenance");
26639
+ return false;
26640
+ }
26641
+ let replay = saved.replay;
26642
+ if (!validFloor(reader, sessionID, replay.floor)) {
26643
+ const floor = replay.floor;
26644
+ const anchor = floor?.kind === "start" && Number.isSafeInteger(floor.seq) && floor.after === floor.seq - 1 ? reader.range(sessionID, floor.seq - 1, floor.seq).find((row) => row.id === floor.id && row.session_id === sessionID && conversational(row)) : undefined;
26645
+ if (!anchor) {
26646
+ this.report(sessionID, "replay refused: invalid checkpoint floor or provenance");
26647
+ return false;
26648
+ }
26649
+ replay = { ...replay, floor: floorFor(anchor, "start") };
26650
+ this.editedAdmissions.set(sessionID, { original: saved, replay });
26651
+ this.staleHeads.add(sessionID);
26652
+ this.invalidate(sessionID);
26653
+ await this.retainReplay(sessionID, replay, this.tail(sessionID)?.model ?? "", cut.seq - 1);
26654
+ return false;
26655
+ }
26656
+ await this.retainReplay(sessionID, saved.replay, this.tail(sessionID)?.model ?? "", cut.seq - 1);
26657
+ if (proof.historyDigest !== historyDigest(reader, sessionID, cut.seq - 1, saved.replay.floor.after)) {
26658
+ this.staleHeads.add(sessionID);
26659
+ this.invalidate(sessionID);
26660
+ this.editedAdmissions.set(sessionID, { original: saved, replay });
26661
+ await this.retainReplay(sessionID, saved.replay, this.tail(sessionID)?.model ?? "", cut.seq - 1);
26662
+ return false;
26663
+ }
26664
+ await this.storage.supply(sessionID, cut.id, JSON.stringify({
26665
+ source: this.storage.sourceID,
26666
+ sessionID,
26667
+ admissionID: cut.id,
26668
+ summary: cut.data.summary
26669
+ }));
26670
+ return true;
26671
+ }
26206
26672
  if (!isLocalCheckpoint(cut) || cut.session_id !== sessionID)
26207
26673
  return false;
26208
26674
  if (isAdmittedLocalCheckpoint(this.storage, sessionID, cut))
@@ -26234,6 +26700,121 @@ class NativeFoldReplay {
26234
26700
  return false;
26235
26701
  }
26236
26702
  }
26703
+ async commitEditedAdmission(sessionID) {
26704
+ const pending = this.editedAdmissions.get(sessionID);
26705
+ const admissions = this.admissions;
26706
+ if (!pending || !admissions)
26707
+ return false;
26708
+ const current = await this.readV3(sessionID);
26709
+ if (JSON.stringify(current) !== JSON.stringify(pending.original))
26710
+ return false;
26711
+ const reader = this.openReader(sessionID);
26712
+ try {
26713
+ const cut = reader.latestCompaction(sessionID);
26714
+ const proof = pending.original.proof;
26715
+ const replay = this.tail(sessionID)?.replay ?? pending.replay;
26716
+ if (!cut || cut.id !== proof.admissionID || !isLocalCheckpoint(cut) || proof.sourceDigest !== foldDigest(reader.hostIdentity()) || proof.summaryDigest !== foldDigest(cut.data.summary ?? "") || !validFloor(reader, sessionID, replay.floor))
26717
+ return false;
26718
+ const value = {
26719
+ ...pending.original,
26720
+ replay: {
26721
+ ...replay,
26722
+ controls: controlsThrough(replay.controls, reader, sessionID, cut.seq - 1)
26723
+ },
26724
+ proof: {
26725
+ ...proof,
26726
+ historyDigest: historyDigest(reader, sessionID, cut.seq - 1, replay.floor.after)
26727
+ }
26728
+ };
26729
+ const payload = encodeAdmissionV3(value);
26730
+ await admissions.set(this.admissionKey(sessionID), {
26731
+ payload,
26732
+ digest: foldDigest(payload)
26733
+ });
26734
+ this.editedAdmissions.delete(sessionID);
26735
+ return true;
26736
+ } finally {
26737
+ reader.close();
26738
+ }
26739
+ }
26740
+ cancelEditedAdmission(sessionID) {
26741
+ this.editedAdmissions.delete(sessionID);
26742
+ }
26743
+ async replayAdmission(sessionID, cut, reader) {
26744
+ if (this.options.protocol === 3) {
26745
+ const saved = await this.readV3(sessionID);
26746
+ if (!saved)
26747
+ return "legacy";
26748
+ if (saved.proof.admissionID !== cut.id)
26749
+ return "legacy";
26750
+ return saved.proof.sourceDigest === foldDigest(reader.hostIdentity()) && saved.proof.summaryDigest === foldDigest(cut.data.summary ?? "") && validFloor(reader, sessionID, saved.replay.floor) && saved.proof.historyDigest === historyDigest(reader, sessionID, cut.seq - 1, saved.replay.floor.after) ? "native" : undefined;
26751
+ }
26752
+ if (!isLocalCheckpoint(cut) || cut.session_id !== sessionID)
26753
+ return;
26754
+ try {
26755
+ const source = reader.hostIdentity();
26756
+ const observed = this.sources.get(sessionID);
26757
+ if (observed && observed !== source)
26758
+ return;
26759
+ if (observed === source && isAdmittedLocalCheckpoint(this.storage, sessionID, cut))
26760
+ return "native";
26761
+ const saved = await this.admissions?.get(this.admissionKey(sessionID));
26762
+ if (!saved)
26763
+ return "legacy";
26764
+ if (!saved.payload || saved.digest !== foldDigest(saved.payload))
26765
+ return;
26766
+ const snapshot = JSON.parse(saved.payload);
26767
+ if (snapshot.admissionID !== cut.id)
26768
+ return "legacy";
26769
+ if (snapshot.sourceDigest !== foldDigest(source) || snapshot.sessionID !== sessionID || snapshot.summaryDigest !== foldDigest(cut.data.summary ?? "") || snapshot.historyDigest !== historyDigest(reader, sessionID, cut.seq - 1))
26770
+ return;
26771
+ return "native";
26772
+ } catch {
26773
+ return;
26774
+ }
26775
+ }
26776
+ replayInput(args, replayOverride) {
26777
+ const { sessionID, cut, model, reader } = args;
26778
+ if (!isLocalCheckpoint(cut) || cut.session_id !== sessionID)
26779
+ return;
26780
+ let after = -1;
26781
+ if (this.options.protocol === 3) {
26782
+ const replay = replayOverride ?? this.tail(sessionID)?.replay;
26783
+ if (!replay || !validFloor(reader, sessionID, replay.floor))
26784
+ return;
26785
+ after = replay.floor.after;
26786
+ } else if (args.bounded && !this.changed.has(sessionID)) {
26787
+ const state = readSessionMeta(this.storage.db, sessionID);
26788
+ const max = this.storage.db.prepare("SELECT COALESCE(MAX(id),0) AS id FROM m0_mutation_log WHERE session_id=?").get(sessionID);
26789
+ const boundary = this.storage.db.prepare("SELECT cached_m0_last_baseline_end_message_id AS id FROM session_meta WHERE session_id=?").get(sessionID)?.id;
26790
+ if (max.id <= (state.cachedM0MaxMutationId ?? 0) && boundary)
26791
+ after = reader.sequenceForId(sessionID, boundary) ?? -1;
26792
+ }
26793
+ const through = cut.seq - 1;
26794
+ const metadata = (this.metadataThrough.get(sessionID) ?? -1) >= through ? this.metadata.get(sessionID) : undefined;
26795
+ const required = (metadata ?? reader.rowStampsThrough(sessionID, through, this.options.protocol === 3 ? after : undefined)).filter(conversational).filter((row) => row.seq > after && row.seq <= through);
26796
+ const tail = this.tail(sessionID);
26797
+ let records;
26798
+ if (!this.dirty.has(sessionID) && tail?.model === `${model.providerID}/${model.id}` && this.storage.containsRows(sessionID, required.map((row) => row.id))) {
26799
+ records = this.storage.rows(sessionID, after, through);
26800
+ } else {
26801
+ records = reader.range(sessionID, after, through).filter(conversational).map((row) => this.record(row, this.rendered(row, model)));
26802
+ const restored = new Set(records.map((row) => row.id));
26803
+ if (required.some((row) => !restored.has(row.id)))
26804
+ return;
26805
+ }
26806
+ const projected = records.flatMap((row) => {
26807
+ const messages = reviveNative(JSON.parse(row.data));
26808
+ for (const message of messages)
26809
+ coordinates.set(message, row.id);
26810
+ return messages;
26811
+ });
26812
+ return this.options.protocol === 3 ? insertControls(projected, controlsThrough((replayOverride ?? this.tail(sessionID)?.replay)?.controls ?? [], reader, sessionID, through), nativeRowID) : projected;
26813
+ }
26814
+ async projectReplay(args) {
26815
+ const replay = this.options.protocol === 3 ? await this.floorState(args.sessionID, args.reader) : undefined;
26816
+ return this.replayInput(args, replay);
26817
+ }
26237
26818
  rendered(row, model) {
26238
26819
  return restoreRow(row, model, hostUsesMediaAssets() ? {
26239
26820
  asset: hostMediaAsset,
@@ -26244,15 +26825,31 @@ class NativeFoldReplay {
26244
26825
  const data = JSON.stringify(encodeNative(messages));
26245
26826
  return { id: row.id, type: row.type, seq: row.seq, data, digest: foldDigest(data) };
26246
26827
  }
26247
- records(sessionID, native, reader) {
26248
- let metadata = this.metadata.get(sessionID);
26828
+ records(sessionID, native, reader, after) {
26249
26829
  const through = reader.latestSequence(sessionID);
26830
+ const retained = this.stampMRU;
26831
+ let metadata = this.metadata.get(sessionID);
26832
+ if (!metadata && retained?.sessionID === sessionID && retained.source === reader.hostIdentity() && retained.after === after && retained.through === through) {
26833
+ metadata = retained.rows;
26834
+ this.metadata.set(sessionID, metadata);
26835
+ this.metadataThrough.set(sessionID, through);
26836
+ this.metadataAfter.set(sessionID, after);
26837
+ }
26250
26838
  const known = new Set(metadata?.map((row) => row.id));
26251
- if (!metadata || (this.metadataThrough.get(sessionID) ?? -1) < through || native.some((message) => message.id && !known.has(message.id))) {
26252
- metadata = reader.rowStampsThrough(sessionID, through).filter(conversational);
26839
+ if (!metadata || this.metadataAfter.get(sessionID) !== after || (this.metadataThrough.get(sessionID) ?? -1) < through || native.some((message) => message.id && !known.has(message.id))) {
26840
+ metadata = reader.rowStampsThrough(sessionID, through, after).filter(conversational);
26253
26841
  this.metadata.set(sessionID, metadata);
26254
26842
  this.metadataThrough.set(sessionID, through);
26843
+ this.metadataAfter.set(sessionID, after);
26255
26844
  }
26845
+ if (this.options.protocol === 3)
26846
+ this.stampMRU = {
26847
+ sessionID,
26848
+ source: reader.hostIdentity(),
26849
+ through,
26850
+ after,
26851
+ rows: metadata
26852
+ };
26256
26853
  const byID = new Map(metadata.map((row) => [row.id, row]));
26257
26854
  const grouped = new Map;
26258
26855
  const anchorIndex = native.findIndex((message) => {
@@ -26269,6 +26866,14 @@ class NativeFoldReplay {
26269
26866
  let owner;
26270
26867
  for (const message of native) {
26271
26868
  let id = nativeRowID(message);
26869
+ if (this.options.protocol === 3 && !id && message.role === "system") {
26870
+ const text = message.content.filter((part) => part.type === "text").map((part) => part.text).join(`
26871
+ `);
26872
+ const source = metadata.filter((row) => row.type === "system" && row.seq > cursor).find((row) => reader.range(sessionID, row.seq - 1, row.seq).some((stored) => stored.id === row.id && stored.data.text === text));
26873
+ id = source?.id;
26874
+ if (!id)
26875
+ continue;
26876
+ }
26272
26877
  if (!id && message.role === "system") {
26273
26878
  if (leadingIDs.has(message)) {
26274
26879
  id = leadingIDs.get(message);
@@ -26292,15 +26897,65 @@ class NativeFoldReplay {
26292
26897
  }
26293
26898
  return [...grouped].map(([row, messages]) => this.record(row, messages));
26294
26899
  }
26295
- async capture(draft, native) {
26900
+ async capture(draft, native, boundary) {
26296
26901
  const release = this.storage.hold(draft.sessionID);
26902
+ let replay;
26903
+ let sourceSeq = -1;
26297
26904
  try {
26298
26905
  rememberHostMedia(native);
26299
26906
  const reader = this.openReader(draft.sessionID);
26300
26907
  try {
26301
- const rows = this.records(draft.sessionID, native, reader);
26302
- const baseline = draft.messages.find((message) => message.id === HEAD_IDS[0])?.content.find((part) => part.type === "text")?.text;
26908
+ let captured = native;
26909
+ if (this.options.protocol === 3) {
26910
+ replay = await this.floorState(draft.sessionID, reader, boundary, draft);
26911
+ if (!replay)
26912
+ throw new NativeReplayUnavailable("No usable host replay boundary");
26913
+ replay = { ...replay, blocked: false };
26914
+ const replayAfter = replay.floor.after;
26915
+ const replayStart = replay.floor.kind === "start";
26916
+ captured = native.filter((message) => {
26917
+ if (effortPart(message))
26918
+ return false;
26919
+ const id = nativeRowID(message);
26920
+ if (HEAD_IDS.some((head) => head === id))
26921
+ return false;
26922
+ const baseline = this.servedBaseline(draft);
26923
+ if (!id)
26924
+ return !(baseline && message.role === "user" && message.content.some((part) => part.type === "text" && part.text === baseline));
26925
+ if (replayStart)
26926
+ return true;
26927
+ const seq = reader.sequenceForId(draft.sessionID, id);
26928
+ return seq === undefined || seq > replayAfter;
26929
+ });
26930
+ }
26931
+ let rows = this.records(draft.sessionID, captured, reader, replay?.floor.after);
26932
+ if (replay) {
26933
+ const identities = new Map;
26934
+ for (const row of rows.filter((row) => row.type === "system")) {
26935
+ for (const message of reviveNative(JSON.parse(row.data))) {
26936
+ const key = JSON.stringify(message.content);
26937
+ const found = identities.get(key) ?? [];
26938
+ found.push(row.id);
26939
+ identities.set(key, found);
26940
+ }
26941
+ }
26942
+ const ids = new Set(rows.map((row) => row.id));
26943
+ replay = {
26944
+ ...replay,
26945
+ blocked: false,
26946
+ controls: captureControls(draft, (message) => nativeRowID(message) ?? (message.role === "system" ? identities.get(JSON.stringify(message.content))?.shift() : undefined), ids)
26947
+ };
26948
+ }
26949
+ const baseline = this.servedBaseline(draft);
26303
26950
  const through = Math.max(-1, ...rows.map((row) => row.seq));
26951
+ sourceSeq = through;
26952
+ if (boundary && baseline === boundary.summary) {
26953
+ const after = reader.sequenceForId(draft.sessionID, boundary.id);
26954
+ if (after !== undefined) {
26955
+ rows = rows.filter((row) => row.seq > after);
26956
+ this.storage.replaceRows(draft.sessionID, through, rows);
26957
+ }
26958
+ }
26304
26959
  const tail = {
26305
26960
  model: `${draft.model.providerID}/${draft.model.id}`,
26306
26961
  sourceSeq: through,
@@ -26315,13 +26970,48 @@ class NativeFoldReplay {
26315
26970
  } finally {
26316
26971
  reader.close();
26317
26972
  }
26318
- } catch {
26973
+ } catch (error) {
26319
26974
  this.unavailable.add(draft.sessionID);
26320
26975
  this.invalidate(draft.sessionID);
26976
+ if (replay)
26977
+ replay = { ...replay, blocked: true };
26978
+ if (this.options.protocol === 3)
26979
+ this.report(draft.sessionID, `capture unavailable: ${String(error)}`);
26321
26980
  } finally {
26322
26981
  this.account(draft.sessionID);
26323
26982
  release();
26324
26983
  }
26984
+ if (replay) {
26985
+ await this.retainReplay(draft.sessionID, replay, `${draft.model.providerID}/${draft.model.id}`, sourceSeq);
26986
+ const reader = this.openReader(draft.sessionID);
26987
+ try {
26988
+ await this.saveCapturedReplay(draft.sessionID, replay, reader);
26989
+ const saved = await this.readV3(draft.sessionID);
26990
+ const cut = reader.latestCompaction(draft.sessionID);
26991
+ if (saved && !this.editedAdmissions.has(draft.sessionID) && cut?.id === saved.proof.admissionID && replay.floor.after > saved.replay.floor.after && boundary && this.servedBaseline(draft) === boundary.summary) {
26992
+ const value = {
26993
+ ...saved,
26994
+ replay: {
26995
+ ...replay,
26996
+ controls: controlsThrough(replay.controls, reader, draft.sessionID, cut.seq - 1)
26997
+ },
26998
+ proof: {
26999
+ ...saved.proof,
27000
+ historyDigest: historyDigest(reader, draft.sessionID, cut.seq - 1, replay.floor.after)
27001
+ }
27002
+ };
27003
+ const payload = encodeAdmissionV3(value);
27004
+ await this.admissions?.set(this.admissionKey(draft.sessionID), {
27005
+ payload,
27006
+ digest: foldDigest(payload)
27007
+ });
27008
+ }
27009
+ } catch (error) {
27010
+ this.report(draft.sessionID, `capture provenance update unavailable: ${String(error)}`);
27011
+ } finally {
27012
+ reader.close();
27013
+ }
27014
+ }
26325
27015
  }
26326
27016
  async canReplay(sessionID, _reader) {
26327
27017
  return !this.unavailable.has(sessionID) && typeof await this.baseline(sessionID) === "string";
@@ -26337,20 +27027,62 @@ class NativeFoldReplay {
26337
27027
  }
26338
27028
  async supplyHeld(args) {
26339
27029
  const { draft, reader, summary } = args;
27030
+ if (this.options.protocol === 3) {
27031
+ if (this.unprovenControls.has(draft.sessionID))
27032
+ return false;
27033
+ if (await this.admissions?.get(admissionKey(draft.sessionID)) && !await this.readV3(draft.sessionID))
27034
+ return false;
27035
+ const running = reader.latestRunningCompaction(draft.sessionID);
27036
+ const replay = await this.floorState(draft.sessionID, reader, undefined, undefined, true);
27037
+ if (!running || !replay || replay.blocked) {
27038
+ this.report(draft.sessionID, "fold refused: no usable host checkpoint boundary");
27039
+ return false;
27040
+ }
27041
+ const model = `${draft.model.providerID}/${draft.model.id}`;
27042
+ if (this.tail(draft.sessionID)?.model !== model)
27043
+ this.storage.replaceRows(draft.sessionID, reader.latestSequence(draft.sessionID), []);
27044
+ await this.retainReplay(draft.sessionID, replay, model, reader.latestSequence(draft.sessionID));
27045
+ await this.storage.supply(draft.sessionID, running.id, JSON.stringify({
27046
+ source: this.storage.sourceID,
27047
+ sessionID: draft.sessionID,
27048
+ admissionID: running.id,
27049
+ summary
27050
+ }));
27051
+ const value = {
27052
+ version: 3,
27053
+ replay,
27054
+ proof: {
27055
+ sourceDigest: foldDigest(reader.hostIdentity()),
27056
+ sessionID: draft.sessionID,
27057
+ admissionID: running.id,
27058
+ summaryDigest: foldDigest(summary),
27059
+ historyDigest: historyDigest(reader, draft.sessionID, running.seq - 1, replay.floor.after)
27060
+ }
27061
+ };
27062
+ const payload = encodeAdmissionV3(value);
27063
+ await this.admissions?.set(this.admissionKey(draft.sessionID), {
27064
+ payload,
27065
+ digest: foldDigest(payload)
27066
+ });
27067
+ return true;
27068
+ }
26340
27069
  const tail = this.tail(draft.sessionID);
26341
27070
  const running = reader.latestRunningCompaction(draft.sessionID);
26342
27071
  const id = running?.id;
26343
- if (!id || !tail || tail.model !== `${draft.model.providerID}/${draft.model.id}`)
27072
+ const model = `${draft.model.providerID}/${draft.model.id}`;
27073
+ if (!id || tail && tail.model !== model)
26344
27074
  return false;
26345
27075
  const through = reader.latestSequence(draft.sessionID);
26346
- const after = this.dirty.has(draft.sessionID) ? -1 : tail.sourceSeq;
26347
- const fresh = reader.range(draft.sessionID, after, through).filter(conversational);
27076
+ const after = this.dirty.has(draft.sessionID) ? -1 : tail?.sourceSeq ?? through;
27077
+ const fresh = tail ? reader.range(draft.sessionID, after, through).filter(conversational) : [];
26348
27078
  const records = fresh.map((row) => this.record(row, this.rendered(row, draft.model)));
26349
27079
  if (this.dirty.has(draft.sessionID))
26350
27080
  this.storage.replaceRows(draft.sessionID, through, records);
26351
27081
  await this.storage.saveTail(draft.sessionID, JSON.stringify({
26352
27082
  ...tail,
26353
- sourceSeq: Math.max(tail.sourceSeq, ...fresh.map((row) => row.seq))
27083
+ model,
27084
+ baseline: tail?.baseline ?? summary,
27085
+ sourceSeq: Math.max(tail?.sourceSeq ?? through, ...fresh.map((row) => row.seq))
26354
27086
  }), records);
26355
27087
  this.dirty.delete(draft.sessionID);
26356
27088
  this.metadata.delete(draft.sessionID);
@@ -26381,13 +27113,36 @@ class NativeFoldReplay {
26381
27113
  return true;
26382
27114
  }
26383
27115
  async restore(sessionID, cut, model, options = {}) {
27116
+ let replay;
27117
+ let controls = [];
27118
+ if (this.options.protocol === 3) {
27119
+ const reader = this.openReader(sessionID);
27120
+ try {
27121
+ replay = await this.floorState(sessionID, reader);
27122
+ if (replay)
27123
+ controls = controlsThrough(replay.controls, reader, sessionID, cut.seq - 1);
27124
+ } finally {
27125
+ reader.close();
27126
+ }
27127
+ if (!replay) {
27128
+ this.report(sessionID, "replay refused: missing usable checkpoint boundary");
27129
+ throw new NativeReplayUnavailable("Host checkpoint replay boundary is unavailable");
27130
+ }
27131
+ options = { ...options, bounded: false, after: replay.floor.after };
27132
+ }
26384
27133
  const release = this.storage.hold(sessionID);
27134
+ let result;
26385
27135
  try {
26386
- return await this.restoreHeld(sessionID, cut, model, options);
27136
+ result = await this.restoreHeld(sessionID, cut, model, options);
26387
27137
  } finally {
26388
27138
  this.account(sessionID);
26389
27139
  release();
26390
27140
  }
27141
+ if (replay) {
27142
+ await this.retainReplay(sessionID, replay, model, cut.seq - 1);
27143
+ return result && insertControls(result, controls, nativeRowID);
27144
+ }
27145
+ return result;
26391
27146
  }
26392
27147
  async restoreHeld(sessionID, cut, model, options) {
26393
27148
  if (!isLocalCheckpoint(cut))
@@ -26397,23 +27152,24 @@ class NativeFoldReplay {
26397
27152
  id: model.slice(model.indexOf("/") + 1)
26398
27153
  };
26399
27154
  const tail = this.tail(sessionID);
26400
- if (tail && tail.model !== model)
27155
+ if (tail && tail.model !== model && !(this.options.protocol === 3 && tail.model === ""))
26401
27156
  this.invalidate(sessionID);
26402
27157
  let after = options.after ?? -1;
26403
- if (options.bounded && options.after === undefined && !this.changed.has(sessionID)) {
26404
- const state = getOrCreateSessionMeta(this.storage.db, sessionID);
26405
- const max = this.storage.db.prepare("SELECT COALESCE(MAX(id),0) AS id FROM m0_mutation_log WHERE session_id=?").get(sessionID);
26406
- const boundary = this.storage.db.prepare("SELECT cached_m0_last_baseline_end_message_id AS id FROM session_meta WHERE session_id=?").get(sessionID)?.id;
26407
- if (max.id <= (state.cachedM0MaxMutationId ?? 0) && boundary)
26408
- after = this.storage.sequenceForID(sessionID, boundary) ?? -1;
26409
- }
26410
- const through = cut.seq - 1;
26411
27158
  let reader;
26412
27159
  try {
27160
+ if (options.bounded && options.after === undefined && !this.changed.has(sessionID)) {
27161
+ const state = getOrCreateSessionMeta(this.storage.db, sessionID);
27162
+ const max = this.storage.db.prepare("SELECT COALESCE(MAX(id),0) AS id FROM m0_mutation_log WHERE session_id=?").get(sessionID);
27163
+ const boundary = this.storage.db.prepare("SELECT cached_m0_last_baseline_end_message_id AS id FROM session_meta WHERE session_id=?").get(sessionID)?.id;
27164
+ if (max.id <= (state.cachedM0MaxMutationId ?? 0) && boundary) {
27165
+ after = this.storage.sequenceForID(sessionID, boundary) ?? (reader = this.openReader(sessionID)).sequenceForId(sessionID, boundary) ?? -1;
27166
+ }
27167
+ }
27168
+ const through = cut.seq - 1;
26413
27169
  let metadata = this.metadata.get(sessionID);
26414
27170
  if (!metadata || (this.metadataThrough.get(sessionID) ?? -1) < through) {
26415
- reader = this.openReader(sessionID);
26416
- metadata = reader.rowStampsThrough(sessionID, through).filter(conversational);
27171
+ reader ??= this.openReader(sessionID);
27172
+ metadata = reader.rowStampsThrough(sessionID, through, this.options.protocol === 3 ? after : undefined).filter(conversational);
26417
27173
  this.metadata.set(sessionID, metadata);
26418
27174
  this.metadataThrough.set(sessionID, through);
26419
27175
  }
@@ -26449,26 +27205,34 @@ class NativeFoldReplay {
26449
27205
  async restoreRead(sessionID, cut, model) {
26450
27206
  const reader = this.openReader(sessionID);
26451
27207
  try {
26452
- return reader.range(sessionID, -1, cut.seq - 1).filter(conversational).flatMap((row) => {
27208
+ const replay = this.options.protocol === 3 ? await this.floorState(sessionID, reader) : undefined;
27209
+ if (this.options.protocol === 3 && !replay) {
27210
+ this.report(sessionID, "replay refused: missing usable checkpoint boundary");
27211
+ throw new NativeReplayUnavailable("Host checkpoint replay boundary is unavailable");
27212
+ }
27213
+ const messages = reader.range(sessionID, replay?.floor.after ?? -1, cut.seq - 1).filter(conversational).flatMap((row) => {
26453
27214
  const messages = this.rendered(row, model);
26454
27215
  for (const message of messages)
26455
27216
  coordinates.set(message, row.id);
26456
27217
  return messages;
26457
27218
  });
27219
+ return replay ? insertControls(messages, controlsThrough(replay.controls, reader, sessionID, cut.seq - 1), nativeRowID) : messages;
26458
27220
  } finally {
26459
27221
  reader.close();
26460
27222
  }
26461
27223
  }
26462
27224
  sourceChanged(sessionID) {
26463
- return this.changed.has(sessionID);
27225
+ return this.changed.has(sessionID) || this.editedAdmissions.has(sessionID);
26464
27226
  }
26465
27227
  needsHeadRebuild(sessionID) {
26466
- return this.staleHeads.has(sessionID);
27228
+ return this.staleHeads.has(sessionID) || this.editedAdmissions.has(sessionID);
26467
27229
  }
26468
27230
  clear(sessionID) {
26469
27231
  this.sources.delete(sessionID);
26470
27232
  this.metadata.delete(sessionID);
26471
27233
  this.metadataThrough.delete(sessionID);
27234
+ this.metadataAfter.delete(sessionID);
27235
+ this.metadataAfter.delete(sessionID);
26472
27236
  this.loaded.delete(sessionID);
26473
27237
  this.unavailable.delete(sessionID);
26474
27238
  this.dirty.delete(sessionID);
@@ -26476,6 +27240,11 @@ class NativeFoldReplay {
26476
27240
  this.staleHeads.delete(sessionID);
26477
27241
  }
26478
27242
  async forget(sessionID) {
27243
+ if (this.stampMRU?.sessionID === sessionID)
27244
+ this.stampMRU = undefined;
27245
+ this.unprovenControls.delete(sessionID);
27246
+ this.cancelLegacyUpgrade(sessionID);
27247
+ this.cancelEditedAdmission(sessionID);
26479
27248
  if (this.admissions)
26480
27249
  await forgetNativeFoldProvenance(this.admissions, sessionID);
26481
27250
  await this.storage.forget(sessionID);
@@ -26494,9 +27263,9 @@ class HostFoldPolicy {
26494
27263
  owned(sessionID, cut, id) {
26495
27264
  return cut.id === id && isAdmittedLocalCheckpoint(this.deps.storage, sessionID, cut);
26496
27265
  }
26497
- async idle(sessionID) {
27266
+ async idle(sessionID, eligible = () => true) {
26498
27267
  const { storage, session, threshold } = this.deps;
26499
- if (!Number.isSafeInteger(threshold) || threshold <= 0 || typeof session.compact !== "function" || this.active.has(sessionID))
27268
+ if (!Number.isSafeInteger(threshold) || threshold <= 0 || typeof session.compact !== "function" || !eligible() || this.active.has(sessionID))
26500
27269
  return;
26501
27270
  this.active.add(sessionID);
26502
27271
  const now = this.deps.now ?? Date.now;
@@ -26515,8 +27284,11 @@ class HostFoldPolicy {
26515
27284
  }
26516
27285
  const after = cut?.seq ?? -1;
26517
27286
  const before = reader.storedRowsAfter(sessionID, after);
26518
- if (before < threshold || !await this.deps.canReplay(sessionID, reader))
27287
+ if (before < threshold)
27288
+ return;
27289
+ if (this.deps.canFold && !await this.deps.canFold(sessionID, reader))
26519
27290
  return;
27291
+ const capture = await this.deps.canReplay(sessionID, reader);
26520
27292
  const retry = old?.after === after ? old.attempt + (previous?.status === "failed" || previous?.status === "coalesced" ? 1 : 0) : 0;
26521
27293
  const id = old?.after === after && previous?.status === "pending" ? old.id : `msg_mc_fold_${foldDigest(`${storage.sourceID}/${sessionID}/${after}/${retry}`).slice(0, 24)}`;
26522
27294
  attempt = {
@@ -26525,7 +27297,8 @@ class HostFoldPolicy {
26525
27297
  watermark: reader.latestSequence(sessionID),
26526
27298
  attempt: retry,
26527
27299
  id,
26528
- started: now()
27300
+ started: now(),
27301
+ capture
26529
27302
  };
26530
27303
  claimed = await storage.claim(sessionID, id, JSON.stringify(attempt), this.owner, now());
26531
27304
  if (!claimed)
@@ -26533,6 +27306,10 @@ class HostFoldPolicy {
26533
27306
  } finally {
26534
27307
  reader.close();
26535
27308
  }
27309
+ if (!eligible()) {
27310
+ await storage.finish(sessionID, attempt.id, this.owner, "coalesced", now());
27311
+ return;
27312
+ }
26536
27313
  const admitted = await session.compact({
26537
27314
  sessionID,
26538
27315
  id: attempt.id,
@@ -26549,7 +27326,7 @@ class HostFoldPolicy {
26549
27326
  }
26550
27327
  const after = settled.storedRowsAfter(sessionID, cut.seq);
26551
27328
  if (await storage.finish(sessionID, attempt.id, this.owner, "completed", now()))
26552
- this.deps.log(sessionID, `v2 host fold: rows_before=${attempt.before} rows_after=${after} duration_ms=${now() - attempt.started} reason=row_threshold id=${cut.id} status=completed`);
27329
+ this.deps.log(sessionID, `v2 host fold: rows_before=${attempt.before} rows_after=${after} duration_ms=${now() - attempt.started} reason=row_threshold id=${cut.id} capture=${attempt.capture ? "present" : "absent"} status=completed`);
26553
27330
  } finally {
26554
27331
  settled.close();
26555
27332
  }
@@ -26572,7 +27349,7 @@ class HostFoldPolicy {
26572
27349
  }
26573
27350
 
26574
27351
  // src/v2/fork-inheritance.ts
26575
- var RAW_TYPES = new Set(RAW_MESSAGE_TYPES);
27352
+ var RAW_TYPES = new Set(RAW_MESSAGE_TYPES2);
26576
27353
  function forkBoundarySeq(origin, sequenceForId) {
26577
27354
  const seq = sequenceForId(origin.parentSessionID, origin.boundary.messageID);
26578
27355
  if (seq === undefined)
@@ -36701,7 +37478,7 @@ class V2RetrospectiveRawProvider {
36701
37478
  contextDb;
36702
37479
  openReader;
36703
37480
  reader;
36704
- constructor(contextDb, openReader = () => new V2StoreReader(gaDatabasePath(getDataDir(), process.env.OPENCODE_CHANNEL ?? "latest"))) {
37481
+ constructor(contextDb, openReader = () => new V2StoreReader2(gaDatabasePath2(getDataDir(), process.env.OPENCODE_CHANNEL ?? "latest"))) {
36705
37482
  this.contextDb = contextDb;
36706
37483
  this.openReader = openReader;
36707
37484
  }
@@ -37505,7 +38282,7 @@ function startDreamTrigger(context, args) {
37505
38282
  if (!db)
37506
38283
  continue;
37507
38284
  try {
37508
- const reader = args.openReader?.() ?? new V2StoreReader(gaDatabasePath(getDataDir(), process.env.OPENCODE_CHANNEL ?? "latest"));
38285
+ const reader = args.openReader?.() ?? new V2StoreReader2(gaDatabasePath2(getDataDir(), process.env.OPENCODE_CHANNEL ?? "latest"));
37509
38286
  try {
37510
38287
  const activity = reader.rootSessionActivity([event.data.sessionID]).get(event.data.sessionID);
37511
38288
  if (activity !== undefined)
@@ -37709,7 +38486,7 @@ function hiddenTerminalError(event) {
37709
38486
 
37710
38487
  // src/v2/hooks/lkg-system.ts
37711
38488
  import { createHash as createHash15 } from "node:crypto";
37712
- function identity(slot) {
38489
+ function identity2(slot) {
37713
38490
  return createHash15("sha256").update(JSON.stringify({
37714
38491
  capturedAt: slot.capturedAt,
37715
38492
  captureSequence: slot.captureSequence,
@@ -37725,7 +38502,7 @@ class V2LkgSystemReplay {
37725
38502
  systems = new BoundedSessionMap(1000);
37726
38503
  capture(sessionId, slot, input, served, head) {
37727
38504
  this.systems.set(sessionId, {
37728
- slot: identity(slot),
38505
+ slot: identity2(slot),
37729
38506
  input: hostInputKey(input),
37730
38507
  served: structuredClone(served),
37731
38508
  head: head ? structuredClone(head) : null
@@ -37733,7 +38510,7 @@ class V2LkgSystemReplay {
37733
38510
  }
37734
38511
  restore(sessionId, slot, input, target) {
37735
38512
  const saved = this.systems.get(sessionId);
37736
- if (!slot || !saved || saved.slot !== identity(slot) || saved.input !== hostInputKey(input))
38513
+ if (!slot || !saved || saved.slot !== identity2(slot) || saved.input !== hostInputKey(input))
37737
38514
  return;
37738
38515
  target.splice(0, target.length, ...structuredClone(saved.served));
37739
38516
  return { head: saved.head ? structuredClone(saved.head) : null };
@@ -37789,6 +38566,112 @@ async function warmModelLimitCacheFromCatalog(context, options = {}) {
37789
38566
  }
37790
38567
  }
37791
38568
 
38569
+ // src/v2/hooks/overflow-recovery.ts
38570
+ function isRateLimit(error) {
38571
+ const pending = [error];
38572
+ const seen = new Set;
38573
+ for (let i = 0;pending.length && i < 16; i++) {
38574
+ const value = pending.shift();
38575
+ if (seen.has(value))
38576
+ continue;
38577
+ seen.add(value);
38578
+ if (typeof value === "string") {
38579
+ try {
38580
+ pending.push(JSON.parse(value));
38581
+ } catch {}
38582
+ } else if (value && typeof value === "object") {
38583
+ const p = value;
38584
+ if (p.status === 429 || p.statusCode === 429 || [p.type, p.name, p.code, p._tag].some((tag) => typeof tag === "string" && /rate[_ .-]?limit|throttl/i.test(tag)))
38585
+ return true;
38586
+ pending.push(p.data, p.error, p.cause);
38587
+ }
38588
+ }
38589
+ return false;
38590
+ }
38591
+
38592
+ class V2OverflowRecovery {
38593
+ deps;
38594
+ requests = new BoundedSessionMap(1000);
38595
+ constructor(deps) {
38596
+ this.deps = deps;
38597
+ }
38598
+ begin(input) {
38599
+ if (input.kind !== "primary" || this.deps.isHidden(input.sessionID))
38600
+ return;
38601
+ const prior = this.requests.get(input.sessionID);
38602
+ if (input.assistantMessageID && prior?.assistantMessageID === input.assistantMessageID && prior.model.providerID === input.model.providerID && prior.model.id === input.model.id)
38603
+ return;
38604
+ this.requests.set(input.sessionID, {
38605
+ model: { ...input.model },
38606
+ assistantMessageID: input.assistantMessageID,
38607
+ observed: false
38608
+ });
38609
+ }
38610
+ forget(sessionID) {
38611
+ this.requests.delete(sessionID);
38612
+ }
38613
+ observeTerminal(event, readStep) {
38614
+ if (!["session.step.failed", "session.execution.failed", "session.error"].includes(event.type ?? ""))
38615
+ return;
38616
+ const sessionID = event.data?.sessionID;
38617
+ if (!sessionID || this.deps.isHidden(sessionID))
38618
+ return;
38619
+ const error = event.type === "session.step.failed" ? event.data?.error : hiddenTerminalError(event);
38620
+ if (error === undefined)
38621
+ return;
38622
+ const prior = this.requests.get(sessionID);
38623
+ if (prior?.observed || isRateLimit(error) || !detectOverflow(error).isOverflow)
38624
+ return;
38625
+ const messageID = event.data?.assistantMessageID;
38626
+ const step = readStep(sessionID, messageID);
38627
+ if (!step)
38628
+ return;
38629
+ if (!messageID && (!step?.error || !detectOverflow(step.error).isOverflow))
38630
+ return;
38631
+ if (!prior && step.model)
38632
+ this.begin({
38633
+ sessionID,
38634
+ kind: "primary",
38635
+ model: step.model,
38636
+ assistantMessageID: step.id
38637
+ });
38638
+ const request = this.requests.get(sessionID);
38639
+ if (!request)
38640
+ return;
38641
+ this.observe({
38642
+ sessionID,
38643
+ error,
38644
+ model: step?.model ?? request.model,
38645
+ assistantMessageID: messageID ?? step?.id
38646
+ });
38647
+ }
38648
+ observe(input) {
38649
+ if (!this.requests.has(input.sessionID) && input.kind === "primary")
38650
+ this.begin({ ...input, kind: "primary" });
38651
+ const request = this.requests.get(input.sessionID);
38652
+ if (!request || request.observed || this.deps.isHidden(input.sessionID) || request.model.providerID !== input.model.providerID || request.model.id !== input.model.id || input.assistantMessageID && request.assistantMessageID && input.assistantMessageID !== request.assistantMessageID)
38653
+ return;
38654
+ if (input.status === 429 || isRateLimit(input.error))
38655
+ return;
38656
+ const detection = detectOverflow(input.error);
38657
+ if (!detection.isOverflow)
38658
+ return;
38659
+ const db = this.deps.database();
38660
+ if (!db)
38661
+ return;
38662
+ const modelKey = `${input.model.providerID}/${input.model.id}`;
38663
+ if (this.deps.compactionOff) {
38664
+ if (detection.reportedLimit)
38665
+ recordDetectedContextLimit(db, input.sessionID, detection.reportedLimit, modelKey, detection.reportedLimitProvenance);
38666
+ } else {
38667
+ recordOverflowDetected(db, input.sessionID, detection.reportedLimit, modelKey, "provider_overflow", detection.reportedLimitProvenance, detection.reportedInputTokens);
38668
+ }
38669
+ request.observed = true;
38670
+ if (!this.deps.compactionOff && detection.reportedInputTokens)
38671
+ this.deps.onInputTokens?.(input.sessionID, detection.reportedInputTokens, getOverflowState(db, input.sessionID, modelKey).detectedContextLimit);
38672
+ }
38673
+ }
38674
+
37792
38675
  // src/v2/hooks/refusal.ts
37793
38676
  class V2ContextRefusal extends Error {
37794
38677
  constructor(message = "Context full — /ctx-flush or /clear to continue.", options) {
@@ -38519,257 +39402,6 @@ async function probeV2StorageAtBoot(storage, timeoutMs = 15000) {
38519
39402
  }
38520
39403
  }
38521
39404
 
38522
- // src/v2/hooks/store.ts
38523
- var rawMessageTypes = new Set(RAW_MESSAGE_TYPES);
38524
- var isRawRow = (row) => rawMessageTypes.has(row.type);
38525
- var NO_MODEL = { providerID: "", id: "" };
38526
- function hostServesRowById(row) {
38527
- return isRawRow(row) && restoreRow(row, NO_MODEL).some((message) => message.id === row.id);
38528
- }
38529
- function projectRawMessages(rows, ordinalFor) {
38530
- return rows.filter(isRawRow).map((row, index) => {
38531
- const message = {
38532
- id: row.id,
38533
- ordinal: ordinalFor(row, index),
38534
- role: row.type === "assistant" ? "assistant" : row.type === "system" ? "system" : "user",
38535
- createdAt: row.time_created ?? row.data.time?.created,
38536
- parts: row.type === "assistant" ? (row.data.content ?? []).map((part) => {
38537
- if (part.type !== "tool")
38538
- return { ...part };
38539
- const state = part.state;
38540
- const content = state.content;
38541
- return {
38542
- type: "tool",
38543
- tool: part.name,
38544
- callID: part.id,
38545
- state: {
38546
- ...state,
38547
- output: state.status === "error" ? toolStateContent(state) : content?.filter((p) => p.type === "text").map((p) => p.text).join(`
38548
- `) ?? ""
38549
- }
38550
- };
38551
- }) : [{ type: "text", text: row.data.text ?? "" }]
38552
- };
38553
- Object.defineProperty(message, "storeType", { value: row.type, enumerable: false });
38554
- if (!hostServesRowById(row))
38555
- markHostUnservedRow(message);
38556
- return message;
38557
- });
38558
- }
38559
- function rawMessages(rows, history = rows) {
38560
- const ordinals = new Map(history.filter(isRawRow).map((row, index) => [row.id, index + 1]));
38561
- return projectRawMessages(rows, (row) => {
38562
- return ordinals.get(row.id) ?? 0;
38563
- });
38564
- }
38565
- function rawMessagePage(rows, afterOrdinal) {
38566
- return projectRawMessages(rows, (_row, index) => afterOrdinal + index + 1);
38567
- }
38568
- var SERVED_BOUNDARY_PAGE = 50;
38569
- function servedBoundaryRow(reader, sessionID, messageID) {
38570
- const boundary = reader.messageById(sessionID, messageID);
38571
- if (!boundary)
38572
- return null;
38573
- if (hostServesRowById(boundary))
38574
- return boundary;
38575
- let through = boundary.seq - 1;
38576
- for (;; ) {
38577
- const rows = reader.rawRowsThrough(sessionID, through, SERVED_BOUNDARY_PAGE);
38578
- const served = rows.find(hostServesRowById);
38579
- if (served)
38580
- return served;
38581
- const oldest = rows.at(-1);
38582
- if (rows.length < SERVED_BOUNDARY_PAGE || !oldest)
38583
- return null;
38584
- through = oldest.seq - 1;
38585
- }
38586
- }
38587
- function resolveV2BoundaryUserMessage(reader, sessionID, endMessageID) {
38588
- const end = reader.messageById(sessionID, endMessageID);
38589
- if (!end || !isRawRow(end))
38590
- return null;
38591
- let through = end.seq;
38592
- for (;; ) {
38593
- const rows = reader.rawRowsThrough(sessionID, through, SERVED_BOUNDARY_PAGE);
38594
- const user = rows.find((row) => row.type !== "assistant");
38595
- if (user)
38596
- return rawMessagePage([user], 0)[0] ?? null;
38597
- const oldest = rows.at(-1);
38598
- if (rows.length < SERVED_BOUNDARY_PAGE || !oldest)
38599
- return null;
38600
- through = oldest.seq - 1;
38601
- }
38602
- }
38603
- function readAllV2RawMessagesForConversion(openReader, sessionID) {
38604
- const reader = openReader();
38605
- try {
38606
- return rawMessages(reader.history(sessionID));
38607
- } finally {
38608
- reader.close();
38609
- }
38610
- }
38611
- var CONVERSION_PAGE_ROWS = 1000;
38612
- function* readV2RawMessagePagesForConversion(openReader, sessionID, pageRows = CONVERSION_PAGE_ROWS) {
38613
- const reader = openReader();
38614
- try {
38615
- let after = -1;
38616
- let ordinal = 0;
38617
- for (;; ) {
38618
- const page = reader.page(sessionID, { after, limit: pageRows });
38619
- const messages = rawMessagePage(page.rows, ordinal);
38620
- ordinal += messages.length;
38621
- if (messages.length > 0)
38622
- yield messages;
38623
- if (page.rows.length < pageRows || page.cursor === undefined)
38624
- return;
38625
- after = page.cursor;
38626
- }
38627
- } finally {
38628
- reader.close();
38629
- }
38630
- }
38631
- function createV2RawMessageReader(openReader) {
38632
- const servedBoundaryCache = new Map;
38633
- return {
38634
- getRevision: (sessionID) => {
38635
- const reader = openReader();
38636
- try {
38637
- return reader.latestSequence(sessionID);
38638
- } finally {
38639
- reader.close();
38640
- }
38641
- },
38642
- getCountAfterRevision: (sessionID, after, through) => {
38643
- const reader = openReader();
38644
- try {
38645
- return reader.messageCountAfterSequence(sessionID, after, through);
38646
- } finally {
38647
- reader.close();
38648
- }
38649
- },
38650
- readPage: (sessionID, afterOrdinal, limit, finalWatermark, after) => {
38651
- const reader = openReader();
38652
- try {
38653
- return rawMessagePage(reader.messagePage(sessionID, afterOrdinal, limit, finalWatermark, after), afterOrdinal);
38654
- } finally {
38655
- reader.close();
38656
- }
38657
- },
38658
- findById: (sessionID, messageID) => {
38659
- const reader = openReader();
38660
- try {
38661
- const ordinal = reader.messageOrdinalById(sessionID, messageID);
38662
- const row = reader.messageById(sessionID, messageID);
38663
- if (ordinal === null || row === null)
38664
- return null;
38665
- return rawMessagePage([row], ordinal - 1)[0] ?? null;
38666
- } finally {
38667
- reader.close();
38668
- }
38669
- },
38670
- findPartsById: (sessionID, messageID) => {
38671
- const reader = openReader();
38672
- try {
38673
- const row = reader.messageById(sessionID, messageID);
38674
- return row ? rawMessagePage([row], 0)[0] ?? null : null;
38675
- } finally {
38676
- reader.close();
38677
- }
38678
- },
38679
- hasById: (sessionID, messageID) => {
38680
- const reader = openReader();
38681
- try {
38682
- return reader.messageExistsById(sessionID, messageID);
38683
- } finally {
38684
- reader.close();
38685
- }
38686
- },
38687
- ordinalOf: (sessionID, messageID) => {
38688
- const reader = openReader();
38689
- try {
38690
- return reader.messageOrdinalById(sessionID, messageID);
38691
- } finally {
38692
- reader.close();
38693
- }
38694
- },
38695
- orderOf: (sessionID, messageID) => {
38696
- const reader = openReader();
38697
- try {
38698
- return reader.sequenceForId(sessionID, messageID) ?? null;
38699
- } finally {
38700
- reader.close();
38701
- }
38702
- },
38703
- ordinalMapForRange: (sessionID, fromOrdinal, toOrdinal) => {
38704
- const reader = openReader();
38705
- try {
38706
- return reader.messageIdOrdinals(sessionID, fromOrdinal, toOrdinal);
38707
- } finally {
38708
- reader.close();
38709
- }
38710
- },
38711
- readOrdinalPage: (sessionID, after, limit) => {
38712
- const reader = openReader();
38713
- try {
38714
- return reader.messageOrdinalPage(sessionID, after, limit);
38715
- } finally {
38716
- reader.close();
38717
- }
38718
- },
38719
- getCount: (sessionID) => {
38720
- const reader = openReader();
38721
- try {
38722
- return reader.messageCount(sessionID);
38723
- } finally {
38724
- reader.close();
38725
- }
38726
- },
38727
- getStoredCount: (sessionID) => {
38728
- const reader = openReader();
38729
- try {
38730
- return reader.storedMessageCount(sessionID);
38731
- } finally {
38732
- reader.close();
38733
- }
38734
- },
38735
- servedBoundaryIdOf: (sessionID, messageID) => {
38736
- const key = `${sessionID}\x00${messageID}`;
38737
- if (servedBoundaryCache.has(key))
38738
- return servedBoundaryCache.get(key) ?? null;
38739
- const reader = openReader();
38740
- try {
38741
- const served = servedBoundaryRow(reader, sessionID, messageID)?.id ?? null;
38742
- if (servedBoundaryCache.size >= 1000)
38743
- servedBoundaryCache.clear();
38744
- if (served !== null)
38745
- servedBoundaryCache.set(key, served);
38746
- return served;
38747
- } finally {
38748
- reader.close();
38749
- }
38750
- }
38751
- };
38752
- }
38753
- function createV2RawMessageProvider(reader, sessionID) {
38754
- return {
38755
- readMessagePage: (afterOrdinal, limit, finalWatermark, after) => reader.readPage(sessionID, afterOrdinal, limit, finalWatermark, after),
38756
- readMessageById: (messageID) => reader.findById(sessionID, messageID),
38757
- readMessagePartsById: (messageID) => reader.findPartsById(sessionID, messageID),
38758
- hasMessageById: (messageID) => reader.hasById(sessionID, messageID),
38759
- readMessageOrdinalById: (messageID) => reader.ordinalOf(sessionID, messageID),
38760
- ...reader.orderOf ? {
38761
- readMessageOrderById: (messageID) => reader.orderOf?.(sessionID, messageID) ?? null
38762
- } : {},
38763
- readMessageIdOrdinalsForRange: (fromOrdinal, toOrdinal) => reader.ordinalMapForRange(sessionID, fromOrdinal, toOrdinal),
38764
- readMessageOrdinalPage: (after, limit) => reader.readOrdinalPage(sessionID, after, limit),
38765
- getMessageCount: () => reader.getCount(sessionID),
38766
- getStoredMessageCount: () => reader.getStoredCount(sessionID),
38767
- ...reader.servedBoundaryIdOf ? {
38768
- readServedBoundaryId: (messageID) => reader.servedBoundaryIdOf?.(sessionID, messageID) ?? null
38769
- } : {}
38770
- };
38771
- }
38772
-
38773
39405
  // src/v2/hooks/system-prompt-response.ts
38774
39406
  function bindV2SystemPromptResponse(sessionId, reader) {
38775
39407
  const request = currentLkgRequestIdentity(sessionId);
@@ -49887,7 +50519,7 @@ var ZodObject = /* @__PURE__ */ $constructor("ZodObject", (inst, def) => {
49887
50519
  inst.partial = (...args) => partial(ZodOptional, inst, args[0]);
49888
50520
  inst.required = (...args) => required(ZodNonOptional, inst, args[0]);
49889
50521
  });
49890
- function object(shape, params) {
50522
+ function object2(shape, params) {
49891
50523
  const def = {
49892
50524
  type: "object",
49893
50525
  get shape() {
@@ -50557,236 +51189,6 @@ function resolveCtxExpandMode(args, domain) {
50557
51189
  return { kind: "error", message: rangeError(domain) };
50558
51190
  }
50559
51191
 
50560
- // src/tools/ctx-expand/render.ts
50561
- import { createHash as createHash16 } from "node:crypto";
50562
- function isRecord6(value) {
50563
- return value !== null && typeof value === "object" && !Array.isArray(value);
50564
- }
50565
- function roleLabel(role) {
50566
- if (role === "assistant")
50567
- return "A (assistant)";
50568
- if (role === "user")
50569
- return "U (user)";
50570
- return role;
50571
- }
50572
- function verboseRoleLabel(msg) {
50573
- if (msg.role === "user" && msg.parts.length > 0 && msg.parts.every((part) => {
50574
- if (!isRecord6(part))
50575
- return false;
50576
- if (part.type === "tool_result")
50577
- return true;
50578
- return part.type === "tool" && asToolPart(part)?.output != null;
50579
- }))
50580
- return "tool results";
50581
- return roleLabel(msg.role);
50582
- }
50583
- function truncate3(value, max) {
50584
- const t = value.trim();
50585
- return t.length <= max ? t : `${t.slice(0, max)}…`;
50586
- }
50587
- function keyArg(input) {
50588
- if (!input)
50589
- return "";
50590
- for (const k of ["filePath", "path", "pattern", "query", "symbol", "module", "action"]) {
50591
- const v = input[k];
50592
- if (typeof v === "string" && v.length > 0)
50593
- return truncate3(v, 60);
50594
- }
50595
- if (typeof input.description === "string")
50596
- return truncate3(input.description, 60);
50597
- return "";
50598
- }
50599
- function asToolPart(part) {
50600
- const type = typeof part.type === "string" ? part.type : "";
50601
- if (type === "tool") {
50602
- const state = isRecord6(part.state) ? part.state : null;
50603
- const output = state && typeof state.output === "string" ? state.output : state && state.output != null ? JSON.stringify(state.output) : null;
50604
- const metadata = state && isRecord6(state.metadata) ? state.metadata : null;
50605
- const title = state && typeof state.title === "string" && state.title || metadata && typeof metadata.title === "string" && metadata.title || null;
50606
- return {
50607
- name: typeof part.tool === "string" ? part.tool : "tool",
50608
- callId: typeof part.callID === "string" ? part.callID : "",
50609
- title,
50610
- input: state && isRecord6(state.input) ? state.input : null,
50611
- output
50612
- };
50613
- }
50614
- if (type === "tool_use") {
50615
- return {
50616
- name: typeof part.name === "string" ? part.name : "tool",
50617
- callId: typeof part.id === "string" ? part.id : "",
50618
- title: null,
50619
- input: isRecord6(part.input) ? part.input : null,
50620
- output: null
50621
- };
50622
- }
50623
- if (type === "tool_result") {
50624
- const content = part.content;
50625
- const output = typeof content === "string" ? content : content != null ? JSON.stringify(content) : null;
50626
- return {
50627
- name: "tool_result",
50628
- callId: typeof part.tool_use_id === "string" ? part.tool_use_id : "",
50629
- title: null,
50630
- input: null,
50631
- output
50632
- };
50633
- }
50634
- return null;
50635
- }
50636
- function textOf(part) {
50637
- if (part.type === "text" && typeof part.text === "string")
50638
- return part.text;
50639
- return null;
50640
- }
50641
- function reasoningOf(part) {
50642
- if ((part.type === "reasoning" || part.type === "thinking") && typeof part.text === "string") {
50643
- return part.text;
50644
- }
50645
- return null;
50646
- }
50647
- function renderPartPreview(part, expandTools) {
50648
- if (!isRecord6(part))
50649
- return null;
50650
- const expansion = expandToolPart(part, expandTools, true);
50651
- if (expansion !== null)
50652
- return ` • tool ${part.tool}: ${expansion}`;
50653
- const text = textOf(part);
50654
- if (text !== null) {
50655
- const t = truncate3(text, 200);
50656
- return t.length > 0 ? ` • ${t}` : null;
50657
- }
50658
- const tool = asToolPart(part);
50659
- if (tool) {
50660
- const arg = keyArg(tool.input);
50661
- const head = arg ? `${tool.name}(${arg})` : tool.name;
50662
- return tool.output !== null ? ` • tool ${head} → output ~${estimateTokens(tool.output)} tok` : ` • tool ${head}`;
50663
- }
50664
- const reasoning = reasoningOf(part);
50665
- if (reasoning !== null)
50666
- return ` • [reasoning] ${truncate3(reasoning, 120)}`;
50667
- const type = typeof part.type === "string" ? part.type : "part";
50668
- if (type === "file")
50669
- return " • [file]";
50670
- if (type === "step-start" || type === "step-finish")
50671
- return null;
50672
- return ` • [${type}]`;
50673
- }
50674
- function renderPartFull(part) {
50675
- if (!isRecord6(part))
50676
- return null;
50677
- const text = textOf(part);
50678
- if (text !== null) {
50679
- return text.trim().length > 0 ? ` [text]
50680
- ${text}` : null;
50681
- }
50682
- const tool = asToolPart(part);
50683
- if (tool) {
50684
- const lines = [];
50685
- const idSuffix = tool.callId ? ` #${tool.callId}` : "";
50686
- lines.push(` [tool: ${tool.name}${idSuffix}]`);
50687
- if (tool.title && tool.title.trim().length > 0) {
50688
- lines.push(` description: ${tool.title.trim()}`);
50689
- }
50690
- if (tool.input)
50691
- lines.push(` input: ${JSON.stringify(tool.input)}`);
50692
- if (tool.output !== null)
50693
- lines.push(` output:
50694
- ${tool.output}`);
50695
- return lines.join(`
50696
- `);
50697
- }
50698
- const type = typeof part.type === "string" ? part.type : "part";
50699
- if (type === "file") {
50700
- const name = typeof part.filename === "string" && part.filename || typeof part.url === "string" && part.url || "";
50701
- return ` [file]${name ? ` ${name}` : ""}`;
50702
- }
50703
- return null;
50704
- }
50705
- function renderMessageByOrdinal(sessionId, ordinal) {
50706
- const found = [];
50707
- visitRawSessionMessages2(sessionId, ordinal, ordinal, (m) => {
50708
- if (m.ordinal === ordinal)
50709
- found.push(m);
50710
- return false;
50711
- });
50712
- const msg = found[0];
50713
- if (!msg) {
50714
- return `No message at ordinal ${ordinal} in this session's stored history — it was deleted ` + `(session prune/revert) or the ordinal is wrong, so it can't be recovered. ` + `Re-run the tool if you still need the data.`;
50715
- }
50716
- const rendered = msg.parts.map(renderPartFull).filter((l) => l !== null);
50717
- const lines = [`[${msg.ordinal}] ${roleLabel(msg.role)} — full recovery:`, ""];
50718
- if (rendered.length === 0) {
50719
- lines.push(" (no recoverable content — message had only structural/reasoning parts)");
50720
- } else {
50721
- lines.push(...rendered);
50722
- }
50723
- return lines.join(`
50724
- `);
50725
- }
50726
- function renderVerboseRange(sessionId, start, end, tokenBudget, expandTools) {
50727
- const out = [];
50728
- let usedTokens = 0;
50729
- let lastOrdinal = start - 1;
50730
- let truncated = false;
50731
- visitRawSessionMessages2(sessionId, start, end, (msg) => {
50732
- const header = `[${msg.ordinal}] ${verboseRoleLabel(msg)}`;
50733
- const partLines = msg.parts.map((part) => renderPartPreview(part, expandTools)).filter((l) => l !== null);
50734
- const block = partLines.length > 0 ? `${header}
50735
- ${partLines.join(`
50736
- `)}` : header;
50737
- const blockTokens = estimateTokens(block);
50738
- if (usedTokens + blockTokens > tokenBudget && out.length > 0) {
50739
- truncated = true;
50740
- return false;
50741
- }
50742
- out.push(block);
50743
- usedTokens += blockTokens;
50744
- lastOrdinal = msg.ordinal;
50745
- return true;
50746
- });
50747
- return { text: out.join(`
50748
-
50749
- `), lastOrdinal, truncated };
50750
- }
50751
- function renderItemByTag(db, sessionId, number, textIndexDomain = "part") {
50752
- const tag = getTagById2(db, sessionId, number);
50753
- if (!tag)
50754
- return `no tag ${number} in this session; if ${number} came from a <session-history> heading or a ctx_search hit, it is an ordinal: use message=${number}`;
50755
- if (tag.type === "tool") {
50756
- const owner = tag.toolOwnerMessageId;
50757
- if (!owner)
50758
- return `Tag ${number}'s tool owner is unknown; its original call cannot be resolved safely.`;
50759
- const message = readRawSessionMessageById2(sessionId, owner);
50760
- if (!message)
50761
- return `Tag ${number}'s original tool owner is no longer in stored history.`;
50762
- const parts = message?.parts.filter((part) => isRecord6(part) && asToolPart(part)?.callId === tag.messageId) ?? [];
50763
- if (!parts.some((part) => isRecord6(part) && asToolPart(part)?.output !== null)) {
50764
- visitRawSessionMessages2(sessionId, message.ordinal + 1, Number.MAX_SAFE_INTEGER, (candidate) => {
50765
- const matching = candidate.parts.filter((part) => isRecord6(part) && asToolPart(part)?.callId === tag.messageId);
50766
- if (matching.some((part) => isRecord6(part) && part.type === "tool_use"))
50767
- return false;
50768
- parts.push(...matching);
50769
- return matching.length === 0;
50770
- });
50771
- }
50772
- const rendered = parts.map(renderPartFull).filter((part) => part !== null);
50773
- return rendered.length ? rendered.join(`
50774
- `) : `Tag ${number}'s original tool call is no longer in stored history.`;
50775
- }
50776
- const scoped = /^(.*):p(\d+)$/.exec(tag.messageId);
50777
- const derived = /^(.*):mc-text-v1:([a-f0-9]+):([a-f0-9]+):o(\d+)$/.exec(tag.messageId);
50778
- const owner = scoped?.[1] ?? derived?.[1] ?? tag.messageId;
50779
- const message = readRawSessionMessageById2(sessionId, owner);
50780
- if (!message)
50781
- return `Tag ${number}'s original text is no longer in stored history.`;
50782
- const index = scoped ? Number(scoped[2]) : 0;
50783
- const piText = message.parts.filter((part) => isRecord6(part) && part.type === "text");
50784
- const part = message.parts[index];
50785
- const matching = derived ? piText.filter((part) => isRecord6(part) && typeof part.text === "string" && createHash16("sha256").update(part.text).digest("hex") === derived[3]) : [];
50786
- const selected = derived ? matching[Number(derived[4])] : textIndexDomain === "text" ? piText[index] : part;
50787
- return selected ? renderPartFull(selected) ?? "" : `Tag ${number}'s original text part is no longer in stored history.`;
50788
- }
50789
-
50790
51192
  // src/tools/ctx-expand/tools.ts
50791
51193
  var CTX_EXPAND_RUST_TAG_REFUSAL = "Tag lookup isn't available on this session: its §N§ tags are numbered by the Rust transform engine and ctx_expand cannot resolve those numbers, so no content was returned. Expand by message instead: ctx_expand(message=<ordinal>) or ctx_expand(start=<ordinal>, end=<ordinal>), using ordinals from a <session-history> heading or a ctx_search hit.";
50792
51194
  var ctxExpandArgsShape = {
@@ -50820,11 +51222,36 @@ function createCtxExpandTool(deps) {
50820
51222
  if (mode.kind === "error") {
50821
51223
  return mode.message;
50822
51224
  }
51225
+ const source = rawMessageWorkerSource2(sessionId);
51226
+ const path = getSqliteDatabasePath2(deps.db);
50823
51227
  if (mode.kind === "tag") {
50824
- return renderItemByTag(deps.db, sessionId, mode.tag);
51228
+ if (source) {
51229
+ if (!path)
51230
+ throw new Error("Search archive worker unavailable: private archive has no off-thread source");
51231
+ const text = await readV2ArchiveOffThread2(path, source.path, sessionId, {
51232
+ kind: "tag",
51233
+ tag: mode.tag
51234
+ });
51235
+ if (text === null)
51236
+ throw new Error("Search archive worker unavailable: unexpected tag reply");
51237
+ return text;
51238
+ }
51239
+ return renderItemByTag2(deps.db, sessionId, mode.tag, "part", deps.recoveryAttachments);
50825
51240
  }
50826
51241
  if (mode.kind === "message") {
50827
- return await renderSearchArchiveOffThread2(deps.db, sessionId, mode.message, mode.message, CTX_EXPAND_TOKEN_BUDGET) ?? renderMessageByOrdinal(sessionId, mode.message);
51242
+ if (source) {
51243
+ if (!path)
51244
+ throw new Error("Search archive worker unavailable: private archive has no off-thread source");
51245
+ const text = await readV2ArchiveOffThread2(path, source.path, sessionId, {
51246
+ kind: "message",
51247
+ message: mode.message,
51248
+ tokenBudget: CTX_EXPAND_TOKEN_BUDGET
51249
+ });
51250
+ if (text === null)
51251
+ throw new Error("Search archive worker unavailable: unexpected message reply");
51252
+ return text;
51253
+ }
51254
+ return await renderSearchArchiveOffThread2(deps.db, sessionId, mode.message, mode.message, CTX_EXPAND_TOKEN_BUDGET) ?? renderMessageByOrdinal2(sessionId, mode.message, deps.recoveryAttachments);
50828
51255
  }
50829
51256
  const { start, end, verbose } = mode;
50830
51257
  const lastCompartmentEnd = getLastCompartmentEndMessage(deps.db, sessionId);
@@ -50832,24 +51259,25 @@ function createCtxExpandTool(deps) {
50832
51259
  return `Range ${start}-${end} is entirely within the live tail (after the last compacted message ${lastCompartmentEnd}); those messages are already visible in context.`;
50833
51260
  }
50834
51261
  const effectiveEnd = lastCompartmentEnd >= 0 ? Math.min(end, lastCompartmentEnd) : end;
51262
+ if (verbose && source) {
51263
+ if (!path)
51264
+ throw new Error("Search archive worker unavailable: private archive has no off-thread source");
51265
+ const text = await readV2ArchiveOffThread2(path, source.path, sessionId, {
51266
+ kind: "verbose",
51267
+ start,
51268
+ end: effectiveEnd,
51269
+ tokenBudget: CTX_EXPAND_TOKEN_BUDGET,
51270
+ expandTools: deps.expandTools
51271
+ });
51272
+ if (text === null)
51273
+ throw new Error("Search archive worker unavailable: unexpected verbose reply");
51274
+ return text;
51275
+ }
50835
51276
  const archived = await renderSearchArchiveOffThread2(deps.db, sessionId, start, effectiveEnd, CTX_EXPAND_TOKEN_BUDGET);
50836
51277
  if (archived)
50837
51278
  return archived;
50838
51279
  if (verbose) {
50839
- const v = renderVerboseRange(sessionId, start, effectiveEnd, CTX_EXPAND_TOKEN_BUDGET, deps.expandTools);
50840
- if (!v.text) {
50841
- return `No messages found in range ${start}-${effectiveEnd}. The range may be outside this session's history.`;
50842
- }
50843
- const out = [
50844
- `Messages ${start}-${v.lastOrdinal} (verbose). Recover any one in full with ctx_expand(message=<ordinal>):`,
50845
- "",
50846
- v.text
50847
- ];
50848
- if (v.truncated) {
50849
- out.push("", `Truncated at message ${v.lastOrdinal} (budget: ~${CTX_EXPAND_TOKEN_BUDGET} tokens). Call again with start=${v.lastOrdinal + 1} end=${effectiveEnd} verbose=true for more.`);
50850
- }
50851
- return out.join(`
50852
- `);
51280
+ return renderVerboseRangeForTool2(sessionId, start, effectiveEnd, CTX_EXPAND_TOKEN_BUDGET, deps.expandTools, deps.recoveryAttachments);
50853
51281
  }
50854
51282
  const chunk = readSessionChunk2(sessionId, CTX_EXPAND_TOKEN_BUDGET, start, effectiveEnd + 1, { expand: false });
50855
51283
  if (!chunk.text || chunk.messageCount === 0) {
@@ -52314,7 +52742,7 @@ function formatCtxReduceReply(stampedCount, selfStampCount = 0) {
52314
52742
  return parts.join(" ");
52315
52743
  }
52316
52744
  // src/tools/ctx-reduce/tools.ts
52317
- import { createHash as createHash17 } from "node:crypto";
52745
+ import { createHash as createHash16 } from "node:crypto";
52318
52746
 
52319
52747
  // src/features/magic-context/range-parser.ts
52320
52748
  function parseRangeString(input) {
@@ -52377,11 +52805,11 @@ function createCtxReduceTool(deps) {
52377
52805
  const stableId = `oc-${sessionId}-${callId}`;
52378
52806
  if (Buffer.byteLength(stableId) <= 128)
52379
52807
  return stableId;
52380
- return `oc-${createHash17("sha256").update(stableId).digest("hex")}`;
52808
+ return `oc-${createHash16("sha256").update(stableId).digest("hex")}`;
52381
52809
  }
52382
52810
  fallbackCommandSequence += 1;
52383
52811
  const monotonicId = `oc-${sessionId}-${fallbackCommandSequence}`;
52384
- return Buffer.byteLength(monotonicId) <= 128 ? monotonicId : `oc-${createHash17("sha256").update(monotonicId).digest("hex")}`;
52812
+ return Buffer.byteLength(monotonicId) <= 128 ? monotonicId : `oc-${createHash16("sha256").update(monotonicId).digest("hex")}`;
52385
52813
  };
52386
52814
  return tool({
52387
52815
  description: CTX_REDUCE_DESCRIPTION,
@@ -53038,8 +53466,10 @@ function applyCheckpointHead(draft, head) {
53038
53466
  const { checkpoint, submitted } = head;
53039
53467
  const first = draft.messages.find((message) => message.id === HEAD_IDS[0]);
53040
53468
  const baseline = first?.content.find((part) => part.type === "text")?.text;
53041
- if (typeof baseline !== "string")
53042
- return false;
53469
+ if (typeof baseline !== "string") {
53470
+ draft.messages.unshift(checkpoint);
53471
+ return true;
53472
+ }
53043
53473
  for (const part of checkpoint.content)
53044
53474
  if (part.type === "text" && typeof part.text === "string") {
53045
53475
  part.text = part.text.replace(`<summary>
@@ -53054,6 +53484,105 @@ ${baseline}
53054
53484
  draft.messages.splice(0, draft.messages.length, checkpoint, ...draft.messages.filter((message) => message !== first));
53055
53485
  return true;
53056
53486
  }
53487
+ function bindKeptInstructionCoordinates(messages, incoming, reader, sessionID) {
53488
+ const rows = reader.instructionRowsThrough(sessionID, reader.latestSequence(sessionID));
53489
+ let previous;
53490
+ let pending = [];
53491
+ const bind = (next) => {
53492
+ if (!pending.length)
53493
+ return;
53494
+ const candidates = rows.filter((row) => (previous === undefined || row.seq > previous) && (next === undefined || row.seq < next));
53495
+ const selected = previous === undefined ? candidates.slice(-pending.length) : next === undefined ? candidates.slice(0, pending.length) : candidates;
53496
+ if (selected.length === pending.length && selected.every((row, index) => {
53497
+ const message = pending[index];
53498
+ return message?.role === "system" && message.content.length === 1 && message.content[0]?.type === "text" && message.content[0].text === row.data.text;
53499
+ })) {
53500
+ selected.forEach((row, index) => {
53501
+ const message = pending[index];
53502
+ if (message)
53503
+ bindNativeRowID(message, row.id);
53504
+ });
53505
+ }
53506
+ pending = [];
53507
+ };
53508
+ for (const message of messages) {
53509
+ if (message === incoming || effortPart(message))
53510
+ continue;
53511
+ const id = nativeRowID(message);
53512
+ const seq = id ? reader.sequenceForId(sessionID, id) : undefined;
53513
+ if (seq !== undefined) {
53514
+ bind(seq);
53515
+ previous = seq;
53516
+ } else if (!id && message.role === "system")
53517
+ pending.push(message);
53518
+ }
53519
+ bind();
53520
+ }
53521
+ function controlSuffixKeys(messages, skip) {
53522
+ const keys = new Map;
53523
+ let before;
53524
+ let occurrence = 0;
53525
+ for (let index = messages.length - 1;index >= 0; index--) {
53526
+ const message = messages[index];
53527
+ if (!message || message === skip)
53528
+ continue;
53529
+ const part = effortPart(message);
53530
+ if (part) {
53531
+ if (before)
53532
+ keys.set(message, JSON.stringify({
53533
+ before,
53534
+ occurrence: occurrence++,
53535
+ effort: part.effort,
53536
+ previous: part.previous
53537
+ }));
53538
+ } else {
53539
+ before = nativeRowID(message);
53540
+ occurrence = 0;
53541
+ }
53542
+ }
53543
+ return keys;
53544
+ }
53545
+ function restoreNativeCheckpointInput(messages, incoming, restored, reader, sessionID) {
53546
+ bindKeptInstructionCoordinates(messages, incoming, reader, sessionID);
53547
+ const present = new Set(messages.flatMap((message) => nativeRowID(message) ?? []));
53548
+ const currentControls = new Map;
53549
+ const currentSuffixKeys = controlSuffixKeys(messages, incoming);
53550
+ const restoredSuffixKeys = controlSuffixKeys(restored);
53551
+ const leadingControls = new Set;
53552
+ let after;
53553
+ for (const message of messages) {
53554
+ const part = effortPart(message);
53555
+ if (part) {
53556
+ const suffixKey = currentSuffixKeys.get(message);
53557
+ if (!after && suffixKey) {
53558
+ leadingControls.add(suffixKey);
53559
+ continue;
53560
+ }
53561
+ const key = controlKey({
53562
+ after,
53563
+ effort: part.effort,
53564
+ previous: part.previous
53565
+ });
53566
+ currentControls.set(key, (currentControls.get(key) ?? 0) + 1);
53567
+ } else if (message !== incoming && nativeRowID(message))
53568
+ after = nativeRowID(message);
53569
+ }
53570
+ const hidden = restored.filter((message) => {
53571
+ const suffixKey = restoredSuffixKeys.get(message);
53572
+ if (suffixKey && leadingControls.delete(suffixKey))
53573
+ return false;
53574
+ const key = rememberedControlKey(message);
53575
+ const count = key ? currentControls.get(key) ?? 0 : 0;
53576
+ if (key && count > 0) {
53577
+ currentControls.set(key, count - 1);
53578
+ return false;
53579
+ }
53580
+ const id = nativeRowID(message);
53581
+ return !id || !present.has(id);
53582
+ });
53583
+ const at = messages.indexOf(incoming);
53584
+ return [...messages.slice(0, at), ...hidden, ...messages.slice(at + 1)];
53585
+ }
53057
53586
  function estimateCheckpointRequest(draft) {
53058
53587
  let toolDefinitionTokens = 0;
53059
53588
  for (const tool of Object.values(draft.tools)) {
@@ -53310,8 +53839,11 @@ async function registerContext(context) {
53310
53839
  }
53311
53840
  const embeddings = createV2EmbeddingScope(resolveProjectIdentityForSession(directory, config.allow_home_project));
53312
53841
  const folds = new FoldOwner(context.storage);
53313
- const nativeFoldMemory = !compactionOff && process.env.MC_OC2_INVISIBLE_FOLD === "1" ? nativeFoldCache(() => storage.require()) : undefined;
53314
- const nativeFoldReplay = nativeFoldMemory ? new NativeFoldReplay(nativeFoldMemory, () => openStoreReader(), context.storage) : undefined;
53842
+ const nativeFoldMemory = compactionOff ? undefined : nativeFoldCache(() => storage.require());
53843
+ const nativeFoldReplay = nativeFoldMemory ? new NativeFoldReplay(nativeFoldMemory, () => openStoreReader(), context.storage, {
53844
+ protocol: 3,
53845
+ log: sessionLog2
53846
+ }) : undefined;
53315
53847
  setOutputReserveConfig(config.output_reserve);
53316
53848
  const queriedModels = new Set;
53317
53849
  const rawLimits = new Map;
@@ -53365,34 +53897,38 @@ async function registerContext(context) {
53365
53897
  memorySyncRequestedSessions: rustMemorySyncRequestedSessions
53366
53898
  }) : undefined;
53367
53899
  const hiddenChildHook = new HiddenChildHook;
53368
- await context.session.hook("http.request", (draft) => hiddenChildHook.cacheRequest(draft));
53369
- const tools = db && isDatabasePersisted(db) ? await registerTools(context, db, config, moduleToolBackends?.backends, (id) => hiddenChildHook.owns(id), embeddings.ensureRegistered) : undefined;
53370
53900
  const usage = new Map;
53901
+ const overflowRecovery = new V2OverflowRecovery({
53902
+ database: () => db ?? null,
53903
+ compactionOff,
53904
+ isHidden: (sessionID) => hiddenChildHook.owns(sessionID),
53905
+ onInputTokens: (sessionID, inputTokens, limit) => usage.set(sessionID, {
53906
+ usage: { inputTokens, percentage: limit > 0 ? inputTokens / limit * 100 : 100 },
53907
+ hasUsageTokens: true,
53908
+ updatedAt: Date.now()
53909
+ })
53910
+ });
53911
+ await context.session.hook("http.request", async (draft) => {
53912
+ await hiddenChildHook.cacheRequest(draft);
53913
+ if (draft.kind !== "primary" || hiddenChildHook.owns(draft.sessionID))
53914
+ return;
53915
+ const selectedModel = liveModels.get(draft.sessionID);
53916
+ if (selectedModel)
53917
+ overflowRecovery.begin({
53918
+ ...draft,
53919
+ model: { providerID: selectedModel.providerID, id: selectedModel.modelID }
53920
+ });
53921
+ });
53922
+ const tools = db && isDatabasePersisted(db) ? await registerTools(context, db, config, moduleToolBackends?.backends, (id) => hiddenChildHook.owns(id), embeddings.ensureRegistered) : undefined;
53371
53923
  const generateReplay = new V2GenerateReplay;
53372
53924
  await context.session.hook("http.response", async (draft) => {
53373
53925
  if (!db || draft.kind !== "primary" || draft.response.ok)
53374
53926
  return;
53375
- const detection = detectOverflow(await draft.response.clone().text());
53376
- if (!detection.isOverflow)
53377
- return;
53378
- const modelKey = `${draft.model.providerID}/${draft.model.id}`;
53379
- if (compactionOff) {
53380
- if (detection.reportedLimit)
53381
- recordDetectedContextLimit(db, draft.sessionID, detection.reportedLimit, modelKey, detection.reportedLimitProvenance);
53382
- } else {
53383
- recordOverflowDetected(db, draft.sessionID, detection.reportedLimit, modelKey, "provider_overflow", detection.reportedLimitProvenance, detection.reportedInputTokens);
53384
- if (detection.reportedInputTokens) {
53385
- const provenLimit = getOverflowState(db, draft.sessionID, modelKey).detectedContextLimit;
53386
- usage.set(draft.sessionID, {
53387
- usage: {
53388
- inputTokens: detection.reportedInputTokens,
53389
- percentage: provenLimit > 0 ? detection.reportedInputTokens / provenLimit * 100 : 100
53390
- },
53391
- hasUsageTokens: true,
53392
- updatedAt: Date.now()
53393
- });
53394
- }
53395
- }
53927
+ overflowRecovery.observe({
53928
+ ...draft,
53929
+ error: await draft.response.clone().text(),
53930
+ status: draft.response.status
53931
+ });
53396
53932
  });
53397
53933
  await registerHiddenChildAgents(context.agent);
53398
53934
  await context.tool.hook("execute.before", (draft) => {
@@ -53406,9 +53942,9 @@ async function registerContext(context) {
53406
53942
  throw new HiddenCompletionRefusal("hidden_prompt_unrecognized", refusal, true);
53407
53943
  });
53408
53944
  let hiddenAgentsReady;
53409
- const readerPool = new V2StoreReaderPool;
53945
+ const readerPool = new V2StoreReaderPool2;
53410
53946
  const messageTimesCache = new V2MessageTimesCache;
53411
- const openStoreReader = () => readerPool.open(gaDatabasePath(getDataDir(), process.env.OPENCODE_CHANNEL ?? "latest"));
53947
+ const openStoreReader = () => readerPool.open(gaDatabasePath2(getDataDir(), process.env.OPENCODE_CHANNEL ?? "latest"));
53412
53948
  const createHiddenExecutor = async (database) => {
53413
53949
  await cleanupLegacyOnce(database);
53414
53950
  return createV2HiddenCompletionExecutor({
@@ -53568,10 +54104,10 @@ async function registerContext(context) {
53568
54104
  log2("[magic-context] v2 Channel 2 delivery deferred", error);
53569
54105
  }
53570
54106
  });
53571
- const pagedRead = createV2RawMessageReader(openStoreReader);
54107
+ const pagedRead = createV2RawMessageReader2(openStoreReader, gaDatabasePath2(getDataDir(), process.env.OPENCODE_CHANNEL ?? "latest"));
53572
54108
  const prepareHistorySession = (sessionID) => {
53573
54109
  if (!rawProviders.has(sessionID))
53574
- rawProviders.set(sessionID, setBoundedRawMessageProvider2(sessionID, createV2RawMessageProvider(pagedRead, sessionID)));
54110
+ rawProviders.set(sessionID, setBoundedRawMessageProvider2(sessionID, createV2RawMessageProvider2(pagedRead, sessionID)));
53575
54111
  };
53576
54112
  if (db && isDatabasePersisted(db)) {
53577
54113
  const backfillDb = db;
@@ -53586,7 +54122,7 @@ async function registerContext(context) {
53586
54122
  })).catch((error) => log2("[session-project-backfill] OpenCode 2 backfill failed:", error));
53587
54123
  });
53588
54124
  }
53589
- const readAllForConversion = (sessionID) => readAllV2RawMessagesForConversion(openStoreReader, sessionID);
54125
+ const readAllForConversion = (sessionID) => readAllV2RawMessagesForConversion2(openStoreReader, sessionID);
53590
54126
  const readRowsFrom = (sessionID, messageID) => {
53591
54127
  const reader = openStoreReader();
53592
54128
  try {
@@ -53740,9 +54276,11 @@ async function registerContext(context) {
53740
54276
  storage: nativeFoldMemory,
53741
54277
  openReader: openStoreReader,
53742
54278
  canReplay: (sessionID, reader) => nativeFoldReplay.canReplay(sessionID, reader),
54279
+ canFold: (sessionID, reader) => nativeFoldReplay.canFold(sessionID, reader),
53743
54280
  threshold: Number(process.env.MC_OC2_HOST_FOLD_ROWS ?? 1000),
53744
54281
  log: sessionLog2
53745
54282
  }) : undefined;
54283
+ const hostFoldIdle = hostFolds ? new HostFoldIdle((sessionID, eligible) => hostFolds.idle(sessionID, eligible)) : undefined;
53746
54284
  const usageController = new AbortController;
53747
54285
  const usageDone = (async () => {
53748
54286
  let retry = 0;
@@ -53764,10 +54302,26 @@ async function registerContext(context) {
53764
54302
  if (!event.data?.sessionID)
53765
54303
  continue;
53766
54304
  const sessionID = event.data.sessionID;
54305
+ overflowRecovery.observeTerminal(event, (id, messageID) => {
54306
+ const reader = openStoreReader();
54307
+ try {
54308
+ const latest = reader.latestAssistant(id);
54309
+ if (messageID && latest?.id !== messageID)
54310
+ return;
54311
+ const row = messageID ? reader.messageById(id, messageID) : latest;
54312
+ return row ? { id: row.id, model: row.data.model, error: row.data.error } : undefined;
54313
+ } finally {
54314
+ reader.close();
54315
+ }
54316
+ });
53767
54317
  if (db && event.type === "session.revert.committed") {
53768
54318
  const indexDb = db;
53769
54319
  withoutSqliteTransformPass2(() => scheduleClearAndReindex(indexDb, sessionID, pagedRead));
53770
54320
  }
54321
+ if (event.type === "session.execution.started" || event.type === "session.execution.interrupted") {
54322
+ hostFoldIdle?.active(sessionID);
54323
+ continue;
54324
+ }
53771
54325
  if (event.type?.startsWith("session.revert.") || event.type === "session.message.content.updated") {
53772
54326
  nativeFoldReplay?.onEvent(event);
53773
54327
  restoredRows.forget(sessionID);
@@ -53779,6 +54333,7 @@ async function registerContext(context) {
53779
54333
  messageTimesCache.deleteMessage(sessionID, messageID);
53780
54334
  }
53781
54335
  if (event.type === "session.error" || event.type === "session.execution.failed") {
54336
+ hostFoldIdle?.active(sessionID);
53782
54337
  const error = hiddenTerminalError(event);
53783
54338
  if (error !== undefined)
53784
54339
  hiddenSessionErrors.set(sessionID, error);
@@ -53799,6 +54354,8 @@ async function registerContext(context) {
53799
54354
  continue;
53800
54355
  }
53801
54356
  if (event.type === "session.deleted") {
54357
+ overflowRecovery.forget(sessionID);
54358
+ hostFoldIdle?.active(sessionID);
53802
54359
  clearLkgMeasuredRequest(sessionID);
53803
54360
  deletedSessions.add(sessionID);
53804
54361
  const failures = [];
@@ -53853,8 +54410,12 @@ async function registerContext(context) {
53853
54410
  sessionID,
53854
54411
  model: { providerID: model.providerID, id: model.modelID }
53855
54412
  });
53856
- if (!compactionOff && typeof await nativeFoldReplay?.baseline(sessionID) === "string")
53857
- hostFolds?.idle(sessionID);
54413
+ if (!compactionOff) {
54414
+ if (db) {
54415
+ const meta = getOrCreateSessionMeta(db, sessionID);
54416
+ hostFoldIdle?.idle(sessionID, meta.cacheTtl, meta.lastResponseTime);
54417
+ }
54418
+ }
53858
54419
  }
53859
54420
  } catch (error) {
53860
54421
  log2(`[magic-context] v2 event handler failed (type=${event.type ?? "unknown"}, session=${event.data?.sessionID ?? "none"})`, error);
@@ -53926,18 +54487,16 @@ async function registerContext(context) {
53926
54487
  const source = !rustModeModuleClient ? "typescript" : moduleBaseline === null ? "typescript_fallback" : "module";
53927
54488
  if (nativeFoldReplay) {
53928
54489
  try {
53929
- if (await nativeFoldReplay.canReplay(draft.sessionID, reader)) {
53930
- const state = getOrCreateSessionMeta(storage.require(), draft.sessionID);
53931
- const summary = moduleBaseline ?? await nativeFoldReplay.baseline(draft.sessionID) ?? state.cachedM0Bytes?.toString("utf8") ?? "<session-history></session-history>";
53932
- if (await nativeFoldReplay.supply({
53933
- draft,
53934
- reader,
53935
- previousCut: reader.latestCompaction(draft.sessionID),
53936
- summary
53937
- })) {
53938
- draft.result = { summary, metadata: { keepID: undefined } };
53939
- return;
53940
- }
54490
+ const state = getOrCreateSessionMeta(storage.require(), draft.sessionID);
54491
+ const summary = moduleBaseline ?? await nativeFoldReplay.baseline(draft.sessionID) ?? state.cachedM0Bytes?.toString("utf8") ?? "<session-history></session-history>";
54492
+ if (await nativeFoldReplay.supply({
54493
+ draft,
54494
+ reader,
54495
+ previousCut: reader.latestCompaction(draft.sessionID),
54496
+ summary
54497
+ })) {
54498
+ draft.result = { summary, metadata: { keepID: undefined } };
54499
+ return;
53941
54500
  }
53942
54501
  } catch (error) {
53943
54502
  nativeFoldReplay.invalidate(draft.sessionID, true);
@@ -53977,13 +54536,14 @@ async function registerContext(context) {
53977
54536
  }
53978
54537
  return ids;
53979
54538
  };
53980
- const restoreAfterCheckpoint = (args) => {
54539
+ const restoreAfterCheckpoint = async (args) => {
53981
54540
  const { db, reader, draft, cut, boundaryRepair } = args;
53982
54541
  const moduleBoundaryID = rustModeModuleClient ? getPersistedCompactionMarkerState(db, draft.sessionID)?.boundaryMessageId ?? null : null;
53983
54542
  const moduleBoundarySeq = moduleBoundaryID ? reader.sequenceForId(draft.sessionID, moduleBoundaryID) : undefined;
53984
54543
  const boundaryID = db.prepare("SELECT cached_m0_last_baseline_end_message_id AS id FROM session_meta WHERE session_id = ?").get(draft.sessionID)?.id ?? (boundaryRepair?.kind === "repaired" || boundaryRepair?.kind === "baseline-reset" ? boundaryRepair.anchorEndMessageId : null);
53985
- const servedBoundary = boundaryID ? servedBoundaryRow(reader, draft.sessionID, boundaryID) : null;
53986
- const boundary = (nativeFoldReplay?.sourceChanged(draft.sessionID) && !rustModeModuleClient ? (reader.earliestSequence(draft.sessionID) ?? 0) - 1 : undefined) ?? (moduleBoundarySeq !== undefined ? moduleBoundarySeq - 1 : undefined) ?? servedBoundary?.seq ?? reader.sequenceForId(draft.sessionID, boundaryID) ?? (reader.earliestSequence(draft.sessionID) ?? 0) - 1;
54544
+ const servedBoundary = boundaryID ? servedBoundaryRow2(reader, draft.sessionID, boundaryID) : null;
54545
+ const nativeFloor = await nativeFoldReplay?.restorationFloor(draft.sessionID, cut, reader);
54546
+ const boundary = Math.max(nativeFloor ?? -Infinity, (nativeFoldReplay?.sourceChanged(draft.sessionID) && !rustModeModuleClient ? (reader.earliestSequence(draft.sessionID) ?? 0) - 1 : undefined) ?? (moduleBoundarySeq !== undefined ? moduleBoundarySeq - 1 : undefined) ?? servedBoundary?.seq ?? reader.sequenceForId(draft.sessionID, boundaryID) ?? (reader.earliestSequence(draft.sessionID) ?? 0) - 1);
53987
54547
  if (moduleBoundarySeq !== undefined)
53988
54548
  sessionLog2(draft.sessionID, `v2 restore: from the module boundary ${moduleBoundaryID} to the host checkpoint`);
53989
54549
  const present = new Set(args.messages.map((message) => message.id));
@@ -53999,6 +54559,7 @@ async function registerContext(context) {
53999
54559
  };
54000
54560
  const checkpointPassPermissions = new Map;
54001
54561
  const checkpointInputEstimates = new Map;
54562
+ const admissionRebuildPasses = new Set;
54002
54563
  const initializeTransform = (database) => transform ??= createTransform({
54003
54564
  ...createV2TransformFeatureDeps(config, compactionOff, directory, embeddings.ensureRegistered),
54004
54565
  cacheTtlConfig: config.cache_ttl,
@@ -54068,7 +54629,7 @@ async function registerContext(context) {
54068
54629
  compactionMarkerStrategy: rustModeModuleClient ? createV2RustCompactionMarkerStrategy((sessionID, endMessageID) => {
54069
54630
  const reader = openStoreReader();
54070
54631
  try {
54071
- return resolveV2BoundaryUserMessage(reader, sessionID, endMessageID);
54632
+ return resolveV2BoundaryUserMessage2(reader, sessionID, endMessageID);
54072
54633
  } finally {
54073
54634
  reader.close();
54074
54635
  }
@@ -54126,6 +54687,7 @@ async function registerContext(context) {
54126
54687
  providerID: draft.model.providerID,
54127
54688
  modelID: draft.model.id
54128
54689
  });
54690
+ overflowRecovery.begin({ sessionID: draft.sessionID, kind: "primary", model: draft.model });
54129
54691
  variants.set(draft.sessionID, draft.model.variant);
54130
54692
  if (!modelLimitCacheWarm())
54131
54693
  withoutSqliteTransformPass2(() => warmModelLimitCacheFromCatalog(context));
@@ -54180,7 +54742,7 @@ async function registerContext(context) {
54180
54742
  const cut = reader.latestCompaction(draft.sessionID);
54181
54743
  const localCut = cut && isLocalCheckpoint(cut) ? cut : undefined;
54182
54744
  const incoming = localCut && messages.find((message) => message.id === localCut.id);
54183
- if (localCut && !incoming || cut && nativeFoldReplay)
54745
+ if (localCut && !incoming)
54184
54746
  return;
54185
54747
  checkpointAtEntry = incoming || null;
54186
54748
  const modeDb = db ?? storage.current();
@@ -54195,17 +54757,33 @@ async function registerContext(context) {
54195
54757
  if (message.id && candidates.has(message.id) && await isAdmittedSynthetic(context, draft.sessionID, message.id))
54196
54758
  admitted.add(message.id);
54197
54759
  const replayDb = db ?? storage.current();
54198
- if (localCut && incoming && replayDb)
54199
- messages = restoreAfterCheckpoint({
54200
- db: replayDb,
54201
- reader,
54202
- draft,
54203
- messages,
54204
- cut: localCut,
54205
- incoming,
54206
- boundaryRepair: undefined
54207
- });
54208
- else if (localCut)
54760
+ if (localCut && incoming && replayDb) {
54761
+ const admission = nativeFoldReplay ? await nativeFoldReplay.replayAdmission(draft.sessionID, localCut, reader) : "legacy";
54762
+ if (admission === undefined)
54763
+ return;
54764
+ if (admission === "native" && nativeFoldReplay) {
54765
+ const restored = await nativeFoldReplay.projectReplay({
54766
+ sessionID: draft.sessionID,
54767
+ cut: localCut,
54768
+ model: draft.model,
54769
+ reader,
54770
+ bounded: true
54771
+ });
54772
+ if (!restored)
54773
+ return;
54774
+ messages = restoreNativeCheckpointInput(messages, incoming, restored, reader, draft.sessionID);
54775
+ } else {
54776
+ messages = await restoreAfterCheckpoint({
54777
+ db: replayDb,
54778
+ reader,
54779
+ draft,
54780
+ messages,
54781
+ cut: localCut,
54782
+ incoming,
54783
+ boundaryRepair: undefined
54784
+ });
54785
+ }
54786
+ } else if (localCut)
54209
54787
  return;
54210
54788
  times = readTimes(reader, messages);
54211
54789
  }
@@ -54286,7 +54864,7 @@ async function registerContext(context) {
54286
54864
  sessionId: draft.sessionID,
54287
54865
  generation: "v2",
54288
54866
  readMessages: readAllForConversion,
54289
- readMessagePages: (sessionID) => readV2RawMessagePagesForConversion(openStoreReader, sessionID)
54867
+ readMessagePages: (sessionID) => readV2RawMessagePagesForConversion2(openStoreReader, sessionID)
54290
54868
  });
54291
54869
  } catch (error) {
54292
54870
  sessionLog2(draft.sessionID, "store projection rebase failed before system prompt (retrying in transform):", error);
@@ -54345,6 +54923,7 @@ async function registerContext(context) {
54345
54923
  const reader = openStoreReader();
54346
54924
  let checkpoint;
54347
54925
  let submitted;
54926
+ let upgradeCheckpointSequence;
54348
54927
  try {
54349
54928
  const candidates = syntheticCandidates(context, draft.sessionID, reader.syntheticMessageIDs(draft.sessionID));
54350
54929
  for (const message of draft.messages) {
@@ -54365,8 +54944,31 @@ async function registerContext(context) {
54365
54944
  if (localCut && !incoming)
54366
54945
  throw new Error("The host checkpoint disappeared from the context draft");
54367
54946
  checkpointAtEntry = incoming || null;
54368
- let nativeRestored;
54369
- if (cut && nativeFoldReplay && await nativeFoldReplay.admits(draft.sessionID, cut, reader)) {
54947
+ if (localCut && nativeFoldReplay) {
54948
+ await nativeFoldReplay.prepareLegacyUpgrade({
54949
+ draft,
54950
+ cut: localCut,
54951
+ reader
54952
+ });
54953
+ const carrier = await nativeFoldReplay.checkpointForReplay(draft.sessionID, reader);
54954
+ if (carrier) {
54955
+ const identity = await folds.observe({
54956
+ sessionID: draft.sessionID,
54957
+ cutSeq: carrier.row.seq,
54958
+ summary: carrier.submitted,
54959
+ rendered: carrier.rendered,
54960
+ onHard: () => {
54961
+ historyRefreshSessions.add(draft.sessionID);
54962
+ requestPendingMaterialization(pendingMaterializationSessions, draft.sessionID, "host_compaction");
54963
+ }
54964
+ });
54965
+ checkpoint = structuredClone(identity.rendered ?? carrier.rendered);
54966
+ submitted = identity.renderedSummary ?? carrier.submitted;
54967
+ upgradeCheckpointSequence = carrier.row.seq;
54968
+ }
54969
+ }
54970
+ let nativeRestored = localCut ? nativeFoldReplay?.legacyUpgradeInput(draft.sessionID, draft.model) : undefined;
54971
+ if (nativeRestored === undefined && cut && nativeFoldReplay && await nativeFoldReplay.admits(draft.sessionID, cut, reader)) {
54370
54972
  try {
54371
54973
  nativeRestored = await nativeFoldReplay.restore(draft.sessionID, cut, `${draft.model.providerID}/${draft.model.id}`, { bounded: !rustModeModuleClient });
54372
54974
  } catch (error) {
@@ -54384,14 +54986,10 @@ async function registerContext(context) {
54384
54986
  requestPendingMaterialization(pendingMaterializationSessions, draft.sessionID, "host_history_change");
54385
54987
  }
54386
54988
  if (cut && incoming && nativeRestored) {
54387
- const present = new Set(draft.messages.flatMap((message) => message.id ? [message.id] : []));
54388
- const hidden = nativeRestored.filter((message) => {
54389
- const id = nativeRowID(message);
54390
- return !id || !present.has(id);
54391
- });
54392
- draft.messages.splice(0, draft.messages.length, ...hidden, ...draft.messages.filter((message) => message !== incoming));
54989
+ draft.messages.splice(0, draft.messages.length, ...restoreNativeCheckpointInput(draft.messages, incoming, nativeRestored, reader, draft.sessionID));
54393
54990
  } else if (localCut && cut && incoming) {
54394
- if (!nativeFoldReplay) {
54991
+ const legacy = await folds.read(draft.sessionID);
54992
+ if (legacy?.cutSeq === cut.seq && legacy.submittedSha === foldDigest(cut.data.summary ?? "")) {
54395
54993
  const identity = await folds.observe({
54396
54994
  sessionID: draft.sessionID,
54397
54995
  cutSeq: cut.seq,
@@ -54406,7 +55004,7 @@ async function registerContext(context) {
54406
55004
  checkpoint = structuredClone(identity.rendered ?? incoming);
54407
55005
  submitted = identity.rendered ? identity.renderedSummary ?? identity.submitted : cut.data.summary ?? "";
54408
55006
  }
54409
- draft.messages.splice(0, draft.messages.length, ...restoreAfterCheckpoint({
55007
+ draft.messages.splice(0, draft.messages.length, ...await restoreAfterCheckpoint({
54410
55008
  db,
54411
55009
  reader,
54412
55010
  draft,
@@ -54462,9 +55060,28 @@ async function registerContext(context) {
54462
55060
  checkpointPassPermissions.delete(draft.sessionID);
54463
55061
  checkpointInputEstimates.delete(draft.sessionID);
54464
55062
  if (checkpoint?.id && checkpointPermission && replayHead === undefined) {
54465
- const stripped = await folds.stripRecentContext(draft.sessionID, checkpoint.id);
54466
- if (stripped?.rendered)
54467
- checkpoint = structuredClone(stripped.rendered);
55063
+ let covered = upgradeCheckpointSequence === undefined;
55064
+ if (upgradeCheckpointSequence !== undefined) {
55065
+ const boundary = db.prepare("SELECT cached_m0_last_baseline_end_message_id AS id FROM session_meta WHERE session_id=?").get(draft.sessionID);
55066
+ const source = openStoreReader();
55067
+ try {
55068
+ const through = upgradeCheckpointSequence - 1;
55069
+ const last = source.rowStampsThrough(draft.sessionID, through).filter((row) => RAW_MESSAGE_TYPES2.includes(row.type)).at(-1)?.seq;
55070
+ const end = boundary?.id ? source.sequenceForId(draft.sessionID, boundary.id) : undefined;
55071
+ covered = last === undefined || end !== undefined && end >= last;
55072
+ } finally {
55073
+ source.close();
55074
+ }
55075
+ }
55076
+ if (covered) {
55077
+ const checkpointID = checkpoint.id;
55078
+ const stripped = await folds.stripRecentContext(draft.sessionID, checkpointID);
55079
+ if (stripped?.rendered) {
55080
+ checkpoint = structuredClone(stripped.rendered);
55081
+ if (upgradeCheckpointSequence !== undefined)
55082
+ await nativeFoldReplay?.checkpointCovered(draft.sessionID, checkpointID);
55083
+ }
55084
+ }
54468
55085
  }
54469
55086
  stageOpenCodeV2TransformDecision({
54470
55087
  sessionId: draft.sessionID,
@@ -54476,14 +55093,18 @@ async function registerContext(context) {
54476
55093
  const head = replayHead !== undefined ? replayHead : checkpoint && submitted !== undefined ? { checkpoint, submitted } : null;
54477
55094
  const servedHead = head && structuredClone(head);
54478
55095
  const headApplied = head ? applyCheckpointHead(draft, head) : false;
54479
- if (nativeMessages && !checkpoint) {
55096
+ if (nativeMessages && (!checkpoint || upgradeCheckpointSequence !== undefined)) {
54480
55097
  try {
54481
- await nativeFoldReplay?.capture(draft, nativeMessages);
55098
+ const state = db && getOrCreateSessionMeta(db, draft.sessionID);
55099
+ const boundary = db?.prepare("SELECT cached_m0_last_baseline_end_message_id AS id FROM session_meta WHERE session_id=?").get(draft.sessionID);
55100
+ await nativeFoldReplay?.capture(draft, nativeMessages, boundary?.id && state?.cachedM0Bytes ? { id: boundary.id, summary: state.cachedM0Bytes.toString("utf8") } : undefined);
54482
55101
  } catch (error) {
54483
55102
  nativeFoldReplay?.invalidate(draft.sessionID, true);
54484
55103
  sessionLog2(draft.sessionID, "v2 host fold: optional capture unavailable", error);
54485
55104
  }
54486
55105
  }
55106
+ if (checkpointPermission === true && replayHead === undefined)
55107
+ admissionRebuildPasses.add(draft.sessionID);
54487
55108
  const capturedSlot = getSlot(draft.sessionID);
54488
55109
  if (capturedSlot && (!slotAtEntry || capturedSlot.capturedAt !== slotAtEntry.capturedAt || capturedSlot.captureSequence !== slotAtEntry.captureSequence || capturedSlot.jsonPrefix !== slotAtEntry.jsonPrefix)) {
54489
55110
  lkgSystems.capture(draft.sessionID, capturedSlot, { system: systemAtEntry, checkpoint: checkpointAtEntry ?? null }, draft.system, headApplied ? servedHead : null);
@@ -54564,12 +55185,20 @@ async function registerContext(context) {
54564
55185
  throw new V2ContextRefusal("Magic Context refused an oversized host checkpoint.");
54565
55186
  };
54566
55187
  await context.session.hook("context", (draft) => withSqliteTransformPass2(async () => {
55188
+ hostFoldIdle?.active(draft.sessionID);
54567
55189
  const anchor = generateReplayAnchor(draft.messages);
54568
55190
  try {
54569
55191
  await runManagedContext(draft);
54570
55192
  if (!compactionOff)
54571
55193
  await refuseOversizedCheckpoint(draft);
55194
+ if (!deletedSessions.has(draft.sessionID) && admissionRebuildPasses.has(draft.sessionID)) {
55195
+ await nativeFoldReplay?.commitLegacyUpgrade(draft.sessionID, true);
55196
+ await nativeFoldReplay?.commitEditedAdmission(draft.sessionID);
55197
+ }
54572
55198
  } finally {
55199
+ admissionRebuildPasses.delete(draft.sessionID);
55200
+ nativeFoldReplay?.cancelLegacyUpgrade(draft.sessionID);
55201
+ nativeFoldReplay?.cancelEditedAdmission(draft.sessionID);
54573
55202
  checkpointInputEstimates.delete(draft.sessionID);
54574
55203
  checkpointPassPermissions.delete(draft.sessionID);
54575
55204
  }
@@ -54698,6 +55327,7 @@ async function registerContext(context) {
54698
55327
  return {
54699
55328
  async dispose() {
54700
55329
  messageTimesCache.clear();
55330
+ hostFoldIdle?.dispose();
54701
55331
  usageController.abort();
54702
55332
  await hiddenCompletionExecutor?.dispose();
54703
55333
  await usageDone;