@retaw106/mmc-oc 1.2.3 → 2.1.0

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 (290) hide show
  1. package/dist/cli.js +7095 -0
  2. package/dist/config/index.d.ts +0 -12
  3. package/dist/config/index.d.ts.map +1 -1
  4. package/dist/config/legacy-harness-blocks.d.ts +27 -0
  5. package/dist/config/legacy-harness-blocks.d.ts.map +1 -0
  6. package/dist/config/live-run-config.d.ts.map +1 -1
  7. package/dist/config/live-snapshot.d.ts +2 -1
  8. package/dist/config/live-snapshot.d.ts.map +1 -1
  9. package/dist/config/project-security.d.ts +4 -5
  10. package/dist/config/project-security.d.ts.map +1 -1
  11. package/dist/config/raw-loader.d.ts +7 -26
  12. package/dist/config/raw-loader.d.ts.map +1 -1
  13. package/dist/config/schema/magic-context.d.ts +164 -259
  14. package/dist/config/schema/magic-context.d.ts.map +1 -1
  15. package/dist/config/variable.d.ts +8 -0
  16. package/dist/config/variable.d.ts.map +1 -1
  17. package/dist/config-init.js +5595 -0
  18. package/dist/{context-a6px04s0.js → context-vhcstgs3.js} +5758 -4727
  19. package/dist/{derive-budgets-fhk00zv8.js → derive-budgets-rjjz5f7y.js} +2 -2
  20. package/dist/features/magic-context/compaction-marker.d.ts.map +1 -1
  21. package/dist/features/magic-context/memory/types.d.ts +1 -0
  22. package/dist/features/magic-context/memory/types.d.ts.map +1 -1
  23. package/dist/features/magic-context/message-index.d.ts +2 -0
  24. package/dist/features/magic-context/message-index.d.ts.map +1 -1
  25. package/dist/features/magic-context/migration-v3-perf-schema.d.ts +8 -0
  26. package/dist/features/magic-context/migration-v3-perf-schema.d.ts.map +1 -0
  27. package/dist/features/magic-context/migration-v4-temporal-decisions.d.ts +12 -0
  28. package/dist/features/magic-context/migration-v4-temporal-decisions.d.ts.map +1 -0
  29. package/dist/features/magic-context/migrations.d.ts.map +1 -1
  30. package/dist/features/magic-context/overflow-detection.d.ts +6 -0
  31. package/dist/features/magic-context/overflow-detection.d.ts.map +1 -1
  32. package/dist/features/magic-context/reclaim-protection.d.ts +15 -10
  33. package/dist/features/magic-context/reclaim-protection.d.ts.map +1 -1
  34. package/dist/features/magic-context/session-cache-ttl.d.ts +4 -2
  35. package/dist/features/magic-context/session-cache-ttl.d.ts.map +1 -1
  36. package/dist/features/magic-context/session-project-storage.d.ts +8 -2
  37. package/dist/features/magic-context/session-project-storage.d.ts.map +1 -1
  38. package/dist/features/magic-context/storage-db.d.ts +1 -1
  39. package/dist/features/magic-context/storage-db.d.ts.map +1 -1
  40. package/dist/features/magic-context/storage-historian-runs.d.ts +2 -0
  41. package/dist/features/magic-context/storage-historian-runs.d.ts.map +1 -1
  42. package/dist/features/magic-context/storage-meta-persisted.d.ts +12 -0
  43. package/dist/features/magic-context/storage-meta-persisted.d.ts.map +1 -1
  44. package/dist/features/magic-context/storage-meta-session.d.ts +6 -0
  45. package/dist/features/magic-context/storage-meta-session.d.ts.map +1 -1
  46. package/dist/features/magic-context/storage-ops.d.ts +2 -0
  47. package/dist/features/magic-context/storage-ops.d.ts.map +1 -1
  48. package/dist/features/magic-context/storage-session-tables.d.ts.map +1 -1
  49. package/dist/features/magic-context/storage-tags.d.ts +17 -4
  50. package/dist/features/magic-context/storage-tags.d.ts.map +1 -1
  51. package/dist/features/magic-context/storage.d.ts +2 -2
  52. package/dist/features/magic-context/storage.d.ts.map +1 -1
  53. package/dist/features/magic-context/temporal-decisions.d.ts +10 -0
  54. package/dist/features/magic-context/temporal-decisions.d.ts.map +1 -0
  55. package/dist/features/magic-context/tool-definition-tokens.d.ts +3 -0
  56. package/dist/features/magic-context/tool-definition-tokens.d.ts.map +1 -1
  57. package/dist/features/magic-context/transform-decision-log.d.ts +3 -1
  58. package/dist/features/magic-context/transform-decision-log.d.ts.map +1 -1
  59. package/dist/hooks/magic-context/active-anthropic-turn.d.ts +8 -0
  60. package/dist/hooks/magic-context/active-anthropic-turn.d.ts.map +1 -0
  61. package/dist/hooks/magic-context/apply-operations.d.ts +15 -0
  62. package/dist/hooks/magic-context/apply-operations.d.ts.map +1 -1
  63. package/dist/hooks/magic-context/auto-search-deadline.d.ts +10 -3
  64. package/dist/hooks/magic-context/auto-search-deadline.d.ts.map +1 -1
  65. package/dist/hooks/magic-context/auto-search-runner.d.ts +1 -1
  66. package/dist/hooks/magic-context/auto-search-runner.d.ts.map +1 -1
  67. package/dist/hooks/magic-context/caveman-cleanup.d.ts.map +1 -1
  68. package/dist/hooks/magic-context/channel2-cycle.d.ts +2 -0
  69. package/dist/hooks/magic-context/channel2-cycle.d.ts.map +1 -1
  70. package/dist/hooks/magic-context/compaction-marker-manager.d.ts.map +1 -1
  71. package/dist/hooks/magic-context/compartment-render-epoch.d.ts +8 -0
  72. package/dist/hooks/magic-context/compartment-render-epoch.d.ts.map +1 -1
  73. package/dist/hooks/magic-context/compartment-runner-partial-recomp.d.ts.map +1 -1
  74. package/dist/hooks/magic-context/compartment-runner-recomp.d.ts.map +1 -1
  75. package/dist/hooks/magic-context/compartment-runner-types.d.ts +3 -5
  76. package/dist/hooks/magic-context/compartment-runner-types.d.ts.map +1 -1
  77. package/dist/hooks/magic-context/compartment-runner.d.ts +2 -1
  78. package/dist/hooks/magic-context/compartment-runner.d.ts.map +1 -1
  79. package/dist/hooks/magic-context/compartment-trigger.d.ts +3 -1
  80. package/dist/hooks/magic-context/compartment-trigger.d.ts.map +1 -1
  81. package/dist/hooks/magic-context/ctx-reduce-availability.d.ts +12 -0
  82. package/dist/hooks/magic-context/ctx-reduce-availability.d.ts.map +1 -1
  83. package/dist/hooks/magic-context/decision-calibration.d.ts +3 -0
  84. package/dist/hooks/magic-context/decision-calibration.d.ts.map +1 -1
  85. package/dist/hooks/magic-context/emergency-drop.d.ts +2 -0
  86. package/dist/hooks/magic-context/emergency-drop.d.ts.map +1 -1
  87. package/dist/hooks/magic-context/emergency-fail-closed.d.ts +21 -1
  88. package/dist/hooks/magic-context/emergency-fail-closed.d.ts.map +1 -1
  89. package/dist/hooks/magic-context/final-wire-token-estimate.d.ts +32 -1
  90. package/dist/hooks/magic-context/final-wire-token-estimate.d.ts.map +1 -1
  91. package/dist/hooks/magic-context/heuristic-cleanup.d.ts +2 -0
  92. package/dist/hooks/magic-context/heuristic-cleanup.d.ts.map +1 -1
  93. package/dist/hooks/magic-context/historian-drain-gate.d.ts +11 -0
  94. package/dist/hooks/magic-context/historian-drain-gate.d.ts.map +1 -0
  95. package/dist/hooks/magic-context/inject-compartments.d.ts +10 -8
  96. package/dist/hooks/magic-context/inject-compartments.d.ts.map +1 -1
  97. package/dist/hooks/magic-context/latest-assistant-turn.d.ts +25 -0
  98. package/dist/hooks/magic-context/latest-assistant-turn.d.ts.map +1 -0
  99. package/dist/hooks/magic-context/lkg-measured-request.d.ts +69 -0
  100. package/dist/hooks/magic-context/lkg-measured-request.d.ts.map +1 -0
  101. package/dist/hooks/magic-context/lkg-replay-fit.d.ts +118 -0
  102. package/dist/hooks/magic-context/lkg-replay-fit.d.ts.map +1 -0
  103. package/dist/hooks/magic-context/lkg-replay.d.ts +2 -0
  104. package/dist/hooks/magic-context/lkg-replay.d.ts.map +1 -1
  105. package/dist/hooks/magic-context/protected-tail-boundary.d.ts.map +1 -1
  106. package/dist/hooks/magic-context/read-session-formatting.d.ts +3 -0
  107. package/dist/hooks/magic-context/read-session-formatting.d.ts.map +1 -1
  108. package/dist/hooks/magic-context/read-session-true-raw-tokens.d.ts.map +1 -1
  109. package/dist/hooks/magic-context/reasoning-budget-status.d.ts +15 -0
  110. package/dist/hooks/magic-context/reasoning-budget-status.d.ts.map +1 -0
  111. package/dist/hooks/magic-context/reasoning-budget.d.ts +40 -0
  112. package/dist/hooks/magic-context/reasoning-budget.d.ts.map +1 -0
  113. package/dist/hooks/magic-context/reasoning-removal.d.ts +6 -6
  114. package/dist/hooks/magic-context/reasoning-removal.d.ts.map +1 -1
  115. package/dist/hooks/magic-context/recomp-orchestrator.d.ts +2 -0
  116. package/dist/hooks/magic-context/recomp-orchestrator.d.ts.map +1 -1
  117. package/dist/hooks/magic-context/sentinel.d.ts +2 -0
  118. package/dist/hooks/magic-context/sentinel.d.ts.map +1 -1
  119. package/dist/hooks/magic-context/strip-content.d.ts +7 -3
  120. package/dist/hooks/magic-context/strip-content.d.ts.map +1 -1
  121. package/dist/hooks/magic-context/supersession-reclaim.d.ts +4 -0
  122. package/dist/hooks/magic-context/supersession-reclaim.d.ts.map +1 -1
  123. package/dist/hooks/magic-context/tag-messages.d.ts +13 -0
  124. package/dist/hooks/magic-context/tag-messages.d.ts.map +1 -1
  125. package/dist/hooks/magic-context/tail-hygiene-walk.d.ts +5 -0
  126. package/dist/hooks/magic-context/tail-hygiene-walk.d.ts.map +1 -1
  127. package/dist/hooks/magic-context/temporal-awareness.d.ts +6 -3
  128. package/dist/hooks/magic-context/temporal-awareness.d.ts.map +1 -1
  129. package/dist/hooks/magic-context/temporal-served-projection.d.ts +4 -0
  130. package/dist/hooks/magic-context/temporal-served-projection.d.ts.map +1 -0
  131. package/dist/hooks/magic-context/tool-reclaim.d.ts +2 -0
  132. package/dist/hooks/magic-context/tool-reclaim.d.ts.map +1 -1
  133. package/dist/hooks/magic-context/transform-compartment-phase.d.ts +3 -28
  134. package/dist/hooks/magic-context/transform-compartment-phase.d.ts.map +1 -1
  135. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts +34 -12
  136. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
  137. package/dist/hooks/magic-context/transform.d.ts +11 -5
  138. package/dist/hooks/magic-context/transform.d.ts.map +1 -1
  139. package/dist/hooks/magic-context/wrapup-orchestrator.d.ts.map +1 -1
  140. package/dist/{index-fg34g6a5.js → index-1j34a56j.js} +49 -8
  141. package/dist/index-33gprt9g.js +30 -0
  142. package/dist/{index-zx63j2e2.js → index-5cep2r9n.js} +3 -2
  143. package/dist/{index-5pg0acf7.js → index-amycb7b1.js} +1 -1
  144. package/dist/{index-wgt4gamw.js → index-dr0gepzw.js} +507 -53
  145. package/dist/{index-1vs6anwz.js → index-n0vnzz6h.js} +2 -1
  146. package/dist/{index-977gxfz0.js → index-ramz5kkm.js} +1 -1
  147. package/dist/{index-by6h2pav.js → index-wtb9hzk6.js} +499 -284
  148. package/dist/{index-3wagyrnj.js → index-x37vg474.js} +5 -1
  149. package/dist/{index-me3zcj5t.js → index-z2g20msd.js} +4 -8
  150. package/dist/index.js +1 -1
  151. package/dist/{message-time-backfill-5ewk0axe.js → message-time-backfill-phrwp2fz.js} +2 -2
  152. package/dist/{model-resolution-5haaxnpt.js → model-resolution-wazv26n0.js} +1 -1
  153. package/dist/plugin/rpc-handlers.d.ts +4 -0
  154. package/dist/plugin/rpc-handlers.d.ts.map +1 -1
  155. package/dist/{read-session-chunk-apjwrttc.js → read-session-chunk-82rkqa8j.js} +4 -4
  156. package/dist/{recomp-orchestrator-gyeevxaw.js → recomp-orchestrator-vc5dkzy2.js} +9 -9
  157. package/dist/{send-session-notification-y29y9fsr.js → send-session-notification-rnc4nrsr.js} +3 -3
  158. package/dist/shared/auto-search-lifecycle.d.ts +7 -0
  159. package/dist/shared/auto-search-lifecycle.d.ts.map +1 -0
  160. package/dist/shared/cache-ttl-display.d.ts +6 -4
  161. package/dist/shared/cache-ttl-display.d.ts.map +1 -1
  162. package/dist/shared/harness.d.ts +1 -1
  163. package/dist/shared/harness.d.ts.map +1 -1
  164. package/dist/shared/historian-tool-expansions.d.ts +1 -1
  165. package/dist/shared/historian-tool-expansions.d.ts.map +1 -1
  166. package/dist/shared/historian-tool-template.d.ts +2 -2
  167. package/dist/shared/historian-tool-template.d.ts.map +1 -1
  168. package/dist/shared/model-cache-ttl.d.ts +1 -1
  169. package/dist/shared/model-cache-ttl.d.ts.map +1 -1
  170. package/dist/shared/model-resolution.d.ts +6 -3
  171. package/dist/shared/model-resolution.d.ts.map +1 -1
  172. package/dist/shared/model-suggestion-retry.d.ts +2 -0
  173. package/dist/shared/model-suggestion-retry.d.ts.map +1 -1
  174. package/dist/shared/protected-tools-policy.d.ts +6 -0
  175. package/dist/shared/protected-tools-policy.d.ts.map +1 -0
  176. package/dist/shared/provider-output-failure.d.ts +19 -0
  177. package/dist/shared/provider-output-failure.d.ts.map +1 -0
  178. package/dist/shared/sqlite.d.ts +14 -1
  179. package/dist/shared/sqlite.d.ts.map +1 -1
  180. package/dist/shared/temporal-upgrade-fixture.d.ts +19 -0
  181. package/dist/shared/temporal-upgrade-fixture.d.ts.map +1 -0
  182. package/dist/shared/window-geometry.d.ts +4 -0
  183. package/dist/shared/window-geometry.d.ts.map +1 -1
  184. package/dist/shared/write-transaction-timing.d.ts +8 -1
  185. package/dist/shared/write-transaction-timing.d.ts.map +1 -1
  186. package/dist/tools/ctx-expand/render.d.ts.map +1 -1
  187. package/dist/tools/ctx-reduce/tools.d.ts +2 -0
  188. package/dist/tools/ctx-reduce/tools.d.ts.map +1 -1
  189. package/dist/v2/fold/host-media.d.ts +4 -0
  190. package/dist/v2/fold/host-media.d.ts.map +1 -1
  191. package/dist/v2/fold/memory-cache.d.ts +70 -0
  192. package/dist/v2/fold/memory-cache.d.ts.map +1 -0
  193. package/dist/v2/fold/native-codec.d.ts +10 -0
  194. package/dist/v2/fold/native-codec.d.ts.map +1 -0
  195. package/dist/v2/fold/native-replay.d.ts +58 -0
  196. package/dist/v2/fold/native-replay.d.ts.map +1 -0
  197. package/dist/v2/fold/policy.d.ts +24 -0
  198. package/dist/v2/fold/policy.d.ts.map +1 -0
  199. package/dist/v2/hidden-child-native.d.ts +7 -0
  200. package/dist/v2/hidden-child-native.d.ts.map +1 -1
  201. package/dist/v2/hidden-child-record.d.ts +19 -0
  202. package/dist/v2/hidden-child-record.d.ts.map +1 -1
  203. package/dist/v2/hidden-completion.d.ts.map +1 -1
  204. package/dist/v2/hooks/context.d.ts.map +1 -1
  205. package/dist/v2/hooks/hidden-child.d.ts +46 -2
  206. package/dist/v2/hooks/hidden-child.d.ts.map +1 -1
  207. package/dist/v2/hooks/payload.d.ts.map +1 -1
  208. package/dist/v2/hooks/store.d.ts.map +1 -1
  209. package/dist/v2/hooks/tools.d.ts.map +1 -1
  210. package/dist/v2/hooks/types.d.ts +14 -0
  211. package/dist/v2/hooks/types.d.ts.map +1 -1
  212. package/dist/v2/server.js +13226 -11340
  213. package/dist/v2/store-reader.d.ts +16 -0
  214. package/dist/v2/store-reader.d.ts.map +1 -1
  215. package/dist/v2/tool-result.d.ts +8 -0
  216. package/dist/v2/tool-result.d.ts.map +1 -0
  217. package/dist/web/api.d.ts +6 -0
  218. package/dist/web/api.d.ts.map +1 -1
  219. package/dist/web/context-store.d.ts +13 -0
  220. package/dist/web/context-store.d.ts.map +1 -1
  221. package/dist/web/display-path.d.ts +28 -0
  222. package/dist/web/display-path.d.ts.map +1 -0
  223. package/dist/web/entry-args.d.ts +33 -0
  224. package/dist/web/entry-args.d.ts.map +1 -0
  225. package/dist/web/fixtures.d.ts +41 -0
  226. package/dist/web/fixtures.d.ts.map +1 -1
  227. package/dist/web/host-opencode.d.ts +9 -0
  228. package/dist/web/host-opencode.d.ts.map +1 -1
  229. package/dist/web/host-pi.d.ts +2 -0
  230. package/dist/web/host-pi.d.ts.map +1 -1
  231. package/dist/web/main.d.ts +4 -6
  232. package/dist/web/main.d.ts.map +1 -1
  233. package/dist/web/main.js +1477 -130
  234. package/dist/web/memories.d.ts +18 -2
  235. package/dist/web/memories.d.ts.map +1 -1
  236. package/dist/web/message-stats.d.ts +45 -0
  237. package/dist/web/message-stats.d.ts.map +1 -0
  238. package/dist/web/ui/index.html +1 -0
  239. package/dist/web/ui/panel.css +7 -0
  240. package/dist/web/ui/panel.js +332 -124
  241. package/dist/web/views.d.ts +73 -9
  242. package/dist/web/views.d.ts.map +1 -1
  243. package/dist/{wrapup-orchestrator-z9sqpqjf.js → wrapup-orchestrator-x9xamts2.js} +10 -9
  244. package/package.json +7 -2
  245. package/src/config/index.test.ts +257 -126
  246. package/src/config/index.ts +45 -39
  247. package/src/config/legacy-harness-blocks.test.ts +78 -0
  248. package/src/config/legacy-harness-blocks.ts +71 -0
  249. package/src/config/live-run-config.test.ts +49 -5
  250. package/src/config/live-run-config.ts +29 -0
  251. package/src/config/live-snapshot.ts +5 -1
  252. package/src/config/profiles.ts +1 -1
  253. package/src/config/project-config-trust-boundary.test.ts +2 -2
  254. package/src/config/project-security.hostile-matrix.test.ts +51 -65
  255. package/src/config/project-security.test.ts +6 -1
  256. package/src/config/project-security.ts +13 -12
  257. package/src/config/protected-tokens.test.ts +1 -1
  258. package/src/config/raw-loader.test.ts +29 -352
  259. package/src/config/raw-loader.ts +17 -406
  260. package/src/config/removed-config-keys.test.ts +1 -1
  261. package/src/config/schema/magic-context.test.ts +60 -64
  262. package/src/config/schema/magic-context.ts +105 -137
  263. package/src/config/variable.ts +21 -12
  264. package/src/shared/auto-search-lifecycle.ts +27 -0
  265. package/src/shared/cache-ttl-display.test.ts +1 -1
  266. package/src/shared/cache-ttl-display.ts +17 -16
  267. package/src/shared/harness.ts +1 -1
  268. package/src/shared/historian-tool-defaults.json +6 -6
  269. package/src/shared/historian-tool-expansions.ts +65 -8
  270. package/src/shared/historian-tool-preview-defaults.json +13 -0
  271. package/src/shared/historian-tool-template.ts +48 -14
  272. package/src/shared/model-cache-ttl.test.ts +2 -2
  273. package/src/shared/model-cache-ttl.ts +8 -4
  274. package/src/shared/model-resolution.test.ts +22 -32
  275. package/src/shared/model-resolution.ts +14 -19
  276. package/src/shared/model-suggestion-retry.ts +63 -7
  277. package/src/shared/protected-tools-policy.ts +25 -0
  278. package/src/shared/provider-output-failure.ts +176 -0
  279. package/src/shared/sqlite-acquisition-routing.test.ts +18 -0
  280. package/src/shared/sqlite.ts +100 -15
  281. package/src/shared/status-detail-text.test.ts +1 -1
  282. package/src/shared/status-view.test.ts +1 -1
  283. package/src/shared/temporal-upgrade-fixture.ts +50 -0
  284. package/src/shared/window-geometry.ts +10 -0
  285. package/src/shared/write-transaction-attribution.test.ts +2 -2
  286. package/src/shared/write-transaction-timing.ts +25 -1
  287. package/dist/features/magic-context/window-report-ledger.d.ts +0 -70
  288. package/dist/features/magic-context/window-report-ledger.d.ts.map +0 -1
  289. package/dist/index-e1q8002h.js +0 -16
  290. package/src/config/misplaced-agent-model.test.ts +0 -55
@@ -21,9 +21,11 @@ import {
21
21
  isTransientSqliteError,
22
22
  beginSqliteWriterAsync,
23
23
  withPrivilegedWriter
24
- } from "./index-fg34g6a5.js";
24
+ } from "./index-1j34a56j.js";
25
25
  import {
26
26
  toolTemplateError,
27
+ DEFAULT_PROTECTED_TOOLS,
28
+ mergeProtectedTools,
27
29
  isRecord,
28
30
  detectOverflow,
29
31
  removeSystemReminders,
@@ -34,6 +36,8 @@ import {
34
36
  stripTagPrefix,
35
37
  peelLeadingMcTagNotation,
36
38
  stableStringify,
39
+ installV3PerfSchema,
40
+ queuePendingDropForUnchangedTag,
37
41
  getAllStatusTagTokenTotalsFlat,
38
42
  updateTagStatus,
39
43
  foldShrunkPartTags,
@@ -55,8 +59,10 @@ import {
55
59
  resolveHostServedBoundaryId2,
56
60
  hasRawMessageProvider2,
57
61
  cleanUserText2,
62
+ withRawSessionMessageCache2,
58
63
  getRawSessionMessageOrdinalCount2,
59
64
  readRawSessionMessageRange2,
65
+ primeTailRawMessageCache2,
60
66
  getCachedAbsoluteMessageCount2,
61
67
  readRawSessionMessageIdOrdinalsForRange2,
62
68
  hasRawSessionMessageById2,
@@ -66,7 +72,7 @@ import {
66
72
  getRawSessionTagKeysThrough2,
67
73
  getLegacyProtectedTailStartOrdinal2,
68
74
  readSessionChunk2
69
- } from "./index-wgt4gamw.js";
75
+ } from "./index-dr0gepzw.js";
70
76
  import {
71
77
  piModelRefToCanonical,
72
78
  modelRefLookupOrder,
@@ -74,7 +80,7 @@ import {
74
80
  providerMass,
75
81
  calibrationForModelKey,
76
82
  historyLocalBudget
77
- } from "./index-3wagyrnj.js";
83
+ } from "./index-x37vg474.js";
78
84
  import {
79
85
  closeQuietly,
80
86
  isKnownAutocommit,
@@ -85,7 +91,7 @@ import {
85
91
  claimOpenCodeDbDiagnosticOnce,
86
92
  withReadOnlySessionDb,
87
93
  getMessageTimesFromOpenCodeDb
88
- } from "./index-977gxfz0.js";
94
+ } from "./index-ramz5kkm.js";
89
95
  import {
90
96
  shouldEnforcePrivateStoragePermissions,
91
97
  ensureStorageDirectorySync,
@@ -99,7 +105,7 @@ import {
99
105
  deriveTriggerBudget2,
100
106
  resolveHistorianProducerLimits2,
101
107
  producerSourceLocalBudget2
102
- } from "./index-zx63j2e2.js";
108
+ } from "./index-5cep2r9n.js";
103
109
  import {
104
110
  pushNotification2
105
111
  } from "./index-jdxxq8cz.js";
@@ -107,10 +113,11 @@ import {
107
113
  getErrorMessage,
108
114
  describeError,
109
115
  sendStatusNotification2
110
- } from "./index-5pg0acf7.js";
116
+ } from "./index-amycb7b1.js";
111
117
  import {
112
- logSlowWriteTransaction
113
- } from "./index-e1q8002h.js";
118
+ logSlowWriteTransaction,
119
+ WriteTransactionSteps
120
+ } from "./index-33gprt9g.js";
114
121
 
115
122
  // src/agents/memory-maintainer.ts
116
123
  var MEMORY_MAINTAINER_A_AGENT = "magic-context-maintainer-a";
@@ -7458,64 +7465,28 @@ var PromptSurfaceConfigSchema = object({
7458
7465
  message: "tool description values must not be empty or whitespace-only"
7459
7466
  })).optional().describe("USER-LEVEL ONLY top-level description overrides keyed by mmc_* tool ID; parameter schemas and descriptions are unchanged.")
7460
7467
  }).describe("Prompt-surface preset routing. Project config may select default/models, while guidance_override_path and tool_descriptions are user-level only.");
7461
- var PER_HARNESS_MIGRATION_INVENTORY = {
7462
- historian: {
7463
- retained: [
7464
- "temperature",
7465
- "top_p",
7466
- "prompt",
7467
- "tools",
7468
- "disable",
7469
- "description",
7470
- "mode",
7471
- "color",
7472
- "maxSteps",
7473
- "permission",
7474
- "maxTokens",
7475
- "two_pass",
7476
- "disallowed_tools"
7477
- ],
7478
- migrated_execution: ["model", "fallback_models", "variant", "thinking_level"]
7479
- }
7480
- };
7481
- var PER_HARNESS_MODEL_KEYS = ["opencode", "pi"];
7482
- var OcEntryObjectSchema = object({
7483
- model: string2().describe("OpenCode model ID (for example, provider/model)."),
7484
- variant: string2().optional().describe("OpenCode reasoning variant for this entry.")
7485
- }).strict();
7486
- var OcEntrySchema = union([string2(), OcEntryObjectSchema]);
7487
- var PiEntryObjectSchema = object({
7488
- model: string2().describe("Pi model ID (for example, provider/model)."),
7468
+ var HISTORIAN_MODEL_RESOLUTION_FIELDS = [
7469
+ "model",
7470
+ "fallback_models",
7471
+ "variant",
7472
+ "thinking_level"
7473
+ ];
7474
+ var LEGACY_HARNESS_BLOCK_KEYS = ["opencode", "pi"];
7475
+ var HistorianModelEntryObjectSchema = object({
7476
+ model: string2().describe("Model ID (for example, provider/model)."),
7477
+ variant: string2().optional().describe("OpenCode reasoning variant for this entry."),
7489
7478
  thinking_level: PiThinkingLevelSchema.describe("Pi thinking level for this entry.")
7490
7479
  }).strict();
7491
- var PiEntrySchema = union([string2(), PiEntryObjectSchema]);
7492
- var OpenCodeHarnessBlockSchema = object({
7493
- model: OcEntrySchema.optional().describe("Primary OpenCode model entry."),
7494
- fallback_models: array(OcEntrySchema).optional().describe("Ordered fallback OpenCode entries. New-shape configuration requires an array; legacy singleton values migrate to a one-element array."),
7495
- variant: string2().optional().describe("OpenCode reasoning variant for the primary entry when it declares none. Fallback entries declare variants per-entry.")
7496
- }).strict().describe("Strict OpenCode model-resolution block. It accepts no Pi vocabulary.");
7497
- var PiHarnessBlockSchema = object({
7498
- model: PiEntrySchema.optional().describe("Primary Pi model entry."),
7499
- fallback_models: array(PiEntrySchema).optional().describe("Ordered fallback Pi entries. New-shape configuration requires an array; legacy singleton values migrate to a one-element array."),
7500
- thinking_level: PiThinkingLevelSchema.describe("Pi thinking level for the primary entry when it declares none. Fallback entries declare thinking levels per-entry.")
7501
- }).strict().describe("Strict Pi model-resolution block. It accepts no OpenCode vocabulary.");
7502
- var ProfileOpenCodeModelBlockSchema = object({
7503
- model: OcEntrySchema.optional().describe("Primary OpenCode model entry."),
7504
- fallback_models: array(OcEntrySchema).optional().describe("Ordered fallback OpenCode model entries."),
7505
- variant: string2().optional().describe("OpenCode reasoning variant for the primary model entry.")
7506
- }).strict().describe("Strict profile-only OpenCode model-selection block.");
7507
- var ProfilePiModelBlockSchema = object({
7508
- model: PiEntrySchema.optional().describe("Primary Pi model entry."),
7509
- fallback_models: array(PiEntrySchema).optional().describe("Ordered fallback Pi model entries."),
7510
- thinking_level: PiThinkingLevelSchema.describe("Pi thinking level for the primary model entry.")
7511
- }).strict().describe("Strict profile-only Pi model-selection block.");
7480
+ var HistorianModelEntrySchema = union([string2(), HistorianModelEntryObjectSchema]);
7512
7481
  var ProfileHistorianSchema = object({
7513
- opencode: ProfileOpenCodeModelBlockSchema.optional(),
7514
- pi: ProfilePiModelBlockSchema.optional()
7515
- }).strict();
7482
+ model: HistorianModelEntrySchema.optional().describe("Primary historian model entry."),
7483
+ fallback_models: array(HistorianModelEntrySchema).optional().describe("Ordered fallback historian model entries."),
7484
+ variant: string2().optional().describe("OpenCode reasoning variant for the primary entry. Ignored by Pi."),
7485
+ thinking_level: PiThinkingLevelSchema.describe("Pi thinking level for the primary entry. Ignored by OpenCode.")
7486
+ }).strict().describe("Strict profile-only historian model-selection block.");
7516
7487
  var ConfigProfileSchema = object({
7517
7488
  historian: ProfileHistorianSchema.optional()
7518
- }).strict().describe("User-owned model-selection overlay. Only historian harness model blocks are allowed.");
7489
+ }).strict().describe("User-owned model-selection overlay. Only the flat historian model-resolution fields are allowed.");
7519
7490
  var ConfigProfilesSchema = record(string2().trim().min(1, "Profile names must not be empty or whitespace-only."), ConfigProfileSchema);
7520
7491
  var AgentMetadataSchema = AgentOverrideConfigSchema.pick({
7521
7492
  temperature: true,
@@ -7539,20 +7510,22 @@ var HistorianConfigSchema = AgentMetadataSchema.extend({
7539
7510
  }),
7540
7511
  literal(false)
7541
7512
  ])).optional().describe('Readable historian tool expansions, keyed by exact host tool name. Templates override built-in defaults; false disables an expansion. Supports ${input.path}, ${output.path}, bare ${output}, array [N], [*].field, .each("${field}"), .join("separator"), .count and final .truncate(N). Missing fields are empty; placeholders default to 300 characters, lists to 10 elements, expansions to 1000 characters. Valid in user and project config; affects historian/recomp and verbose ctx_expand only, never the wire or default ctx_expand transcript.'),
7542
- opencode: OpenCodeHarnessBlockSchema.optional(),
7543
- pi: PiHarnessBlockSchema.optional(),
7513
+ model: HistorianModelEntrySchema.optional().describe("Primary historian model entry. The active harness reads its own qualifier (OpenCode variant, Pi thinking_level); the other harness's qualifier is ignored."),
7514
+ fallback_models: array(HistorianModelEntrySchema).optional().describe("Ordered fallback historian model entries, tried in order."),
7515
+ variant: string2().optional().describe("OpenCode reasoning variant for the primary entry when it declares none. Ignored by Pi."),
7516
+ thinking_level: PiThinkingLevelSchema.describe("Pi thinking level for the primary entry when it declares none. Ignored by OpenCode."),
7544
7517
  two_pass: boolean2().default(false).describe("Run a second editor pass over historian output to clean low-signal U: lines and cross-compartment duplicates. Adds ~1 extra API call and ~1.3x cost per historian run. Useful for models without extended thinking support. (default: false)"),
7545
7518
  disallowed_tools: array(_enum(["*", "read", "aft_outline", "aft_zoom", "aft_search"])).default([]).describe(`OpenCode only. Tools to REMOVE from the historian's default allow-list [read, aft_outline, aft_zoom, aft_search]. Applies to both historian and historian-editor agents. Use ["*"] to strip all tool definitions from the model request — this prevents weak instruction-following models (e.g. mistral-small-latest) from entering tool-calling loops. Individual tool names remove just that tool. Note: a user-supplied historian.permission override can re-allow a tool that disallowed_tools removed — disallowed_tools sets the baseline, permission overrides take precedence. (default: [])`)
7546
- }).optional();
7519
+ }).strict().optional();
7547
7520
  var MagicContextConfigSchema = object({
7548
7521
  enabled: boolean2().default(true).describe("Enable magic context (default: true)"),
7549
7522
  allow_home_project: boolean2().default(false).describe("Allow Magic Context sessions launched from the exact canonical home directory. A non-git home uses its deterministic dir: identity; a home repository uses its git: identity. USER-LEVEL ONLY: project config is ignored. The home identity is excluded from registry seed exports, never resolves descendants by containment, and cannot join a workspace."),
7550
7523
  auto_update: boolean2().optional().describe("DEPRECATED no-op: the automatic update check was removed (the package is private-registry-only, so public npm checks always 404). The key is still accepted so existing configs keep parsing; upgrade via the host's own plugin update channel."),
7551
7524
  language: string2().trim().toLowerCase().refine((s) => isValidLanguageCode(s), 'language must be a 2-letter ISO 639-1 code (e.g. "tr", "es", "de")').optional().describe("Output language for Magic Context's generated content and guidance, as a " + '2-letter ISO 639-1 code (e.g. "tr", "es", "de", "ja", "pt"). When set, the ' + "historian and the agent-guidance block instruct the model to " + "write its PROSE in this language while keeping all structural tokens (XML tags, " + "the five memory category names, code identifiers, file paths) in English. " + "USER-LEVEL ONLY (ignored in project config for security). Unset = today's " + "behavior (model mirrors the conversation; English scaffolding). Changing it " + "triggers one cache re-materialization; existing compartments/memories keep their " + "original language until naturally rewritten."),
7552
7525
  profile: string2().trim().min(1).optional().describe("Select a named user-owned model profile. A valid project name overrides this user default; an empty string, null, or other non-string project value is ignored with a warning so the user selection still applies. Unknown names warn and use the base configuration."),
7553
- profiles: ConfigProfilesSchema.optional().describe("User-level named model profiles. A profile may contain only historian model, fallback_models, OpenCode variant, and Pi thinking_level fields. Project configs may select a name but cannot define profiles."),
7554
- historian: HistorianConfigSchema.describe("Historian metadata plus independent strict OpenCode and Pi execution blocks. Retained metadata stays at historian; model, fallback_models, variant, and thinking_level belong only in historian.opencode or historian.pi."),
7555
- cache_ttl: union([string2(), object({ default: string2() }).catchall(string2())]).default("5m").describe(`How long Magic Context assumes the provider's cached prefix stays valid. This is MC's own deferral gate — it does not change the provider's actual cache lifetime. String (e.g. "5m", "1h", "30s") or per-model object ({ default: "5m", "provider/model": "1h", "provider/*": "never" }); keys resolve most-specific first (exact provider/model, bare model ID, shorter dash-prefixes, then the provider/* wildcard). Explicit per-model entries win; otherwise GPT-5.6 and later (including gpt-6*, through any provider prefix) use a built-in 30m lifetime before the object default or 5m fallback. An unset or global "5m" opts into built-in defaults; any other global string is an explicit policy and wins. Policy is frozen per session, including across restarts; a model switch resolves against that frozen policy. /mmc-status shows the effective value and source. OpenAI documents at least 30 minutes since the latest write or reuse: https://developers.openai.com/api/docs/guides/prompt-caching (Cache lifetime and Summary of model differences). Set to "never" to mean MC never assumes expiry (for lanes kept warm externally by a cache-keep tool) — disables the idle-TTL heuristic so MC never initiates a rebuild based on elapsed time. Provider-side extended TTL is a separate request-level concern (cache_control: { ttl } in the request body).`),
7526
+ profiles: ConfigProfilesSchema.optional().describe("User-level named model profiles. A profile may contain only the flat historian model-resolution fields (model, fallback_models, OpenCode variant, Pi thinking_level). Project configs may select a name but cannot define profiles."),
7527
+ historian: HistorianConfigSchema.describe("Historian metadata plus the flat model-resolution fields (model, fallback_models, variant, thinking_level). The active harness reads its own qualifier; the removed historian.opencode / historian.pi blocks are no longer accepted."),
7528
+ cache_ttl: union([string2(), object({ default: string2() }).catchall(string2())]).default("5m").describe(`How long Magic Context assumes the provider's cached prefix stays valid. This is MC's own deferral gate — it does not change the provider's actual cache lifetime. String (e.g. "5m", "1h", "30s") or per-model object ({ default: "5m", "provider/model": "1h", "provider/*": "never" }); keys resolve most-specific first (exact provider/model, bare model ID, shorter dash-prefixes, then the provider/* wildcard). Explicit per-model entries win; otherwise GPT-5.6 and later (including gpt-6*, through any provider prefix) use a built-in 30m lifetime before the object default or 5m fallback. An unset or global "5m" opts into built-in defaults; any other global string is an explicit policy and wins. User and project settings, including an explicit "5m" or object default, apply on the next pass. Only built-in defaults are frozen per session (per model), including across restarts. /mmc-status shows the effective value and source. OpenAI documents at least 30 minutes since the latest write or reuse: https://developers.openai.com/api/docs/guides/prompt-caching (Cache lifetime and Summary of model differences). Set to "never" to mean MC never assumes expiry (for lanes kept warm externally by a cache-keep tool) — disables the idle-TTL heuristic so MC never initiates a rebuild based on elapsed time. Provider-side extended TTL is a separate request-level concern (cache_control: { ttl } in the request body).`),
7556
7529
  prompt_surface: PromptSurfaceConfigSchema.default({ default: "full" }).describe("Prompt-surface presets: default is full; models use bare model IDs, provider/model, or provider/* routing keys. Guidance and tool-description overrides are user-level only. OpenCode 1.x and Pi register tool descriptions once per process (they follow the default preset). OpenCode 2 rewrites the five mmc_* descriptions per request from the draft model."),
7557
7530
  output_reserve: union([
7558
7531
  number2().min(0),
@@ -7570,7 +7543,13 @@ var MagicContextConfigSchema = object({
7570
7543
  default: number2().min(5000).max(2000000).optional()
7571
7544
  }).catchall(number2().min(5000).max(2000000)).optional().describe("Absolute token thresholds per model. When matched, overrides execute_threshold_percentage for that model. Accepts `default` for all models or per-model keys. Values above 90% × context_limit are clamped with a warning log. Min 5_000, max 2_000_000."),
7572
7545
  protected_tokens: number2().int().min(PROTECTED_TOKENS_MIN).max(1e6).optional().describe("Positive integer token floor to protect from automatic reclaim (min: 4_000, max: 1_000_000). When omitted, the derived default is clamp(round(0.05 × usableSoft), min(16_000, round(0.08 × usableSoft)), 64_000)."),
7573
- clear_reasoning_age: number2().min(10).default(50).describe("Clear reasoning/thinking blocks older than N tags (default: 50)"),
7546
+ clear_reasoning_age: unknown().optional().describe("Deprecated and ignored. Use keep_reasoning_tokens instead.").meta({ deprecated: true }),
7547
+ keep_reasoning_tokens: union([
7548
+ number2().int().min(0).max(1e6),
7549
+ object({
7550
+ default: number2().int().min(0).max(1e6).optional()
7551
+ }).catchall(number2().int().min(0).max(1e6))
7552
+ ]).optional().describe("Reasoning tokens to keep on rebuilding passes. Number or per-model object; exact, shorter model keys, provider/*, then default. Omitted: fixed 10,000. 0 removes all eligible historical reasoning; newest and exempt steps always stay."),
7574
7553
  history_budget_percentage: number2().min(0.05).max(0.5).default(DEFAULT_HISTORY_BUDGET_PERCENTAGE).describe("Fraction of usable context (context_limit × execute_threshold) reserved for the session history block (default: 0.15)"),
7575
7554
  historian_timeout_ms: number2().min(60000).default(DEFAULT_HISTORIAN_TIMEOUT_MS).describe("Timeout for each historian prompt call in both TypeScript and Rust transform modes, in milliseconds (default: 600000)"),
7576
7555
  commit_cluster_trigger: object({
@@ -7603,7 +7582,8 @@ var MagicContextConfigSchema = object({
7603
7582
  overlay: boolean2().default(true).describe("Pi only: show the persistent todo overlay above the editor while tasks are active.")
7604
7583
  }).default({ enabled: false, overlay: true }).describe("Pi-only todowrite tool and overlay controls. Pi registers tools and widgets at extension boot, so changing this after /cd requires /reload or restart."),
7605
7584
  pi: PiConfigSchema.describe("Pi-only child-process extension controls. This setting is user-level only; project configuration cannot choose which extensions a user's subagent children load."),
7606
- smart_drops: boolean2().default(false).describe("Content-aware reclaim of provably-superseded tool output, layered on the existing execute-pass auto-drop. When on: superseded todowrite (keep newest 1), spent mmc_reduce (keep newest 3), and zero-value meta (bash_status, bash_kill, mmc_note read/dismiss) outputs are dropped; older edits to a file are compressed to a filePath-preserving marker while the newest edit per file stays full. Only acts on passes already busting the cache, so it never originates a cache bust. Honors the protected-tag reserve. Experimental: opt-in, default off until cache stability is proven; when off the wire is byte-identical to the positional-only reclaim. Requires a restart."),
7585
+ smart_drops: union([boolean2(), record(string2(), unknown())]).optional(),
7586
+ protected_tools: record(string2(), number2().int().nonnegative()).default({ ...DEFAULT_PROTECTED_TOOLS }).transform((map) => mergeProtectedTools(map)).describe("Keep each tool's newest N still-active results in every automatic drop lane (upstream issue 621). User and project maps merge over defaults {todowrite: 1, mmc_reduce: 3}; 0 turns protection off. Names are case-insensitive and ignore leading mcp_ (upstream's ctx_reduce maps to mmc_reduce). Holds even at 95% pressure, with no byte cap: large protected outputs can reach refusal sooner. Queued drops, from the agent or historian publication, are held until newer calls displace the result and a later cache-rebuilding pass applies them. The historian's summary is unaffected; the raw result leaves at the next fold. Frozen strips are unaffected. Changes and rotation never originate a bust; dropped results are never restored."),
7607
7587
  caveman_text_compression: object({
7608
7588
  enabled: boolean2().default(false).describe("Apply deterministic caveman-style text compression to old conversation text. Active for primary sessions when enabled; never for subagents. Compresses user/assistant text in oldest-first tiers: ultra (oldest 20%), full, lite, untouched (newest 40%)."),
7609
7589
  min_chars: number2().min(100).max(1e4).default(500).describe("Text parts shorter than this (characters) stay untouched. Min 100, max 10000. Default: 500.")
@@ -7669,13 +7649,12 @@ var MagicContextConfigSchema = object({
7669
7649
  }).describe("Automatic memory-maintenance run controls (dreamer replacement). USER-LEVEL ONLY: the whole group is stripped from project-tier config so a cloned repository cannot raise budgets, relax cooldowns, or loosen the anomaly guard.")
7670
7650
  });
7671
7651
  var LIVE_RELOAD_CONFIG_PATHS = [
7652
+ "cache_ttl",
7672
7653
  "toast_duration_ms",
7673
- "historian.opencode.model",
7674
- "historian.opencode.fallback_models",
7675
- "historian.opencode.variant",
7676
- "historian.pi.model",
7677
- "historian.pi.fallback_models",
7678
- "historian.pi.thinking_level",
7654
+ "historian.model",
7655
+ "historian.fallback_models",
7656
+ "historian.variant",
7657
+ "historian.thinking_level",
7679
7658
  "historian.two_pass",
7680
7659
  "historian.expand_tools",
7681
7660
  "historian.maxTokens",
@@ -8844,6 +8823,41 @@ function emergencyDrainExitThreshold(executeThresholdPercentage) {
8844
8823
  }
8845
8824
  return Math.max(0, executeThresholdPercentage - EMERGENCY_DRAIN_EXIT_MARGIN);
8846
8825
  }
8826
+ function resolvedEmergencyDrainLatch(meta, usagePercentage, executeThresholdPercentage, now) {
8827
+ const { forceMaterializationPercentage } = escalationBands(executeThresholdPercentage);
8828
+ if (usagePercentage >= forceMaterializationPercentage)
8829
+ return meta.emergencyDrainActive > 0 ? meta.emergencyDrainActive : now;
8830
+ if (usagePercentage < emergencyDrainExitThreshold(executeThresholdPercentage) || now - meta.emergencyDrainActive > EMERGENCY_DRAIN_MAX_LATCH_MS)
8831
+ return 0;
8832
+ return meta.emergencyDrainActive;
8833
+ }
8834
+ function drainFailureBackoffActive(meta, now) {
8835
+ return meta.historianDrainFailureAt > 0 && meta.historianDrainFailureAt <= now && now - meta.historianDrainFailureAt < EMERGENCY_DRAIN_FAILURE_BACKOFF_MS;
8836
+ }
8837
+ function getProtectedTailDrainBudgetSkip(args) {
8838
+ const now = args.now ?? Date.now();
8839
+ const meta = loadProtectedTailMeta(args.db, args.sessionId);
8840
+ const latch = resolvedEmergencyDrainLatch(meta, args.usagePercentage, args.executeThresholdPercentage, now);
8841
+ if (latch !== meta.emergencyDrainActive) {
8842
+ args.db.prepare("UPDATE session_meta SET emergency_drain_active = ? WHERE session_id = ? AND emergency_drain_active = ?").run(latch, args.sessionId, meta.emergencyDrainActive);
8843
+ }
8844
+ const startedAt = meta.protectedTailDrainWindowStartedAt;
8845
+ if (startedAt <= 0 || startedAt > now || now - startedAt >= DRAIN_WINDOW_MS)
8846
+ return null;
8847
+ const limitTokens = protectedTailWindowBudget(args.usagePercentage, args.usable, args.perRunCap);
8848
+ if (meta.protectedTailDrainTokens < limitTokens)
8849
+ return null;
8850
+ if (latch > 0 && !drainFailureBackoffActive(meta, now))
8851
+ return null;
8852
+ return {
8853
+ windowStartedAt: startedAt,
8854
+ resetsAt: startedAt + DRAIN_WINDOW_MS,
8855
+ nextEligibleAt: latch > 0 ? Math.min(startedAt + DRAIN_WINDOW_MS, meta.historianDrainFailureAt + EMERGENCY_DRAIN_FAILURE_BACKOFF_MS) : startedAt + DRAIN_WINDOW_MS,
8856
+ resetInMs: startedAt + DRAIN_WINDOW_MS - now,
8857
+ spentTokens: meta.protectedTailDrainTokens,
8858
+ limitTokens
8859
+ };
8860
+ }
8847
8861
  function reserveProtectedTailDrainTokens(args) {
8848
8862
  const now = args.now ?? Date.now();
8849
8863
  const requested = Math.max(0, Math.floor(args.trueRawTokens));
@@ -8875,17 +8889,7 @@ function reserveProtectedTailDrainTokens(args) {
8875
8889
  WHERE session_id = ?`).run(now, args.sessionId);
8876
8890
  meta = loadProtectedTailMeta(args.db, args.sessionId);
8877
8891
  }
8878
- const exitThreshold = emergencyDrainExitThreshold(args.executeThresholdPercentage);
8879
- let latchActiveSince = meta.emergencyDrainActive;
8880
- const { forceMaterializationPercentage } = escalationBands(args.executeThresholdPercentage);
8881
- if (args.usagePercentage >= forceMaterializationPercentage) {
8882
- if (latchActiveSince <= 0)
8883
- latchActiveSince = now;
8884
- } else if (latchActiveSince > 0) {
8885
- const expired = now - latchActiveSince > EMERGENCY_DRAIN_MAX_LATCH_MS;
8886
- if (args.usagePercentage < exitThreshold || expired)
8887
- latchActiveSince = 0;
8888
- }
8892
+ const latchActiveSince = resolvedEmergencyDrainLatch(meta, args.usagePercentage, args.executeThresholdPercentage, now);
8889
8893
  if (latchActiveSince !== meta.emergencyDrainActive) {
8890
8894
  args.db.prepare("UPDATE session_meta SET emergency_drain_active = ? WHERE session_id = ?").run(latchActiveSince, args.sessionId);
8891
8895
  }
@@ -8894,7 +8898,7 @@ function reserveProtectedTailDrainTokens(args) {
8894
8898
  const remaining = Math.max(0, budget - meta.protectedTailDrainTokens);
8895
8899
  let reserved = Math.min(requested, args.perRunCap, remaining);
8896
8900
  let bypass = false;
8897
- const inFailureBackoff = meta.historianDrainFailureAt > 0 && meta.historianDrainFailureAt <= now && now - meta.historianDrainFailureAt < EMERGENCY_DRAIN_FAILURE_BACKOFF_MS;
8901
+ const inFailureBackoff = drainFailureBackoffActive(meta, now);
8898
8902
  if (reserved <= 0 && latchActive && !inFailureBackoff) {
8899
8903
  reserved = Math.min(requested, args.perRunCap);
8900
8904
  bypass = true;
@@ -9828,9 +9832,6 @@ function resolveEpochFloorForPass(db, sessionId, inputs) {
9828
9832
  return preSnapshotResult(firstObservedMemo, resolvedInputs);
9829
9833
  }
9830
9834
 
9831
- // src/hooks/magic-context/lkg-slot.ts
9832
- import { createHash as createHash4 } from "node:crypto";
9833
-
9834
9835
  // src/shared/bounded-session-map.ts
9835
9836
  class BoundedSessionMap {
9836
9837
  maxEntries;
@@ -9877,6 +9878,7 @@ class BoundedSessionMap {
9877
9878
  }
9878
9879
 
9879
9880
  // src/hooks/magic-context/lkg-slot.ts
9881
+ import { createHash as createHash4 } from "node:crypto";
9880
9882
  var LKG_TOTAL_BYTES = 64 * 1024 * 1024;
9881
9883
  var LKG_SINGLE_SLOT_BYTES = 24 * 1024 * 1024;
9882
9884
  var LKG_METADATA_BYTES = 256;
@@ -10401,6 +10403,29 @@ function layoutLkgPrefix(jsonPrefix) {
10401
10403
  const chunkHashes = chunks.map(hashLkgChunk);
10402
10404
  return { chunks, chunkHashes, chars: jsonPrefix.length, hash: hashLkgChunkList(chunkHashes) };
10403
10405
  }
10406
+ function assembleLkgPrefix(expected, rows) {
10407
+ const { chars, chunks, hash } = expected;
10408
+ if (typeof chars !== "number" || !Number.isSafeInteger(chars) || typeof chunks !== "number" || !Number.isSafeInteger(chunks) || typeof hash !== "string" || rows.length !== chunks) {
10409
+ return;
10410
+ }
10411
+ const bodies = [];
10412
+ let length = 0;
10413
+ for (let index = 0;index < rows.length; index += 1) {
10414
+ const row = rows[index];
10415
+ if (row?.chunk !== index || typeof row.body !== "string")
10416
+ return;
10417
+ bodies.push(row.body);
10418
+ length += row.body.length;
10419
+ }
10420
+ if (length !== chars)
10421
+ return;
10422
+ const chunkHashes = bodies.map(hashLkgChunk);
10423
+ if (chunkHashes.some((chunkHash, index) => rows[index]?.hash !== chunkHash))
10424
+ return;
10425
+ if (hashLkgChunkList(chunkHashes) !== hash)
10426
+ return;
10427
+ return { jsonPrefix: bodies.join(""), chunkHashes, hash };
10428
+ }
10404
10429
 
10405
10430
  // src/features/magic-context/migration-v2-write-split.ts
10406
10431
  var LKG_SLOT_CHUNKS_DDL = `
@@ -10559,6 +10584,113 @@ function splitReplayDecisions(db) {
10559
10584
  db.exec("DROP TABLE temp.v2_replay_documents");
10560
10585
  }
10561
10586
 
10587
+ // src/features/magic-context/temporal-decisions.ts
10588
+ var PREFIX = "temporal-message-v1:";
10589
+ function decodeTemporalDecision(entry) {
10590
+ if (!entry.startsWith(PREFIX))
10591
+ return null;
10592
+ try {
10593
+ const pair = JSON.parse(entry.slice(PREFIX.length));
10594
+ if (Array.isArray(pair) && pair.length === 2 && typeof pair[0] === "string" && pair[0] && typeof pair[1] === "string")
10595
+ return [pair[0], pair[1]];
10596
+ } catch {}
10597
+ return null;
10598
+ }
10599
+ function readRows(db, sessionId, messageIds) {
10600
+ if (!messageIds)
10601
+ return db.prepare("SELECT message_id,marker FROM temporal_decisions WHERE session_id=?").all(sessionId);
10602
+ const ids = [...messageIds];
10603
+ const result = [];
10604
+ for (let offset = 0;offset < ids.length; offset += 400) {
10605
+ const chunk = ids.slice(offset, offset + 400);
10606
+ result.push(...db.prepare(`SELECT message_id,marker FROM temporal_decisions WHERE session_id=? AND message_id IN (${chunk.map(() => "?").join(",")})`).all(sessionId, ...chunk));
10607
+ }
10608
+ return result;
10609
+ }
10610
+ function getTemporalDecisions(db, sessionId, messageIds) {
10611
+ return new Map(readRows(db, sessionId, messageIds).flatMap((row) => row.marker === null ? [] : [[row.message_id, row.marker]]));
10612
+ }
10613
+ function observeTemporalDecisions(db, sessionId, candidates, previouslyServed, messageIds) {
10614
+ const ids = new Set([...candidates.keys(), ...messageIds ?? []]);
10615
+ const rows = readRows(db, sessionId, ids);
10616
+ const known = new Set(rows.map((row) => row.message_id));
10617
+ const missing = [...candidates].filter(([id]) => !known.has(id));
10618
+ if (!missing.length)
10619
+ return new Map(rows.flatMap((row) => row.marker === null ? [] : [[row.message_id, row.marker]]));
10620
+ const transient = new Map;
10621
+ db.transaction(() => {
10622
+ const insert = db.prepare("INSERT OR IGNORE INTO temporal_decisions(session_id,message_id,marker) VALUES (?,?,?)");
10623
+ const servedTag = db.prepare("SELECT 1 FROM tags WHERE session_id=? AND message_id=? UNION ALL SELECT 1 FROM tags WHERE session_id=? AND message_id>=? AND message_id<? LIMIT 1");
10624
+ let served;
10625
+ for (const [id, candidate] of missing) {
10626
+ const historical = servedTag.get(sessionId, id, sessionId, `${id}:p`, `${id}:q`);
10627
+ if (historical) {
10628
+ served ??= previouslyServed?.(missing.map(([missingId]) => missingId)) ?? new Map;
10629
+ const previous = served.get(id);
10630
+ if (previous === undefined) {
10631
+ transient.set(id, candidate);
10632
+ continue;
10633
+ }
10634
+ insert.run(sessionId, id, previous === "" && candidate !== "" ? null : previous);
10635
+ } else {
10636
+ insert.run(sessionId, id, null);
10637
+ }
10638
+ }
10639
+ }).immediate();
10640
+ return new Map([...transient, ...getTemporalDecisions(db, sessionId, ids)]);
10641
+ }
10642
+ function freezeTemporalDecisions(db, sessionId, candidates) {
10643
+ if (candidates.size === 0)
10644
+ return new Map;
10645
+ return db.transaction(() => {
10646
+ const insert = db.prepare("INSERT INTO temporal_decisions(session_id,message_id,marker) VALUES (?,?,?) ON CONFLICT(session_id,message_id) DO UPDATE SET marker=excluded.marker WHERE temporal_decisions.marker IS NULL");
10647
+ for (const [id, marker] of candidates) {
10648
+ insert.run(sessionId, id, marker);
10649
+ }
10650
+ return getTemporalDecisions(db, sessionId, candidates.keys());
10651
+ }).immediate();
10652
+ }
10653
+
10654
+ // src/features/magic-context/migration-v4-temporal-decisions.ts
10655
+ var TEMPORAL_DECISIONS_DDL = `CREATE TABLE IF NOT EXISTS temporal_decisions (
10656
+ session_id TEXT NOT NULL,
10657
+ message_id TEXT NOT NULL,
10658
+ marker TEXT,
10659
+ PRIMARY KEY (session_id, message_id)
10660
+ ) WITHOUT ROWID`;
10661
+ function installV4TemporalDecisions(db) {
10662
+ const schema = new Map(db.prepare("SELECT name FROM sqlite_master").all().map((row) => [row.name, true]));
10663
+ if (!schema.has("temporal_decisions")) {
10664
+ db.exec(TEMPORAL_DECISIONS_DDL);
10665
+ if (schema.has("session_meta")) {
10666
+ const rows = db.prepare("SELECT session_id, merged_reasoning_stripped_ids AS entries FROM session_meta WHERE merged_reasoning_stripped_ids LIKE '%temporal-message-v1:%'").all();
10667
+ const insert = db.prepare("INSERT OR IGNORE INTO temporal_decisions(session_id,message_id,marker) VALUES (?,?,?)");
10668
+ for (const row of rows) {
10669
+ let entries;
10670
+ try {
10671
+ entries = JSON.parse(row.entries);
10672
+ } catch {
10673
+ sessionLog(row.session_id, "v4 temporal metadata: malformed JSON skipped; original blob retained");
10674
+ continue;
10675
+ }
10676
+ if (!Array.isArray(entries)) {
10677
+ sessionLog(row.session_id, "v4 temporal metadata: non-array JSON skipped; original blob retained");
10678
+ continue;
10679
+ }
10680
+ const kept = [];
10681
+ for (const entry of entries) {
10682
+ const decision = typeof entry === "string" ? decodeTemporalDecision(entry) : null;
10683
+ if (decision)
10684
+ insert.run(row.session_id, ...decision);
10685
+ else
10686
+ kept.push(entry);
10687
+ }
10688
+ db.prepare("UPDATE session_meta SET merged_reasoning_stripped_ids=? WHERE session_id=?").run(JSON.stringify(kept), row.session_id);
10689
+ }
10690
+ }
10691
+ }
10692
+ }
10693
+
10562
10694
  // src/features/magic-context/migrations.ts
10563
10695
  var FORK_MIGRATION_VERSION_FLOOR = 1e4;
10564
10696
  var MIGRATION_LOCK_RETRY_DELAYS_MS = [1000, 2000, 4000, 8000, 15000];
@@ -10590,6 +10722,20 @@ var MIGRATIONS = [
10590
10722
  splitLkgSlotPrefixes(db);
10591
10723
  splitReplayDecisions(db);
10592
10724
  }
10725
+ },
10726
+ {
10727
+ version: 3,
10728
+ description: "drop redundant single-column session indexes; add FTS rowid-map lookup",
10729
+ up(db) {
10730
+ installV3PerfSchema(db);
10731
+ }
10732
+ },
10733
+ {
10734
+ version: 4,
10735
+ description: "store temporal replay decisions per message identity",
10736
+ up(db) {
10737
+ installV4TemporalDecisions(db);
10738
+ }
10593
10739
  }
10594
10740
  ];
10595
10741
  var LATEST_MIGRATION_VERSION = MIGRATIONS.reduce((max, m) => Math.max(max, m.version), 0);
@@ -10994,7 +11140,7 @@ function getSchemaFenceRejection() {
10994
11140
  function getMigrationOnOpenRefusal() {
10995
11141
  return lastMigrationOnOpenRefusal;
10996
11142
  }
10997
- var LATEST_SUPPORTED_VERSION = 2;
11143
+ var LATEST_SUPPORTED_VERSION = 4;
10998
11144
  var BOOT_SQLITE_BUSY_TIMEOUT_MS = 5000;
10999
11145
  function ensureSecureStorageDir(dir) {
11000
11146
  ensureStorageDirectorySync(dir);
@@ -11386,8 +11532,8 @@ function finishDatabaseOpen(db, dbPath, explicitDbPath, latestSupportedVersion)
11386
11532
  startMessageFtsRowidMapBackfill(db).then(async () => {
11387
11533
  if (!readsOpenCodeStore)
11388
11534
  return;
11389
- const { readRawSessionMessagePage, readRawSessionMessages } = await import("./read-session-chunk-apjwrttc.js");
11390
- const { startMessageTimeBackfill } = await import("./message-time-backfill-5ewk0axe.js");
11535
+ const { readRawSessionMessagePage, readRawSessionMessages } = await import("./read-session-chunk-82rkqa8j.js");
11536
+ const { startMessageTimeBackfill } = await import("./message-time-backfill-phrwp2fz.js");
11391
11537
  await startMessageTimeBackfill(db, Object.assign(readRawSessionMessages, {
11392
11538
  readPage: readRawSessionMessagePage
11393
11539
  }));
@@ -11483,7 +11629,6 @@ function initializeDatabase(db, busyTimeoutMs = BOOT_SQLITE_BUSY_TIMEOUT_MS) {
11483
11629
  harness TEXT NOT NULL DEFAULT 'opencode',
11484
11630
  UNIQUE(session_id, sequence)
11485
11631
  );
11486
- CREATE INDEX IF NOT EXISTS idx_compartments_session ON compartments(session_id);
11487
11632
 
11488
11633
  CREATE TABLE IF NOT EXISTS compartment_chunk_embeddings (
11489
11634
  id INTEGER PRIMARY KEY AUTOINCREMENT,
@@ -11544,7 +11689,6 @@ function initializeDatabase(db, busyTimeoutMs = BOOT_SQLITE_BUSY_TIMEOUT_MS) {
11544
11689
  harness TEXT NOT NULL DEFAULT 'opencode',
11545
11690
  PRIMARY KEY(session_id, message_ordinal)
11546
11691
  );
11547
- CREATE INDEX IF NOT EXISTS idx_compression_depth_session ON compression_depth(session_id);
11548
11692
 
11549
11693
  CREATE TABLE IF NOT EXISTS session_facts (
11550
11694
  id INTEGER PRIMARY KEY AUTOINCREMENT,
@@ -12063,7 +12207,6 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
12063
12207
  stale_reason TEXT,
12064
12208
  PRIMARY KEY (project_path, path)
12065
12209
  );
12066
- CREATE INDEX IF NOT EXISTS idx_project_key_files_project ON project_key_files(project_path);
12067
12210
  CREATE INDEX IF NOT EXISTS idx_project_key_files_generated_at ON project_key_files(project_path, generated_at);
12068
12211
 
12069
12212
  CREATE TABLE IF NOT EXISTS project_key_files_version (
@@ -12423,10 +12566,6 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
12423
12566
  input_tokens INTEGER NOT NULL DEFAULT 0,
12424
12567
  PRIMARY KEY (session_id, harness, message_id)
12425
12568
  );
12426
- CREATE INDEX IF NOT EXISTS idx_transform_decisions_session_harness
12427
- ON transform_decisions(session_id, harness);
12428
-
12429
- CREATE INDEX IF NOT EXISTS idx_tags_session_tag_number ON tags(session_id, tag_number);
12430
12569
  CREATE INDEX IF NOT EXISTS idx_tags_session_message_id ON tags(session_id, message_id);
12431
12570
 
12432
12571
  -- Clone/import paths can write tags before session bootstrap. Keep trigger-created
@@ -12472,10 +12611,7 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
12472
12611
  WHERE NEW.session_id != OLD.session_id
12473
12612
  ON CONFLICT(session_id) DO UPDATE SET tags_version = tags_version + 1;
12474
12613
  END;
12475
- CREATE INDEX IF NOT EXISTS idx_pending_ops_session ON pending_ops(session_id);
12476
12614
  CREATE INDEX IF NOT EXISTS idx_pending_ops_session_tag_id ON pending_ops(session_id, tag_id);
12477
- CREATE INDEX IF NOT EXISTS idx_source_contents_session ON source_contents(session_id);
12478
-
12479
12615
  CREATE TABLE IF NOT EXISTS recomp_compartments (
12480
12616
  id INTEGER PRIMARY KEY AUTOINCREMENT,
12481
12617
  session_id TEXT NOT NULL,
@@ -12820,8 +12956,6 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
12820
12956
  input_tokens INTEGER NOT NULL DEFAULT 0,
12821
12957
  PRIMARY KEY (session_id, harness, message_id)
12822
12958
  );
12823
- CREATE INDEX IF NOT EXISTS idx_transform_decisions_session_harness
12824
- ON transform_decisions(session_id, harness);
12825
12959
  `);
12826
12960
  ensureColumn(db, "transform_decisions", "system_hash_prev", "TEXT");
12827
12961
  ensureColumn(db, "transform_decisions", "system_hash_new", "TEXT");
@@ -12857,6 +12991,8 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
12857
12991
  ON tags(session_id, message_id)
12858
12992
  WHERE type = 'tool' AND tool_owner_message_id IS NULL;
12859
12993
  `);
12994
+ installV3PerfSchema(db);
12995
+ installV4TemporalDecisions(db);
12860
12996
  }
12861
12997
  var CHANNEL2_CLAIM_TTL_MS = 10 * 60000;
12862
12998
  var channel2HealStatements = new WeakMap;
@@ -13041,7 +13177,9 @@ function getDatabasePersistenceError(db) {
13041
13177
  }
13042
13178
 
13043
13179
  // src/v2/store-reader.ts
13180
+ import { createHash as createHash7 } from "node:crypto";
13044
13181
  import { statSync as statSync3 } from "node:fs";
13182
+ import { hostname } from "node:os";
13045
13183
  import { resolve as resolve2 } from "node:path";
13046
13184
  function gaDatabasePath(dataHome, channel = "latest", env = process.env) {
13047
13185
  return resolveOpenCodeDbPath("v2", { dataHome, channel, env }).path;
@@ -13155,6 +13293,8 @@ function decode2(row) {
13155
13293
  return { ...row, data };
13156
13294
  }
13157
13295
  function connect(path, identity = "") {
13296
+ const stat = statSync3(path);
13297
+ const acquiredIdentity = identity || `${stat.dev}:${stat.ino}:${stat.birthtimeMs}`;
13158
13298
  const db = new Database(path, { readonly: true, fileMustExist: true });
13159
13299
  try {
13160
13300
  assertOpenCodeStoreGeneration(db, "v2", path);
@@ -13166,7 +13306,7 @@ function connect(path, identity = "") {
13166
13306
  counters.openReaders += 1;
13167
13307
  counters.readersOpened += 1;
13168
13308
  counters.maxOpenReaders = Math.max(counters.maxOpenReaders, counters.openReaders);
13169
- return { db, statements: new Map, identity, leases: 0, retired: false };
13309
+ return { db, statements: new Map, identity: acquiredIdentity, leases: 0, retired: false };
13170
13310
  }
13171
13311
  function closeConnection(connection) {
13172
13312
  connection.statements.clear();
@@ -13238,15 +13378,20 @@ class V2StoreReaderPool {
13238
13378
  }
13239
13379
 
13240
13380
  class V2StoreReader {
13381
+ path;
13241
13382
  pool;
13242
13383
  db;
13243
13384
  connection;
13244
13385
  closed = false;
13245
13386
  constructor(path, pool) {
13387
+ this.path = path;
13246
13388
  this.pool = pool;
13247
13389
  this.connection = pool ? pool.acquire(path) : connect(path);
13248
13390
  this.db = this.connection.db;
13249
13391
  }
13392
+ hostIdentity() {
13393
+ return createHash7("sha256").update(JSON.stringify([hostname(), resolve2(this.path), this.connection.identity])).digest("hex");
13394
+ }
13250
13395
  prepare(sql) {
13251
13396
  if (this.closed)
13252
13397
  throw new Error("Store reader is closed");
@@ -13342,6 +13487,10 @@ class V2StoreReader {
13342
13487
  return null;
13343
13488
  return typeof row.parent_id === "string" && row.parent_id.length > 0;
13344
13489
  }
13490
+ storedRowsAfter(sessionID, after) {
13491
+ const row = this.prepare("SELECT COUNT(*) AS count FROM session_message WHERE session_id = ? AND seq > ?").get(sessionID, after);
13492
+ return row.count;
13493
+ }
13345
13494
  storedMessageCount(sessionID) {
13346
13495
  return trackDecodeOperation("storedMessageCount", () => {
13347
13496
  const row = this.prepare("SELECT COUNT(*) AS count FROM session_message WHERE session_id = ?").get(sessionID);
@@ -13594,6 +13743,10 @@ var SESSION_SCOPED_TABLES = [
13594
13743
  { table: "tool_owner_backfill_state" },
13595
13744
  { table: "tags", harnessScoped: true },
13596
13745
  { table: "session_meta", harnessScoped: true },
13746
+ {
13747
+ table: "temporal_decisions",
13748
+ extraPredicate: "NOT EXISTS (SELECT 1 FROM session_meta AS remaining WHERE remaining.session_id = temporal_decisions.session_id)"
13749
+ },
13597
13750
  {
13598
13751
  table: "session_replay_decisions",
13599
13752
  extraPredicate: "NOT EXISTS (SELECT 1 FROM session_meta AS remaining WHERE remaining.session_id = session_replay_decisions.session_id)"
@@ -13699,11 +13852,14 @@ function getSessionMetaSelectColumns(db) {
13699
13852
  sessionMetaSelectColumnsCache.set(db, projection);
13700
13853
  return projection;
13701
13854
  }
13702
- function getOrCreateSessionMeta(db, sessionId) {
13855
+ function findSessionMeta(db, sessionId) {
13703
13856
  const result = db.prepare(`SELECT ${getSessionMetaSelectColumns(db)} FROM session_meta WHERE session_id = ?`).get(sessionId);
13704
- if (isSessionMetaRow(result)) {
13705
- return toSessionMeta(result);
13706
- }
13857
+ return isSessionMetaRow(result) ? toSessionMeta(result) : undefined;
13858
+ }
13859
+ function getOrCreateSessionMeta(db, sessionId) {
13860
+ const existing = findSessionMeta(db, sessionId);
13861
+ if (existing)
13862
+ return existing;
13707
13863
  const harness = getHarness();
13708
13864
  const defaults = getDefaultSessionMeta(sessionId);
13709
13865
  const fallbackSubagent = harness === "opencode" ? resolveIsSubagentFromOpenCodeDb(sessionId) : harness === "opencode2" ? resolveIsSubagentFromOpenCode2Db(sessionId) : null;
@@ -13767,7 +13923,7 @@ function clearSession(db, sessionId) {
13767
13923
  logSlowWriteTransaction("clear-session", transactionStartedAt);
13768
13924
  }
13769
13925
  // src/features/magic-context/message-index.ts
13770
- import { createHash as createHash7 } from "node:crypto";
13926
+ import { createHash as createHash8 } from "node:crypto";
13771
13927
  var MESSAGE_HISTORY_ORPHAN_SAFETY_AGE_MS = 24 * 60 * 60 * 1000;
13772
13928
  var MESSAGE_HISTORY_ORPHAN_SWEEP_COOLDOWN_MS = 10 * 60 * 1000;
13773
13929
  var MESSAGE_HISTORY_ORPHAN_UNAVAILABLE_REPROBE_MS = 24 * 60 * 60 * 1000;
@@ -13928,7 +14084,7 @@ function toMessageIndexSource(message) {
13928
14084
  role: message.role,
13929
14085
  createdAt: message.createdAt,
13930
14086
  sourceVersion: normalizeSourceVersion(message.version),
13931
- contentHash: createHash7("sha256").update(content).digest("hex"),
14087
+ contentHash: createHash8("sha256").update(content).digest("hex"),
13932
14088
  content
13933
14089
  };
13934
14090
  }
@@ -14165,15 +14321,15 @@ function createPreAdoptionToolSweepResolver(db, sessionId) {
14165
14321
  }
14166
14322
 
14167
14323
  // src/features/magic-context/pi-content-decisions.ts
14168
- var PREFIX = "pi-content-replay-v1:";
14324
+ var PREFIX2 = "pi-content-replay-v1:";
14169
14325
  function encodePiContentDecision(kind, messageId) {
14170
- return PREFIX + JSON.stringify([kind, messageId]);
14326
+ return PREFIX2 + JSON.stringify([kind, messageId]);
14171
14327
  }
14172
14328
  function decodePiContentDecision(value) {
14173
- if (!value.startsWith(PREFIX))
14329
+ if (!value.startsWith(PREFIX2))
14174
14330
  return null;
14175
14331
  try {
14176
- const pair = JSON.parse(value.slice(PREFIX.length));
14332
+ const pair = JSON.parse(value.slice(PREFIX2.length));
14177
14333
  if (Array.isArray(pair) && pair.length === 2 && (pair[0] === "reminder-strip" || pair[0] === "seam-temporal-strip") && typeof pair[1] === "string" && pair[1].length > 0)
14178
14334
  return [pair[0], pair[1]];
14179
14335
  } catch {}
@@ -14983,101 +15139,6 @@ function dismissNotes(db, noteIds, scope) {
14983
15139
  function dismissNote(db, noteId, scope) {
14984
15140
  return dismissNotes(db, [noteId], scope)[0]?.outcome === "dismissed";
14985
15141
  }
14986
- // src/features/magic-context/storage-ops.ts
14987
- var queuePendingOpStatements = new WeakMap;
14988
- var queueUnchangedDropStatements = new WeakMap;
14989
- var getPendingOpsStatements = new WeakMap;
14990
- var getPendingOpsCountStatements = new WeakMap;
14991
- var clearPendingOpsStatements = new WeakMap;
14992
- var removePendingOpStatements = new WeakMap;
14993
- function getQueuePendingOpStatement(db) {
14994
- let stmt = queuePendingOpStatements.get(db);
14995
- if (!stmt) {
14996
- stmt = db.prepare("INSERT INTO pending_ops (session_id, tag_id, operation, queued_at, harness) VALUES (?, ?, ?, ?, ?)");
14997
- queuePendingOpStatements.set(db, stmt);
14998
- }
14999
- return stmt;
15000
- }
15001
- function getPendingOpsStatement(db) {
15002
- let stmt = getPendingOpsStatements.get(db);
15003
- if (!stmt) {
15004
- stmt = db.prepare("SELECT id, session_id, tag_id, operation, queued_at FROM pending_ops WHERE session_id = ? ORDER BY queued_at ASC, id ASC");
15005
- getPendingOpsStatements.set(db, stmt);
15006
- }
15007
- return stmt;
15008
- }
15009
- function getClearPendingOpsStatement(db) {
15010
- let stmt = clearPendingOpsStatements.get(db);
15011
- if (!stmt) {
15012
- stmt = db.prepare("DELETE FROM pending_ops WHERE session_id = ?");
15013
- clearPendingOpsStatements.set(db, stmt);
15014
- }
15015
- return stmt;
15016
- }
15017
- function getRemovePendingOpStatement(db) {
15018
- let stmt = removePendingOpStatements.get(db);
15019
- if (!stmt) {
15020
- stmt = db.prepare("DELETE FROM pending_ops WHERE session_id = ? AND tag_id = ?");
15021
- removePendingOpStatements.set(db, stmt);
15022
- }
15023
- return stmt;
15024
- }
15025
- function isPendingOpRow(row) {
15026
- if (row === null || typeof row !== "object")
15027
- return false;
15028
- const r = row;
15029
- return typeof r.id === "number" && typeof r.session_id === "string" && typeof r.tag_id === "number" && typeof r.operation === "string" && typeof r.queued_at === "number";
15030
- }
15031
- function toPendingOp(row) {
15032
- if (row.operation !== "drop") {
15033
- sessionLog(row.session_id, `unknown pending operation "${row.operation}"; ignoring`);
15034
- return null;
15035
- }
15036
- return {
15037
- id: row.id,
15038
- sessionId: row.session_id,
15039
- tagId: row.tag_id,
15040
- operation: row.operation,
15041
- queuedAt: row.queued_at
15042
- };
15043
- }
15044
- function queuePendingOp(db, sessionId, tagId, operation, queuedAt = Date.now()) {
15045
- getQueuePendingOpStatement(db).run(sessionId, tagId, operation, queuedAt, getHarness());
15046
- }
15047
- function queuePendingDropForUnchangedTag(db, sessionId, tag) {
15048
- let statement = queueUnchangedDropStatements.get(db);
15049
- if (!statement) {
15050
- statement = db.prepare(`INSERT INTO pending_ops (session_id, tag_id, operation, queued_at, harness)
15051
- SELECT session_id, tag_number, 'drop', ?, ? FROM tags
15052
- WHERE id = ? AND session_id = ? AND tag_number = ? AND message_id = ?
15053
- AND type = ? AND tool_owner_message_id IS ? AND status = 'active'`);
15054
- queueUnchangedDropStatements.set(db, statement);
15055
- }
15056
- return statement.run(Date.now(), getHarness(), tag.id ?? null, sessionId, tag.tagNumber, tag.messageId, tag.type, tag.toolOwnerMessageId).changes > 0;
15057
- }
15058
- function getPendingOps(db, sessionId) {
15059
- const rows = getPendingOpsStatement(db).all(sessionId).filter(isPendingOpRow);
15060
- return rows.map(toPendingOp).filter((op) => op !== null);
15061
- }
15062
- function getPendingOpsCount(db, sessionId) {
15063
- try {
15064
- let statement = getPendingOpsCountStatements.get(db);
15065
- if (!statement) {
15066
- statement = db.prepare("SELECT COUNT(*) AS count FROM pending_ops WHERE session_id = ?");
15067
- getPendingOpsCountStatements.set(db, statement);
15068
- }
15069
- const row = statement.get(sessionId);
15070
- return typeof row?.count === "number" && Number.isFinite(row.count) ? row.count : null;
15071
- } catch {
15072
- return null;
15073
- }
15074
- }
15075
- function clearPendingOps(db, sessionId) {
15076
- getClearPendingOpsStatement(db).run(sessionId);
15077
- }
15078
- function removePendingOp(db, sessionId, tagId) {
15079
- getRemovePendingOpStatement(db).run(sessionId, tagId);
15080
- }
15081
15142
  // src/features/magic-context/storage-primers.ts
15082
15143
  var PRIMER_CANDIDATE_TTL_MS = 90 * 24 * 60 * 60 * 1000;
15083
15144
  var PRIMER_CANDIDATE_MAX_AGE_MS = 180 * 24 * 60 * 60 * 1000;
@@ -15282,7 +15343,7 @@ var ERROR_CLASSES = new Set([
15282
15343
  "unknown"
15283
15344
  ]);
15284
15345
  // src/features/magic-context/workspaces.ts
15285
- import { createHash as createHash8 } from "node:crypto";
15346
+ import { createHash as createHash9 } from "node:crypto";
15286
15347
 
15287
15348
  // src/features/magic-context/memory/constants.ts
15288
15349
  var V2_MEMORY_CATEGORIES = [
@@ -15509,7 +15570,7 @@ function computeWorkspaceEpochFingerprint(db, identities) {
15509
15570
  const canonical = uniqueSorted(identities.filter((identity) => identity.length > 0));
15510
15571
  const epochs = getEpochMap(db, canonical);
15511
15572
  const shareCategories = selectWorkspaceShareCategories(db, canonical);
15512
- const hash = createHash8("sha256");
15573
+ const hash = createHash9("sha256");
15513
15574
  hash.update("share_categories", "utf8");
15514
15575
  hash.update("\x00");
15515
15576
  hash.update(shareCategories === null ? "NO_WORKSPACE" : JSON.stringify(shareCategories), "utf8");
@@ -16353,9 +16414,6 @@ function renderCapabilityRefusal(capability) {
16353
16414
  return renderUserFacingFailure(CAPABILITY_FAILURES[capability]);
16354
16415
  }
16355
16416
 
16356
- // src/v2/hooks/hidden-child.ts
16357
- import { createHash as createHash9 } from "node:crypto";
16358
-
16359
16417
  // src/hooks/magic-context/compartment-runner-types.ts
16360
16418
  class HiddenCompletionRefusal extends Error {
16361
16419
  code;
@@ -16369,6 +16427,7 @@ class HiddenCompletionRefusal extends Error {
16369
16427
  }
16370
16428
 
16371
16429
  // src/v2/hooks/hidden-child.ts
16430
+ import { createHash as createHash10 } from "node:crypto";
16372
16431
  var HIDDEN_HISTORIAN_AGENT = "historian";
16373
16432
  var AGENT_TOOL_ALLOWLIST = {
16374
16433
  [HIDDEN_HISTORIAN_AGENT]: [],
@@ -16378,9 +16437,22 @@ var AGENT_TOOL_ALLOWLIST = {
16378
16437
  var AGENT_STEP_CAPS = {
16379
16438
  [MEMORY_MAINTAINER_A_AGENT]: MEMORY_MAINTAINER_A_STEP_CAP
16380
16439
  };
16440
+ function hiddenAgentAllowedTools(agent) {
16441
+ return agent !== undefined && Object.hasOwn(AGENT_TOOL_ALLOWLIST, agent) ? AGENT_TOOL_ALLOWLIST[agent] : undefined;
16442
+ }
16443
+ function hiddenChildPermissions(agent) {
16444
+ return [
16445
+ { action: "*", resource: "*", effect: "deny" },
16446
+ ...(AGENT_TOOL_ALLOWLIST[agent] ?? []).map((tool) => ({
16447
+ action: tool,
16448
+ resource: "*",
16449
+ effect: "allow"
16450
+ }))
16451
+ ];
16452
+ }
16381
16453
  async function registerHiddenChildAgents(agent) {
16382
16454
  await agent.transform((editor) => {
16383
- for (const [id, allowed] of Object.entries(AGENT_TOOL_ALLOWLIST)) {
16455
+ for (const id of Object.keys(AGENT_TOOL_ALLOWLIST)) {
16384
16456
  editor.update(id, (config) => {
16385
16457
  config.system = "Magic Context hidden completion carrier.";
16386
16458
  config.description = "Internal Magic Context hidden completion carrier.";
@@ -16392,14 +16464,7 @@ async function registerHiddenChildAgents(agent) {
16392
16464
  const stepCap = AGENT_STEP_CAPS[id];
16393
16465
  if (stepCap !== undefined)
16394
16466
  config.steps = stepCap;
16395
- config.permissions = [
16396
- { action: "*", resource: "*", effect: "deny" },
16397
- ...allowed.map((tool) => ({
16398
- action: tool,
16399
- resource: "*",
16400
- effect: "allow"
16401
- }))
16402
- ];
16467
+ config.permissions = hiddenChildPermissions(id);
16403
16468
  });
16404
16469
  }
16405
16470
  });
@@ -16472,7 +16537,7 @@ function markerCandidates(text) {
16472
16537
  function textDigest(text) {
16473
16538
  return {
16474
16539
  length: text.length,
16475
- sha256: createHash9("sha256").update(text).digest("hex").slice(0, 16)
16540
+ sha256: createHash10("sha256").update(text).digest("hex").slice(0, 16)
16476
16541
  };
16477
16542
  }
16478
16543
  function firstDifference(a, b) {
@@ -16492,17 +16557,21 @@ function firstDifference(a, b) {
16492
16557
 
16493
16558
  class HiddenChildHook {
16494
16559
  note;
16495
- childIDs = new Set;
16560
+ childIDs = new Map;
16496
16561
  attempts = new Map;
16497
16562
  active = new Map;
16498
16563
  constructor(note = log) {
16499
16564
  this.note = note;
16500
16565
  }
16501
- registerChild(sessionID) {
16502
- this.childIDs.add(sessionID);
16566
+ registerChild(sessionID, agent) {
16567
+ if (agent !== undefined || !this.childIDs.has(sessionID))
16568
+ this.childIDs.set(sessionID, agent ?? this.childIDs.get(sessionID));
16569
+ }
16570
+ agentFor(sessionID) {
16571
+ return this.childIDs.get(sessionID);
16503
16572
  }
16504
16573
  registerAttempt(marker, attempt) {
16505
- this.registerChild(attempt.childSessionId);
16574
+ this.registerChild(attempt.childSessionId, attempt.agent);
16506
16575
  attempt.marker = marker;
16507
16576
  this.attempts.set(marker, attempt);
16508
16577
  }
@@ -16516,9 +16585,24 @@ class HiddenChildHook {
16516
16585
  owns(sessionID) {
16517
16586
  return this.childIDs.has(sessionID);
16518
16587
  }
16519
- compactionSummary(sessionID) {
16520
- if (!this.owns(sessionID))
16588
+ toolCallRefusal(call) {
16589
+ const owned = this.owns(call.sessionID);
16590
+ const agent = owned ? this.agentFor(call.sessionID) ?? call.agent : call.agent;
16591
+ const allowed = hiddenAgentAllowedTools(agent);
16592
+ if (allowed === undefined) {
16593
+ return owned ? `Magic Context hidden child ${call.sessionID} has no tool allowlist; ${call.tool} refused` : undefined;
16594
+ }
16595
+ if (allowed.includes(call.tool))
16596
+ return;
16597
+ return `Magic Context hidden agent ${agent} may only use ${allowed.length > 0 ? allowed.join(", ") : "no tools"}; ${call.tool} refused`;
16598
+ }
16599
+ compactionSummary(sessionID, agent) {
16600
+ if (!this.owns(sessionID)) {
16601
+ if (hiddenAgentAllowedTools(agent) !== undefined) {
16602
+ this.refuse("Refusing to compact a Magic Context hidden-agent session this instance did not register", { sessionID, messages: [] }, undefined);
16603
+ }
16521
16604
  return;
16605
+ }
16522
16606
  const active = this.active.get(sessionID);
16523
16607
  const pending = [...this.attempts.values()].filter((attempt) => attempt.childSessionId === sessionID && !attempt.shaped);
16524
16608
  const inFlight = active ? [active] : pending;
@@ -16563,8 +16647,12 @@ class HiddenChildHook {
16563
16647
  return parts;
16564
16648
  }
16565
16649
  apply(draft) {
16566
- if (!this.owns(draft.sessionID))
16650
+ if (!this.owns(draft.sessionID)) {
16651
+ if (hiddenAgentAllowedTools(draft.agent) !== undefined) {
16652
+ this.refuse("Refusing a Magic Context hidden-agent turn this instance did not register", draft, newestUserText(draft));
16653
+ }
16567
16654
  return false;
16655
+ }
16568
16656
  const raw = newestUserText(draft);
16569
16657
  let attempt;
16570
16658
  for (const candidate of raw === undefined ? [] : markerCandidates(raw)) {
@@ -16832,13 +16920,13 @@ var muralCueColumnCache = new WeakMap;
16832
16920
  var muralCueRejectionColumnCache = new WeakMap;
16833
16921
 
16834
16922
  // src/features/magic-context/memory/normalize-hash.ts
16835
- import { createHash as createHash10 } from "node:crypto";
16923
+ import { createHash as createHash11 } from "node:crypto";
16836
16924
  function normalizeMemoryContent(content) {
16837
16925
  return content.toLowerCase().replace(/\s+/g, " ").trim();
16838
16926
  }
16839
16927
  function computeNormalizedHash(content) {
16840
16928
  const normalized = normalizeMemoryContent(content);
16841
- return createHash10("md5").update(normalized).digest("hex");
16929
+ return createHash11("md5").update(normalized).digest("hex");
16842
16930
  }
16843
16931
 
16844
16932
  // src/features/magic-context/memory/visibility.ts
@@ -17411,14 +17499,14 @@ function archiveMemory(db, id, reason) {
17411
17499
  }
17412
17500
 
17413
17501
  // src/features/magic-context/compaction-marker.ts
17414
- import { createHash as createHash11 } from "node:crypto";
17502
+ import { createHash as createHash12 } from "node:crypto";
17415
17503
  import { existsSync as existsSync4 } from "node:fs";
17416
17504
  var BASE62_CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
17417
17505
  var ID_PREFIX_HEX_LENGTH = 12;
17418
17506
  var ID_SUFFIX_LENGTH = 14;
17419
17507
  var ID_PREFIX_MASK = (1n << BigInt(ID_PREFIX_HEX_LENGTH * 4)) - 1n;
17420
17508
  function deterministicBase62(seed, length) {
17421
- let value = BigInt(`0x${createHash11("sha256").update(seed).digest("hex")}`);
17509
+ let value = BigInt(`0x${createHash12("sha256").update(seed).digest("hex")}`);
17422
17510
  const chars = Array(length);
17423
17511
  for (let index = length - 1;index >= 0; index -= 1) {
17424
17512
  chars[index] = BASE62_CHARS[Number(value % 62n)];
@@ -17567,19 +17655,19 @@ function findBoundaryUserMessage(sessionId, endMessageId) {
17567
17655
  AND NOT (COALESCE(json_extract(data, '$.summary'), 0) = 1
17568
17656
  AND COALESCE(json_extract(data, '$.finish'), '') = 'stop')
17569
17657
  AND COALESCE(json_extract(data, '$.role'), '') = 'user'
17570
- AND (time_created < ? OR (time_created = ? AND id <= ?))
17658
+ AND (time_created, id) <= (?, ?)
17571
17659
  AND NOT (
17572
17660
  EXISTS (SELECT 1 FROM part p
17573
- WHERE p.message_id = message.id AND +p.session_id = message.session_id
17661
+ WHERE likelihood(p.message_id = message.id, 0.000001) AND +p.session_id = message.session_id
17574
17662
  AND COALESCE(json_extract(p.data, '$.type'), '') <> 'compaction')
17575
17663
  AND NOT EXISTS (SELECT 1 FROM part p
17576
- WHERE p.message_id = message.id AND +p.session_id = message.session_id
17664
+ WHERE likelihood(p.message_id = message.id, 0.000001) AND +p.session_id = message.session_id
17577
17665
  AND COALESCE(json_extract(p.data, '$.type'), '') <> 'compaction'
17578
17666
  AND COALESCE(json_extract(p.data, '$.synthetic'), 0) <> 1
17579
17667
  AND COALESCE(json_extract(p.data, '$.syntheticTodoMarker'), 0) <> 1)
17580
17668
  )
17581
17669
  ORDER BY time_created DESC, id DESC
17582
- LIMIT 1`).get(sessionId, target.timeCreated, target.timeCreated, target.id);
17670
+ LIMIT 1`).get(sessionId, target.timeCreated, target.id);
17583
17671
  if (typeof boundary?.id !== "string" || typeof boundary.time_created !== "number") {
17584
17672
  return null;
17585
17673
  }
@@ -18048,9 +18136,17 @@ function existingMarkerAlreadyCoversTarget(sessionId, existing, targetOrdinal, t
18048
18136
  return true;
18049
18137
  }
18050
18138
  function applyDeferredCompactionMarker(db, sessionId, pending, directory, trustedBoundary) {
18139
+ let stepStartedAt = performance.now();
18140
+ const stepMs = [];
18141
+ const endStep = (name) => {
18142
+ const now = performance.now();
18143
+ stepMs.push(`${name}Ms=${(now - stepStartedAt).toFixed(1)}`);
18144
+ stepStartedAt = now;
18145
+ };
18051
18146
  try {
18052
18147
  const responseFencesTarget = trustedBoundary !== undefined && Number.isSafeInteger(trustedBoundary.rowVersion) && trustedBoundary.rowVersion > 0 && trustedBoundary.ordinal === pending.ordinal && trustedBoundary.endMessageId === pending.endMessageId;
18053
18148
  const validation = responseFencesTarget ? "ok" : validatePendingTarget(db, sessionId, pending);
18149
+ endStep("validate");
18054
18150
  if (validation !== "ok") {
18055
18151
  sessionLog(sessionId, `compaction-marker drain: stale-skip (${validation}) for ordinal ${pending.ordinal} endMessageId=${pending.endMessageId}`);
18056
18152
  return { kind: "stale-skip", reason: validation };
@@ -18060,12 +18156,14 @@ function applyDeferredCompactionMarker(db, sessionId, pending, directory, truste
18060
18156
  return { kind: "already-current" };
18061
18157
  }
18062
18158
  const boundary = findBoundaryUserMessage(sessionId, pending.endMessageId);
18159
+ endStep("boundary");
18063
18160
  if (!boundary) {
18064
18161
  return {
18065
18162
  kind: "retryable-failure",
18066
18163
  error: new Error(`no user boundary found at or before endMessageId ${pending.endMessageId} (ordinal ${pending.ordinal}); preserving existing marker`)
18067
18164
  };
18068
18165
  }
18166
+ endStep("discardCheck");
18069
18167
  const removedSummaryMessageId = existing?.summaryMessageId ?? null;
18070
18168
  const replacement = replaceCompactionMarker(existing, {
18071
18169
  sessionId,
@@ -18075,6 +18173,7 @@ function applyDeferredCompactionMarker(db, sessionId, pending, directory, truste
18075
18173
  directory: directory ?? process.cwd(),
18076
18174
  resolvedBoundary: boundary
18077
18175
  });
18176
+ endStep("replace");
18078
18177
  if (replacement.kind !== "committed") {
18079
18178
  return {
18080
18179
  kind: "retryable-failure",
@@ -18087,7 +18186,8 @@ function applyDeferredCompactionMarker(db, sessionId, pending, directory, truste
18087
18186
  boundaryOrdinal: pending.ordinal,
18088
18187
  targetEndMessageId: pending.endMessageId
18089
18188
  }, removedSummaryMessageId);
18090
- sessionLog(sessionId, `compaction-marker drain: applied at ordinal ${pending.ordinal}, boundary user msg ${result.boundaryMessageId}`);
18189
+ endStep("persist");
18190
+ sessionLog(sessionId, `compaction-marker drain: applied at ordinal ${pending.ordinal}, boundary user msg ${result.boundaryMessageId} ${stepMs.join(" ")}`);
18091
18191
  return {
18092
18192
  kind: "applied",
18093
18193
  markerOrdinal: pending.ordinal
@@ -18192,6 +18292,7 @@ var MEMORY_EPOCH_COMPONENT_PREFIX = "|memory-render:";
18192
18292
  var MURAL_COMPONENT_PREFIX = "|mural-enabled:";
18193
18293
  var BUDGET_COMPONENT_PREFIX = "|render-budgets:";
18194
18294
  var RENDERED_BUDGETS_COMPONENT_PREFIX = "|rendered-budgets:";
18295
+ var M0_MEMORY_IDS_COMPONENT_PREFIX = "|m0-memory-ids:";
18195
18296
  function encodeCachedM0UpgradeIdentity(upgradeState, compartmentRenderEpoch = COMPARTMENT_RENDER_EPOCH, muralEnabled = null, renderBudgetIdentity = null, memoryRenderEpoch = MEMORY_RENDER_FORMAT_EPOCH, renderedBudgets = null) {
18196
18297
  let encoded = upgradeState ?? "";
18197
18298
  if (compartmentRenderEpoch !== null) {
@@ -18236,7 +18337,8 @@ function decodeCachedM0UpgradeIdentity(value) {
18236
18337
  value.indexOf(MEMORY_EPOCH_COMPONENT_PREFIX),
18237
18338
  value.indexOf(MURAL_COMPONENT_PREFIX),
18238
18339
  value.indexOf(BUDGET_COMPONENT_PREFIX),
18239
- value.indexOf(RENDERED_BUDGETS_COMPONENT_PREFIX)
18340
+ value.indexOf(RENDERED_BUDGETS_COMPONENT_PREFIX),
18341
+ value.indexOf(M0_MEMORY_IDS_COMPONENT_PREFIX)
18240
18342
  ].filter((index) => index >= 0);
18241
18343
  const identityEnd = componentIndexes.length > 0 ? Math.min(...componentIndexes) : value.length;
18242
18344
  const upgradeState = value.slice(0, identityEnd);
@@ -18250,6 +18352,22 @@ function decodeCachedM0UpgradeIdentity(value) {
18250
18352
  renderedBudgets: component(value, RENDERED_BUDGETS_COMPONENT_PREFIX)
18251
18353
  };
18252
18354
  }
18355
+ function withCachedM0MemoryIds(identity, ids) {
18356
+ const withoutIds = (identity ?? "").replace(/\|m0-memory-ids:[^|]*/g, "");
18357
+ return `${withoutIds}${M0_MEMORY_IDS_COMPONENT_PREFIX}${JSON.stringify(ids)}`;
18358
+ }
18359
+ function readCachedM0MemoryIds(identity, legacyVisibleIds, maxMemoryId) {
18360
+ const encoded = component(identity ?? "", M0_MEMORY_IDS_COMPONENT_PREFIX);
18361
+ if (encoded !== null) {
18362
+ try {
18363
+ const ids = JSON.parse(encoded);
18364
+ if (Array.isArray(ids) && ids.every((id) => Number.isSafeInteger(id) && id > 0)) {
18365
+ return ids;
18366
+ }
18367
+ } catch {}
18368
+ }
18369
+ return legacyVisibleIds.filter((id) => id <= maxMemoryId);
18370
+ }
18253
18371
  function renderBudgetIdentityChanged(cached, current) {
18254
18372
  const legacy = /^(m[^-]+)-h\d+$/.exec(cached);
18255
18373
  if (legacy && current.startsWith("m") && current.includes("-hp")) {
@@ -18530,6 +18648,7 @@ function formatDate(ms) {
18530
18648
  return `${yyyy}-${mm}-${dd}`;
18531
18649
  }
18532
18650
  var TEMPORAL_MARKER_PATTERN = /^<!-- \+[\d]+[mhdw](?: [\d]+[mhdw])? -->\n/;
18651
+ var TEMPORAL_MARKER_REPLAY_PATTERN = /^<!-- \+[\d]+[mhdw](?: [\d]+[mhdw])? -->(?:\n|$)/;
18533
18652
  function temporalMarkerPrefix(seconds) {
18534
18653
  const marker = formatGap(seconds);
18535
18654
  if (!marker)
@@ -18553,7 +18672,23 @@ function findFirstVisibleTextPart(parts) {
18553
18672
  }
18554
18673
  return null;
18555
18674
  }
18556
- function injectTemporalMarkers(messages) {
18675
+ function collectTemporalCandidates(messages) {
18676
+ const candidates = new Map;
18677
+ let prev = null;
18678
+ for (const raw of messages) {
18679
+ if (!raw || typeof raw !== "object")
18680
+ continue;
18681
+ const msg = raw;
18682
+ if (msg.info?.id && msg.info.role === "user" && Array.isArray(msg.parts) && hasMeaningfulUserText2(msg.parts)) {
18683
+ const current = msg.info.time?.created;
18684
+ const prior = prev?.info?.time;
18685
+ candidates.set(msg.info.id, current !== undefined && prior?.created !== undefined ? temporalMarkerPrefix((current - (prior.completed ?? prior.created)) / 1000) ?? "" : "");
18686
+ }
18687
+ prev = msg;
18688
+ }
18689
+ return candidates;
18690
+ }
18691
+ function injectTemporalMarkers(messages, frozen) {
18557
18692
  let injected = 0;
18558
18693
  let prev = null;
18559
18694
  for (const raw of messages) {
@@ -18561,6 +18696,20 @@ function injectTemporalMarkers(messages) {
18561
18696
  continue;
18562
18697
  const msg = raw;
18563
18698
  const role = msg.info?.role;
18699
+ if (frozen) {
18700
+ const marker = msg.info?.id ? frozen.get(msg.info.id) : undefined;
18701
+ const target = Array.isArray(msg.parts) ? findFirstVisibleTextPart(msg.parts) : null;
18702
+ if (marker !== undefined && target?.text !== undefined) {
18703
+ const { tagPrefix, body } = peelLeadingMcTagNotation(target.text);
18704
+ const source = body.replace(TEMPORAL_MARKER_REPLAY_PATTERN, "");
18705
+ const text = tagPrefix + (source ? marker + source : marker.trimEnd());
18706
+ if (text !== target.text) {
18707
+ target.text = text;
18708
+ injected++;
18709
+ }
18710
+ }
18711
+ continue;
18712
+ }
18564
18713
  const authoredUser = role === "user" && Array.isArray(msg.parts) && hasMeaningfulUserText2(msg.parts);
18565
18714
  if (prev !== null && authoredUser) {
18566
18715
  const prevTime = prev.info?.time;
@@ -19442,6 +19591,9 @@ function mustMaterialize(args) {
19442
19591
  return withToolSetHashComparison({ value: true, reason: "project_change" });
19443
19592
  }
19444
19593
  }
19594
+ if (args.state.cachedM0ProjectMemoryEpoch !== current.projectMemoryEpoch) {
19595
+ return { value: true, reason: "project_memory_epoch" };
19596
+ }
19445
19597
  if (args.state.cachedM0MaxMutationId !== current.maxMutationId) {
19446
19598
  return withToolSetHashComparison({ value: true, reason: "max_mutation_id" });
19447
19599
  }
@@ -19692,7 +19844,7 @@ ${sessionHistory}
19692
19844
 
19693
19845
  `).trim();
19694
19846
  }
19695
- function applyMarkersToState(state, m0Bytes, markers, m1Bytes) {
19847
+ function applyMarkersToState(state, m0Bytes, markers, m1Bytes, renderedM0Ids) {
19696
19848
  state.cachedM0Bytes = m0Bytes;
19697
19849
  if (m1Bytes)
19698
19850
  state.cachedM1Bytes = m1Bytes;
@@ -19706,7 +19858,7 @@ function applyMarkersToState(state, m0Bytes, markers, m1Bytes) {
19706
19858
  state.cachedM0ProjectDocsHash = markers.projectDocsHash;
19707
19859
  state.cachedM0MaterializedAt = markers.materializedAt;
19708
19860
  state.cachedM0SessionFactsVersion = markers.sessionFactsVersion;
19709
- state.cachedM0UpgradeState = encodeCachedM0UpgradeIdentity(markers.upgradeState, markers.compartmentRenderEpoch, markers.muralEnabled, markers.renderBudgetIdentity, markers.memoryRenderEpoch, markers.renderedBudgets ?? null);
19861
+ state.cachedM0UpgradeState = withCachedM0MemoryIds(encodeCachedM0UpgradeIdentity(markers.upgradeState, markers.compartmentRenderEpoch, markers.muralEnabled, markers.renderBudgetIdentity, markers.memoryRenderEpoch, markers.renderedBudgets ?? null), renderedM0Ids);
19710
19862
  state.cachedM0SystemHash = markers.systemHash;
19711
19863
  state.cachedM0ToolSetHash = markers.toolSetHash;
19712
19864
  state.cachedM0ModelKey = markers.modelKey;
@@ -19805,10 +19957,18 @@ function materializeM0(options) {
19805
19957
  snapshotMarkers.materializedAt = foldMaterializedAt;
19806
19958
  const renderedMemoryIds = trimmed.renderOrder.map((m) => m.id);
19807
19959
  options.beforePhase3ForTest?.();
19960
+ const steps = new WriteTransactionSteps;
19961
+ const upgradeIdentity = withCachedM0MemoryIds(encodeCachedM0UpgradeIdentity(snapshotMarkers.upgradeState, snapshotMarkers.compartmentRenderEpoch, snapshotMarkers.muralEnabled, snapshotMarkers.renderBudgetIdentity, snapshotMarkers.memoryRenderEpoch, snapshotMarkers.renderedBudgets ?? null), renderedMemoryIds);
19962
+ const baselineEndMessageId = lastCompartmentBoundaryId(compartments);
19963
+ steps.mark("pre_metadata");
19964
+ const commitFold = options.onFoldPrepare?.();
19965
+ steps.mark("pre_onFoldPrepare");
19808
19966
  let m1Text = M1_EMPTY_PLACEHOLDER;
19809
19967
  let m1Bytes = Buffer4.from(m1Text, "utf8");
19968
+ options.beforeCacheCommitForTest?.();
19810
19969
  const transactionStartedAt = performance.now();
19811
19970
  options.db.exec("BEGIN IMMEDIATE");
19971
+ steps.reset();
19812
19972
  try {
19813
19973
  const currentWorkspace = resolveWorkspaceRenderContext({
19814
19974
  db: options.db,
@@ -19837,23 +19997,26 @@ function materializeM0(options) {
19837
19997
  renderBudgetIdentity: snapshotMarkers.renderBudgetIdentity,
19838
19998
  renderedBudgets: snapshotMarkers.renderedBudgets
19839
19999
  };
19840
- const stale = current.projectUserProfileVersion !== snapshotMarkers.projectUserProfileVersion || current.maxCompartmentSeq !== snapshotMarkers.maxCompartmentSeq || current.maxMutationId !== snapshotMarkers.maxMutationId || current.maxMemoryMutationId !== snapshotMarkers.maxMemoryMutationId || current.sessionFactsVersion !== snapshotMarkers.sessionFactsVersion || current.upgradeState !== snapshotMarkers.upgradeState || (current.projectIdentity ?? null) !== (snapshotMarkers.projectIdentity ?? null);
20000
+ const stale = current.projectUserProfileVersion !== snapshotMarkers.projectUserProfileVersion || current.projectMemoryEpoch !== snapshotMarkers.projectMemoryEpoch || current.maxCompartmentSeq !== snapshotMarkers.maxCompartmentSeq || current.maxMutationId !== snapshotMarkers.maxMutationId || current.maxMemoryMutationId !== snapshotMarkers.maxMemoryMutationId || current.sessionFactsVersion !== snapshotMarkers.sessionFactsVersion || current.upgradeState !== snapshotMarkers.upgradeState || (current.projectIdentity ?? null) !== (snapshotMarkers.projectIdentity ?? null);
19841
20001
  if (stale) {
19842
20002
  options.db.exec("ROLLBACK");
19843
20003
  throw new MaterializeContentionError({ reason: "snapshot changed before Phase 3" });
19844
20004
  }
19845
- const m1Render = renderM1WithMetadata({
20005
+ steps.mark("staleCheck");
20006
+ const rendered = renderM1WithMetadata({
19846
20007
  ...options,
19847
20008
  workspaceIdentitySet: {
19848
20009
  identities: workspace.identities,
19849
20010
  namesByIdentity: workspace.namesByIdentity
19850
20011
  }
19851
20012
  }, snapshotMarkers, renderedMemoryIds);
19852
- m1Text = m1Render.text;
20013
+ m1Text = rendered.text;
19853
20014
  m1Bytes = Buffer4.from(m1Text, "utf8");
19854
20015
  const visibleMemoryIds = [
19855
- ...new Set([...renderedMemoryIds, ...m1Render.renderedMemoryIds])
20016
+ ...new Set([...renderedMemoryIds, ...rendered.renderedMemoryIds])
19856
20017
  ];
20018
+ const visibleIdsJson = JSON.stringify(visibleMemoryIds);
20019
+ steps.mark("m1Render");
19857
20020
  persistCachedM0(options.db, options.sessionId, {
19858
20021
  m0Bytes,
19859
20022
  muralDataUrl: frozenMuralDataUrl,
@@ -19869,21 +20032,24 @@ function materializeM0(options) {
19869
20032
  projectDocsHash: snapshotMarkers.projectDocsHash,
19870
20033
  materializedAt: snapshotMarkers.materializedAt,
19871
20034
  sessionFactsVersion: snapshotMarkers.sessionFactsVersion,
19872
- upgradeState: encodeCachedM0UpgradeIdentity(snapshotMarkers.upgradeState, snapshotMarkers.compartmentRenderEpoch, snapshotMarkers.muralEnabled, snapshotMarkers.renderBudgetIdentity, snapshotMarkers.memoryRenderEpoch, snapshotMarkers.renderedBudgets ?? null),
20035
+ upgradeState: upgradeIdentity,
19873
20036
  systemHash: snapshotMarkers.systemHash,
19874
20037
  toolSetHash: snapshotMarkers.toolSetHash,
19875
20038
  modelKey: snapshotMarkers.modelKey,
19876
20039
  projectIdentity: snapshotMarkers.projectIdentity
19877
20040
  });
19878
- options.db.prepare("UPDATE session_meta SET memory_block_count = ?, memory_block_ids = ? WHERE session_id = ?").run(visibleMemoryIds.length, JSON.stringify(visibleMemoryIds), options.sessionId);
19879
- const baselineEndMessageId = lastCompartmentBoundaryId(compartments);
20041
+ steps.mark("persistCachedM0");
20042
+ options.db.prepare("UPDATE session_meta SET memory_block_count = ?, memory_block_ids = ?, cached_m0_last_baseline_end_message_id = ? WHERE session_id = ?").run(visibleMemoryIds.length, visibleIdsJson, baselineEndMessageId, options.sessionId);
19880
20043
  options.db.prepare("UPDATE session_meta SET cached_m0_last_baseline_end_message_id = ? WHERE session_id = ?").run(baselineEndMessageId, options.sessionId);
19881
- options.onFoldCommit?.(options.db, {
20044
+ steps.mark("sessionMeta");
20045
+ commitFold?.(options.db, {
19882
20046
  m0Bytes,
19883
20047
  m1Bytes
19884
20048
  });
20049
+ steps.mark("onFoldCommit");
19885
20050
  options.db.exec("COMMIT");
19886
- logSlowWriteTransaction("opencode_materialize_cache", transactionStartedAt);
20051
+ steps.mark("commit");
20052
+ logSlowWriteTransaction("opencode_materialize_cache", transactionStartedAt, undefined, performance.now(), steps.durations);
19887
20053
  options.state.cachedM0MuralDataUrl = frozenMuralDataUrl;
19888
20054
  options.state.cachedM0MuralHash = frozenMuralHash;
19889
20055
  } catch (error) {
@@ -20013,7 +20179,7 @@ ${newCompartments.map((compartment) => renderCompartmentAtTier(compartment, 1)).
20013
20179
  const newMemoriesBlock = renderMemoryBlockV2(deltaMemories, "new-memories", newMemoryRenderOptions);
20014
20180
  if (newMemoriesBlock)
20015
20181
  blocks.push(newMemoriesBlock);
20016
- const renderedNewMemoryIds = newMemoriesBlock ? trimmedNewMemories.map((memory) => memory.id) : [];
20182
+ const renderedNewMemoryIds = newMemoriesBlock ? deltaMemories.map((memory) => memory.id) : [];
20017
20183
  if (blocks.length === 0) {
20018
20184
  return {
20019
20185
  text: M1_EMPTY_PLACEHOLDER,
@@ -20156,8 +20322,11 @@ function replayCachedM1(state) {
20156
20322
  return decodeM0Bytes(state.cachedM1Bytes) ?? M1_EMPTY_PLACEHOLDER;
20157
20323
  }
20158
20324
  function softRefreshCachedM1(options) {
20325
+ const steps = new WriteTransactionSteps;
20326
+ options.beforeCacheCommitForTest?.();
20159
20327
  const transactionStartedAt = performance.now();
20160
20328
  options.db.exec("BEGIN IMMEDIATE");
20329
+ steps.reset();
20161
20330
  try {
20162
20331
  const row = readCachedM0M1Row(options.db, options.sessionId);
20163
20332
  if (!row || !cachedRowMatchesState(row, options.state)) {
@@ -20172,23 +20341,28 @@ function softRefreshCachedM1(options) {
20172
20341
  renderedMemoryIds: []
20173
20342
  };
20174
20343
  }
20344
+ steps.mark("staleCheck");
20175
20345
  const markers = markersFromCachedRow(row);
20176
20346
  if (!markers)
20177
20347
  throw new RenderM1InvalidMarkersError(options.sessionId);
20178
- const persistedVisibleIds = parseMemoryBlockIds(row.memory_block_ids);
20179
- const renderedM0Ids = persistedVisibleIds.filter((id) => id <= markers.maxMemoryId);
20180
- const rendered = renderM1WithMetadata({ ...options }, markers, renderedM0Ids);
20348
+ const renderedM0Ids = readCachedM0MemoryIds(row.cached_m0_upgrade_state, parseMemoryBlockIds(row.memory_block_ids), markers.maxMemoryId);
20349
+ const rendered = renderM1WithMetadata(options, markers, renderedM0Ids);
20181
20350
  const visibleMemoryIds = [...new Set([...renderedM0Ids, ...rendered.renderedMemoryIds])];
20182
20351
  const m1Bytes = Buffer4.from(rendered.text, "utf8");
20352
+ const visibleIdsJson = JSON.stringify(visibleMemoryIds);
20183
20353
  const baselineEndMessageId = getLastCompartmentEndMessageId(options.db, options.sessionId);
20354
+ steps.mark("m1Render");
20184
20355
  options.db.prepare(`UPDATE session_meta
20185
20356
  SET cached_m1_bytes = ?,
20186
20357
  cached_m0_last_baseline_end_message_id = ?,
20187
20358
  memory_block_count = ?,
20188
- memory_block_ids = ?
20189
- WHERE session_id = ?`).run(m1Bytes, baselineEndMessageId, visibleMemoryIds.length, JSON.stringify(visibleMemoryIds), options.sessionId);
20359
+ memory_block_ids = ?,
20360
+ cached_m0_upgrade_state = ?
20361
+ WHERE session_id = ?`).run(m1Bytes, baselineEndMessageId, visibleMemoryIds.length, visibleIdsJson, withCachedM0MemoryIds(row.cached_m0_upgrade_state, renderedM0Ids), options.sessionId);
20362
+ steps.mark("sessionMeta");
20190
20363
  options.db.exec("COMMIT");
20191
- logSlowWriteTransaction("opencode_soft_refresh_cache", transactionStartedAt);
20364
+ steps.mark("commit");
20365
+ logSlowWriteTransaction("opencode_soft_refresh_cache", transactionStartedAt, undefined, performance.now(), steps.durations);
20192
20366
  options.state.cachedM1Bytes = m1Bytes;
20193
20367
  options.state.snapshotMarkers = markers;
20194
20368
  return rendered;
@@ -20603,7 +20777,7 @@ function injectM0M1(options) {
20603
20777
  if (decision.value) {
20604
20778
  try {
20605
20779
  const materialized = materializeWithRetry(options);
20606
- applyMarkersToState(options.state, materialized.m0Bytes, materialized.snapshotMarkers, materialized.m1Bytes);
20780
+ applyMarkersToState(options.state, materialized.m0Bytes, materialized.snapshotMarkers, materialized.m1Bytes, materialized.renderedMemoryIds);
20607
20781
  m1Render = {
20608
20782
  text: materialized.m1Text,
20609
20783
  memoryUpdateCount: 0,
@@ -20694,7 +20868,7 @@ function injectM0M1(options) {
20694
20868
  if (!rematerialized && !contentionExhausted && m1Recomputed && options.isCacheBustingPass && (memoryUpdateCount > 40 || m1OverAbsoluteCap || m1HasContent && m0Tokens >= M0_DRIFT_RATIO_FLOOR_TOKENS && m1Tokens > m0Tokens * M1_DRIFT_RATIO)) {
20695
20869
  try {
20696
20870
  const refolded = materializeWithRetry(options);
20697
- applyMarkersToState(options.state, refolded.m0Bytes, refolded.snapshotMarkers, refolded.m1Bytes);
20871
+ applyMarkersToState(options.state, refolded.m0Bytes, refolded.snapshotMarkers, refolded.m1Bytes, refolded.renderedMemoryIds);
20698
20872
  rematerialized = true;
20699
20873
  m0Text = decodeM0Bytes(options.state.cachedM0Bytes) ?? M0_EMPTY_BODY;
20700
20874
  m1Text = refolded.m1Text;
@@ -20950,12 +21124,14 @@ function applyHeadCap(args) {
20950
21124
  diagnostics.completedRefence.tokenMass = index.rangeTokens(Math.min(...component.map((arc) => arc.invocation)), Math.max(...component.map((arc) => arc.result)) + 1);
20951
21125
  });
20952
21126
  diagnostics.completedRefence.to = end;
20953
- diagnostics.eligibleEnd = end <= offset ? offset : Math.min(end, protectedTailStart);
21127
+ if (end > protectedTailStart)
21128
+ end = offset;
21129
+ diagnostics.eligibleEnd = end <= offset ? offset : end;
20954
21130
  args.observeDiagnostics?.(diagnostics);
20955
21131
  if (end <= offset && offset < protectedTailStart) {
20956
21132
  return { eligibleEndOrdinal: offset, oversizeAtomicUnit };
20957
21133
  }
20958
- return { eligibleEndOrdinal: Math.min(end, protectedTailStart), oversizeAtomicUnit };
21134
+ return { eligibleEndOrdinal: end, oversizeAtomicUnit };
20959
21135
  }
20960
21136
  function resolveProtectedTailBoundary(ctx) {
20961
21137
  const createdAt = ctx.createdAt ?? Date.now();
@@ -21110,6 +21286,7 @@ function resolveProtectedTailBoundary(ctx) {
21110
21286
  }
21111
21287
  protectedTailStart = clampOrdinal(protectedTailStart, rawMessageCount);
21112
21288
  protectedTailStart = retreatPastHostUnservedRows(messages, protectedTailStart, offset);
21289
+ protectedTailStart = Math.max(offset, fenceBoundaryForCompletedToolArcs(protectedTailStart, arcs, 1));
21113
21290
  const perRunCap = selectPerRunCap({
21114
21291
  usagePercentage,
21115
21292
  N: scaledN,
@@ -21129,7 +21306,8 @@ function resolveProtectedTailBoundary(ctx) {
21129
21306
  capTokens: perRunCap,
21130
21307
  recentOpenArcCutoff
21131
21308
  });
21132
- const eligibleEndOrdinal = retreatPastHostUnservedRows(messages, head.eligibleEndOrdinal, offset);
21309
+ const servedEndOrdinal = retreatPastHostUnservedRows(messages, head.eligibleEndOrdinal, offset);
21310
+ const eligibleEndOrdinal = Math.max(offset, fenceBoundaryForCompletedToolArcs(servedEndOrdinal, arcs, 1));
21133
21311
  const rawRangeFingerprint = computeRawRangeFingerprint(messages, offset, eligibleEndOrdinal);
21134
21312
  return {
21135
21313
  sessionId: ctx.sessionId,
@@ -21157,7 +21335,7 @@ function resolveProtectedTailBoundary(ctx) {
21157
21335
  cacheNamespace: ctx.cacheNamespace,
21158
21336
  createdAt,
21159
21337
  rawRangeFingerprint,
21160
- trueRawEligibleTokens: index.rangeTokens(offset, protectedTailStart),
21338
+ trueRawEligibleTokens: index.rangeTokens(offset, eligibleEndOrdinal),
21161
21339
  oversizeAtomicUnit: head.oversizeAtomicUnit,
21162
21340
  boundaryReason,
21163
21341
  diagnostics: boundaryDiagnostics({
@@ -21388,6 +21566,8 @@ function getRawHistoryEligibility(db, sessionId) {
21388
21566
  function hasRunnableCompartmentWindow(snapshot) {
21389
21567
  if (snapshot.offset >= snapshot.protectedTailStart)
21390
21568
  return false;
21569
+ if (snapshot.eligibleEndOrdinal <= snapshot.offset)
21570
+ return false;
21391
21571
  const forceMaterializationPercentage = escalationBands(snapshot.executeThresholdPercentage).forceMaterializationPercentage;
21392
21572
  if (snapshot.usagePercentage >= forceMaterializationPercentage || snapshot.emergencyTailScale) {
21393
21573
  return snapshot.trueRawEligibleTokens >= deriveMinForceEligibleTokens(snapshot.N) || snapshot.eligibleEndOrdinal > snapshot.offset;
@@ -21628,6 +21808,22 @@ function searchMemoriesFTSUnion(db, projectPaths, query, limit = DEFAULT_SEARCH_
21628
21808
  function clearMemoryVerifications(db, memoryId) {
21629
21809
  db.prepare("DELETE FROM memory_verifications WHERE memory_id = ?").run(memoryId);
21630
21810
  }
21811
+ // src/features/magic-context/memory/types.ts
21812
+ var MEMORY_CATEGORY_RECORD = {
21813
+ PROJECT_RULES: true,
21814
+ ARCHITECTURE: true,
21815
+ CONFIG_VALUES: true,
21816
+ ARCHITECTURE_DECISIONS: true,
21817
+ CONSTRAINTS: true,
21818
+ CONFIG_DEFAULTS: true,
21819
+ NAMING: true,
21820
+ USER_PREFERENCES: true,
21821
+ USER_DIRECTIVES: true,
21822
+ ENVIRONMENT: true,
21823
+ WORKFLOW_RULES: true,
21824
+ KNOWN_ISSUES: true
21825
+ };
21826
+ var MEMORY_CATEGORIES = Object.keys(MEMORY_CATEGORY_RECORD);
21631
21827
  // src/features/magic-context/memory/verification-paths.ts
21632
21828
  import { execFile as execFile2 } from "node:child_process";
21633
21829
  import { promisify } from "node:util";
@@ -21743,6 +21939,10 @@ function hasLengthCappedOutput(value) {
21743
21939
  return Object.values(value).some((item) => hasLengthCappedOutput(item));
21744
21940
  }
21745
21941
 
21942
+ // src/shared/provider-output-failure.ts
21943
+ import { AsyncLocalStorage } from "node:async_hooks";
21944
+ var primaryQuotas = new AsyncLocalStorage;
21945
+
21746
21946
  // src/shared/resolve-fallbacks.ts
21747
21947
  function parseProviderModel(spec) {
21748
21948
  const slash = spec.indexOf("/");
@@ -27119,7 +27319,7 @@ Found ${existingStaging.compartments.length} staged compartment(s) from ${existi
27119
27319
  afterPublish("publication-signal", () => deps.onCompartmentStatePublished?.(sessionId));
27120
27320
  if (lastCompartmentEnd > 0) {
27121
27321
  afterPublish("compaction-marker", () => {
27122
- const markerUpdated = updateCompactionMarkerAfterPublication(db, sessionId, lastCompartmentEnd, deps.directory);
27322
+ const markerUpdated = (deps.compactionMarkerStrategy?.publish ?? updateCompactionMarkerAfterPublication)(db, sessionId, lastCompartmentEnd, deps.directory);
27123
27323
  if (markerUpdated) {
27124
27324
  const stalePending = getPendingCompactionMarkerState(db, sessionId);
27125
27325
  if (stalePending) {
@@ -27355,7 +27555,7 @@ Another process acquired the compartment-state lease before recomp could publish
27355
27555
  afterPublish("publication-signal", () => deps.onCompartmentStatePublished?.(sessionId));
27356
27556
  if (lastCompartmentEnd > 0) {
27357
27557
  afterPublish("compaction-marker", () => {
27358
- const markerUpdated = updateCompactionMarkerAfterPublication(db, sessionId, lastCompartmentEnd, deps.directory);
27558
+ const markerUpdated = (deps.compactionMarkerStrategy?.publish ?? updateCompactionMarkerAfterPublication)(db, sessionId, lastCompartmentEnd, deps.directory);
27359
27559
  if (markerUpdated) {
27360
27560
  const stalePending = getPendingCompactionMarkerState(db, sessionId);
27361
27561
  if (stalePending) {
@@ -27508,7 +27708,7 @@ Could not acquire the compartment-state lease for this session.`;
27508
27708
  deps.onCompartmentStatePublished?.(sessionId);
27509
27709
  const lastEnd = merged[merged.length - 1]?.endMessage ?? snapEnd;
27510
27710
  if (lastEnd > 0) {
27511
- const markerUpdated = updateCompactionMarkerAfterPublication(db, sessionId, lastEnd, deps.directory);
27711
+ const markerUpdated = (deps.compactionMarkerStrategy?.publish ?? updateCompactionMarkerAfterPublication)(db, sessionId, lastEnd, deps.directory);
27512
27712
  if (markerUpdated) {
27513
27713
  const stalePending = getPendingCompactionMarkerState(db, sessionId);
27514
27714
  if (stalePending) {
@@ -27761,10 +27961,10 @@ function startLeaseRenewal(deps, holderId) {
27761
27961
  }
27762
27962
  }, COMPARTMENT_LEASE_RENEWAL_MS);
27763
27963
  }
27764
- function startCompartmentAgent(deps, runAgent = runCompartmentAgent) {
27765
- withoutSqliteTransformPass(() => startBackgroundCompartmentAgent(deps, runAgent));
27964
+ function startCompartmentAgent(deps, runAgent = runCompartmentAgent, prepareBoundary) {
27965
+ withoutSqliteTransformPass(() => startBackgroundCompartmentAgent(deps, runAgent, prepareBoundary));
27766
27966
  }
27767
- function startBackgroundCompartmentAgent(deps, runAgent) {
27967
+ function startBackgroundCompartmentAgent(deps, runAgent, prepareBoundary) {
27768
27968
  const existing = activeRuns.get(deps.sessionId);
27769
27969
  if (existing) {
27770
27970
  return;
@@ -27789,15 +27989,33 @@ function startBackgroundCompartmentAgent(deps, runAgent) {
27789
27989
  return;
27790
27990
  }
27791
27991
  const renewal = startLeaseRenewal(deps, holderId);
27792
- let realRunStarted = false;
27793
27992
  const runnerDeps = withPublishedCallback({
27794
27993
  ...deps,
27795
- compartmentLeaseHolderId: holderId,
27796
- onHistorianRunStarted: () => {
27797
- realRunStarted = true;
27798
- }
27994
+ compartmentLeaseHolderId: holderId
27799
27995
  });
27800
- const promise = runAgent(runnerDeps).catch((err) => {
27996
+ const promise = new Promise((resolve) => setTimeout(resolve, 0)).then(() => withRawSessionMessageCache2(() => {
27997
+ const snapshot = deps.boundarySnapshot;
27998
+ try {
27999
+ primeTailRawMessageCache2({
28000
+ sessionId: deps.sessionId,
28001
+ lastCompartmentEnd: snapshot?.lastCompartmentEndMessageId !== undefined ? snapshot.offset - 1 : getLastCompartmentEndMessage(deps.db, deps.sessionId),
28002
+ anchorMessageId: snapshot?.lastCompartmentEndMessageId !== undefined ? snapshot.lastCompartmentEndMessageId : getLastCompartmentEndMessageId(deps.db, deps.sessionId)
28003
+ });
28004
+ } catch (error) {
28005
+ sessionLog(deps.sessionId, "compartment agent: tail prime failed (non-fatal):", error);
28006
+ }
28007
+ if (prepareBoundary) {
28008
+ const boundary = prepareBoundary();
28009
+ if (!boundary) {
28010
+ updateSessionMeta(deps.db, deps.sessionId, {
28011
+ compartmentInProgress: false
28012
+ });
28013
+ return;
28014
+ }
28015
+ runnerDeps.boundarySnapshot = boundary;
28016
+ }
28017
+ return runAgent(runnerDeps);
28018
+ })).catch((err) => {
27801
28019
  sessionLog(deps.sessionId, "compartment agent: unhandled rejection:", err);
27802
28020
  try {
27803
28021
  updateSessionMeta(deps.db, deps.sessionId, { compartmentInProgress: false });
@@ -27814,9 +28032,6 @@ function startBackgroundCompartmentAgent(deps, runAgent) {
27814
28032
  }
27815
28033
  });
27816
28034
  activeRuns.set(deps.sessionId, { promise, published: false, kind: "incremental" });
27817
- if (!realRunStarted && activeRuns.get(deps.sessionId)?.promise === promise) {
27818
- activeRuns.delete(deps.sessionId);
27819
- }
27820
28035
  }
27821
28036
  async function executeContextRecompWithResult(deps, options = {}) {
27822
28037
  const { sessionId } = deps;
@@ -27880,4 +28095,4 @@ async function executeContextRecomp(deps, options = {}) {
27880
28095
  return (await executeContextRecompWithResult(deps, options)).message;
27881
28096
  }
27882
28097
 
27883
- export { MEMORY_MAINTAINER_A_AGENT, MEMORY_MAINTAINER_B_AGENT, MEMORY_MAINTAINER_A_STEP_CAP, MEMORY_MAINTAINER_A_SYSTEM_PROMPT, MEMORY_MAINTAINER_B_SYSTEM_PROMPT, MEMORY_MAINTAINER_FINALIZE_INSTRUCTION, buildMemoryMaintainerStageAPrompt, buildMemoryMaintainerStageBPrompt, getOpenCodeGlobalConfigDir, getOpenCodeConfigDirs, opencodeUserConfigBasePath, mmcProjectConfigBasePath, buildPrimaryLanguageDirective, resolveModelConfigValue, DEFAULT_EXECUTE_THRESHOLD_PERCENTAGE, PROTECTED_TOKENS_MIN, PER_HARNESS_MIGRATION_INVENTORY, PER_HARNESS_MODEL_KEYS, ConfigProfilesSchema, MagicContextConfigSchema, LIVE_RELOAD_CONFIG_PATHS, formatFailClosedBlockingMessage, formatFailClosedBlockingSummary, createFailClosedBlockingError, isFailClosedBlockingError, setHomeProjectPermission, shouldSkipHomeProjectMemory, ProjectIdentityError, takeDubiousOwnershipProjectIdentityWarning, isUserHomeDirectory, describeUnresolvedProjectIdentity, resolveProjectIdentityForSession, normalizeStoredProjectPath, storedPathBelongsToIdentity, V2_MEMORY_CATEGORIES, CATEGORY_PRIORITY, computeNormalizedHash, hasMemoryShareableColumn, hasMemoryClassifiedAtColumn, ModuleMemoryAuthorityError, insertMemory, insertMemoryIdempotent, getMemoryByHash, getMemoriesByProject, getMemoriesByProjects, getMemoryById, getMemoriesByIds, updateMemorySeenCount, updateMemoryRetrievalCount, supersededMemory, mergeMemoryStats, archiveMemory, relaxedFtsQuery, sanitizeFtsQuery, searchMemoriesFTS, searchMemoriesFTSUnion, clearMemoryVerifications, queueMemoryMutation, registerOwnRpcServerInstance, rpcPortDir, rpcPortFilePath, parseRpcPortFile, inspectProcessesAsync, COMPARTMENT_LEASE_RENEWAL_MS, acquireCompartmentLease, renewCompartmentLease, releaseCompartmentLeaseBestEffort, isCompartmentLeaseHeld, queueM0Mutation, getMaxM0MutationId, clearCachedM0M1, getCompartments, getLastCompartmentEndMessage, getLastCompartmentEndMessageId, getAuthorityManagedMarker, getLastIndexedOrdinal, getIndexedMessageIdAtOrdinal, getIndexedMessageCorpusSize, getMessageIndexReconciliationStartOrdinal, isMessageIndexReconciledThrough, clearIndexedMessages, indexMessagesAfterOrdinal, layoutLkgPrefix, MAX_EXECUTE_THRESHOLD, escalationBands, MERGED_REASONING_PARTS_PREFIX, readFrozenMergedReasoningParts, HYGIENE_PROVIDER_UNITS_VERSION, sessionDecisionCalibration, transitionSessionHygieneUnits, getProtectionWindowForSession, ReplayDocumentError, readReplayEnvelope, updateReplayDocument, isEmergencyRecoveryArmed, loadPersistedUsage, loadProtectedTailMeta, resetProtectedTailNoEligibleHead, getWrapupInProgressState, acquireWrapupInProgress, updateWrapupInProgress, releaseWrapupInProgress, resolveCompactionModeRecord, getCompactionModeRecord, setCompactionModeRecord, clearPersistedReasoningWatermark, getEmergencyInputSample, setEmergencyDropSample, clearEmergencyDropSample, getLastNudgeUndropped, setLastNudgeUndropped, getChannel1NudgeState, setChannel1NudgeState, markChannel1PostReduceGracePending, captureChannel1PostReduceGraceBaseline, getChannel2NudgeState, setChannel2NudgeState, casChannel2NudgeState, claimChannel2NudgeState, casChannel2NudgeClaim, getAutoSearchHintDecisions, appendAutoSearchHintDecision, pruneAutoSearchHintDecisions, getPersistedTodoPermissionDenied, setPersistedTodoPermissionDenied, getPersistedTodoSyntheticAnchor, setPersistedTodoSyntheticAnchor, clearPersistedTodoSyntheticAnchor, getHistorianFailureState, clearHistorianFailureState, getOverflowState, loadTransformPassStateSnapshot, recordOverflowDetected, recordDetectedContextLimit, clearEmergencyRecovery, clearDetectedContextLimit, getPersistedCompactionMarkerState, setPersistedCompactionMarkerState, getDeferredClearedCompactionMarkerState, retireDeferredClearedCompactionMarkerState, applyStrippedPlaceholderDelta, THINKING_BINDING_RECOVERY_FROZEN_PREFIX, thinkingBindingRecoveryFrozenId, clearThinkingBindingRecoveryIf, getMergedReasoningStrippedIds, addMergedReasoningStrippedIds, getTrailingBlankDecisions, addTrailingBlankDecisions, demoteTrailingBlankKeepDecisions, addStaleReduceStrippedIds, addProcessedImageStrippedIds, getPendingCompactionMarkerState, getCompactionMarkerHealth, loadPostprocessReplaySnapshot, clearPendingCompactionMarkerStateIf, setSessionWorkMetrics, getObservedEpochFloor, resolveEpochFloorForPass, BoundedSessionMap, beginLkgPass, lkgContentDigest, captureSlot, getInMemorySlot, getSlot, dropSlot, noteEntry, getLkgSlotHeapStats, useScopedToolSweep, createPreAdoptionToolSweepResolver, copySessionStateForClone, scheduleAfterBootQuiet, getSchemaFenceRejection, getMigrationOnOpenRefusal, LATEST_SUPPORTED_VERSION, getPersistedSchemaVersion, openDatabase, openDatabaseAsync, isDatabasePersisted, getDatabasePersistenceError, gaDatabasePath, RAW_MESSAGE_TYPES, V2StoreReaderPool, getOrCreateSessionMeta, updateSessionMeta, advanceToolReclaimWatermark, markSessionCleanupPending, clearSession, getNoteByIdInScope, getNotes, addNote, getSessionNotes, updateNote, dismissNotes, dismissNote, queuePendingOp, getPendingOps, getPendingOpsCount, clearPendingOps, removePendingOp, getActivePrimers, saveSourceContent, replaceSourceContent, getSourceContents, resolveWorkspaceShareCategories, resolveWorkspaceIdentitySet, expandWorkspaceIdentitySetWithAliases, resolveStoredPathWorkspaceIdentity, storedPathBelongsToWorkspace, sourceNameForMemory, rebaseSessionCoordinatesAsync, renderUserFacingFailure, userFacingFailureCode, renderCapabilityRefusal, HiddenCompletionRefusal, HIDDEN_HISTORIAN_AGENT, registerHiddenChildAgents, HiddenAgentStepLimit, HiddenChildHook, parseProviderModel, toModelEntry, ACTIVE_TOOL_IDS, promptSurfaceHashMaterial, createPromptSurfaceRuntime, createPromptSurfaceGuidanceEpochCache, getOpenCodeDbPath, compareOpenCodeMessagesByCanonicalOrder, removeMcOwnedCompactionMarkers, MARKER_SUMMARY_TEXT, applyDeferredCompactionMarker, HISTORIAN_AGENT, HISTORIAN_RECOMP_AGENT, HISTORIAN_EDITOR_AGENT, runTokenLog, extractM0Block, injectTemporalMarkers, clearInjectionCache, getVisibleMemoryIds, selectHiddenMessagesAtCompactionSeam, prepareCompartmentInjection, renderCompartmentInjection, mustMaterialize, trimMemoriesToBudgetV2, renderMemoryBlockV2, materializeM0, resetPrefixTrimFallbackState, findHostCompactionWindow, capturePrefixTrimSourceOrder, prepareCachedM0M1Replay, hasCompleteCachedM0M1, injectM0M1, describeBoundaryDiagnostics, RECOVERY_NO_HEAD_LIMIT, resolveOpenCodeProtectedTailBoundary, resolveWrapupProtectedTailBoundary, getRawHistoryEligibility, hasRunnableCompartmentWindow, recordHighPressureNoEligibleHead, runCompartmentAgent, getActiveCompartmentRun, markActiveCompartmentRunPublished, registerActiveCompartmentRun, startCompartmentAgent, executeContextRecomp };
28098
+ export { MEMORY_MAINTAINER_A_AGENT, MEMORY_MAINTAINER_B_AGENT, MEMORY_MAINTAINER_A_STEP_CAP, MEMORY_MAINTAINER_A_SYSTEM_PROMPT, MEMORY_MAINTAINER_B_SYSTEM_PROMPT, MEMORY_MAINTAINER_FINALIZE_INSTRUCTION, buildMemoryMaintainerStageAPrompt, buildMemoryMaintainerStageBPrompt, getOpenCodeGlobalConfigDir, getOpenCodeConfigDirs, opencodeUserConfigBasePath, mmcProjectConfigBasePath, buildPrimaryLanguageDirective, resolveModelConfigValue, DEFAULT_EXECUTE_THRESHOLD_PERCENTAGE, PROTECTED_TOKENS_MIN, HISTORIAN_MODEL_RESOLUTION_FIELDS, LEGACY_HARNESS_BLOCK_KEYS, ConfigProfilesSchema, MagicContextConfigSchema, LIVE_RELOAD_CONFIG_PATHS, formatFailClosedBlockingMessage, formatFailClosedBlockingSummary, createFailClosedBlockingError, isFailClosedBlockingError, setHomeProjectPermission, shouldSkipHomeProjectMemory, ProjectIdentityError, takeDubiousOwnershipProjectIdentityWarning, isUserHomeDirectory, describeUnresolvedProjectIdentity, resolveProjectIdentityForSession, normalizeStoredProjectPath, storedPathBelongsToIdentity, V2_MEMORY_CATEGORIES, CATEGORY_PRIORITY, computeNormalizedHash, hasMemoryShareableColumn, hasMemoryClassifiedAtColumn, ModuleMemoryAuthorityError, insertMemory, insertMemoryIdempotent, getMemoryByHash, getMemoriesByProject, getMemoriesByProjects, getMemoryById, getMemoriesByIds, updateMemorySeenCount, updateMemoryRetrievalCount, supersededMemory, mergeMemoryStats, archiveMemory, relaxedFtsQuery, sanitizeFtsQuery, searchMemoriesFTS, searchMemoriesFTSUnion, clearMemoryVerifications, queueMemoryMutation, registerOwnRpcServerInstance, rpcPortDir, rpcPortFilePath, parseRpcPortFile, inspectProcessesAsync, COMPARTMENT_LEASE_RENEWAL_MS, acquireCompartmentLease, renewCompartmentLease, releaseCompartmentLeaseBestEffort, isCompartmentLeaseHeld, queueM0Mutation, getMaxM0MutationId, clearCachedM0M1, getCompartments, getLastCompartmentEndMessage, getLastCompartmentEndMessageId, getAuthorityManagedMarker, getLastIndexedOrdinal, getIndexedMessageIdAtOrdinal, getIndexedMessageCorpusSize, getMessageIndexReconciliationStartOrdinal, isMessageIndexReconciledThrough, clearIndexedMessages, indexMessagesAfterOrdinal, layoutLkgPrefix, assembleLkgPrefix, getTemporalDecisions, observeTemporalDecisions, freezeTemporalDecisions, MAX_EXECUTE_THRESHOLD, escalationBands, MERGED_REASONING_PARTS_PREFIX, readFrozenMergedReasoningParts, HYGIENE_PROVIDER_UNITS_VERSION, sessionDecisionCalibration, transitionSessionHygieneUnits, getProtectionWindowForSession, ReplayDocumentError, readReplayEnvelope, updateReplayDocument, isEmergencyRecoveryArmed, loadPersistedUsage, loadProtectedTailMeta, resetProtectedTailNoEligibleHead, getWrapupInProgressState, acquireWrapupInProgress, updateWrapupInProgress, releaseWrapupInProgress, resolveCompactionModeRecord, getCompactionModeRecord, setCompactionModeRecord, getProtectedTailDrainBudgetSkip, clearPersistedReasoningWatermark, getEmergencyInputSample, setEmergencyDropSample, clearEmergencyDropSample, getLastNudgeUndropped, setLastNudgeUndropped, getChannel1NudgeState, setChannel1NudgeState, markChannel1PostReduceGracePending, captureChannel1PostReduceGraceBaseline, getChannel2NudgeState, setChannel2NudgeState, casChannel2NudgeState, claimChannel2NudgeState, casChannel2NudgeClaim, getAutoSearchHintDecisions, appendAutoSearchHintDecision, pruneAutoSearchHintDecisions, getPersistedTodoPermissionDenied, setPersistedTodoPermissionDenied, getPersistedTodoSyntheticAnchor, setPersistedTodoSyntheticAnchor, clearPersistedTodoSyntheticAnchor, getHistorianFailureState, clearHistorianFailureState, getOverflowState, loadTransformPassStateSnapshot, recordOverflowDetected, recordDetectedContextLimit, clearEmergencyRecovery, clearDetectedContextLimit, getPersistedCompactionMarkerState, setPersistedCompactionMarkerState, getDeferredClearedCompactionMarkerState, retireDeferredClearedCompactionMarkerState, applyStrippedPlaceholderDelta, THINKING_BINDING_RECOVERY_FROZEN_PREFIX, thinkingBindingRecoveryFrozenId, clearThinkingBindingRecoveryIf, getMergedReasoningStrippedIds, addMergedReasoningStrippedIds, getTrailingBlankDecisions, addTrailingBlankDecisions, demoteTrailingBlankKeepDecisions, addStaleReduceStrippedIds, addProcessedImageStrippedIds, getPendingCompactionMarkerState, getCompactionMarkerHealth, loadPostprocessReplaySnapshot, clearPendingCompactionMarkerStateIf, setSessionWorkMetrics, getObservedEpochFloor, resolveEpochFloorForPass, BoundedSessionMap, beginLkgPass, lkgContentDigest, captureSlot, getInMemorySlot, getSlot, dropSlot, noteEntry, getLkgSlotHeapStats, useScopedToolSweep, createPreAdoptionToolSweepResolver, copySessionStateForClone, scheduleAfterBootQuiet, getSchemaFenceRejection, getMigrationOnOpenRefusal, LATEST_SUPPORTED_VERSION, getPersistedSchemaVersion, openDatabase, openDatabaseAsync, isDatabasePersisted, getDatabasePersistenceError, gaDatabasePath, RAW_MESSAGE_TYPES, V2StoreReaderPool, getOrCreateSessionMeta, updateSessionMeta, advanceToolReclaimWatermark, markSessionCleanupPending, clearSession, getNoteByIdInScope, getNotes, addNote, getSessionNotes, updateNote, dismissNotes, dismissNote, getActivePrimers, saveSourceContent, replaceSourceContent, getSourceContents, resolveWorkspaceShareCategories, resolveWorkspaceIdentitySet, expandWorkspaceIdentitySetWithAliases, resolveStoredPathWorkspaceIdentity, storedPathBelongsToWorkspace, sourceNameForMemory, rebaseSessionCoordinatesAsync, renderUserFacingFailure, userFacingFailureCode, renderCapabilityRefusal, HiddenCompletionRefusal, HIDDEN_HISTORIAN_AGENT, hiddenChildPermissions, registerHiddenChildAgents, HiddenAgentStepLimit, HiddenChildHook, parseProviderModel, toModelEntry, ACTIVE_TOOL_IDS, promptSurfaceHashMaterial, createPromptSurfaceRuntime, createPromptSurfaceGuidanceEpochCache, getOpenCodeDbPath, compareOpenCodeMessagesByCanonicalOrder, removeMcOwnedCompactionMarkers, MARKER_SUMMARY_TEXT, applyDeferredCompactionMarker, HISTORIAN_AGENT, HISTORIAN_RECOMP_AGENT, HISTORIAN_EDITOR_AGENT, runTokenLog, extractM0Block, TEMPORAL_MARKER_REPLAY_PATTERN, collectTemporalCandidates, injectTemporalMarkers, clearInjectionCache, getVisibleMemoryIds, selectHiddenMessagesAtCompactionSeam, prepareCompartmentInjection, renderCompartmentInjection, MaterializeContentionError, mustMaterialize, trimMemoriesToBudgetV2, renderMemoryBlockV2, materializeM0, resetPrefixTrimFallbackState, findHostCompactionWindow, capturePrefixTrimSourceOrder, prepareCachedM0M1Replay, hasCompleteCachedM0M1, injectM0M1, describeBoundaryDiagnostics, RECOVERY_NO_HEAD_LIMIT, deriveProtectedTailTokenTarget, selectPerRunCap, resolveOpenCodeProtectedTailBoundary, resolveWrapupProtectedTailBoundary, getRawHistoryEligibility, hasRunnableCompartmentWindow, recordHighPressureNoEligibleHead, runCompartmentAgent, getActiveCompartmentRun, markActiveCompartmentRunPublished, registerActiveCompartmentRun, startCompartmentAgent, executeContextRecomp };