@cortexkit/opencode-magic-context 0.36.1 → 0.38.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 (176) hide show
  1. package/README.md +2 -0
  2. package/dist/config/index.d.ts.map +1 -1
  3. package/dist/config/project-security.d.ts +2 -1
  4. package/dist/config/project-security.d.ts.map +1 -1
  5. package/dist/config/schema/magic-context.d.ts +10 -0
  6. package/dist/config/schema/magic-context.d.ts.map +1 -1
  7. package/dist/{conflict-warning-hook-mt0ttc4x.js → conflict-warning-hook-an4fxhwf.js} +3 -3
  8. package/dist/{derive-budgets-88mxk2w1.js → derive-budgets-da4yg3tz.js} +3 -2
  9. package/dist/features/magic-context/context-authority.d.ts.map +1 -1
  10. package/dist/features/magic-context/dreamer/classify-prompt.d.ts +5 -1
  11. package/dist/features/magic-context/dreamer/classify-prompt.d.ts.map +1 -1
  12. package/dist/features/magic-context/dreamer/classify.d.ts.map +1 -1
  13. package/dist/features/magic-context/dreamer/evaluate-smart-notes.d.ts.map +1 -1
  14. package/dist/features/magic-context/dreamer/manifest-parser.d.ts +8 -0
  15. package/dist/features/magic-context/dreamer/manifest-parser.d.ts.map +1 -1
  16. package/dist/features/magic-context/dreamer/map-memories-prompt.d.ts +7 -1
  17. package/dist/features/magic-context/dreamer/map-memories-prompt.d.ts.map +1 -1
  18. package/dist/features/magic-context/dreamer/map-memories.d.ts +18 -0
  19. package/dist/features/magic-context/dreamer/map-memories.d.ts.map +1 -1
  20. package/dist/features/magic-context/dreamer/storage-dream-runs.d.ts +5 -0
  21. package/dist/features/magic-context/dreamer/storage-dream-runs.d.ts.map +1 -1
  22. package/dist/features/magic-context/dreamer/task-executor.d.ts.map +1 -1
  23. package/dist/features/magic-context/dreamer/verify-prompt.d.ts +5 -1
  24. package/dist/features/magic-context/dreamer/verify-prompt.d.ts.map +1 -1
  25. package/dist/features/magic-context/dreamer/verify.d.ts.map +1 -1
  26. package/dist/features/magic-context/fail-closed-block.d.ts +6 -1
  27. package/dist/features/magic-context/fail-closed-block.d.ts.map +1 -1
  28. package/dist/features/magic-context/memory/embedding-openai.d.ts +3 -1
  29. package/dist/features/magic-context/memory/embedding-openai.d.ts.map +1 -1
  30. package/dist/features/magic-context/memory/project-identity.d.ts +6 -0
  31. package/dist/features/magic-context/memory/project-identity.d.ts.map +1 -1
  32. package/dist/features/magic-context/migrations.d.ts.map +1 -1
  33. package/dist/features/magic-context/overflow-detection.d.ts.map +1 -1
  34. package/dist/features/magic-context/reclaim-protection.d.ts +13 -0
  35. package/dist/features/magic-context/reclaim-protection.d.ts.map +1 -0
  36. package/dist/features/magic-context/smart-notes/runner.d.ts.map +1 -1
  37. package/dist/features/magic-context/smart-notes/wake-plane.d.ts +21 -0
  38. package/dist/features/magic-context/smart-notes/wake-plane.d.ts.map +1 -0
  39. package/dist/features/magic-context/storage-db.d.ts +19 -3
  40. package/dist/features/magic-context/storage-db.d.ts.map +1 -1
  41. package/dist/features/magic-context/storage-meta-persisted.d.ts +23 -0
  42. package/dist/features/magic-context/storage-meta-persisted.d.ts.map +1 -1
  43. package/dist/features/magic-context/storage-meta-session.d.ts.map +1 -1
  44. package/dist/features/magic-context/storage-meta-shared.d.ts.map +1 -1
  45. package/dist/features/magic-context/storage-primers.d.ts +11 -0
  46. package/dist/features/magic-context/storage-primers.d.ts.map +1 -1
  47. package/dist/features/magic-context/storage-schema-helpers.d.ts.map +1 -1
  48. package/dist/features/magic-context/storage-tags.d.ts +13 -5
  49. package/dist/features/magic-context/storage-tags.d.ts.map +1 -1
  50. package/dist/features/magic-context/user-memory/storage-user-memory.d.ts +7 -0
  51. package/dist/features/magic-context/user-memory/storage-user-memory.d.ts.map +1 -1
  52. package/dist/features/magic-context/window-report-ledger.d.ts +70 -0
  53. package/dist/features/magic-context/window-report-ledger.d.ts.map +1 -0
  54. package/dist/hooks/auto-update-checker/checker.d.ts +8 -1
  55. package/dist/hooks/auto-update-checker/checker.d.ts.map +1 -1
  56. package/dist/hooks/auto-update-checker/index.d.ts.map +1 -1
  57. package/dist/hooks/magic-context/channel2-cycle.d.ts +16 -0
  58. package/dist/hooks/magic-context/channel2-cycle.d.ts.map +1 -0
  59. package/dist/hooks/magic-context/channel2-delivery.d.ts +3 -9
  60. package/dist/hooks/magic-context/channel2-delivery.d.ts.map +1 -1
  61. package/dist/hooks/magic-context/command-handler.d.ts +2 -0
  62. package/dist/hooks/magic-context/command-handler.d.ts.map +1 -1
  63. package/dist/hooks/magic-context/ctx-reduce-nudge.d.ts +33 -103
  64. package/dist/hooks/magic-context/ctx-reduce-nudge.d.ts.map +1 -1
  65. package/dist/hooks/magic-context/emergency-drop.d.ts.map +1 -1
  66. package/dist/hooks/magic-context/event-handler.d.ts.map +1 -1
  67. package/dist/hooks/magic-context/event-resolvers.d.ts +4 -0
  68. package/dist/hooks/magic-context/event-resolvers.d.ts.map +1 -1
  69. package/dist/hooks/magic-context/execute-status.d.ts +3 -1
  70. package/dist/hooks/magic-context/execute-status.d.ts.map +1 -1
  71. package/dist/hooks/magic-context/fold-execution-gate.d.ts +2 -0
  72. package/dist/hooks/magic-context/fold-execution-gate.d.ts.map +1 -0
  73. package/dist/hooks/magic-context/hook-handlers.d.ts.map +1 -1
  74. package/dist/hooks/magic-context/hook.d.ts.map +1 -1
  75. package/dist/hooks/magic-context/inject-compartments.d.ts.map +1 -1
  76. package/dist/hooks/magic-context/live-session-state.d.ts +3 -0
  77. package/dist/hooks/magic-context/live-session-state.d.ts.map +1 -1
  78. package/dist/hooks/magic-context/lkg-replay.d.ts.map +1 -1
  79. package/dist/hooks/magic-context/lkg-slot.d.ts +20 -0
  80. package/dist/hooks/magic-context/lkg-slot.d.ts.map +1 -1
  81. package/dist/hooks/magic-context/module-state-sync.d.ts +8 -0
  82. package/dist/hooks/magic-context/module-state-sync.d.ts.map +1 -1
  83. package/dist/hooks/magic-context/module-transport.d.ts.map +1 -1
  84. package/dist/hooks/magic-context/module-wire.d.ts +6 -1
  85. package/dist/hooks/magic-context/module-wire.d.ts.map +1 -1
  86. package/dist/hooks/magic-context/rust-mode-transform.d.ts +21 -2
  87. package/dist/hooks/magic-context/rust-mode-transform.d.ts.map +1 -1
  88. package/dist/hooks/magic-context/strip-content.d.ts +27 -0
  89. package/dist/hooks/magic-context/strip-content.d.ts.map +1 -1
  90. package/dist/hooks/magic-context/supersession-reclaim.d.ts.map +1 -1
  91. package/dist/hooks/magic-context/system-prompt-hash.d.ts.map +1 -1
  92. package/dist/hooks/magic-context/tail-hygiene-walk.d.ts +78 -0
  93. package/dist/hooks/magic-context/tail-hygiene-walk.d.ts.map +1 -0
  94. package/dist/hooks/magic-context/tool-reclaim.d.ts.map +1 -1
  95. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts +14 -3
  96. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
  97. package/dist/hooks/magic-context/transform.d.ts +10 -0
  98. package/dist/hooks/magic-context/transform.d.ts.map +1 -1
  99. package/dist/hooks/magic-context/wrapup-orchestrator.d.ts.map +1 -1
  100. package/dist/{index-nsx2n9eg.js → index-4cz5nfxf.js} +3 -3
  101. package/dist/{index-f1tnb3vm.js → index-8pqfcghm.js} +21 -9
  102. package/dist/index-9zhhvr4w.js +733 -0
  103. package/dist/{index-zp6x6s6a.js → index-cae89eas.js} +25 -6
  104. package/dist/index-cgyfn1s2.js +53 -0
  105. package/dist/{index-3zqcdwqr.js → index-crke4z5j.js} +7 -4
  106. package/dist/{index-1skzp4dc.js → index-mmvhrqqb.js} +1991 -274
  107. package/dist/{index-tsgs7td8.js → index-pck9vadr.js} +1 -1
  108. package/dist/{index-3tnkymva.js → index-sw8gnq34.js} +1 -1
  109. package/dist/index.d.ts.map +1 -1
  110. package/dist/index.js +1714 -988
  111. package/dist/plugin/hooks/create-session-hooks.d.ts +3 -0
  112. package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
  113. package/dist/plugin/messages-transform.d.ts.map +1 -1
  114. package/dist/plugin/rpc-handlers.d.ts +2 -0
  115. package/dist/plugin/rpc-handlers.d.ts.map +1 -1
  116. package/dist/{recomp-orchestrator-a0g9b52q.js → recomp-orchestrator-jsde4ygw.js} +7 -6
  117. package/dist/{safe-notification-target-c11fdda2.js → safe-notification-target-b693f9x3.js} +2 -2
  118. package/dist/{send-session-notification-bgtf4853.js → send-session-notification-dxske5zm.js} +3 -3
  119. package/dist/shared/conflict-detector.d.ts +63 -0
  120. package/dist/shared/conflict-detector.d.ts.map +1 -1
  121. package/dist/shared/harness-provider-map.d.ts +8 -0
  122. package/dist/shared/harness-provider-map.d.ts.map +1 -1
  123. package/dist/shared/logger.d.ts +8 -0
  124. package/dist/shared/logger.d.ts.map +1 -1
  125. package/dist/shared/models-dev-cache.d.ts +7 -0
  126. package/dist/shared/models-dev-cache.d.ts.map +1 -1
  127. package/dist/shared/prompt-surface-runtime.d.ts.map +1 -1
  128. package/dist/shared/prompt-surface.d.ts +2 -0
  129. package/dist/shared/prompt-surface.d.ts.map +1 -1
  130. package/dist/shared/rpc-client.d.ts.map +1 -1
  131. package/dist/shared/rpc-server.d.ts.map +1 -1
  132. package/dist/shared/rpc-types.d.ts +29 -0
  133. package/dist/shared/rpc-types.d.ts.map +1 -1
  134. package/dist/shared/rpc-utils.d.ts +28 -9
  135. package/dist/shared/rpc-utils.d.ts.map +1 -1
  136. package/dist/shared/tail-hygiene-status.d.ts +15 -0
  137. package/dist/shared/tail-hygiene-status.d.ts.map +1 -0
  138. package/dist/shared/window-geometry.d.ts +90 -0
  139. package/dist/shared/window-geometry.d.ts.map +1 -0
  140. package/dist/{storage-meta-session-df9tstzr.js → storage-meta-session-mk4gsnke.js} +4 -3
  141. package/dist/tools/ctx-memory/tools.d.ts.map +1 -1
  142. package/dist/tools/ctx-note/tools.d.ts.map +1 -1
  143. package/dist/tui/data/context-db.d.ts.map +1 -1
  144. package/dist/tui-compiled/data/context-db.d.ts.map +1 -1
  145. package/package.json +3 -1
  146. package/src/config/index.ts +2 -0
  147. package/src/config/latch-permanence-guard.test.ts +218 -0
  148. package/src/config/project-security.ts +10 -1
  149. package/src/config/schema/magic-context.ts +12 -2
  150. package/src/shared/__fixtures__/window-overlay.v1.json +337 -0
  151. package/src/shared/conflict-detector.test.ts +176 -1
  152. package/src/shared/conflict-detector.ts +126 -3
  153. package/src/shared/harness-provider-map.test.ts +20 -0
  154. package/src/shared/harness-provider-map.ts +19 -0
  155. package/src/shared/logger.test.ts +119 -0
  156. package/src/shared/logger.ts +33 -15
  157. package/src/shared/models-dev-cache.test.ts +42 -0
  158. package/src/shared/models-dev-cache.ts +62 -9
  159. package/src/shared/prompt-surface-runtime.ts +5 -3
  160. package/src/shared/prompt-surface.test.ts +38 -0
  161. package/src/shared/prompt-surface.ts +15 -2
  162. package/src/shared/rpc-client.ts +4 -2
  163. package/src/shared/rpc-server.ts +1 -0
  164. package/src/shared/rpc-types.ts +30 -0
  165. package/src/shared/rpc-utils.test.ts +162 -13
  166. package/src/shared/rpc-utils.ts +224 -31
  167. package/src/shared/tail-hygiene-status.ts +57 -0
  168. package/src/shared/window-geometry.test.ts +342 -0
  169. package/src/shared/window-geometry.ts +626 -0
  170. package/src/tui/data/context-db.ts +5 -0
  171. package/src/tui/index.tsx +33 -1
  172. package/src/tui/slots/sidebar-content.tsx +17 -5
  173. package/src/tui-compiled/data/context-db.ts +5 -0
  174. package/src/tui-compiled/index.tsx +359 -273
  175. package/src/tui-compiled/slots/sidebar-content.tsx +316 -287
  176. package/dist/index-wgvxkqpx.js +0 -342
package/dist/index.js CHANGED
@@ -14,9 +14,12 @@ import {
14
14
  AdmissionClass,
15
15
  BoundedSessionMap,
16
16
  CATEGORY_PRIORITY,
17
+ CHANNEL1_FLOOR_TOKENS,
18
+ CHANNEL1_SENTINEL,
17
19
  COMPARTMENT_AGENT_SYSTEM_PROMPT,
18
20
  COMPARTMENT_LEASE_RENEWAL_MS,
19
21
  COMPARTMENT_STRUCTURAL_SYSTEM_PROMPT,
22
+ CTX_REDUCE_KEEP,
20
23
  DEFAULT_EXECUTE_THRESHOLD_PERCENTAGE,
21
24
  DEFAULT_HISTORIAN_TIMEOUT_MS,
22
25
  DEFAULT_LOCAL_EMBEDDING_MODEL,
@@ -53,9 +56,11 @@ import {
53
56
  acquireCompartmentLease,
54
57
  acquireGitSweepLease,
55
58
  acquireWrapupInProgress,
59
+ addMergedReasoningStrippedIds,
56
60
  addNote,
57
61
  addProcessedImageStrippedIds,
58
62
  addStaleReduceStrippedIds,
63
+ addTrailingBlankDecisions,
59
64
  adoptNullOwnerToolTag,
60
65
  appendAutoSearchHintDecision,
61
66
  applyDeferredCompactionMarker,
@@ -63,10 +68,14 @@ import {
63
68
  applyMirroredNoteCompileFields,
64
69
  applyStrippedPlaceholderDelta,
65
70
  archiveMemory,
71
+ assertTailHygieneContentUnchanged,
66
72
  backfillTagTokenCounts,
67
73
  beginBootQuietPeriod,
68
74
  bootQuietRemainingMs,
75
+ buildChannel1Reminder,
76
+ buildChannel2Reminder,
69
77
  buildPrimaryLanguageDirective,
78
+ buildSyntheticTodoPart,
70
79
  buildWorkspaceMemorySqlFilter,
71
80
  bumpProjectMemoryEpoch,
72
81
  bumpProjectUserProfileVersion,
@@ -93,7 +102,9 @@ import {
93
102
  clearRecompStaging,
94
103
  computeCueContentHash,
95
104
  computeNormalizedHash,
105
+ computeSyntheticCallId,
96
106
  computeWorkspaceEpochFingerprint,
107
+ connectionFileExists,
97
108
  contentSha256,
98
109
  cortexKitProjectConfigBasePath,
99
110
  cortexKitUserConfigBasePath,
@@ -105,6 +116,7 @@ import {
105
116
  createPrimer,
106
117
  createPromptSurfaceGuidanceEpochCache,
107
118
  createPromptSurfaceRuntime,
119
+ decideChannel1,
108
120
  deleteTagsByMessageId,
109
121
  deleteUserMemoryCandidates,
110
122
  deriveTagLoadFloor,
@@ -114,6 +126,7 @@ import {
114
126
  drainAuthority,
115
127
  drainCommitBacklogForProject,
116
128
  dropSlot,
129
+ effectiveTailHygiene,
117
130
  embedBatchForProject,
118
131
  embedItemsForProject,
119
132
  embedSessionCompartmentChunks,
@@ -126,6 +139,9 @@ import {
126
139
  ensureContextStoreUuid,
127
140
  ensureMemoryEmbeddings,
128
141
  escalationBands,
142
+ estimateEmergencyDropReclaimTokens,
143
+ estimateImageTokensFromDataUrl,
144
+ evaluateChannel2,
129
145
  expandWorkspaceIdentitySetWithAliases,
130
146
  exports_external,
131
147
  extractLatestAssistantText,
@@ -133,7 +149,6 @@ import {
133
149
  formatDate,
134
150
  getActiveCompartmentRun,
135
151
  getActivePrimers,
136
- getActiveTagTokenAggregate,
137
152
  getActiveTagTokenTotalsByMessage,
138
153
  getActiveTagsBySession,
139
154
  getActiveToolTagsForAgeReclaim,
@@ -174,6 +189,7 @@ import {
174
189
  getMemoryCountsByStatus,
175
190
  getMemoryMutationsForRenderByProjects,
176
191
  getMemoryVerifications,
192
+ getMergedReasoningStrippedIds,
177
193
  getMigrationOnOpenRefusal,
178
194
  getMirrorCursor,
179
195
  getModuleNoteEvaluationBridge,
@@ -214,7 +230,9 @@ import {
214
230
  getTagNumberByMessageId,
215
231
  getTagsByNumbers,
216
232
  getTagsBySession,
233
+ getTailHygieneTags,
217
234
  getToolTagNumberByOwner,
235
+ getTrailingBlankDecisions,
218
236
  getTriggerTagTokenUpperBound,
219
237
  getUnclassifiedMemoryIds,
220
238
  getUnmappedMemoryIds,
@@ -226,6 +244,7 @@ import {
226
244
  hasMemoryShareableColumn,
227
245
  hasMuralCueColumns,
228
246
  hasRunnableCompartmentWindow,
247
+ incrementalLkgContentDigests,
229
248
  injectM0M1,
230
249
  injectTemporalMarkers,
231
250
  insertMemory,
@@ -240,10 +259,11 @@ import {
240
259
  isEmbeddingEnabled,
241
260
  isEmergencyRecoveryArmed,
242
261
  isFailClosedBlockingError,
262
+ isLinkedGitWorktree,
243
263
  isPidAlive,
244
264
  isProviderOverflowReconfirmed,
265
+ isSyntheticTodoPart,
245
266
  lkgContentDigest,
246
- lkgContentDigestFromFields,
247
267
  loadCompartmentChunkEmbeddingsForSearch,
248
268
  loadPersistedUsage,
249
269
  loadProjectCommitEmbeddings,
@@ -263,6 +283,7 @@ import {
263
283
  nextOccurrence,
264
284
  normalizeSDKResponse,
265
285
  normalizeStoredProjectPath,
286
+ normalizeTodoStateJson,
266
287
  normalizeVerificationFiles,
267
288
  noteEntry,
268
289
  onNoteTrigger,
@@ -275,6 +296,7 @@ import {
275
296
  peekNoteNudgeText,
276
297
  peekProjectEmbeddings,
277
298
  pickNearestPriorOwner,
299
+ planEmergencyDrop,
278
300
  prepareAuthority,
279
301
  prepareCompartmentInjection,
280
302
  primerOccurrenceKey,
@@ -304,6 +326,7 @@ import {
304
326
  recordOverflowDetected,
305
327
  recordSessionProjectIdentity,
306
328
  recordToolDefinition,
329
+ refreshTailHygieneBaseline,
307
330
  registerActiveCompartmentRun,
308
331
  registerModuleNoteEvaluationBridge,
309
332
  registerProjectEmbedding,
@@ -333,6 +356,7 @@ import {
333
356
  resolveLegacyConfigSources,
334
357
  resolveLegacyConfigSourcesForHarness,
335
358
  resolveModelConfigOrDefault,
359
+ resolveMuralWire,
336
360
  resolveOpenCodeProtectedTailBoundary,
337
361
  resolveProjectIdentity,
338
362
  resolveProjectIdentityForSession,
@@ -348,6 +372,7 @@ import {
348
372
  runManagedRecomp,
349
373
  runManagedUpgrade,
350
374
  runSqliteOptimize,
375
+ sameTailHygieneStructuralSignature,
351
376
  sanitizeFtsQuery,
352
377
  saveCommitEmbedding,
353
378
  saveEmbeddingIfHashMatches,
@@ -383,7 +408,9 @@ import {
383
408
  supersededMemory,
384
409
  sweepStaleEmbeddingIdentitiesForProject,
385
410
  tagTokenCountIsNull,
411
+ tailHygieneStructuralSignature,
386
412
  takeDubiousOwnershipProjectIdentityWarning,
413
+ toolOutputTokens,
387
414
  trimMemoriesToBudgetV2,
388
415
  updateCavemanDepth,
389
416
  updateMemoryRetrievalCount,
@@ -400,19 +427,22 @@ import {
400
427
  upsertCommits,
401
428
  verificationFileExists,
402
429
  withContentLanguageDirective
403
- } from "./index-1skzp4dc.js";
430
+ } from "./index-mmvhrqqb.js";
404
431
  import {
405
432
  deriveHistorianChunkTokens,
406
433
  deriveTriggerBudget,
434
+ formatWindowDerivationLine,
407
435
  getSdkContextLimit,
436
+ getSdkWindowGeometry,
408
437
  isSaneLimit,
409
438
  refreshModelLimitsAfterAuthOnce,
410
439
  refreshModelLimitsFromApi,
411
440
  resolveHistorianContextLimit,
412
441
  setOutputReserveConfig,
413
442
  setStoragePrivatePermissionEnforcement,
443
+ setWindowOverlayPath,
414
444
  shouldEnforcePrivateStoragePermissions
415
- } from "./index-wgvxkqpx.js";
445
+ } from "./index-9zhhvr4w.js";
416
446
  import {
417
447
  modelBodyField,
418
448
  resolveFallbackChain
@@ -424,7 +454,7 @@ import {
424
454
  getErrorMessage,
425
455
  sendIgnoredMessage,
426
456
  sendUserPrompt
427
- } from "./index-nsx2n9eg.js";
457
+ } from "./index-4cz5nfxf.js";
428
458
  import {
429
459
  ToolMutationBatch,
430
460
  advanceToolReclaimWatermark,
@@ -482,7 +512,11 @@ import {
482
512
  textMentionsRecentCommit,
483
513
  updateSessionMeta,
484
514
  withRawSessionMessageCache
485
- } from "./index-3zqcdwqr.js";
515
+ } from "./index-crke4z5j.js";
516
+ import {
517
+ modelRefLookupOrder,
518
+ piModelRefToCanonical
519
+ } from "./index-cgyfn1s2.js";
486
520
  import {
487
521
  Database,
488
522
  closeQuietly,
@@ -491,12 +525,13 @@ import {
491
525
  isMidTurn,
492
526
  openCodeDbExists,
493
527
  withReadOnlySessionDb
494
- } from "./index-3tnkymva.js";
528
+ } from "./index-sw8gnq34.js";
495
529
  import {
496
530
  cleanupConflictWarnings,
497
531
  detectConflicts,
532
+ resolveCompactionForBoot,
498
533
  sendConflictWarning
499
- } from "./index-zp6x6s6a.js";
534
+ } from "./index-cae89eas.js";
500
535
  import {
501
536
  detectConfigFile,
502
537
  isPrototypePollutionKey,
@@ -519,11 +554,12 @@ import {
519
554
  pushNotification,
520
555
  registerNotificationSink
521
556
  } from "./index-d62ypazr.js";
522
- import"./index-tsgs7td8.js";
557
+ import"./index-pck9vadr.js";
523
558
  import {
559
+ getLoggerDiagnostics,
524
560
  log,
525
561
  sessionLog
526
- } from "./index-f1tnb3vm.js";
562
+ } from "./index-8pqfcghm.js";
527
563
  import {
528
564
  getDataDir,
529
565
  getHarness,
@@ -9125,6 +9161,11 @@ function stripUnsafeProjectConfigFields(projectRaw) {
9125
9161
  delete projectRaw.output_reserve;
9126
9162
  warnings.push("Ignoring output_reserve from project config (security: output-token reservation only honors user-level config).");
9127
9163
  }
9164
+ const models = projectRaw.models;
9165
+ if (isPlainObject(models) && "window_overlay_path" in models) {
9166
+ delete models.window_overlay_path;
9167
+ warnings.push("Ignoring models.window_overlay_path from project config (security: only user-level config may select model geometry metadata).");
9168
+ }
9128
9169
  if ("language" in projectRaw) {
9129
9170
  delete projectRaw.language;
9130
9171
  warnings.push("Ignoring language from project config (security: output language is a user-level setting).");
@@ -9787,6 +9828,7 @@ function loadPluginConfigDetailed(directory) {
9787
9828
  const recoveredTopLevelKeys = [];
9788
9829
  const config = parsePluginConfig(mergedRaw, recoveredTopLevelKeys);
9789
9830
  setOutputReserveConfig(config.output_reserve);
9831
+ setWindowOverlayPath(config.models?.window_overlay_path);
9790
9832
  if (config.configWarnings?.length) {
9791
9833
  allWarnings.push(...config.configWarnings.map((w) => {
9792
9834
  if (userLoaded && projectLoaded)
@@ -11029,8 +11071,8 @@ function getCurrentRuntimePackageJsonPath(currentModuleUrl = import.meta.url) {
11029
11071
  return null;
11030
11072
  }
11031
11073
  }
11032
- function findPluginEntry(directory) {
11033
- const winner = getWinningConfig(directory, "server");
11074
+ function findPluginEntry(directory, surface = "server") {
11075
+ const winner = getWinningConfig(directory, surface);
11034
11076
  if (!winner)
11035
11077
  return null;
11036
11078
  const entry = winner.entries.find((value) => value === PACKAGE_NAME || value.startsWith(`${PACKAGE_NAME}@`));
@@ -11044,13 +11086,21 @@ function findPluginEntry(directory) {
11044
11086
  configPath: winner.path
11045
11087
  };
11046
11088
  }
11089
+ function hasExplicitNonExactPluginVersion(spec) {
11090
+ if (!spec.startsWith(`${PACKAGE_NAME}@`))
11091
+ return false;
11092
+ return !isValidSemver(spec.slice(PACKAGE_NAME.length + 1));
11093
+ }
11094
+ function isExactOrBarePluginSpec(spec) {
11095
+ return spec === PACKAGE_NAME || spec.startsWith(`${PACKAGE_NAME}@`) && !hasExplicitNonExactPluginVersion(spec);
11096
+ }
11047
11097
  function configUpdateContent(content, version) {
11048
11098
  const parsed = parseJsonConfig(content);
11049
11099
  if (!parsed)
11050
11100
  return null;
11051
11101
  const entries = getPluginEntries(parsed);
11052
11102
  const current = entries.find((entry) => entry === PACKAGE_NAME || entry.startsWith(`${PACKAGE_NAME}@`));
11053
- if (!current)
11103
+ if (!current || !isExactOrBarePluginSpec(current))
11054
11104
  return null;
11055
11105
  const escaped = current.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
11056
11106
  const entryRegex = new RegExp(`(["'])${escaped}\\1`);
@@ -11368,6 +11418,12 @@ async function runBackgroundUpdateCheck(ctx, options) {
11368
11418
  log("[auto-update-checker] Plugin not found in config");
11369
11419
  return;
11370
11420
  }
11421
+ if (hasExplicitNonExactPluginVersion(pluginInfo.entry)) {
11422
+ if (pluginInfo.entry === `${PACKAGE_NAME}@latest`) {
11423
+ log("[auto-update-checker] Explicit @latest leaves the active package unpinned; OpenCode may delete it mid-session.");
11424
+ }
11425
+ return;
11426
+ }
11371
11427
  const cachedVersion = getCachedVersion(pluginInfo.entry);
11372
11428
  const currentVersion = cachedVersion ?? pluginInfo.pinnedVersion;
11373
11429
  if (!currentVersion) {
@@ -11423,6 +11479,7 @@ function createLiveSessionState() {
11423
11479
  liveModelBySession: new Map,
11424
11480
  variantBySession: new Map,
11425
11481
  agentBySession: new Map,
11482
+ channel1StateBySession: new Map,
11426
11483
  historyRefreshSessions: new Set,
11427
11484
  deferredHistoryRefreshSessions: new Set,
11428
11485
  systemPromptRefreshSessions: new Set,
@@ -11566,6 +11623,7 @@ class SubcModuleTransport {
11566
11623
  return error;
11567
11624
  }
11568
11625
  async beforeDeadline(operation, deadlineMs, detail) {
11626
+ operation.catch(() => {});
11569
11627
  const remainingMs = deadlineMs - Date.now();
11570
11628
  if (remainingMs <= 0)
11571
11629
  throw this.deadlineError(detail);
@@ -12700,6 +12758,34 @@ function assertManifestCoversExactly(ids, expectedIds, rootName) {
12700
12758
  throw new Error(`${rootName} manifest missing id ${id}`);
12701
12759
  }
12702
12760
  }
12761
+ var OPEN_TAG_RE = /<([A-Za-z][\w:-]*)\b/;
12762
+ function describeUnrecognizedManifestShape(text, expectedRoot, expectedEntry) {
12763
+ const expected = `expected <${expectedRoot}> with <${expectedEntry}> entries`;
12764
+ const trimmed = text.trim();
12765
+ if (trimmed.startsWith("[") || trimmed.startsWith("{")) {
12766
+ return `JSON ${trimmed.startsWith("[") ? "array" : "object"} unrecognized; ${expected}`;
12767
+ }
12768
+ const firstTag = OPEN_TAG_RE.exec(trimmed)?.[1];
12769
+ if (firstTag && firstTag.toLowerCase() !== expectedRoot.toLowerCase()) {
12770
+ return `root <${firstTag}> unrecognized; ${expected}`;
12771
+ }
12772
+ const escapedRoot = expectedRoot.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
12773
+ const bodyMatch = new RegExp(`<${escapedRoot}\\b[^>]*>([\\s\\S]*?)<\\/${escapedRoot}>`, "i").exec(text);
12774
+ const body = (bodyMatch?.[1] ?? "").trim();
12775
+ if (body.startsWith("[") || body.startsWith("{")) {
12776
+ return `JSON ${body.startsWith("[") ? "array" : "object"} unrecognized; ${expected}`;
12777
+ }
12778
+ const innerTag = OPEN_TAG_RE.exec(body)?.[1];
12779
+ if (innerTag && innerTag.toLowerCase() !== expectedEntry.toLowerCase()) {
12780
+ return `root <${innerTag}> unrecognized; ${expected}`;
12781
+ }
12782
+ return `parsed zero entries; ${expected}`;
12783
+ }
12784
+ function assertParsedManifestNonEmpty(parsedCount, expectedCount, text, expectedRoot, expectedEntry) {
12785
+ if (expectedCount > 0 && parsedCount === 0) {
12786
+ throw new Error(describeUnrecognizedManifestShape(text, expectedRoot, expectedEntry));
12787
+ }
12788
+ }
12703
12789
 
12704
12790
  // src/features/magic-context/dreamer/module-apply.ts
12705
12791
  class DreamerModuleBusyError extends Error {
@@ -13731,9 +13817,19 @@ ${renderAnchors(args.anchors ?? [])}### Memory pool to classify
13731
13817
  ${renderPool2(args.memories)}`;
13732
13818
  }
13733
13819
  var SCOPES = new Set(["project", "ecosystem", "universe"]);
13820
+ function classifyBody(text) {
13821
+ try {
13822
+ return extractCompleteManifestBody(text, "classify");
13823
+ } catch (error) {
13824
+ const described = describeUnrecognizedManifestShape(text, "classify", "memory");
13825
+ if (!described.startsWith("parsed zero entries"))
13826
+ throw new Error(described);
13827
+ throw error;
13828
+ }
13829
+ }
13734
13830
  function parseClassifyManifest(text) {
13735
13831
  const out = [];
13736
- const body = extractCompleteManifestBody(text, "classify");
13832
+ const body = classifyBody(text);
13737
13833
  for (const m of body.matchAll(/<memory\b([^>]*)\/?>/g)) {
13738
13834
  const attrs = m[1];
13739
13835
  const idMatch = attrs.match(/\bid\s*=\s*"(\d+)"/);
@@ -13766,9 +13862,18 @@ function parseClassifyManifest(text) {
13766
13862
  }
13767
13863
  out.push(entry);
13768
13864
  }
13865
+ if (out.length === 0 && body.trim().length > 0) {
13866
+ throw new Error(describeUnrecognizedManifestShape(text, "classify", "memory"));
13867
+ }
13769
13868
  assertNoDuplicateManifestIds(out.map((entry) => entry.id), "classify");
13770
13869
  return out;
13771
13870
  }
13871
+ function validateClassifyManifest(text, expectedIds) {
13872
+ const parsed = parseClassifyManifest(text);
13873
+ assertParsedManifestNonEmpty(parsed.length, expectedIds.size, text, "classify", "memory");
13874
+ assertManifestCoversExactly(parsed.map((entry) => entry.id), expectedIds, "classify");
13875
+ return parsed;
13876
+ }
13772
13877
 
13773
13878
  // src/features/magic-context/dreamer/classify.ts
13774
13879
  var MIN_POOL_TO_CLASSIFY = 10;
@@ -13967,7 +14072,7 @@ async function classifyOneChunk(args, chunk, anchors, sliceMs, signal) {
13967
14072
  if (!text)
13968
14073
  throw new Error("classify returned no output");
13969
14074
  try {
13970
- parseClassifyManifest(text);
14075
+ validateClassifyManifest(text, new Set(chunk.map((candidate) => candidate.id)));
13971
14076
  } catch (error) {
13972
14077
  const providerFailure = providerOutputFailureFromInvalidManifest(messages, text);
13973
14078
  if (providerFailure)
@@ -14035,8 +14140,7 @@ async function runClassifyThroughModule(args, chunk, anchors, signal) {
14035
14140
  if (result.truncated === true) {
14036
14141
  throw new Error("classify returned length-capped output");
14037
14142
  }
14038
- const parsed = parseClassifyManifest(manifestText);
14039
- assertManifestCoversExactly(parsed.map((entry) => entry.id), new Set(chunk.map((candidate) => candidate.id)), "classify");
14143
+ const parsed = validateClassifyManifest(manifestText, new Set(chunk.map((candidate) => candidate.id)));
14040
14144
  const rows = parsed.map((entry) => {
14041
14145
  const candidate = chunk.find((item) => item.id === entry.id);
14042
14146
  if (!candidate)
@@ -15327,6 +15431,63 @@ function backoffMs(failureCount) {
15327
15431
  return minutes * 60 * 1000;
15328
15432
  }
15329
15433
 
15434
+ // src/features/magic-context/smart-notes/wake-plane.ts
15435
+ import { join as join5 } from "node:path";
15436
+ var WAKE_PLANE_CAPABILITY = "wake.create";
15437
+ var WAKE_PLANE_STATUS_TTL_MS = 5 * 60 * 1000;
15438
+ var WAKE_PLANE_HANDSHAKE_TIMEOUT_MS = 2000;
15439
+ var cachedStatus = null;
15440
+ var inFlightProbe = null;
15441
+ var catalogProbe = probeWakePlaneCatalog;
15442
+ var now = () => Date.now();
15443
+ function connectionFile() {
15444
+ return join5(getDataDir(), "cortexkit", "run", "subc-connection.json");
15445
+ }
15446
+ async function probeWakePlaneCatalog() {
15447
+ const file = connectionFile();
15448
+ if (!await connectionFileExists(file)) {
15449
+ throw new Error("subc connection is not configured");
15450
+ }
15451
+ const client = await SubcClient.connect({
15452
+ connectionFile: file,
15453
+ handshakeTimeoutMs: WAKE_PLANE_HANDSHAKE_TIMEOUT_MS
15454
+ });
15455
+ try {
15456
+ return await client.catalogList();
15457
+ } finally {
15458
+ client.close();
15459
+ }
15460
+ }
15461
+ function catalogHasWakePlane(entries) {
15462
+ return entries.some((entry) => Array.isArray(entry.control_ops) && entry.control_ops.includes(WAKE_PLANE_CAPABILITY));
15463
+ }
15464
+ async function probeStatus() {
15465
+ try {
15466
+ return catalogHasWakePlane(await catalogProbe()) ? "present" : "absent";
15467
+ } catch {
15468
+ return "unknown";
15469
+ }
15470
+ }
15471
+ async function wakePlaneStatus() {
15472
+ const cached = cachedStatus;
15473
+ if (cached && now() < cached.expiresAt)
15474
+ return cached.status;
15475
+ if (inFlightProbe)
15476
+ return await inFlightProbe;
15477
+ const startedAt = now();
15478
+ const probe = probeStatus().then((status) => {
15479
+ cachedStatus = { status, expiresAt: startedAt + WAKE_PLANE_STATUS_TTL_MS };
15480
+ return status;
15481
+ });
15482
+ inFlightProbe = probe;
15483
+ try {
15484
+ return await probe;
15485
+ } finally {
15486
+ if (inFlightProbe === probe)
15487
+ inFlightProbe = null;
15488
+ }
15489
+ }
15490
+
15330
15491
  // src/features/magic-context/smart-notes/runner.ts
15331
15492
  function inferEvaluateSmartNotesLeaseHeld(db, projectIdentity) {
15332
15493
  const leaseKey = leaseKeyFor("evaluate-smart-notes", projectIdentity);
@@ -15339,9 +15500,12 @@ var DEFAULT_MAX_CHECKS = 10;
15339
15500
  var DEFAULT_SWEEP_BUDGET_MS = 15000;
15340
15501
  var MAX_FAILURES_BEFORE_REAUTHOR = 3;
15341
15502
  async function runDueCompiledSmartNoteChecks(args) {
15503
+ if (await wakePlaneStatus() === "present") {
15504
+ return { ran: 0, surfaced: 0, failed: 0, networkFailed: 0 };
15505
+ }
15342
15506
  const startedAt = Date.now();
15343
- const now = args.now ?? startedAt;
15344
- const due = getDueCompiledSmartNoteChecks(args.db, args.projectIdentity, now, args.maxChecks ?? DEFAULT_MAX_CHECKS, args.retinaHandoff);
15507
+ const now2 = args.now ?? startedAt;
15508
+ const due = getDueCompiledSmartNoteChecks(args.db, args.projectIdentity, now2, args.maxChecks ?? DEFAULT_MAX_CHECKS, args.retinaHandoff);
15345
15509
  let ran = 0;
15346
15510
  let surfaced = 0;
15347
15511
  let failed = 0;
@@ -15468,6 +15632,11 @@ function createPromptAbortSignal(parent, timeoutMs, timeoutMessage) {
15468
15632
  };
15469
15633
  }
15470
15634
  async function evaluateSmartNotes(args) {
15635
+ if (await wakePlaneStatus() === "present") {
15636
+ const pending = getPendingSmartNotes(args.db, args.projectIdentity).length;
15637
+ log("[dreamer] evaluate-smart-notes: skipped (wake plane active)");
15638
+ return { surfaced: 0, pending, ran: false };
15639
+ }
15471
15640
  const projectRoot = args.sessionDirectory ?? args.projectIdentity;
15472
15641
  const moduleBridge = getModuleNoteEvaluationBridge(args.projectIdentity);
15473
15642
  await moduleBridge?.sync();
@@ -15559,7 +15728,7 @@ async function evaluateSmartNotes(args) {
15559
15728
  assertLeaseHeld("fallback start");
15560
15729
  didWork = true;
15561
15730
  const met = await confirmReadOnly(args, note.id, note.content, note.surfaceCondition, leaseAbortController.signal);
15562
- const now = Date.now();
15731
+ const now2 = Date.now();
15563
15732
  assertLeaseHeld("fallback commit");
15564
15733
  const committed = commitSmartNoteState(args.db, {
15565
15734
  phase: "fallback",
@@ -15570,7 +15739,7 @@ async function evaluateSmartNotes(args) {
15570
15739
  markNoteReady(args.db, note.id, `Smart note #${note.id}: read-only confirmation evaluator returned met=true`);
15571
15740
  } else {
15572
15741
  markNoteChecked(args.db, note.id);
15573
- markSmartNoteCheckStatus(args.db, note.id, "fallback", now);
15742
+ markSmartNoteCheckStatus(args.db, note.id, "fallback", now2);
15574
15743
  }
15575
15744
  }
15576
15745
  });
@@ -15601,7 +15770,7 @@ async function compileNote(args, note, projectRoot, assertLeaseHeld, leaseHeld,
15601
15770
  model: args.model,
15602
15771
  fallbackModels: args.fallbackModels
15603
15772
  });
15604
- const now = Date.now();
15773
+ const now2 = Date.now();
15605
15774
  assertLeaseHeld("compile commit");
15606
15775
  if (!result.ok) {
15607
15776
  if (result.cancelled)
@@ -15612,13 +15781,13 @@ async function compileNote(args, note, projectRoot, assertLeaseHeld, leaseHeld,
15612
15781
  expected: sourceRevisionExpectation(note),
15613
15782
  leaseHeld,
15614
15783
  write: () => {
15615
- markSmartNoteCompilationFailure(args.db, note.id, now, MAX_COMPILATION_FAILURES);
15784
+ markSmartNoteCompilationFailure(args.db, note.id, now2, MAX_COMPILATION_FAILURES);
15616
15785
  }
15617
15786
  });
15618
15787
  return false;
15619
15788
  }
15620
15789
  const nextDueAt = nextSmartNoteCheckDueAt(result.checkCron, {
15621
- now,
15790
+ now: now2,
15622
15791
  noteId: note.id,
15623
15792
  hash: result.checkHash
15624
15793
  });
@@ -15634,12 +15803,12 @@ async function compileNote(args, note, projectRoot, assertLeaseHeld, leaseHeld,
15634
15803
  checkHash: result.checkHash,
15635
15804
  checkCron: result.checkCron,
15636
15805
  nextDueAt,
15637
- now
15806
+ now: now2
15638
15807
  });
15639
15808
  if (result.dryRun.met) {
15640
15809
  markNoteReady(args.db, note.id, `Smart note #${note.id}: compiled check returned met=true`);
15641
15810
  } else {
15642
- markCompiledCheckFalse(args.db, note.id, nextDueAt, now);
15811
+ markCompiledCheckFalse(args.db, note.id, nextDueAt, now2);
15643
15812
  }
15644
15813
  }
15645
15814
  });
@@ -15660,9 +15829,9 @@ async function runLivenessCheck(args, note, projectRoot, assertLeaseHeld, leaseH
15660
15829
  });
15661
15830
  if (!result.ok && result.cancelled)
15662
15831
  return false;
15663
- const now = Date.now();
15832
+ const now2 = Date.now();
15664
15833
  const nextDueAt = result.ok && !result.result.met ? nextSmartNoteCheckDueAt(note.checkCron, {
15665
- now,
15834
+ now: now2,
15666
15835
  noteId: note.id,
15667
15836
  hash: note.checkHash
15668
15837
  }) : null;
@@ -15672,13 +15841,13 @@ async function runLivenessCheck(args, note, projectRoot, assertLeaseHeld, leaseH
15672
15841
  expected: compiledCheckExpectation(note, compiledCheck),
15673
15842
  leaseHeld,
15674
15843
  write: () => {
15675
- markSmartNoteLivenessChecked(args.db, note.id, now);
15844
+ markSmartNoteLivenessChecked(args.db, note.id, now2);
15676
15845
  if (result.ok && result.result.met) {
15677
15846
  markNoteReady(args.db, note.id, `Smart note #${note.id}: max-staleness liveness check returned met=true`);
15678
15847
  } else if (result.ok && nextDueAt !== null) {
15679
- markCompiledCheckFalse(args.db, note.id, nextDueAt, now);
15848
+ markCompiledCheckFalse(args.db, note.id, nextDueAt, now2);
15680
15849
  } else if (!result.ok && !result.network) {
15681
- markSmartNoteCheckStatus(args.db, note.id, "failing", now);
15850
+ markSmartNoteCheckStatus(args.db, note.id, "failing", now2);
15682
15851
  }
15683
15852
  }
15684
15853
  });
@@ -15804,7 +15973,7 @@ Output exactly JSON: {"met": false}`;
15804
15973
 
15805
15974
  // src/features/magic-context/dreamer/maintain-docs-protected-enforcement.ts
15806
15975
  import { existsSync as existsSync7, readFileSync as readFileSync5, writeFileSync as writeFileSync3 } from "node:fs";
15807
- import { join as join5 } from "node:path";
15976
+ import { join as join6 } from "node:path";
15808
15977
 
15809
15978
  // src/features/magic-context/dreamer/protected-regions.ts
15810
15979
  var PROTECTED_START_TOKEN = "mc:protected START";
@@ -15905,7 +16074,7 @@ var MAINTAIN_DOCS_SNAPSHOT_FILES = ["ARCHITECTURE.md", "STRUCTURE.md"];
15905
16074
  function snapshotMaintainDocsFiles(docsDir) {
15906
16075
  const snapshot = new Map;
15907
16076
  for (const name of MAINTAIN_DOCS_SNAPSHOT_FILES) {
15908
- const path3 = join5(docsDir, name);
16077
+ const path3 = join6(docsDir, name);
15909
16078
  try {
15910
16079
  if (existsSync7(path3)) {
15911
16080
  snapshot.set(name, readFileSync5(path3, "utf8"));
@@ -15916,7 +16085,7 @@ function snapshotMaintainDocsFiles(docsDir) {
15916
16085
  }
15917
16086
  function enforceMaintainDocsProtectedRegions(args) {
15918
16087
  for (const [fileName, original] of args.snapshot) {
15919
- const path3 = join5(args.docsDir, fileName);
16088
+ const path3 = join6(args.docsDir, fileName);
15920
16089
  try {
15921
16090
  const current = readFileSync5(path3, "utf8");
15922
16091
  const { text, violated } = enforceProtectedRegions(original, current);
@@ -16000,11 +16169,33 @@ For each memory below, find the repo file(s) it makes a claim about, or mark it
16000
16169
  ${list}
16001
16170
  </memories>`;
16002
16171
  }
16172
+ var MEMORY_ELEMENT_PATTERN = "<memory\\b([^>]*)(?:\\/>|>([\\s\\S]*?)<\\/memory>)";
16173
+ var NESTED_FILE_PATTERN = "<file\\b([^>]*)\\/?>";
16174
+ function extractNestedFilePaths(inner) {
16175
+ const files = [];
16176
+ for (const match of inner.matchAll(new RegExp(NESTED_FILE_PATTERN, "gi"))) {
16177
+ const pathMatch = match[1].match(/\bpath\s*=\s*"([^"]+)"/);
16178
+ if (pathMatch)
16179
+ files.push(pathMatch[1].trim());
16180
+ }
16181
+ return files.filter(Boolean);
16182
+ }
16183
+ function mappingsBody(text) {
16184
+ try {
16185
+ return extractCompleteManifestBody(text, "mappings");
16186
+ } catch (error) {
16187
+ const described = describeUnrecognizedManifestShape(text, "mappings", "memory");
16188
+ if (!described.startsWith("parsed zero entries"))
16189
+ throw new Error(described);
16190
+ throw error;
16191
+ }
16192
+ }
16003
16193
  function parseMapMemoriesManifest(text) {
16004
16194
  const out = [];
16005
- const body = extractCompleteManifestBody(text, "mappings");
16006
- for (const m of body.matchAll(/<memory\b([^>]*)\/?>/g)) {
16195
+ const body = mappingsBody(text);
16196
+ for (const m of body.matchAll(new RegExp(MEMORY_ELEMENT_PATTERN, "gi"))) {
16007
16197
  const attrs = m[1];
16198
+ const inner = m[2];
16008
16199
  const idMatch = attrs.match(/\bid\s*=\s*"(\d+)"/);
16009
16200
  if (!idMatch)
16010
16201
  throw new Error("mappings manifest entry missing numeric id");
@@ -16013,24 +16204,67 @@ function parseMapMemoriesManifest(text) {
16013
16204
  throw new Error("mappings manifest entry missing numeric id");
16014
16205
  const independent = /\bindependent\s*=\s*"(?:true|1)"/i.test(attrs);
16015
16206
  const filesMatch = attrs.match(/\bfiles\s*=\s*"([^"]*)"/);
16016
- const files = filesMatch ? filesMatch[1].split(",").map((f) => f.trim()).filter(Boolean) : [];
16017
- out.push({ id, files, independent: independent || files.length === 0 });
16207
+ const attrFiles = filesMatch ? filesMatch[1].split(",").map((f) => f.trim()).filter(Boolean) : [];
16208
+ const nestedFiles = inner ? extractNestedFilePaths(inner) : [];
16209
+ const files = attrFiles.length > 0 ? attrFiles : nestedFiles;
16210
+ if (!independent && files.length === 0) {
16211
+ throw new Error(`mappings manifest entry ${id} has neither files nor independent="true"`);
16212
+ }
16213
+ out.push({
16214
+ id,
16215
+ files: independent && files.length === 0 ? [] : files,
16216
+ independent: independent && files.length === 0
16217
+ });
16218
+ }
16219
+ if (out.length === 0 && body.trim().length > 0) {
16220
+ throw new Error(describeUnrecognizedManifestShape(text, "mappings", "memory"));
16018
16221
  }
16019
16222
  assertNoDuplicateManifestIds(out.map((entry) => entry.id), "mappings");
16020
16223
  return out;
16021
16224
  }
16225
+ function validateMapMemoriesManifest(text, expectedIds) {
16226
+ const parsed = parseMapMemoriesManifest(text);
16227
+ assertParsedManifestNonEmpty(parsed.length, expectedIds.size, text, "mappings", "memory");
16228
+ assertManifestCoversExactly(parsed.map((entry) => entry.id), expectedIds, "mappings");
16229
+ return parsed;
16230
+ }
16022
16231
 
16023
16232
  // src/features/magic-context/dreamer/map-memories.ts
16024
16233
  var MAP_BATCH_SIZE = 80;
16025
- function loadUnmappedInputs(db, projectIdentity, repoDir) {
16234
+ var MAX_INDEPENDENT_REQUEUE_PER_RUN = MAP_BATCH_SIZE;
16235
+ function shouldRequeueIndependentMapping(state, content, repoDir) {
16236
+ if (!state.hasSentinel || state.files.length > 0)
16237
+ return false;
16238
+ return extractMemoryCandidatePaths(content, repoDir).length > 0;
16239
+ }
16240
+ function toMapInput(memory, repoDir) {
16241
+ return {
16242
+ id: memory.id,
16243
+ category: memory.category,
16244
+ content: memory.content,
16245
+ candidates: extractMemoryCandidatePaths(memory.content, repoDir)
16246
+ };
16247
+ }
16248
+ function selectMapMemoryInputs(db, projectIdentity, repoDir) {
16026
16249
  const active = getMemoriesByProject(db, projectIdentity);
16027
- const unmapped = new Set(getUnmappedMemoryIds(db, active.map((m) => m.id)));
16028
- return active.filter((m) => unmapped.has(m.id)).map((m) => ({
16029
- id: m.id,
16030
- category: m.category,
16031
- content: m.content,
16032
- candidates: extractMemoryCandidatePaths(m.content, repoDir)
16033
- }));
16250
+ const activeIds = active.map((m) => m.id);
16251
+ const unmapped = new Set(getUnmappedMemoryIds(db, activeIds));
16252
+ const verifications = getMemoryVerifications(db, activeIds);
16253
+ const unmappedInputs = active.filter((m) => unmapped.has(m.id)).map((m) => toMapInput(m, repoDir));
16254
+ const requeue = [];
16255
+ for (const memory of active) {
16256
+ if (unmapped.has(memory.id))
16257
+ continue;
16258
+ const state = verifications.get(memory.id);
16259
+ if (!state)
16260
+ continue;
16261
+ if (!shouldRequeueIndependentMapping(state, memory.content, repoDir))
16262
+ continue;
16263
+ requeue.push(toMapInput(memory, repoDir));
16264
+ if (requeue.length >= MAX_INDEPENDENT_REQUEUE_PER_RUN)
16265
+ break;
16266
+ }
16267
+ return [...unmappedInputs, ...requeue];
16034
16268
  }
16035
16269
  async function mapMemories(args) {
16036
16270
  const result = {
@@ -16040,7 +16274,7 @@ async function mapMemories(args) {
16040
16274
  remaining: 0,
16041
16275
  complete: true
16042
16276
  };
16043
- const inputs = loadUnmappedInputs(args.db, args.projectIdentity, args.sessionDirectory);
16277
+ const inputs = selectMapMemoryInputs(args.db, args.projectIdentity, args.sessionDirectory);
16044
16278
  if (inputs.length === 0)
16045
16279
  return result;
16046
16280
  const batches = [];
@@ -16119,7 +16353,7 @@ async function mapOneBatch(args, batch, sliceMs, signal) {
16119
16353
  const text = extractLatestAssistantText(messages);
16120
16354
  if (!text)
16121
16355
  throw new Error("map-memories returned no output");
16122
- parseMapMemoriesManifest(text);
16356
+ validateMapMemoriesManifest(text, new Set(batch.map((memory) => memory.id)));
16123
16357
  return text;
16124
16358
  }
16125
16359
  });
@@ -16153,10 +16387,13 @@ async function applyBatchMappings(args, batch, manifestText) {
16153
16387
  return { mapped: 0, independent: 0 };
16154
16388
  const planned = [];
16155
16389
  for (const p of parsed) {
16156
- if (p.independent || p.files.length === 0) {
16390
+ if (p.independent) {
16157
16391
  planned.push({ id: p.id, files: [], independent: true });
16158
16392
  continue;
16159
16393
  }
16394
+ if (p.files.length === 0) {
16395
+ throw new Error(`mapping entry ${p.id} has no files and no independent sentinel`);
16396
+ }
16160
16397
  const normalized = await normalizeVerificationFiles({
16161
16398
  cwd: args.sessionDirectory,
16162
16399
  files: p.files
@@ -16212,10 +16449,10 @@ async function applyBatchMappings(args, batch, manifestText) {
16212
16449
  }
16213
16450
  return { mapped, independent };
16214
16451
  }
16215
- const now = Date.now();
16452
+ const now2 = Date.now();
16216
16453
  runLeaseGuardedWrite(args.db, args.holderId, args.leaseKey, () => {
16217
16454
  for (const item of planned) {
16218
- recordMemoryMapping(args.db, item.id, item.files, now);
16455
+ recordMemoryMapping(args.db, item.id, item.files, now2);
16219
16456
  item.independent ? independent += 1 : mapped += 1;
16220
16457
  }
16221
16458
  });
@@ -16387,7 +16624,7 @@ async function embedMissingCandidates(args, assertLeaseHeld) {
16387
16624
  updatePrimerCandidateEmbedding(args.db, candidates[i].id, vector, batch.modelId);
16388
16625
  }
16389
16626
  }
16390
- function pruneExpiredPrimerCandidatesForProject(db, projectIdentity, now = Date.now(), ttlMs = PRIMER_CANDIDATE_TTL_MS, maxAgeMs = PRIMER_CANDIDATE_MAX_AGE_MS) {
16627
+ function pruneExpiredPrimerCandidatesForProject(db, projectIdentity, now2 = Date.now(), ttlMs = PRIMER_CANDIDATE_TTL_MS, maxAgeMs = PRIMER_CANDIDATE_MAX_AGE_MS) {
16391
16628
  const protectedIds = new Set;
16392
16629
  for (const primer of getActivePrimers(db, projectIdentity)) {
16393
16630
  for (const id of primer.sourceCandidateIds)
@@ -16395,8 +16632,8 @@ function pruneExpiredPrimerCandidatesForProject(db, projectIdentity, now = Date.
16395
16632
  }
16396
16633
  const oldRows = db.prepare(`SELECT id, source_message_time
16397
16634
  FROM primer_candidates
16398
- WHERE project_path = ? AND source_message_time < ?`).all(projectIdentity, now - ttlMs);
16399
- const toDelete = oldRows.filter((row) => !protectedIds.has(row.id) || row.source_message_time < now - maxAgeMs).map((row) => row.id);
16635
+ WHERE project_path = ? AND source_message_time < ?`).all(projectIdentity, now2 - ttlMs);
16636
+ const toDelete = oldRows.filter((row) => !protectedIds.has(row.id) || row.source_message_time < now2 - maxAgeMs).map((row) => row.id);
16400
16637
  if (toDelete.length === 0)
16401
16638
  return 0;
16402
16639
  const stmt = db.prepare("DELETE FROM primer_candidates WHERE id = ? AND project_path = ?");
@@ -17301,9 +17538,22 @@ function attrOf(s, name) {
17301
17538
  function filesOf(s) {
17302
17539
  return (attrOf(s, "files") ?? "").split(",").map((f) => f.trim()).filter(Boolean);
17303
17540
  }
17541
+ function verifyIds(parsed) {
17542
+ return [...parsed.verified, ...parsed.updated, ...parsed.archived].map((entry) => entry.id);
17543
+ }
17544
+ function verifyBody(text) {
17545
+ try {
17546
+ return extractCompleteManifestBody(text, "verify");
17547
+ } catch (error) {
17548
+ const described = describeUnrecognizedManifestShape(text, "verify", "verified");
17549
+ if (!described.startsWith("parsed zero entries"))
17550
+ throw new Error(described);
17551
+ throw error;
17552
+ }
17553
+ }
17304
17554
  function parseVerifyManifest(text) {
17305
17555
  const out = { verified: [], updated: [], archived: [] };
17306
- const body = extractCompleteManifestBody(text, "verify");
17556
+ const body = verifyBody(text);
17307
17557
  for (const m of body.matchAll(/<verified\b([^>]*)\/?>/g)) {
17308
17558
  const id = Number.parseInt(attrOf(m[1], "id") ?? "", 10);
17309
17559
  if (!Number.isInteger(id))
@@ -17322,9 +17572,19 @@ function parseVerifyManifest(text) {
17322
17572
  throw new Error("verify manifest entry missing numeric id");
17323
17573
  out.archived.push({ id, reason: attrOf(m[1], "reason") ?? "" });
17324
17574
  }
17325
- assertNoDuplicateManifestIds([...out.verified, ...out.updated, ...out.archived].map((entry) => entry.id), "verify");
17575
+ if (verifyIds(out).length === 0 && body.trim().length > 0) {
17576
+ throw new Error(describeUnrecognizedManifestShape(text, "verify", "verified"));
17577
+ }
17578
+ assertNoDuplicateManifestIds(verifyIds(out), "verify");
17326
17579
  return out;
17327
17580
  }
17581
+ function validateVerifyManifest(text, expectedIds) {
17582
+ const parsed = parseVerifyManifest(text);
17583
+ const ids = verifyIds(parsed);
17584
+ assertParsedManifestNonEmpty(ids.length, expectedIds.size, text, "verify", "verified");
17585
+ assertManifestCoversExactly(ids, expectedIds, "verify");
17586
+ return parsed;
17587
+ }
17328
17588
 
17329
17589
  // src/features/magic-context/dreamer/verify.ts
17330
17590
  var VERIFY_BATCH_SIZE = 50;
@@ -17476,7 +17736,7 @@ async function verifyOneBatch(args, batch, sliceMs, signal) {
17476
17736
  if (!text)
17477
17737
  throw new Error("verify returned no output");
17478
17738
  try {
17479
- parseVerifyManifest(text);
17739
+ validateVerifyManifest(text, new Set(batch.map((memory) => memory.id)));
17480
17740
  } catch (error) {
17481
17741
  const providerFailure = providerOutputFailureFromInvalidManifest(messages, text);
17482
17742
  if (providerFailure)
@@ -17511,7 +17771,7 @@ async function applyVerifyManifest(args, batch, manifestText) {
17511
17771
  const batchIds = new Set(batch.map((m) => m.id));
17512
17772
  const parsed = parseVerifyManifest(manifestText);
17513
17773
  assertManifestCoversExactly([...parsed.verified, ...parsed.updated, ...parsed.archived].map((entry) => entry.id), batchIds, "verify");
17514
- const now = Date.now();
17774
+ const now2 = Date.now();
17515
17775
  const writes = [];
17516
17776
  for (const v of parsed.verified) {
17517
17777
  const files = await normalizeFiles(args, v.files);
@@ -17598,7 +17858,7 @@ async function applyVerifyManifest(args, batch, manifestText) {
17598
17858
  if (!isPrimaryMutable(memory))
17599
17859
  continue;
17600
17860
  if (w.kind === "verify") {
17601
- recordMemoryVerifications(args.db, w.id, w.files, now);
17861
+ recordMemoryVerifications(args.db, w.id, w.files, now2);
17602
17862
  verified += 1;
17603
17863
  } else if (w.kind === "update") {
17604
17864
  rewriteMemoryContent(args.db, memory, w.content, w.hash);
@@ -17696,6 +17956,18 @@ function loadActiveMemoryPromptMemories(db, projectIdentity) {
17696
17956
  const verificationById = getMemoryVerifications(db, memories.map((memory) => memory.id));
17697
17957
  return memories.map((memory) => toCuratePromptMemory(memory, verificationById));
17698
17958
  }
17959
+ var TEXTUAL_CURATE_TOOL_CALL_PATTERNS = [
17960
+ /\[\s*historical tool call\s*\][\s\S]*?(?:^|\n)\s*name\s*:\s*ctx_memory\b[\s\S]*?(?:^|\n)\s*arguments\s*:/im,
17961
+ /(?:^|\n)\s*name\s*:\s*ctx_memory\b[\s\S]*?(?:^|\n)\s*arguments\s*:/im,
17962
+ /(?:^|\n)\s*(?:```[^\n]*\n\s*)?ctx_memory\s*\(\s*action\s*=/im,
17963
+ /["']name["']\s*:\s*["']ctx_memory["'][\s\S]*?["']arguments["']\s*:/i
17964
+ ];
17965
+ function validateCurateAssistantText(text) {
17966
+ if (TEXTUAL_CURATE_TOOL_CALL_PATTERNS.some((pattern) => pattern.test(text))) {
17967
+ throw new Error("Curate returned an unresolved textual ctx_memory tool call.");
17968
+ }
17969
+ return text;
17970
+ }
17699
17971
  function createDreamTaskExecutor(deps) {
17700
17972
  let parentSessionIdPromise;
17701
17973
  const resolveParentSessionId = () => {
@@ -17766,7 +18038,8 @@ function createDreamTaskExecutor(deps) {
17766
18038
  name: config.task,
17767
18039
  durationMs: Date.now() - startedAt,
17768
18040
  resultChars: 0,
17769
- ...error ? { error } : {},
18041
+ ...status === "failed" && error ? { error } : {},
18042
+ ...extra?.progress ? { progress: extra.progress } : {},
17770
18043
  backlog: (() => {
17771
18044
  const end = extra?.backlogAfter ?? getDreamTaskBacklog(db, projectIdentity, config.task);
17772
18045
  const processed = processedDreamTaskItems(backlogAtStart.pending, end.pending);
@@ -17909,11 +18182,12 @@ function createDreamTaskExecutor(deps) {
17909
18182
  const backlogAfter = config.task === "verify-broad" ? { pending: result.remaining, total: backlogAtStart.total } : undefined;
17910
18183
  if (!result.complete) {
17911
18184
  if (broadProgress && processed > 0) {
17912
- recordRun("completed", broadProgress, {
18185
+ recordRun("completed", null, {
18186
+ progress: broadProgress,
17913
18187
  memoryChanges: computeMemoryDelta(memoryBefore),
17914
18188
  backlogAfter
17915
18189
  });
17916
- return { status: "completed", error: broadProgress };
18190
+ return { status: "completed" };
17917
18191
  }
17918
18192
  const error = incompleteMessage(result.remaining);
17919
18193
  recordRun("failed", error, {
@@ -17922,11 +18196,12 @@ function createDreamTaskExecutor(deps) {
17922
18196
  });
17923
18197
  return { status: "failed", transient: true, error };
17924
18198
  }
17925
- recordRun("completed", broadProgress, {
18199
+ recordRun("completed", null, {
18200
+ progress: broadProgress,
17926
18201
  memoryChanges: computeMemoryDelta(memoryBefore),
17927
18202
  backlogAfter
17928
18203
  });
17929
- return broadProgress ? { status: "completed", error: broadProgress } : { status: "completed" };
18204
+ return { status: "completed" };
17930
18205
  }
17931
18206
  if (config.task === "classify-memories") {
17932
18207
  let moduleArgs;
@@ -18393,7 +18668,7 @@ async function runAgenticTask(config, ctx, helpers) {
18393
18668
  const text = extractLatestAssistantText(messages);
18394
18669
  if (!text)
18395
18670
  throw new Error("Dreamer returned no assistant output.");
18396
- return text;
18671
+ return task === "curate" ? validateCurateAssistantText(text) : text;
18397
18672
  }
18398
18673
  });
18399
18674
  if (leaseLost)
@@ -18431,17 +18706,17 @@ async function runAgenticTask(config, ctx, helpers) {
18431
18706
 
18432
18707
  // src/features/magic-context/dreamer/task-scheduler.ts
18433
18708
  var MAX_TASK_RETRIES = 3;
18434
- function ensureSeeded(db, projectIdentity, config, now) {
18709
+ function ensureSeeded(db, projectIdentity, config, now2) {
18435
18710
  if (getTaskScheduleState(db, projectIdentity, config.task))
18436
18711
  return;
18437
18712
  const legacy = getDreamState(db, `last_dream_at:${projectIdentity}`);
18438
18713
  const legacyLastRun = legacy ? Number(legacy) : null;
18439
18714
  const lastRunAt = legacyLastRun && Number.isFinite(legacyLastRun) ? legacyLastRun : null;
18440
- const nextDueAt = nextDueAtMs(config.schedule, now);
18715
+ const nextDueAt = nextDueAtMs(config.schedule, now2);
18441
18716
  seedTaskScheduleState(db, projectIdentity, config.task, nextDueAt, lastRunAt, config.schedule);
18442
18717
  }
18443
- function reconcileSchedule(db, projectIdentity, config, now) {
18444
- ensureSeeded(db, projectIdentity, config, now);
18718
+ function reconcileSchedule(db, projectIdentity, config, now2) {
18719
+ ensureSeeded(db, projectIdentity, config, now2);
18445
18720
  const stored = getTaskScheduleState(db, projectIdentity, config.task);
18446
18721
  if (!stored || stored.schedule === config.schedule)
18447
18722
  return;
@@ -18456,22 +18731,22 @@ function reconcileSchedule(db, projectIdentity, config, now) {
18456
18731
  writeTaskScheduleState(db, {
18457
18732
  ...stored,
18458
18733
  schedule: config.schedule,
18459
- nextDueAt: nextDueAtMs(config.schedule, now),
18734
+ nextDueAt: nextDueAtMs(config.schedule, now2),
18460
18735
  retryCount: 0
18461
18736
  });
18462
18737
  }
18463
- function planDueTasks(db, projectIdentity, tasks, now) {
18738
+ function planDueTasks(db, projectIdentity, tasks, now2) {
18464
18739
  const pruned = pruneNonCanonicalTaskRows(db, projectIdentity, tasks.map((t) => t.task));
18465
18740
  if (pruned > 0) {
18466
18741
  log(`[dreamer] pruned ${pruned} retired task row(s) for ${projectIdentity}`);
18467
18742
  }
18468
18743
  const due = [];
18469
18744
  for (const config of tasks) {
18470
- reconcileSchedule(db, projectIdentity, config, now);
18745
+ reconcileSchedule(db, projectIdentity, config, now2);
18471
18746
  const state = getTaskScheduleState(db, projectIdentity, config.task);
18472
18747
  if (!state || state.nextDueAt === null)
18473
18748
  continue;
18474
- if (now >= state.nextDueAt) {
18749
+ if (now2 >= state.nextDueAt) {
18475
18750
  due.push({ config, scheduledAt: state.nextDueAt });
18476
18751
  }
18477
18752
  }
@@ -18593,7 +18868,7 @@ async function runDomainGroup(deps, group, cb) {
18593
18868
  }
18594
18869
  }
18595
18870
  async function runManualDream(deps) {
18596
- const now = Date.now();
18871
+ const now2 = Date.now();
18597
18872
  const result = {
18598
18873
  ran: [],
18599
18874
  skippedNoWork: [],
@@ -18620,8 +18895,8 @@ async function runManualDream(deps) {
18620
18895
  result.backlogBefore = getDreamTaskBacklogs(deps.db, deps.projectIdentity, selectedTaskNames);
18621
18896
  result.backlogAfter = { ...result.backlogBefore };
18622
18897
  for (const cfg of selected)
18623
- ensureSeeded(deps.db, deps.projectIdentity, cfg, now);
18624
- const dueAll = selected.map((config) => ({ config, scheduledAt: now }));
18898
+ ensureSeeded(deps.db, deps.projectIdentity, cfg, now2);
18899
+ const dueAll = selected.map((config) => ({ config, scheduledAt: now2 }));
18625
18900
  const gated = [];
18626
18901
  for (const d of dueAll) {
18627
18902
  if (forceGate) {
@@ -18666,8 +18941,8 @@ async function runManualDream(deps) {
18666
18941
  return result;
18667
18942
  }
18668
18943
  async function runDueTasksForProject(deps) {
18669
- const now = deps.now ?? Date.now();
18670
- const due = planDueTasks(deps.db, deps.projectIdentity, deps.tasks, now);
18944
+ const now2 = deps.now ?? Date.now();
18945
+ const due = planDueTasks(deps.db, deps.projectIdentity, deps.tasks, now2);
18671
18946
  if (due.length === 0)
18672
18947
  return 0;
18673
18948
  const gated = [];
@@ -18682,7 +18957,7 @@ async function runDueTasksForProject(deps) {
18682
18957
  if (pass) {
18683
18958
  gated.push(d);
18684
18959
  } else {
18685
- advanceAfterRun(deps.db, deps.projectIdentity, d, now, "skipped", null);
18960
+ advanceAfterRun(deps.db, deps.projectIdentity, d, now2, "skipped", null);
18686
18961
  }
18687
18962
  }
18688
18963
  if (gated.length === 0)
@@ -19669,6 +19944,26 @@ function createCompactionHandler() {
19669
19944
 
19670
19945
  // src/hooks/magic-context/event-resolvers.ts
19671
19946
  var DEFAULT_CONTEXT_LIMIT = 128000;
19947
+ function resolveContextWindowGeometry(providerID, modelID, ctx) {
19948
+ if (!providerID || !modelID)
19949
+ return;
19950
+ const modelKey = resolveModelKey(providerID, modelID);
19951
+ let detected;
19952
+ let detectedLimitProvenance = "unknown";
19953
+ if (ctx?.db && ctx.sessionID) {
19954
+ try {
19955
+ const overflow = getOverflowState(ctx.db, ctx.sessionID, modelKey);
19956
+ if (overflow.detectedContextLimit > 0) {
19957
+ detected = overflow.detectedContextLimit;
19958
+ detectedLimitProvenance = overflow.detectedContextLimitProvenance;
19959
+ }
19960
+ } catch {}
19961
+ }
19962
+ return getSdkWindowGeometry(providerID, modelID, detected, {
19963
+ detectedLimitProvenance,
19964
+ harness: "opencode"
19965
+ });
19966
+ }
19672
19967
  function resolveContextLimit(providerID, modelID, ctx) {
19673
19968
  const modelKey = resolveModelKey(providerID, modelID);
19674
19969
  let detected;
@@ -19711,7 +20006,7 @@ function resolveTrustedContextLimit(providerID, modelID, ctx) {
19711
20006
  if (modelKey && ctx?.db && ctx.sessionID) {
19712
20007
  try {
19713
20008
  const persisted = loadPersistedUsage(ctx.db, ctx.sessionID);
19714
- if (persisted?.lastObservedModelKey === modelKey && isSaneLimit(persisted.lastUsageContextLimit)) {
20009
+ if (persisted !== null && piModelRefToCanonical(persisted.lastObservedModelKey ?? "") === piModelRefToCanonical(modelKey) && isSaneLimit(persisted.lastUsageContextLimit)) {
19715
20010
  return persisted.lastUsageContextLimit;
19716
20011
  }
19717
20012
  } catch {}
@@ -19730,11 +20025,13 @@ function isFinitePositive(v) {
19730
20025
  }
19731
20026
  function* modelKeyLookupOrder(modelKey) {
19732
20027
  const slash = modelKey.indexOf("/");
19733
- const provider = slash >= 0 ? modelKey.slice(0, slash) : "";
20028
+ const providerRefs = slash >= 0 ? modelRefLookupOrder(modelKey) : [];
19734
20029
  let modelId = slash >= 0 ? modelKey.slice(slash + 1) : modelKey;
19735
20030
  while (modelId.length > 0) {
19736
- if (provider)
19737
- yield `${provider}/${modelId}`;
20031
+ for (const providerRef of providerRefs) {
20032
+ const providerSlash = providerRef.indexOf("/");
20033
+ yield `${providerRef.slice(0, providerSlash)}/${modelId}`;
20034
+ }
19738
20035
  yield modelId;
19739
20036
  const lastDash = modelId.lastIndexOf("-");
19740
20037
  if (lastDash <= 0)
@@ -19852,7 +20149,7 @@ function resolveModelKey(providerID, modelID) {
19852
20149
  if (!providerID || !modelID) {
19853
20150
  return;
19854
20151
  }
19855
- return `${providerID}/${modelID}`;
20152
+ return piModelRefToCanonical(`${providerID}/${modelID}`);
19856
20153
  }
19857
20154
  function resolveSessionId(properties) {
19858
20155
  if (typeof properties?.sessionID === "string") {
@@ -20248,6 +20545,44 @@ function createTagger() {
20248
20545
  // src/hooks/magic-context/command-handler.ts
20249
20546
  import { randomUUID as randomUUID2 } from "node:crypto";
20250
20547
 
20548
+ // src/shared/tail-hygiene-status.ts
20549
+ function finiteNumber(value, fallback = 0) {
20550
+ return typeof value === "number" && Number.isFinite(value) ? value : fallback;
20551
+ }
20552
+ function resolveTailHygieneStatus(tsBaseline, rustBaseline) {
20553
+ if (rustBaseline !== undefined && rustBaseline !== null) {
20554
+ const t2 = Math.max(0, finiteNumber(rustBaseline.t));
20555
+ const u2 = Math.min(t2, Math.max(0, finiteNumber(rustBaseline.u)));
20556
+ return {
20557
+ u: u2,
20558
+ t: t2,
20559
+ severity: Math.min(1, Math.max(0, finiteNumber(rustBaseline.severity, u2 / Math.max(t2, 1)))),
20560
+ evaluable: rustBaseline.evaluable === true,
20561
+ generationInvalidated: rustBaseline.generation_invalidated === true,
20562
+ baselineGeneration: Math.max(0, finiteNumber(rustBaseline.baseline_generation)),
20563
+ computedAt: Math.max(0, finiteNumber(rustBaseline.computed_at_ms))
20564
+ };
20565
+ }
20566
+ if (tsBaseline === undefined)
20567
+ return;
20568
+ const t = Math.max(0, tsBaseline.baselineT + tsBaseline.turnDeltaT);
20569
+ const u = Math.min(t, Math.max(0, tsBaseline.baselineU + tsBaseline.turnDeltaU));
20570
+ return {
20571
+ u,
20572
+ t,
20573
+ severity: Math.min(1, Math.max(0, u / Math.max(t, 1))),
20574
+ evaluable: tsBaseline.evaluable && !tsBaseline.generationInvalidated,
20575
+ generationInvalidated: tsBaseline.generationInvalidated,
20576
+ baselineGeneration: Math.max(0, tsBaseline.baselineGeneration),
20577
+ computedAt: Math.max(0, tsBaseline.computedAt)
20578
+ };
20579
+ }
20580
+ function formatTailHygiene(status) {
20581
+ const percentage = (status.severity * 100).toFixed(1);
20582
+ const state = status.evaluable ? "" : " · held until baseline refresh";
20583
+ return `${percentage}% · ${status.u.toLocaleString()} / ${status.t.toLocaleString()} tok${state}`;
20584
+ }
20585
+
20251
20586
  // src/hooks/magic-context/execute-flush.ts
20252
20587
  function executeFlush(db, sessionId) {
20253
20588
  try {
@@ -20688,7 +21023,7 @@ function formatExecuteThreshold(detail, contextLimit) {
20688
21023
  }
20689
21024
  return `${percentage}%${clampNote}`;
20690
21025
  }
20691
- function executeStatus(db, sessionId, protectedTags, executeThresholdPercentageConfig = DEFAULT_EXECUTE_THRESHOLD_PERCENTAGE, liveModelKey, historyBudgetPercentage, commitClusterTrigger, executeThresholdTokens, contextLimit, dreamer) {
21026
+ function executeStatus(db, sessionId, protectedTags, executeThresholdPercentageConfig = DEFAULT_EXECUTE_THRESHOLD_PERCENTAGE, liveModelKey, historyBudgetPercentage, commitClusterTrigger, executeThresholdTokens, contextLimit, dreamer, windowGeometry, tailHygiene) {
20692
21027
  const thresholdDetail = resolveExecuteThresholdDetail(executeThresholdPercentageConfig, liveModelKey, DEFAULT_EXECUTE_THRESHOLD_PERCENTAGE, {
20693
21028
  tokensConfig: executeThresholdTokens,
20694
21029
  contextLimit,
@@ -20743,13 +21078,16 @@ function executeStatus(db, sessionId, protectedTags, executeThresholdPercentageC
20743
21078
  `**Protected tags:** ${protectedTags}`,
20744
21079
  `**Subagent session:** ${meta.isSubagent}`
20745
21080
  ];
21081
+ if (tailHygiene !== undefined) {
21082
+ lines.push("", "### Tail Hygiene", `- Reclaimable / eligible: ${formatTailHygiene(tailHygiene)}`, "- Reasoning is excluded from both terms.");
21083
+ }
20746
21084
  if (dreamer?.backlog && Object.keys(dreamer.backlog).length > 0) {
20747
21085
  lines.push("", "### Dreamer", ...dreamer.progress ? [
20748
21086
  `- Running: ${dreamer.progress.task} — ${dreamer.progress.processed}/${dreamer.progress.total} processed`
20749
21087
  ] : [], ...formatDreamTaskBacklogs(dreamer.backlog).split("\\n"));
20750
21088
  }
20751
21089
  if (meta.lastContextPercentage > 0 || meta.lastInputTokens > 0) {
20752
- lines.push("", "### Context Usage", `- Last percentage: ${meta.lastContextPercentage.toFixed(1)}%`, `- Last input tokens: ${meta.lastInputTokens.toLocaleString()}`, `- Resolved context limit: ${displayContextLimit > 0 ? displayContextLimit.toLocaleString() : "unknown"}`, `- Proactive compartment evaluation: ${proactiveCompartmentTrigger}%`, `- Post-drop target for historian: ${(executeThresholdPercentage * POST_DROP_TARGET_RATIO).toFixed(0)}% (${executeThresholdPercentage}% * ${POST_DROP_TARGET_RATIO})`, `- Commit cluster trigger: ${commitClusterTrigger?.enabled !== false ? `enabled (min ${commitClusterTrigger?.min_clusters ?? 3} clusters)` : "disabled"}, tail-size trigger: > 3x compartment budget`);
21090
+ lines.push("", "### Context Usage", `- Last percentage: ${meta.lastContextPercentage.toFixed(1)}%`, `- Last input tokens: ${meta.lastInputTokens.toLocaleString()}`, `- Resolved context limit: ${displayContextLimit > 0 ? displayContextLimit.toLocaleString() : "unknown"}`, ...windowGeometry ? [`- ${formatWindowDerivationLine(meta.lastInputTokens, windowGeometry)}`] : [], `- Proactive compartment evaluation: ${proactiveCompartmentTrigger}%`, `- Post-drop target for historian: ${(executeThresholdPercentage * POST_DROP_TARGET_RATIO).toFixed(0)}% (${executeThresholdPercentage}% * ${POST_DROP_TARGET_RATIO})`, `- Commit cluster trigger: ${commitClusterTrigger?.enabled !== false ? `enabled (min ${commitClusterTrigger?.min_clusters ?? 3} clusters)` : "disabled"}, tail-size trigger: > 3x compartment budget`);
20753
21091
  }
20754
21092
  const compartments = getCompartments(db, sessionId);
20755
21093
  let historyBlockTokens = 0;
@@ -20907,6 +21245,10 @@ ${summary || "Nothing to compact."}`;
20907
21245
  return `## Magic Wrapup — Skipped
20908
21246
 
20909
21247
  /ctx-wrapup is already running for this session${rounds > 0 ? ` (${rounds} round${rounds === 1 ? "" : "s"} complete)` : ""}. Wait for it to finish, then run /ctx-wrapup again if more history remains.`;
21248
+ case "retryable":
21249
+ return `## Magic Wrapup — Partial
21250
+
21251
+ ${summary || "Wrapup made progress but stopped before the keep watermark."} Run /ctx-wrapup again to continue.`;
20910
21252
  default:
20911
21253
  return `## Magic Wrapup — Failed
20912
21254
 
@@ -21213,10 +21555,14 @@ Embedding status is unavailable.`;
21213
21555
  }
21214
21556
  const liveModelKey = deps.getLiveModelKey?.(sessionId);
21215
21557
  const liveContextLimit = deps.getContextLimit?.(sessionId);
21558
+ const modelSlash = liveModelKey?.indexOf("/") ?? -1;
21559
+ const windowGeometry = liveModelKey && modelSlash > 0 ? resolveContextWindowGeometry(liveModelKey.slice(0, modelSlash), liveModelKey.slice(modelSlash + 1), { db: deps.db, sessionID: sessionId }) : undefined;
21560
+ const rustTailHygiene = rustStatus?.tail_hygiene;
21561
+ const tailHygiene = resolveTailHygieneStatus(deps.getTailHygiene?.(sessionId), rustTailHygiene && typeof rustTailHygiene === "object" ? rustTailHygiene : undefined);
21216
21562
  const statusOutput = executeStatus(deps.db, sessionId, deps.protectedTags, deps.executeThresholdPercentage, liveModelKey, deps.historyBudgetPercentage, deps.commitClusterTrigger, deps.executeThresholdTokens, liveContextLimit, deps.dreamer ? {
21217
21563
  backlog: readDreamTaskBacklogsSafely(deps.db, deps.dreamer.projectPath, CANONICAL_DREAM_TASKS),
21218
21564
  progress: deps.getDreamerProgress?.() ?? null
21219
- } : undefined);
21565
+ } : undefined, windowGeometry, tailHygiene);
21220
21566
  const moduleStatus = rustStatus ? `
21221
21567
 
21222
21568
  ${formatRustStatusText(rustStatus)}` : "";
@@ -21239,7 +21585,7 @@ ${combinedStatus}` : combinedStatus;
21239
21585
 
21240
21586
  ${parsed.message}`;
21241
21587
  } else if (rustMode) {
21242
- const keep = Math.min(100, Math.max(5, parsed.messagesToKeep));
21588
+ const keep = parsed.messagesToKeep;
21243
21589
  await deps.sendNotification(sessionId, `## Magic Wrapup
21244
21590
 
21245
21591
  Starting wrapup…`, {});
@@ -21300,8 +21646,8 @@ ${error instanceof Error ? error.message : String(error)}`;
21300
21646
  } else {
21301
21647
  const argsKey = parsedArgs.kind === "partial" ? `${parsedArgs.range.start}-${parsedArgs.range.end}` : "";
21302
21648
  const lastConfirmation = recompConfirmationBySession.get(sessionId);
21303
- const now = Date.now();
21304
- const confirmationValid = lastConfirmation && now - lastConfirmation.timestamp < RECOMP_CONFIRMATION_WINDOW_MS && lastConfirmation.argsKey === argsKey;
21649
+ const now2 = Date.now();
21650
+ const confirmationValid = lastConfirmation && now2 - lastConfirmation.timestamp < RECOMP_CONFIRMATION_WINDOW_MS && lastConfirmation.argsKey === argsKey;
21305
21651
  if (confirmationValid) {
21306
21652
  recompConfirmationBySession.delete(sessionId);
21307
21653
  if (parsedArgs.kind === "partial") {
@@ -21319,7 +21665,7 @@ Historian recomp started. Rebuilding compartments and facts from raw session his
21319
21665
  }
21320
21666
  } else {
21321
21667
  recompConfirmationBySession.set(sessionId, {
21322
- timestamp: now,
21668
+ timestamp: now2,
21323
21669
  argsKey
21324
21670
  });
21325
21671
  const compartments = getCompartments(deps.db, sessionId);
@@ -21974,187 +22320,279 @@ function writeTransformDecisionRowOnDatabase(db, row, configureBusyTimeout) {
21974
22320
  )`).run(row.sessionId, row.harness, row.sessionId, row.harness, retentionOverrideForTests ?? TRANSFORM_DECISIONS_RETENTION);
21975
22321
  }
21976
22322
 
21977
- // src/hooks/magic-context/channel2-delivery.ts
21978
- import { randomUUID as randomUUID3 } from "node:crypto";
21979
-
21980
- // src/hooks/magic-context/ctx-reduce-nudge.ts
21981
- var CHANNEL1_SENTINEL = "<system-reminder>";
21982
- var TOKENS_PER_BYTE = 0.25;
21983
- var CHANNEL1_FLOOR_TOKENS = 1e4;
21984
- var CHANNEL1_REFIRE_FLOOR_TOKENS = 1e4;
21985
- function channel1RefireTokens(workingWindowTokens) {
21986
- const scaled = Math.round(0.05 * Math.max(0, workingWindowTokens));
21987
- return Math.max(CHANNEL1_REFIRE_FLOOR_TOKENS, scaled);
21988
- }
21989
- var S_GENTLE = 0.2;
21990
- var S_FIRM = 0.4;
21991
- var S_URGENT = 0.65;
21992
- var CHANNEL1_PRESSURE_FLOOR = 0.8;
21993
- var LEVEL_RANK = { gentle: 1, firm: 2, urgent: 3 };
21994
- var DROP_SENTINELS = ["[dropped", "[truncated"];
21995
- function isDroppedToolOutput(output) {
21996
- const head = output.slice(0, 16);
21997
- return DROP_SENTINELS.some((s) => head.startsWith(s));
21998
- }
21999
- function isToolPartWithStringOutput(part) {
22000
- if (part === null || typeof part !== "object")
22001
- return false;
22002
- const p = part;
22003
- if (p.type !== "tool" && p.type !== "tool-invocation")
22004
- return false;
22005
- const state = p.state;
22006
- return typeof state?.output === "string";
22007
- }
22008
- function toolOutputTokens(output) {
22009
- return Math.round(byteSize(output) * TOKENS_PER_BYTE);
22010
- }
22011
- function stringTokens(value) {
22012
- return Math.round(byteSize(value) * TOKENS_PER_BYTE);
22323
+ // src/features/magic-context/window-report-ledger.ts
22324
+ import * as fs from "node:fs";
22325
+ import * as path5 from "node:path";
22326
+ var WINDOW_REPORTS_FILE = "window-reports.jsonl";
22327
+ var ROTATED_WINDOW_REPORTS_FILE = `${WINDOW_REPORTS_FILE}.1`;
22328
+ var WINDOW_REPORTS_ROTATION_BYTES = 16 * 1024 * 1024;
22329
+ var FORWARDING_PROVIDER_IDS = new Set([
22330
+ "302ai",
22331
+ "abacus",
22332
+ "ai-router",
22333
+ "aiand",
22334
+ "aihubmix",
22335
+ "alibaba-cn",
22336
+ "alibaba-coding-plan",
22337
+ "alibaba-coding-plan-cn",
22338
+ "alibaba-token-plan",
22339
+ "alibaba-token-plan-cn",
22340
+ "ambient",
22341
+ "anyapi",
22342
+ "auriko",
22343
+ "azure",
22344
+ "azure-cognitive-services",
22345
+ "baseten",
22346
+ "berget",
22347
+ "blueclaw",
22348
+ "chutes",
22349
+ "clarifai",
22350
+ "cline-pass",
22351
+ "cloudferro-sherlock",
22352
+ "cloudflare-ai-gateway",
22353
+ "cloudflare-workers-ai",
22354
+ "coralbricks",
22355
+ "cortecs",
22356
+ "crof",
22357
+ "crossmodel",
22358
+ "daoxe",
22359
+ "deepinfra",
22360
+ "digitalocean",
22361
+ "dinference",
22362
+ "drun",
22363
+ "empiriolabs",
22364
+ "evroc",
22365
+ "fastrouter",
22366
+ "fireworks-ai",
22367
+ "freemodel",
22368
+ "friendli",
22369
+ "frogbot",
22370
+ "github-copilot",
22371
+ "gmicloud",
22372
+ "google-vertex",
22373
+ "greenpt",
22374
+ "groq",
22375
+ "helicone",
22376
+ "hetzner",
22377
+ "hpc-ai",
22378
+ "huggingface",
22379
+ "hyper",
22380
+ "iflowcn",
22381
+ "impossibl",
22382
+ "inceptron",
22383
+ "inference",
22384
+ "inferx",
22385
+ "infomaniak",
22386
+ "io-net",
22387
+ "jiekou",
22388
+ "kenari",
22389
+ "kilo",
22390
+ "lilac",
22391
+ "llmgateway",
22392
+ "lmstudio",
22393
+ "meganova",
22394
+ "merge-gateway",
22395
+ "mixlayer",
22396
+ "modal",
22397
+ "model-oracle-ai",
22398
+ "modelis",
22399
+ "modelscope",
22400
+ "moonshotai-cn",
22401
+ "nano-gpt",
22402
+ "nearai",
22403
+ "nebius",
22404
+ "neon",
22405
+ "neuralwatt",
22406
+ "novita-ai",
22407
+ "nvidia",
22408
+ "ofox",
22409
+ "opencode",
22410
+ "opencode-go",
22411
+ "openrouter",
22412
+ "orcarouter",
22413
+ "ovhcloud",
22414
+ "perplexity-agent",
22415
+ "pioneer",
22416
+ "poe",
22417
+ "poolside",
22418
+ "privatemode-ai",
22419
+ "qihang-ai",
22420
+ "qiniu-ai",
22421
+ "qvac",
22422
+ "regolo-ai",
22423
+ "requesty",
22424
+ "routing-run",
22425
+ "salad-cloud",
22426
+ "sap-ai-core",
22427
+ "scaleway",
22428
+ "siliconflow",
22429
+ "siliconflow-cn",
22430
+ "snowflake-cortex",
22431
+ "stackit",
22432
+ "subconscious",
22433
+ "submodel",
22434
+ "synthetic",
22435
+ "tencent-coding-plan",
22436
+ "tensorx",
22437
+ "thinkingmachines",
22438
+ "tinfoil",
22439
+ "togetherai",
22440
+ "unorouter",
22441
+ "venice",
22442
+ "vercel",
22443
+ "vivgrid",
22444
+ "vultr",
22445
+ "wandb",
22446
+ "watsonx",
22447
+ "xpersona",
22448
+ "zai",
22449
+ "zai-coding-plan",
22450
+ "zenifra",
22451
+ "zenmux",
22452
+ "zhipuai",
22453
+ "zhipuai-coding-plan"
22454
+ ]);
22455
+ var swallowedWriteCount = 0;
22456
+ var lastErrorMessage = null;
22457
+ function getWindowReportsPath() {
22458
+ return path5.join(getMagicContextStorageDir(), WINDOW_REPORTS_FILE);
22013
22459
  }
22014
- function unknownJsonTokens(value) {
22015
- if (value === undefined || value === null)
22016
- return 0;
22460
+ function recordSwallowedWrite(error) {
22017
22461
  try {
22018
- return stringTokens(JSON.stringify(value));
22019
- } catch {
22020
- return 0;
22021
- }
22462
+ swallowedWriteCount++;
22463
+ lastErrorMessage = error instanceof Error ? error.message : String(error);
22464
+ log("[magic-context] window report ledger write failed:", error);
22465
+ } catch {}
22022
22466
  }
22023
- function textFromPart(part) {
22024
- if (part === null || typeof part !== "object")
22025
- return "";
22026
- const p = part;
22027
- if (typeof p.text === "string")
22028
- return p.text;
22029
- if (typeof p.content === "string")
22030
- return p.content;
22031
- if (typeof p.thinking === "string")
22032
- return p.thinking;
22033
- return "";
22467
+ function positiveFiniteNumber(value) {
22468
+ return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : undefined;
22034
22469
  }
22035
- function computeTailTokenEstimate(messages) {
22036
- let toolOutputTokensTotal = 0;
22037
- let toolCallTokensTotal = 0;
22038
- let conversationTokens = 0;
22039
- for (const message of messages) {
22040
- for (const part of message.parts) {
22041
- if (isToolPartWithStringOutput(part)) {
22042
- const outputTokens = isDroppedToolOutput(part.state.output) ? 0 : toolOutputTokens(part.state.output);
22043
- const inputTokens = unknownJsonTokens(part.state?.input);
22044
- toolOutputTokensTotal += outputTokens;
22045
- toolCallTokensTotal += outputTokens + inputTokens;
22046
- continue;
22047
- }
22048
- conversationTokens += stringTokens(textFromPart(part));
22470
+ function observedStatus(error) {
22471
+ if (!error || typeof error !== "object")
22472
+ return;
22473
+ const candidate = error;
22474
+ for (const value of [candidate.status, candidate.statusCode]) {
22475
+ if (typeof value === "number" && Number.isInteger(value) && value >= 100 && value <= 599) {
22476
+ return value;
22049
22477
  }
22050
22478
  }
22051
- return {
22052
- tailToolTokens: toolOutputTokensTotal,
22053
- liveTailTokens: conversationTokens + toolCallTokensTotal
22054
- };
22479
+ const nested = candidate.response;
22480
+ if (nested && typeof nested === "object") {
22481
+ return observedStatus(nested);
22482
+ }
22483
+ return;
22055
22484
  }
22056
- function decideChannel1(input) {
22057
- const { undroppedTokens, workingWindowTokens, hasRecentReduce } = input;
22058
- const pressure = Math.min(1, Math.max(0, input.pressure));
22059
- const resetCycle = hasRecentReduce || undroppedTokens < input.lastNudgeUndropped;
22060
- const lastNudge = resetCycle ? 0 : input.lastNudgeUndropped;
22061
- const lastLevel = resetCycle ? "" : input.lastNudgeLevel;
22062
- const quiet = () => ({
22063
- fire: false,
22064
- level: "gentle",
22065
- undroppedTokens,
22066
- nextLastNudge: lastNudge,
22067
- nextLastNudgeLevel: lastLevel
22068
- });
22069
- if (hasRecentReduce)
22070
- return quiet();
22071
- if (undroppedTokens < CHANNEL1_FLOOR_TOKENS)
22072
- return quiet();
22073
- if (pressure < CHANNEL1_PRESSURE_FLOOR)
22074
- return quiet();
22075
- const denom = Math.max(input.estimatedInputTokens, 1);
22076
- const severity = Math.min(1, undroppedTokens / denom);
22077
- if (severity < S_GENTLE)
22078
- return quiet();
22079
- let level;
22080
- if (severity >= S_URGENT)
22081
- level = "urgent";
22082
- else if (severity >= S_FIRM)
22083
- level = "firm";
22084
- else
22085
- level = "gentle";
22086
- if (lastLevel === "") {
22087
- if (undroppedTokens < lastNudge + channel1RefireTokens(workingWindowTokens)) {
22088
- return quiet();
22089
- }
22090
- } else if (LEVEL_RANK[level] <= LEVEL_RANK[lastLevel]) {
22091
- return quiet();
22485
+ function observedHeaderHint(headers) {
22486
+ if (!headers || typeof headers !== "object")
22487
+ return;
22488
+ const values = headers;
22489
+ for (const key of ["x-served-by", "x-upstream", "x-backend"]) {
22490
+ const fromGet = typeof values.get === "function" ? values.get(key) : undefined;
22491
+ const value = fromGet ?? values[key] ?? values[key.toUpperCase()];
22492
+ if (typeof value === "string" && value.trim())
22493
+ return value.trim();
22092
22494
  }
22093
- return {
22094
- fire: true,
22095
- level,
22096
- undroppedTokens,
22097
- nextLastNudge: undroppedTokens,
22098
- nextLastNudgeLevel: level
22099
- };
22495
+ return;
22100
22496
  }
22101
- function computePressure(input) {
22102
- const { lastInputTokens, turnToolTokens, contextLimit, executeThresholdPercentage } = input;
22103
- if (contextLimit <= 0 || executeThresholdPercentage <= 0)
22104
- return 0;
22105
- const estimatedInput = lastInputTokens + turnToolTokens;
22106
- const usagePercentage = estimatedInput / contextLimit * 100;
22107
- return usagePercentage / executeThresholdPercentage;
22497
+ function observedErrorBodyHint(error) {
22498
+ if (!error || typeof error !== "object")
22499
+ return;
22500
+ const message = error.message;
22501
+ const body = typeof message === "string" ? message : undefined;
22502
+ const match = body?.match(/(?:served by|upstream|backend)\s*[:=]?\s*([a-z0-9._-]+)/i);
22503
+ return match?.[1];
22504
+ }
22505
+ function observedErrorHint(error) {
22506
+ if (!error || typeof error !== "object")
22507
+ return;
22508
+ const candidate = error;
22509
+ const direct = candidate.served_by ?? candidate.servedBy ?? candidate.upstream ?? candidate.backend;
22510
+ if (typeof direct === "string" && direct.trim())
22511
+ return direct.trim();
22512
+ const headerHint = observedHeaderHint(candidate.headers);
22513
+ if (headerHint)
22514
+ return headerHint;
22515
+ const bodyHint = observedErrorBodyHint(error);
22516
+ if (bodyHint)
22517
+ return bodyHint;
22518
+ const response = candidate.response;
22519
+ if (response && typeof response === "object")
22520
+ return observedErrorHint(response);
22521
+ return;
22108
22522
  }
22109
- function approxThousands(tokens) {
22110
- return `${Math.round(tokens / 1000)}k`;
22523
+ function observedModelVendorHint(modelID) {
22524
+ if (!modelID)
22525
+ return;
22526
+ const slash = modelID.indexOf("/");
22527
+ return slash > 0 ? modelID.slice(0, slash) : undefined;
22111
22528
  }
22112
- function formatOldestReclaimableHint(hint) {
22113
- if (!hint || hint.length === 0)
22114
- return "";
22115
- const rendered = hint.slice(0, 4).map((tag) => `§${tag.tagNumber}§ ${tag.toolName ?? "tool"}`).join(" · ");
22116
- return rendered.length > 0 ? `
22117
- oldest reclaimable: ${rendered}.` : "";
22118
- }
22119
- var CHANNEL2_USABLE_FRACTION = 1 / 3;
22120
- var CHANNEL2_MIN_RECLAIMABLE = 1e4;
22121
- function shouldTriggerChannel2(input) {
22122
- if (input.reclaimableTokens < CHANNEL2_MIN_RECLAIMABLE)
22123
- return false;
22124
- if (input.usableTokens <= 0)
22125
- return true;
22126
- return input.reclaimableTokens >= input.usableTokens * CHANNEL2_USABLE_FRACTION;
22127
- }
22128
- function buildChannel2Reminder(undroppedTokens, hint) {
22129
- const amount = approxThousands(undroppedTokens);
22130
- const hintText = formatOldestReclaimableHint(hint);
22131
- return `<system-reminder>
22132
- ` + `Routine context housekeeping is near: a large span of this session will be comparted soon, ` + `and ~${amount} tokens of tool output remain unreduced. Drop spent outputs with ctx_reduce ` + `first so the archived span is the part that matters.${hintText}
22133
- ` + `</system-reminder>`;
22134
- }
22135
- function buildChannel1Reminder(level, undroppedTokens, hint) {
22136
- const amount = approxThousands(undroppedTokens);
22137
- const hintText = formatOldestReclaimableHint(hint);
22138
- let body;
22139
- switch (level) {
22140
- case "gentle":
22141
- body = `You have ~${amount} tokens of tool output you have not reduced. ` + `When you are done with earlier outputs, dropping them with ctx_reduce keeps context lean.`;
22142
- break;
22143
- case "firm":
22144
- body = `~${amount} tokens of unreduced tool output has built up. ` + `At your next natural stopping point, consider dropping what you have already processed with ctx_reduce.`;
22145
- break;
22146
- case "urgent":
22147
- body = `~${amount} tokens of unreduced tool output remain, and a large span of this session will be comparted before long. ` + `Consider dropping spent outputs with ctx_reduce so the archived span is the part that matters.`;
22148
- break;
22529
+ function readLargestSuccess(db, sessionId, providerID, modelID) {
22530
+ if (!sessionId || !providerID || !modelID)
22531
+ return;
22532
+ const meta = getOrCreateSessionMeta(db, sessionId);
22533
+ return piModelRefToCanonical(meta.lastObservedModelKey ?? "") === piModelRefToCanonical(`${providerID}/${modelID}`) ? positiveFiniteNumber(meta.observedSafeInputTokens) : undefined;
22534
+ }
22535
+ function buildWindowReport(input) {
22536
+ const report = {
22537
+ access_path: "api",
22538
+ geometry: input.reportedLimitProvenance ?? "unknown",
22539
+ observed_at_ms: input.observedAtMs ?? Date.now(),
22540
+ ...input.providerID && FORWARDING_PROVIDER_IDS.has(input.providerID) ? { path_may_forward: true } : {}
22541
+ };
22542
+ if (input.providerID)
22543
+ report.provider_id = input.providerID;
22544
+ if (input.modelID)
22545
+ report.model_id = input.modelID;
22546
+ if (input.matchedPattern)
22547
+ report.matched_pattern = input.matchedPattern;
22548
+ const limit = positiveFiniteNumber(input.reportedLimit);
22549
+ if (limit) {
22550
+ report.extracted_limit = limit;
22551
+ report.extracted_limit_units = "provider";
22552
+ }
22553
+ const attempted = positiveFiniteNumber(input.attemptedTokens);
22554
+ if (attempted) {
22555
+ report.attempted_tokens = attempted;
22556
+ report.attempted_tokens_units = "estimate";
22557
+ }
22558
+ const status = observedStatus(input.error);
22559
+ if (status)
22560
+ report.status = status;
22561
+ const largestSuccess = readLargestSuccess(input.db, input.sessionID, input.providerID, input.modelID);
22562
+ if (largestSuccess) {
22563
+ report.largest_success = largestSuccess;
22564
+ report.largest_success_units = "estimate";
22565
+ }
22566
+ const servedByHint = observedErrorHint(input.error) ?? observedModelVendorHint(input.modelID);
22567
+ if (servedByHint)
22568
+ report.served_by_hint = servedByHint;
22569
+ return report;
22570
+ }
22571
+ function appendWindowReport(report) {
22572
+ try {
22573
+ const reportPath = getWindowReportsPath();
22574
+ fs.mkdirSync(path5.dirname(reportPath), { recursive: true });
22575
+ if (fs.existsSync(reportPath) && fs.statSync(reportPath).size > WINDOW_REPORTS_ROTATION_BYTES) {
22576
+ const rotatedPath = path5.join(path5.dirname(reportPath), ROTATED_WINDOW_REPORTS_FILE);
22577
+ fs.rmSync(rotatedPath, { force: true });
22578
+ fs.renameSync(reportPath, rotatedPath);
22579
+ }
22580
+ fs.appendFileSync(reportPath, `${JSON.stringify(report)}
22581
+ `);
22582
+ } catch (error) {
22583
+ recordSwallowedWrite(error);
22584
+ }
22585
+ }
22586
+ function captureWindowReport(input) {
22587
+ try {
22588
+ appendWindowReport(buildWindowReport(input));
22589
+ } catch (error) {
22590
+ recordSwallowedWrite(error);
22149
22591
  }
22150
- return `
22151
-
22152
- <system-reminder>
22153
- ${body}${hintText}
22154
- </system-reminder>`;
22155
22592
  }
22156
22593
 
22157
22594
  // src/hooks/magic-context/channel2-delivery.ts
22595
+ import { randomUUID as randomUUID3 } from "node:crypto";
22158
22596
  function subagentRunIsActive(deps, sessionId) {
22159
22597
  try {
22160
22598
  const meta = getOrCreateSessionMeta(deps.db, sessionId);
@@ -22197,19 +22635,18 @@ async function maybeDeliverChannel2(sessionId, deps) {
22197
22635
  clearPendingChannel2Intent(deps.db, sessionId);
22198
22636
  return false;
22199
22637
  }
22200
- if (deps.directiveText === undefined && (deps.reclaimableTokens === undefined || deps.usableTokens === undefined)) {
22638
+ const evaluation = evaluateChannel2(deps.baseline);
22639
+ if (deps.directiveText === undefined && !evaluation.evaluable) {
22201
22640
  return false;
22202
22641
  }
22203
- if (deps.directiveText === undefined && !shouldTriggerChannel2({
22204
- reclaimableTokens: deps.reclaimableTokens,
22205
- usableTokens: deps.usableTokens
22206
- })) {
22642
+ if (deps.directiveText === undefined && !evaluation.shouldTrigger) {
22207
22643
  try {
22208
22644
  casChannel2NudgeState(deps.db, sessionId, "pending", "");
22209
- sessionLog(sessionId, `channel2 intent cleared pre-delivery (reclaimable ${deps.reclaimableTokens}, usable ${deps.usableTokens} — trigger no longer holds; re-armable)`);
22645
+ sessionLog(sessionId, `channel2 intent cleared pre-delivery (U ${evaluation.reclaimableTokens}, T ${evaluation.tailTokens} — trigger no longer holds; re-armable)`);
22210
22646
  } catch {}
22211
22647
  return false;
22212
22648
  }
22649
+ const effectiveU = evaluation.reclaimableTokens;
22213
22650
  const client = deps.client;
22214
22651
  if (!client)
22215
22652
  return false;
@@ -22223,7 +22660,7 @@ async function maybeDeliverChannel2(sessionId, deps) {
22223
22660
  }
22224
22661
  try {
22225
22662
  const promptContext = await resolvePromptContext(client, sessionId);
22226
- const reminder = deps.directiveText ?? buildChannel2Reminder(deps.reclaimableTokens, deps.oldestReclaimableToolTags);
22663
+ const reminder = deps.directiveText ?? buildChannel2Reminder(effectiveU, deps.oldestReclaimableToolTags);
22227
22664
  const body = {
22228
22665
  noReply: false,
22229
22666
  parts: [{ type: "text", text: reminder, synthetic: true }]
@@ -22755,7 +23192,7 @@ function replayCavemanCompression(sessionId, db, targets, tags) {
22755
23192
  }
22756
23193
 
22757
23194
  // src/hooks/magic-context/compaction-off-transition.ts
22758
- import { existsSync as existsSync10 } from "node:fs";
23195
+ import { existsSync as existsSync11 } from "node:fs";
22759
23196
  var loggedUnverifiedMarkerCleanupRetry = false;
22760
23197
  var COMPACTION_OFF_FLIP_NOTICE = [
22761
23198
  "## Magic Context — compaction-off mode is now active",
@@ -22790,7 +23227,7 @@ function clearCachedM0Baseline(db, sessionId) {
22790
23227
  return (result.changes ?? 0) > 0;
22791
23228
  }
22792
23229
  function cleanupOffMarkers(sessionId) {
22793
- if (!existsSync10(getOpenCodeDbPath())) {
23230
+ if (!existsSync11(getOpenCodeDbPath())) {
22794
23231
  return { verified: true, removedLineages: 0, removedRows: 0, retainedLineages: 0 };
22795
23232
  }
22796
23233
  return removeMcOwnedCompactionMarkers(sessionId, MARKER_SUMMARY_TEXT);
@@ -22909,156 +23346,6 @@ class EmergencyFailClosedError extends Error {
22909
23346
  }
22910
23347
  }
22911
23348
 
22912
- // src/hooks/magic-context/image-token-estimate.ts
22913
- var IMAGE_TOKEN_DIVISOR = 750;
22914
- var IMAGE_FALLBACK_TOKENS = 1200;
22915
- var IMAGE_TOKEN_CAP = 4500;
22916
- function estimateImageTokensFromDataUrl(url) {
22917
- const comma = url.indexOf(",");
22918
- if (comma < 0)
22919
- return IMAGE_FALLBACK_TOKENS;
22920
- const header = url.slice(0, comma);
22921
- const payload = url.slice(comma + 1);
22922
- const sliceLen = Math.min(512, payload.length);
22923
- const preview = payload.slice(0, sliceLen);
22924
- let bytes;
22925
- try {
22926
- bytes = base64Decode(preview);
22927
- } catch {
22928
- return IMAGE_FALLBACK_TOKENS;
22929
- }
22930
- if (header.includes("image/png")) {
22931
- const dims = parsePngDimensions(bytes);
22932
- if (dims)
22933
- return clampImageTokens(Math.ceil(dims.w * dims.h / IMAGE_TOKEN_DIVISOR));
22934
- } else if (header.includes("image/jpeg") || header.includes("image/jpg")) {
22935
- const dims = parseJpegDimensions(bytes);
22936
- if (dims)
22937
- return clampImageTokens(Math.ceil(dims.w * dims.h / IMAGE_TOKEN_DIVISOR));
22938
- } else if (header.includes("image/webp")) {
22939
- const dims = parseWebpDimensions(bytes);
22940
- if (dims)
22941
- return clampImageTokens(Math.ceil(dims.w * dims.h / IMAGE_TOKEN_DIVISOR));
22942
- } else if (header.includes("image/gif")) {
22943
- const dims = parseGifDimensions(bytes);
22944
- if (dims)
22945
- return clampImageTokens(Math.ceil(dims.w * dims.h / IMAGE_TOKEN_DIVISOR));
22946
- }
22947
- return IMAGE_FALLBACK_TOKENS;
22948
- }
22949
- function clampImageTokens(n) {
22950
- if (n < 1)
22951
- return 1;
22952
- if (n > IMAGE_TOKEN_CAP)
22953
- return IMAGE_TOKEN_CAP;
22954
- return n;
22955
- }
22956
- function base64Decode(b64) {
22957
- const pad = b64.length % 4;
22958
- const padded = pad === 0 ? b64 : b64 + "=".repeat(4 - pad);
22959
- const binary = atob(padded);
22960
- const out = new Uint8Array(binary.length);
22961
- for (let i = 0;i < binary.length; i++)
22962
- out[i] = binary.charCodeAt(i);
22963
- return out;
22964
- }
22965
- function parsePngDimensions(b) {
22966
- if (b.length < 24)
22967
- return null;
22968
- if (b[0] !== 137 || b[1] !== 80 || b[2] !== 78 || b[3] !== 71 || b[4] !== 13 || b[5] !== 10 || b[6] !== 26 || b[7] !== 10)
22969
- return null;
22970
- const w = readUint32BE(b, 16);
22971
- const h = readUint32BE(b, 20);
22972
- if (!w || !h)
22973
- return null;
22974
- return { w, h };
22975
- }
22976
- function parseJpegDimensions(b) {
22977
- if (b.length < 4 || b[0] !== 255 || b[1] !== 216)
22978
- return null;
22979
- let i = 2;
22980
- while (i < b.length - 8) {
22981
- if (b[i] !== 255) {
22982
- i++;
22983
- continue;
22984
- }
22985
- const marker = b[i + 1];
22986
- if (marker === undefined)
22987
- break;
22988
- if (isSofMarker(marker)) {
22989
- const h = b[i + 5] << 8 | b[i + 6];
22990
- const w = b[i + 7] << 8 | b[i + 8];
22991
- if (w && h)
22992
- return { w, h };
22993
- return null;
22994
- }
22995
- if (marker === 216 || marker === 217 || marker === 1) {
22996
- i += 2;
22997
- continue;
22998
- }
22999
- const segLen = b[i + 2] << 8 | b[i + 3];
23000
- if (segLen < 2)
23001
- return null;
23002
- i += 2 + segLen;
23003
- }
23004
- return null;
23005
- }
23006
- function isSofMarker(m) {
23007
- if (m >= 192 && m <= 195)
23008
- return true;
23009
- if (m >= 197 && m <= 199)
23010
- return true;
23011
- if (m >= 201 && m <= 203)
23012
- return true;
23013
- if (m >= 205 && m <= 207)
23014
- return true;
23015
- return false;
23016
- }
23017
- function parseWebpDimensions(b) {
23018
- if (b.length < 30)
23019
- return null;
23020
- if (b[0] !== 82 || b[1] !== 73 || b[2] !== 70 || b[3] !== 70)
23021
- return null;
23022
- if (b[8] !== 87 || b[9] !== 69 || b[10] !== 66 || b[11] !== 80)
23023
- return null;
23024
- const variant = String.fromCharCode(b[12], b[13], b[14], b[15]);
23025
- if (variant === "VP8 ") {
23026
- const w = (b[26] | b[27] << 8) & 16383;
23027
- const h = (b[28] | b[29] << 8) & 16383;
23028
- if (w && h)
23029
- return { w, h };
23030
- } else if (variant === "VP8L") {
23031
- const b0 = b[21];
23032
- const b1 = b[22];
23033
- const b2 = b[23];
23034
- const b3 = b[24];
23035
- const w = 1 + ((b0 | b1 << 8) & 16383);
23036
- const h = 1 + ((b1 >> 6 | b2 << 2 | b3 << 10) & 16383);
23037
- if (w && h)
23038
- return { w, h };
23039
- } else if (variant === "VP8X") {
23040
- const w = 1 + (b[24] | b[25] << 8 | b[26] << 16);
23041
- const h = 1 + (b[27] | b[28] << 8 | b[29] << 16);
23042
- if (w && h)
23043
- return { w, h };
23044
- }
23045
- return null;
23046
- }
23047
- function parseGifDimensions(b) {
23048
- if (b.length < 10)
23049
- return null;
23050
- if (b[0] !== 71 || b[1] !== 73 || b[2] !== 70)
23051
- return null;
23052
- const w = b[6] | b[7] << 8;
23053
- const h = b[8] | b[9] << 8;
23054
- if (!w || !h)
23055
- return null;
23056
- return { w, h };
23057
- }
23058
- function readUint32BE(b, offset) {
23059
- return (b[offset] << 24 | b[offset + 1] << 16 | b[offset + 2] << 8 | b[offset + 3]) >>> 0;
23060
- }
23061
-
23062
23349
  // src/hooks/magic-context/tokenizer-calibration.ts
23063
23350
  var CALIBRATION_TABLE = [
23064
23351
  { prefix: "anthropic/claude-opus-4-8", systemRatio: 1.51, toolsRatio: 1.57 },
@@ -23433,6 +23720,14 @@ function assertOpenAiCompatAdjacency(messages) {
23433
23720
  }
23434
23721
 
23435
23722
  // src/hooks/magic-context/lkg-replay.ts
23723
+ function canonicalLkgModelKeys(modelKey, providerKey) {
23724
+ const canonicalModelKey = modelKey ? piModelRefToCanonical(modelKey) : null;
23725
+ const slash = canonicalModelKey?.indexOf("/") ?? -1;
23726
+ return {
23727
+ modelKey: canonicalModelKey,
23728
+ providerKey: slash > 0 && canonicalModelKey ? canonicalModelKey.slice(0, slash) : providerKey
23729
+ };
23730
+ }
23436
23731
  function resolveLkgModelKeys(messages) {
23437
23732
  for (let index = messages.length - 1;index >= 0; index -= 1) {
23438
23733
  const info = messages[index]?.info;
@@ -23441,13 +23736,13 @@ function resolveLkgModelKeys(messages) {
23441
23736
  const provider2 = nested.providerID;
23442
23737
  const model2 = nested.modelID;
23443
23738
  if (typeof provider2 === "string" && typeof model2 === "string") {
23444
- return { modelKey: `${provider2}/${model2}`, providerKey: provider2 };
23739
+ return canonicalLkgModelKeys(`${provider2}/${model2}`, provider2);
23445
23740
  }
23446
23741
  }
23447
23742
  const provider = info?.providerID;
23448
23743
  const model = info?.modelID;
23449
23744
  if (info?.role === "assistant" && typeof provider === "string" && typeof model === "string") {
23450
- return { modelKey: `${provider}/${model}`, providerKey: provider };
23745
+ return canonicalLkgModelKeys(`${provider}/${model}`, provider);
23451
23746
  }
23452
23747
  }
23453
23748
  return { modelKey: null, providerKey: null };
@@ -23643,13 +23938,14 @@ function captureLkgSlot(args) {
23643
23938
  const built = buildLkgPrefix(args.input, args.output);
23644
23939
  if (!built)
23645
23940
  return false;
23941
+ const modelKeys = canonicalLkgModelKeys(args.modelKey, args.providerKey);
23646
23942
  return captureSlot(args.sessionId, {
23647
23943
  jsonPrefix: built.jsonPrefix,
23648
23944
  inputIdSeq: built.inputIdSeq,
23649
23945
  inputContentDigests: built.inputContentDigests,
23650
23946
  lastInputMessageId: built.anchorMessageId,
23651
- modelKey: args.modelKey,
23652
- providerKey: args.providerKey,
23947
+ modelKey: modelKeys.modelKey,
23948
+ providerKey: modelKeys.providerKey,
23653
23949
  capturedAt: args.capturedAt ?? Date.now()
23654
23950
  });
23655
23951
  }
@@ -23830,7 +24126,9 @@ function replayLkg(args) {
23830
24126
  const slot = getSlot(args.sessionId);
23831
24127
  if (!slot)
23832
24128
  return { ok: false, reason: "lkg_invalidated_reshape" };
23833
- if (slot.modelKey !== args.modelKey || slot.providerKey !== args.providerKey) {
24129
+ const requestedModelKeys = canonicalLkgModelKeys(args.modelKey, args.providerKey);
24130
+ const capturedModelKeys = canonicalLkgModelKeys(slot.modelKey, slot.providerKey);
24131
+ if (capturedModelKeys.modelKey !== requestedModelKeys.modelKey || capturedModelKeys.providerKey !== requestedModelKeys.providerKey) {
23834
24132
  dropSlot(args.sessionId, "lkg_model_mismatch");
23835
24133
  return { ok: false, reason: "lkg_model_mismatch" };
23836
24134
  }
@@ -23858,13 +24156,13 @@ function replayLkg(args) {
23858
24156
  dropSlot(args.sessionId, "lkg_unsafe_seam");
23859
24157
  return { ok: false, reason: "lkg_unsafe_seam" };
23860
24158
  }
23861
- if (!validateLkgSeam(prefix, entry.pristineTail, args.providerKey)) {
24159
+ if (!validateLkgSeam(prefix, entry.pristineTail, requestedModelKeys.providerKey)) {
23862
24160
  dropSlot(args.sessionId, "lkg_seam_invalid");
23863
24161
  return { ok: false, reason: "lkg_seam_invalid" };
23864
24162
  }
23865
24163
  }
23866
24164
  const replayed = [...prefix, ...entry.pristineTail];
23867
- if (args.providerKey === "anthropic" && !validateAnthropicReasoningRuns(replayed)) {
24165
+ if (requestedModelKeys.providerKey === "anthropic" && !validateAnthropicReasoningRuns(replayed)) {
23868
24166
  dropSlot(args.sessionId, "lkg_anthropic_reasoning_run_invalid");
23869
24167
  return { ok: false, reason: "lkg_anthropic_reasoning_run_invalid" };
23870
24168
  }
@@ -23896,7 +24194,7 @@ function createPassOutcome() {
23896
24194
  }
23897
24195
 
23898
24196
  // src/hooks/magic-context/rust-mode-transform.ts
23899
- import { createHash as createHash13 } from "node:crypto";
24197
+ import { createHash as createHash12 } from "node:crypto";
23900
24198
 
23901
24199
  // src/hooks/magic-context/module-state-sync.ts
23902
24200
  import { createHmac, randomUUID as randomUUID5 } from "node:crypto";
@@ -24076,8 +24374,9 @@ function moduleWireBodyBytes(payload) {
24076
24374
  return Buffer.byteLength(JSON.stringify(toFlatModuleWireBody(payload)));
24077
24375
  }
24078
24376
  function buildPagedModuleTransformPayloads(body) {
24079
- if (Buffer.byteLength(JSON.stringify(body)) <= MODULE_PAGE_MAX_BYTES)
24080
- return [body];
24377
+ const unpagedBytes = Buffer.byteLength(JSON.stringify(body));
24378
+ if (unpagedBytes <= MODULE_PAGE_MAX_BYTES)
24379
+ return [{ page: body, bytes: unpagedBytes }];
24081
24380
  const arrayFields = [
24082
24381
  "input",
24083
24382
  "messages",
@@ -24111,7 +24410,7 @@ function buildPagedModuleTransformPayloads(body) {
24111
24410
  };
24112
24411
  if (args.complete)
24113
24412
  Object.assign(page, scalarFields);
24114
- return page;
24413
+ return { page, bytes: Buffer.byteLength(JSON.stringify(page)) };
24115
24414
  };
24116
24415
  const hasItems = (arrays) => Object.values(arrays).some((values) => values.length > 0);
24117
24416
  const serializedItemBytes = (value) => Buffer.byteLength(JSON.stringify(value) ?? "null");
@@ -24213,12 +24512,7 @@ function buildPagedModuleTransformPayloads(body) {
24213
24512
  complete: true,
24214
24513
  arrays: current
24215
24514
  });
24216
- if (pageByteLength({
24217
- index: pages.length,
24218
- total: assumedTotal,
24219
- complete: true,
24220
- arrayBytes: currentBytes
24221
- }) > MODULE_PAGE_MAX_BYTES) {
24515
+ if (finalPage.bytes > MODULE_PAGE_MAX_BYTES) {
24222
24516
  if (!hasItems(current)) {
24223
24517
  throw new Error("module transform scalar tail exceeds the 512 KiB page limit");
24224
24518
  }
@@ -24236,12 +24530,7 @@ function buildPagedModuleTransformPayloads(body) {
24236
24530
  complete: true,
24237
24531
  arrays: current
24238
24532
  });
24239
- if (pageByteLength({
24240
- index: pages.length,
24241
- total: assumedTotal,
24242
- complete: true,
24243
- arrayBytes: currentBytes
24244
- }) > MODULE_PAGE_MAX_BYTES) {
24533
+ if (finalPage.bytes > MODULE_PAGE_MAX_BYTES) {
24245
24534
  throw new Error("module transform scalar tail exceeds the 512 KiB page limit");
24246
24535
  }
24247
24536
  }
@@ -24272,7 +24561,7 @@ function moduleRawBlockMappings(message) {
24272
24561
  blockIndex += 1;
24273
24562
  continue;
24274
24563
  }
24275
- if (type === "reasoning") {
24564
+ if (["reasoning", "thinking", "redacted_thinking"].includes(type)) {
24276
24565
  mappings.push({ blockIndex, partIndex, kind: "reasoning" });
24277
24566
  blockIndex += 1;
24278
24567
  continue;
@@ -24332,12 +24621,31 @@ function encodeOpenCodeMessagesToCk(messages) {
24332
24621
  content.push({
24333
24622
  kind: { type: "text", text: typeof part.text === "string" ? part.text : "" }
24334
24623
  });
24335
- } else if (type === "reasoning") {
24624
+ } else if (type === "reasoning" || type === "thinking") {
24625
+ const signature = typeof part.signature === "string" ? part.signature : undefined;
24336
24626
  content.push({
24337
24627
  kind: {
24338
24628
  type: "reasoning",
24339
- text: typeof part.text === "string" ? part.text : typeof part.thinking === "string" ? part.thinking : ""
24340
- }
24629
+ text: typeof part.text === "string" ? part.text : typeof part.thinking === "string" ? part.thinking : "",
24630
+ ...signature ? { signature } : {}
24631
+ },
24632
+ ...part.cache_control !== undefined ? {
24633
+ provider_extras: {
24634
+ opencode: { cache_control: part.cache_control }
24635
+ }
24636
+ } : {}
24637
+ });
24638
+ } else if (type === "redacted_thinking") {
24639
+ content.push({
24640
+ kind: {
24641
+ type: "redacted_reasoning",
24642
+ data: typeof part.data === "string" ? part.data : typeof part.redacted === "string" ? part.redacted : ""
24643
+ },
24644
+ ...part.cache_control !== undefined ? {
24645
+ provider_extras: {
24646
+ opencode: { cache_control: part.cache_control }
24647
+ }
24648
+ } : {}
24341
24649
  });
24342
24650
  } else if (type === "tool") {
24343
24651
  const state = part.state !== null && typeof part.state === "object" ? part.state : {};
@@ -24393,21 +24701,54 @@ function encodeOpenCodeMessagesToCk(messages) {
24393
24701
  }
24394
24702
 
24395
24703
  // src/hooks/magic-context/module-state-sync.ts
24396
- async function mirrorModuleCompartments(args) {
24704
+ var compartmentMirrorCursors = new Map;
24705
+ function clearCompartmentMirrorCursor(sessionId) {
24706
+ compartmentMirrorCursors.delete(sessionId);
24707
+ }
24708
+ function validateMirrorRow(compartment, afterSequence, maxSequence) {
24709
+ if (!Number.isSafeInteger(compartment.sequence) || compartment.sequence <= afterSequence || compartment.sequence > maxSequence || !Number.isSafeInteger(compartment.start_message) || !Number.isSafeInteger(compartment.end_message) || typeof compartment.start_message_id !== "string" || typeof compartment.end_message_id !== "string" || typeof compartment.title !== "string" || typeof compartment.content !== "string") {
24710
+ throw new Error("module compartment mirror returned an invalid authoritative row");
24711
+ }
24712
+ }
24713
+ function validateMirrorPage(published, maxSequence) {
24714
+ if (!Number.isSafeInteger(published.max_sequence) || published.max_sequence < -1 || maxSequence !== null && published.max_sequence !== maxSequence) {
24715
+ throw new Error("module compartment mirror changed while its authoritative set was read");
24716
+ }
24717
+ }
24718
+ function compartmentMirrorSetChanged(published, cursor) {
24719
+ if (published.set_changed === true)
24720
+ return true;
24721
+ if (published.revert_epoch !== undefined && cursor.lastRevertEpoch !== undefined && published.revert_epoch !== cursor.lastRevertEpoch) {
24722
+ return true;
24723
+ }
24724
+ if (published.compartment_count === 0 && cursor.lastMaxSequence >= 0 && published.compartments.length === 0) {
24725
+ return true;
24726
+ }
24727
+ if (published.compartment_count !== undefined && published.compartments.length === 0 && published.max_sequence === cursor.lastMaxSequence && published.compartment_count !== (cursor.lastCompartmentCount ?? cursor.lastMaxSequence)) {
24728
+ return true;
24729
+ }
24730
+ return false;
24731
+ }
24732
+ function rememberCompartmentMirrorCursor(sessionId, maxSequence, published, authoritativeCount) {
24733
+ compartmentMirrorCursors.set(sessionId, {
24734
+ lastMaxSequence: maxSequence,
24735
+ lastCompartmentCount: published.compartment_count ?? authoritativeCount,
24736
+ lastRevertEpoch: published.revert_epoch
24737
+ });
24738
+ }
24739
+ async function resyncModuleCompartmentsFromAuthoritative(args) {
24397
24740
  const authoritative = [];
24398
24741
  let afterSequence = -1;
24399
24742
  let maxSequence = null;
24743
+ let lastPublished;
24400
24744
  for (;; ) {
24401
24745
  const published = await args.reader.getCompartmentsAfter(args.sessionId, afterSequence);
24402
- if (!Number.isSafeInteger(published.max_sequence) || published.max_sequence < -1 || maxSequence !== null && published.max_sequence !== maxSequence) {
24403
- throw new Error("module compartment mirror changed while its authoritative set was read");
24404
- }
24746
+ validateMirrorPage(published, maxSequence);
24405
24747
  maxSequence ??= published.max_sequence;
24748
+ lastPublished = published;
24406
24749
  let pageAdvanced = false;
24407
24750
  for (const compartment of published.compartments) {
24408
- if (!Number.isSafeInteger(compartment.sequence) || compartment.sequence <= afterSequence || compartment.sequence > maxSequence || !Number.isSafeInteger(compartment.start_message) || !Number.isSafeInteger(compartment.end_message) || typeof compartment.start_message_id !== "string" || typeof compartment.end_message_id !== "string" || typeof compartment.title !== "string" || typeof compartment.content !== "string") {
24409
- throw new Error("module compartment mirror returned an invalid authoritative row");
24410
- }
24751
+ validateMirrorRow(compartment, afterSequence, maxSequence);
24411
24752
  authoritative.push(compartment);
24412
24753
  afterSequence = compartment.sequence;
24413
24754
  pageAdvanced = true;
@@ -24446,17 +24787,36 @@ async function mirrorModuleCompartments(args) {
24446
24787
  legacy = excluded.legacy,
24447
24788
  created_at = excluded.created_at,
24448
24789
  harness = excluded.harness`);
24449
- const now = Date.now();
24790
+ const now2 = Date.now();
24450
24791
  args.db.transaction(() => {
24451
24792
  if (divergentSequence !== undefined) {
24452
24793
  args.db.prepare("DELETE FROM compartments WHERE session_id = ? AND sequence >= ?").run(args.sessionId, divergentSequence);
24453
24794
  }
24454
24795
  for (const compartment of authoritative) {
24455
- upsert.run(args.sessionId, compartment.sequence, compartment.start_message, compartment.end_message, compartment.start_message_id, compartment.end_message_id, compartment.title, compartment.content, compartment.p1 ?? null, compartment.p2 ?? null, compartment.p3 ?? null, compartment.p4 ?? null, compartment.importance ?? 50, compartment.episode_type ?? null, compartment.legacy ?? (compartment.p1 ? 0 : 1), compartment.created_at ?? now, getHarness());
24796
+ upsert.run(args.sessionId, compartment.sequence, compartment.start_message, compartment.end_message, compartment.start_message_id, compartment.end_message_id, compartment.title, compartment.content, compartment.p1 ?? null, compartment.p2 ?? null, compartment.p3 ?? null, compartment.p4 ?? null, compartment.importance ?? 50, compartment.episode_type ?? null, compartment.legacy ?? (compartment.p1 ? 0 : 1), compartment.created_at ?? now2, getHarness());
24456
24797
  }
24457
24798
  })();
24799
+ rememberCompartmentMirrorCursor(args.sessionId, maxSequence, lastPublished ?? { max_sequence: maxSequence, compartments: [] }, authoritative.length);
24458
24800
  return maxSequence;
24459
24801
  }
24802
+ async function mirrorModuleCompartments(args) {
24803
+ const cursor = compartmentMirrorCursors.get(args.sessionId);
24804
+ if (cursor !== undefined) {
24805
+ const published = await args.reader.getCompartmentsAfter(args.sessionId, cursor.lastMaxSequence);
24806
+ validateMirrorPage(published, null);
24807
+ for (const compartment of published.compartments) {
24808
+ validateMirrorRow(compartment, cursor.lastMaxSequence, published.max_sequence);
24809
+ }
24810
+ const firstNew = published.compartments[0];
24811
+ const hasGap = firstNew !== undefined && firstNew.sequence !== cursor.lastMaxSequence + 1;
24812
+ const regressed = published.max_sequence < cursor.lastMaxSequence;
24813
+ const setChanged = compartmentMirrorSetChanged(published, cursor);
24814
+ if (!regressed && !hasGap && !setChanged && published.compartments.length === 0 && published.max_sequence === cursor.lastMaxSequence) {
24815
+ return published.max_sequence;
24816
+ }
24817
+ }
24818
+ return resyncModuleCompartmentsFromAuthoritative(args);
24819
+ }
24460
24820
  function stableHash(value) {
24461
24821
  return createHmac("sha256", "magic-context-shadow-watermark").update(value).digest("hex");
24462
24822
  }
@@ -25304,121 +25664,6 @@ class RawFallbackContextLimitError extends Error {
25304
25664
  }
25305
25665
  }
25306
25666
 
25307
- // src/hooks/magic-context/todo-view.ts
25308
- import { createHash as createHash11 } from "node:crypto";
25309
- var TODO_STATUS_PENDING = "pending";
25310
- var TODO_STATUS_IN_PROGRESS = "in_progress";
25311
- var TODO_STATUS_COMPLETED = "completed";
25312
- var TODO_STATUS_CANCELLED = "cancelled";
25313
- var TODO_PRIORITY_HIGH = "high";
25314
- var TODO_PRIORITY_MEDIUM = "medium";
25315
- var TODO_PRIORITY_LOW = "low";
25316
- var TODO_STATUSES = [
25317
- TODO_STATUS_PENDING,
25318
- TODO_STATUS_IN_PROGRESS,
25319
- TODO_STATUS_COMPLETED,
25320
- TODO_STATUS_CANCELLED
25321
- ];
25322
- var TODO_PRIORITIES = [
25323
- TODO_PRIORITY_HIGH,
25324
- TODO_PRIORITY_MEDIUM,
25325
- TODO_PRIORITY_LOW
25326
- ];
25327
- var TODO_STATUS_SET = new Set(TODO_STATUSES);
25328
- var TODO_PRIORITY_SET = new Set(TODO_PRIORITIES);
25329
- var TERMINAL_STATUSES = new Set([
25330
- TODO_STATUS_COMPLETED,
25331
- TODO_STATUS_CANCELLED
25332
- ]);
25333
- var TITLE_DONE_STATUSES = new Set([TODO_STATUS_COMPLETED]);
25334
- var SYNTHETIC_CALL_ID_PREFIX = "mc_synthetic_todo_";
25335
- function normalizeTodoStateJson(todos) {
25336
- if (!Array.isArray(todos))
25337
- return null;
25338
- const normalized = [];
25339
- for (const todo of todos) {
25340
- if (!isTodoItem(todo))
25341
- return null;
25342
- normalized.push({
25343
- content: todo.content,
25344
- status: todo.status,
25345
- priority: todo.priority ?? TODO_PRIORITY_MEDIUM
25346
- });
25347
- }
25348
- return JSON.stringify(normalized);
25349
- }
25350
- function buildSyntheticTodoPart(stateJson) {
25351
- const todos = parseTodoState(stateJson);
25352
- if (todos === null || todos.length === 0)
25353
- return null;
25354
- if (todos.every((t) => TERMINAL_STATUSES.has(t.status)))
25355
- return null;
25356
- const callID = computeSyntheticCallId(stateJson);
25357
- const activeCount = todos.filter((t) => !TITLE_DONE_STATUSES.has(t.status)).length;
25358
- const output = JSON.stringify(todos, null, 2);
25359
- const ts = 0;
25360
- return {
25361
- type: "tool",
25362
- callID,
25363
- tool: "todowrite",
25364
- state: {
25365
- status: "completed",
25366
- input: { todos },
25367
- output,
25368
- title: `${activeCount} todos`,
25369
- metadata: { todos, truncated: false },
25370
- time: { start: ts, end: ts }
25371
- },
25372
- syntheticTodoMarker: true
25373
- };
25374
- }
25375
- function computeSyntheticCallId(stateJson) {
25376
- const hash = createHash11("sha256").update(stateJson).digest("hex").slice(0, 16);
25377
- return `${SYNTHETIC_CALL_ID_PREFIX}${hash}`;
25378
- }
25379
- function isSyntheticTodoPart(part) {
25380
- if (part === null || typeof part !== "object")
25381
- return false;
25382
- const p = part;
25383
- if (p.syntheticTodoMarker === true)
25384
- return true;
25385
- return p.type === "tool" && p.tool === "todowrite" && typeof p.callID === "string" && p.callID.startsWith(SYNTHETIC_CALL_ID_PREFIX);
25386
- }
25387
- function parseTodoState(stateJson) {
25388
- if (stateJson.length === 0)
25389
- return null;
25390
- try {
25391
- const parsed = JSON.parse(stateJson);
25392
- if (!Array.isArray(parsed))
25393
- return null;
25394
- const result = [];
25395
- for (const item of parsed) {
25396
- if (!isTodoItem(item))
25397
- return null;
25398
- result.push({
25399
- content: item.content,
25400
- status: item.status,
25401
- priority: item.priority ?? TODO_PRIORITY_MEDIUM
25402
- });
25403
- }
25404
- return result;
25405
- } catch {
25406
- return null;
25407
- }
25408
- }
25409
- function isTodoStatus(value) {
25410
- return typeof value === "string" && TODO_STATUS_SET.has(value);
25411
- }
25412
- function isTodoPriority(value) {
25413
- return typeof value === "string" && TODO_PRIORITY_SET.has(value);
25414
- }
25415
- function isTodoItem(value) {
25416
- if (value === null || typeof value !== "object")
25417
- return false;
25418
- const todo = value;
25419
- return typeof todo.content === "string" && isTodoStatus(todo.status) && (todo.priority === undefined || isTodoPriority(todo.priority));
25420
- }
25421
-
25422
25667
  // src/hooks/magic-context/transform-context-state.ts
25423
25668
  function loadPersistedUsageWatermark(db, sessionId) {
25424
25669
  const result = db.prepare("SELECT last_response_time FROM session_meta WHERE session_id = ?").get(sessionId);
@@ -25522,7 +25767,7 @@ function containsProbeVerbatim(text, probes) {
25522
25767
  }
25523
25768
 
25524
25769
  // src/features/magic-context/search-measurement.ts
25525
- import { createHash as createHash12 } from "node:crypto";
25770
+ import { createHash as createHash11 } from "node:crypto";
25526
25771
  function resultId(result) {
25527
25772
  switch (result.source) {
25528
25773
  case "memory":
@@ -25609,7 +25854,7 @@ async function recordShadowMeasurement(args) {
25609
25854
  }
25610
25855
  }
25611
25856
  function sha256(value) {
25612
- return createHash12("sha256").update(value).digest("hex");
25857
+ return createHash11("sha256").update(value).digest("hex");
25613
25858
  }
25614
25859
 
25615
25860
  // src/features/magic-context/search.ts
@@ -26998,6 +27243,21 @@ ${hintText}`;
26998
27243
  }
26999
27244
  function clearAutoSearchForSession(_sessionId) {}
27000
27245
 
27246
+ // src/hooks/magic-context/channel2-cycle.ts
27247
+ function rearmChannel2AfterCoverageAdvancingHardFold(input) {
27248
+ if (input.compactionOff || !input.foldExecuted || input.previousCoverage === null || input.currentCoverage === null || input.currentCoverage <= input.previousCoverage) {
27249
+ return false;
27250
+ }
27251
+ return casChannel2NudgeState(input.db, input.sessionId, "delivered", "");
27252
+ }
27253
+ function rearmChannel2AfterMeasuredCollapse(input) {
27254
+ if (!input.baseline.evaluable || input.baseline.generationInvalidated)
27255
+ return false;
27256
+ if (effectiveTailHygiene(input.baseline).u >= CHANNEL1_FLOOR_TOKENS)
27257
+ return false;
27258
+ return casChannel2NudgeState(input.db, input.sessionId, "delivered", "");
27259
+ }
27260
+
27001
27261
  // src/hooks/magic-context/drop-stale-reduce-calls.ts
27002
27262
  var STALE_TOOL_NAMES = new Set(["ctx_reduce"]);
27003
27263
  function isReduceToolPart(part) {
@@ -27075,126 +27335,9 @@ function dropStaleReduceCalls(messages, frozenIds, options = {}) {
27075
27335
  return { didDrop, newlyStrippedIds };
27076
27336
  }
27077
27337
 
27078
- // src/hooks/magic-context/emergency-drop.ts
27079
- var TARGET_FRACTION = 0.3;
27080
- var TIER_RECENCY_RESERVE = 0.2;
27081
- var EMERGENCY_REARM_MIN_TOKENS = 2000;
27082
- var T1_TOOLS = new Set(["read", "todowrite", "task", "aft_outline", "aft_zoom"]);
27083
- var T2_TOOLS = new Set(["edit", "write", "apply_patch", "grep", "glob", "aft_search"]);
27084
- function normalizeToolName(toolName) {
27085
- if (!toolName)
27086
- return "";
27087
- let name = toolName.toLowerCase();
27088
- if (name.startsWith("mcp_"))
27089
- name = name.slice(4);
27090
- return name;
27091
- }
27092
- function resolveToolTier(toolName) {
27093
- const name = normalizeToolName(toolName);
27094
- if (T1_TOOLS.has(name))
27095
- return 1;
27096
- if (T2_TOOLS.has(name))
27097
- return 2;
27098
- return 3;
27099
- }
27100
- function tagReclaimBytes(tag) {
27101
- return tag.byteSize + tag.inputByteSize + tag.reasoningByteSize;
27102
- }
27103
- function estimateEmergencyDropReclaimTokens(tag) {
27104
- return Math.round(tagReclaimBytes(tag) * TOKENS_PER_BYTE);
27105
- }
27106
- function planEmergencyDrop(input) {
27107
- const {
27108
- tags,
27109
- floorTags,
27110
- maxTag,
27111
- protectedTags,
27112
- currentTotalInputTokens,
27113
- ceilingTokens,
27114
- priorInputSample,
27115
- hasPriorDrop
27116
- } = input;
27117
- const noop = (reason) => ({
27118
- shouldDrop: false,
27119
- tagNumbers: [],
27120
- reclaimTokens: 0,
27121
- reason
27122
- });
27123
- if (!Number.isFinite(ceilingTokens) || ceilingTokens <= 0) {
27124
- return noop("unknown-ceiling");
27125
- }
27126
- if (!Number.isFinite(currentTotalInputTokens) || currentTotalInputTokens <= 0) {
27127
- return noop("unknown-usage");
27128
- }
27129
- if (hasPriorDrop && currentTotalInputTokens === priorInputSample) {
27130
- return noop("same-input-sample (awaiting fresh usage after prior drop)");
27131
- }
27132
- let tailTokens = 0;
27133
- for (const tag of floorTags) {
27134
- if (tag.status !== "active")
27135
- continue;
27136
- tailTokens += estimateEmergencyDropReclaimTokens(tag);
27137
- }
27138
- const fixedFloor = Math.max(currentTotalInputTokens - tailTokens, 0);
27139
- const workingSpan = Math.max(ceilingTokens - fixedFloor, 0);
27140
- const target = fixedFloor + TARGET_FRACTION * workingSpan;
27141
- const reclaimTokens = Math.round(currentTotalInputTokens - target);
27142
- if (reclaimTokens <= EMERGENCY_REARM_MIN_TOKENS) {
27143
- return noop(`reclaim<=min (${reclaimTokens} <= ${EMERGENCY_REARM_MIN_TOKENS})`);
27144
- }
27145
- const protectedCutoff = maxTag - protectedTags;
27146
- const tierActive = { 1: [], 2: [] };
27147
- for (const tag of tags) {
27148
- if (tag.status !== "active" || tag.type !== "tool")
27149
- continue;
27150
- const tier = resolveToolTier(tag.toolName);
27151
- if (tier === 1 || tier === 2)
27152
- tierActive[tier].push(tag.tagNumber);
27153
- }
27154
- const reserved = new Set;
27155
- for (const tier of [1, 2]) {
27156
- const nums = tierActive[tier];
27157
- if (nums.length === 0)
27158
- continue;
27159
- nums.sort((a, b) => b - a);
27160
- const reserveCount = Math.ceil(TIER_RECENCY_RESERVE * nums.length);
27161
- for (let i = 0;i < reserveCount && i < nums.length; i++) {
27162
- reserved.add(nums[i]);
27163
- }
27164
- }
27165
- const byTier = { 1: [], 2: [], 3: [] };
27166
- for (const tag of tags) {
27167
- if (tag.status !== "active" || tag.type !== "tool")
27168
- continue;
27169
- if (tag.tagNumber > protectedCutoff)
27170
- continue;
27171
- const tier = resolveToolTier(tag.toolName);
27172
- if ((tier === 1 || tier === 2) && reserved.has(tag.tagNumber))
27173
- continue;
27174
- byTier[tier].push(tag);
27175
- }
27176
- const selected = [];
27177
- let reclaimed = 0;
27178
- outer:
27179
- for (const tier of [3, 2, 1]) {
27180
- const group = byTier[tier];
27181
- group.sort((a, b) => a.tagNumber - b.tagNumber);
27182
- for (const tag of group) {
27183
- selected.push(tag.tagNumber);
27184
- reclaimed += estimateEmergencyDropReclaimTokens(tag);
27185
- if (reclaimed >= reclaimTokens)
27186
- break outer;
27187
- }
27188
- }
27189
- if (selected.length === 0) {
27190
- return noop("no-candidates");
27191
- }
27192
- return {
27193
- shouldDrop: true,
27194
- tagNumbers: selected,
27195
- reclaimTokens,
27196
- reason: `tiered drop: ${selected.length} tags, reclaim≈${reclaimed}/${reclaimTokens} tokens (floor≈${fixedFloor}, ceiling=${Math.round(ceilingTokens)})`
27197
- };
27338
+ // src/hooks/magic-context/fold-execution-gate.ts
27339
+ function foldExecutesThisPass(foldDue, materialized) {
27340
+ return foldDue && materialized;
27198
27341
  }
27199
27342
 
27200
27343
  // src/hooks/magic-context/system-injection-stripper.ts
@@ -27784,10 +27927,8 @@ var REASONING_IGNORED_PART_TYPES = new Set([
27784
27927
  "compaction"
27785
27928
  ]);
27786
27929
  var REASONING_PART_TYPES = new Set(["reasoning", "thinking", "redacted_thinking"]);
27787
- function stripReasoningFromMergedAssistants(messages, providerID, options) {
27788
- if (providerID !== "anthropic")
27789
- return 0;
27790
- let stripped = 0;
27930
+ function planMergedAssistantReasoningStrip(messages, mutationExemptMessage) {
27931
+ const plan = [];
27791
27932
  let prevRole;
27792
27933
  let keptReasoningInRun = false;
27793
27934
  for (const message of messages) {
@@ -27800,7 +27941,7 @@ function stripReasoningFromMergedAssistants(messages, providerID, options) {
27800
27941
  const firstInRun = prevRole !== "assistant";
27801
27942
  if (firstInRun)
27802
27943
  keptReasoningInRun = false;
27803
- if (message === options?.mutationExemptMessage) {
27944
+ if (message === mutationExemptMessage) {
27804
27945
  prevRole = role;
27805
27946
  continue;
27806
27947
  }
@@ -27817,27 +27958,157 @@ function stripReasoningFromMergedAssistants(messages, providerID, options) {
27817
27958
  continue;
27818
27959
  if (isSentinel(part))
27819
27960
  continue;
27961
+ if (partType === "text" && typeof part.text === "string" && part.text.trim() === "") {
27962
+ continue;
27963
+ }
27820
27964
  if (REASONING_PART_TYPES.has(partType)) {
27821
27965
  keepIndex = i;
27822
27966
  }
27823
27967
  break;
27824
27968
  }
27825
27969
  }
27970
+ const stripIndices = [];
27826
27971
  for (let i = 0;i < message.parts.length; i++) {
27827
27972
  const part = message.parts[i];
27828
27973
  if (!isRecord(part))
27829
27974
  continue;
27830
27975
  if (!REASONING_PART_TYPES.has(part.type))
27831
27976
  continue;
27977
+ if (part.cache_control !== undefined)
27978
+ continue;
27832
27979
  if (i === keepIndex) {
27833
27980
  keptReasoningInRun = true;
27834
27981
  continue;
27835
27982
  }
27836
- message.parts[i] = makeSentinel(part);
27837
- stripped++;
27983
+ stripIndices.push(i);
27838
27984
  }
27985
+ if (stripIndices.length > 0)
27986
+ plan.push({ message, stripIndices });
27839
27987
  prevRole = role;
27840
27988
  }
27989
+ return plan;
27990
+ }
27991
+ var MAX_FROZEN_TRAILING_BLANKS = 1e4;
27992
+ var CANONICAL_BLANK_PART = { type: "text", text: "" };
27993
+ function isSentinelInvisibleTextPart(part) {
27994
+ return isRecord(part) && part.type === "text" && typeof part.text === "string" && part.text.trim() === "";
27995
+ }
27996
+ function isCanonicalBlankPart(part) {
27997
+ return isRecord(part) && Object.keys(part).length === 2 && part.type === "text" && part.text === "";
27998
+ }
27999
+ function trailingBlankKeepCount(decision) {
28000
+ if (decision === "keep")
28001
+ return 1;
28002
+ if (!decision.startsWith("keep:"))
28003
+ return;
28004
+ const countText = decision.slice("keep:".length);
28005
+ if (!/^[1-9]\d*$/.test(countText))
28006
+ return;
28007
+ const count = Number(countText);
28008
+ return Number.isSafeInteger(count) && count > 0 && count <= MAX_FROZEN_TRAILING_BLANKS ? count : undefined;
28009
+ }
28010
+ function findTrailingBlankDecisionCandidates(messages, frozenDecisions, options) {
28011
+ const decisions = [];
28012
+ for (const message of messages) {
28013
+ const id = message.info.id;
28014
+ if (message.info.role !== "assistant" || typeof id !== "string" || id.length === 0) {
28015
+ continue;
28016
+ }
28017
+ let trailingCount = 0;
28018
+ while (trailingCount < message.parts.length && isSentinelInvisibleTextPart(message.parts[message.parts.length - trailingCount - 1])) {
28019
+ trailingCount += 1;
28020
+ }
28021
+ if (trailingCount > MAX_FROZEN_TRAILING_BLANKS && trailingCount < message.parts.length) {
28022
+ continue;
28023
+ }
28024
+ const decision = message.parts.length === 0 || trailingCount === message.parts.length ? "keep" : trailingCount === 0 ? "strip" : trailingCount === 1 ? "keep" : `keep:${trailingCount}`;
28025
+ const frozen = frozenDecisions.get(id);
28026
+ if (frozen !== undefined && (id !== options?.refreshMessageId || frozen === decision)) {
28027
+ continue;
28028
+ }
28029
+ decisions.push([id, decision]);
28030
+ }
28031
+ return decisions;
28032
+ }
28033
+ function applyFrozenTrailingBlankDecisions(messages, newestAssistantId, frozenDecisions) {
28034
+ let mutations = 0;
28035
+ for (let messageIndex = 0;messageIndex < messages.length; messageIndex += 1) {
28036
+ let message = messages[messageIndex];
28037
+ const id = message.info.id;
28038
+ if (message.info.role !== "assistant" || typeof id !== "string")
28039
+ continue;
28040
+ const decision = frozenDecisions.get(id);
28041
+ if (!decision)
28042
+ continue;
28043
+ let lastMeaningfulIndex = message.parts.length - 1;
28044
+ while (lastMeaningfulIndex >= 0 && isSentinelInvisibleTextPart(message.parts[lastMeaningfulIndex])) {
28045
+ lastMeaningfulIndex -= 1;
28046
+ }
28047
+ const replaceParts = (start, deleteCount, insertBlankCount) => {
28048
+ message = { ...message, parts: [...message.parts] };
28049
+ messages[messageIndex] = message;
28050
+ message.parts.splice(start, deleteCount, ...Array.from({ length: insertBlankCount }, () => ({ ...CANONICAL_BLANK_PART })));
28051
+ };
28052
+ if (lastMeaningfulIndex < 0) {
28053
+ if (message.parts.length !== 1 || !isCanonicalBlankPart(message.parts[0])) {
28054
+ mutations += Math.max(1, message.parts.length);
28055
+ replaceParts(0, message.parts.length, 1);
28056
+ }
28057
+ continue;
28058
+ }
28059
+ const trailingCount = message.parts.length - lastMeaningfulIndex - 1;
28060
+ const keepCount = trailingBlankKeepCount(decision);
28061
+ if (keepCount !== undefined) {
28062
+ const blankIndex = lastMeaningfulIndex + 1;
28063
+ const suffixIsCanonical = trailingCount === keepCount && message.parts.slice(blankIndex).every(isCanonicalBlankPart);
28064
+ if (!suffixIsCanonical) {
28065
+ mutations += Math.max(1, trailingCount, keepCount);
28066
+ replaceParts(blankIndex, trailingCount, keepCount);
28067
+ }
28068
+ continue;
28069
+ }
28070
+ if (id === newestAssistantId || trailingCount === 0)
28071
+ continue;
28072
+ const lastMeaningfulPart = message.parts[lastMeaningfulIndex];
28073
+ if (isRecord(lastMeaningfulPart) && REASONING_PART_TYPES.has(lastMeaningfulPart.type)) {
28074
+ const blankIndex = lastMeaningfulIndex + 1;
28075
+ if (trailingCount !== 1 || !isCanonicalBlankPart(message.parts[blankIndex])) {
28076
+ mutations += Math.max(1, trailingCount);
28077
+ replaceParts(blankIndex, trailingCount, 1);
28078
+ }
28079
+ continue;
28080
+ }
28081
+ mutations += trailingCount;
28082
+ replaceParts(lastMeaningfulIndex + 1, trailingCount, 0);
28083
+ }
28084
+ return mutations;
28085
+ }
28086
+ function findMergedReasoningStripCandidateIds(messages, providerID, options) {
28087
+ if (providerID !== "anthropic")
28088
+ return [];
28089
+ const ids = new Set;
28090
+ for (const entry of planMergedAssistantReasoningStrip(messages, options?.mutationExemptMessage)) {
28091
+ const id = entry.message.info.id;
28092
+ if (typeof id === "string" && id.length > 0)
28093
+ ids.add(id);
28094
+ }
28095
+ return [...ids];
28096
+ }
28097
+ function stripReasoningFromMergedAssistants(messages, providerID, options) {
28098
+ if (providerID !== "anthropic")
28099
+ return 0;
28100
+ let stripped = 0;
28101
+ for (const entry of planMergedAssistantReasoningStrip(messages, options?.mutationExemptMessage)) {
28102
+ if (options?.frozenMessageIds) {
28103
+ const id = entry.message.info.id;
28104
+ if (typeof id !== "string" || !options.frozenMessageIds.has(id))
28105
+ continue;
28106
+ }
28107
+ for (const index of entry.stripIndices) {
28108
+ entry.message.parts[index] = makeSentinel(entry.message.parts[index]);
28109
+ stripped++;
28110
+ }
28111
+ }
27841
28112
  return stripped;
27842
28113
  }
27843
28114
  function stripProcessedImages(messages, frozenIds, options) {
@@ -27885,7 +28156,6 @@ function stripProcessedImages(messages, frozenIds, options) {
27885
28156
 
27886
28157
  // src/hooks/magic-context/supersession-reclaim.ts
27887
28158
  var TODOWRITE_KEEP = 1;
27888
- var CTX_REDUCE_KEEP = 5;
27889
28159
  var ZERO_VALUE_META_TOOLS = new Set(["bash_status", "bash_kill"]);
27890
28160
  var CTX_NOTE_ZERO_VALUE_ACTIONS = new Set(["read", "dismiss"]);
27891
28161
  function buildSupersessionReclaimOps(input) {
@@ -28629,8 +28899,6 @@ function resetDegradedCacheCount(sessionId) {
28629
28899
  degradedCacheCountBySession.delete(sessionId);
28630
28900
  }
28631
28901
  function isSyntheticHeadMessage(message) {
28632
- if (message.info.syntheticHead !== true)
28633
- return false;
28634
28902
  if (message.info.id !== undefined)
28635
28903
  return false;
28636
28904
  if (message.info.role !== "user")
@@ -28747,11 +29015,17 @@ async function applyTodoSynthesis(args) {
28747
29015
  return 0;
28748
29016
  }
28749
29017
  function runRustModePostprocess(args) {
28750
- if (!args.fullFeatureMode)
29018
+ if (!args.fullFeatureMode || args.compactionOff)
28751
29019
  return;
28752
29020
  if (args.messages.some((message) => !message || typeof message !== "object" || !isRecord(message.info))) {
28753
29021
  return;
28754
29022
  }
29023
+ reconcileMarkerRepresentation(args.messages, getPersistedCompactionMarkerState(args.db, args.sessionId), {
29024
+ db: args.db,
29025
+ sessionId: args.sessionId,
29026
+ tagger: args.tagger,
29027
+ ctxReduceAvailability: args.ctxReduceAvailability
29028
+ });
28755
29029
  for (const anchor of getNoteNudgeAnchors(args.db, args.sessionId)) {
28756
29030
  appendReminderToUserMessageById(args.messages, anchor.messageId, anchor.text);
28757
29031
  }
@@ -28898,9 +29172,23 @@ function finalizeMessageRepresentation(messages, resolvedProviderID, options) {
28898
29172
  clearedParts = stripClearedReasoning(targetedMessages);
28899
29173
  }
28900
29174
  }
28901
- const mergedReasoningParts = stripReasoningFromMergedAssistants(messages, resolvedProviderID, {
28902
- mutationExemptMessage: options?.reasoningMutationExemptMessage
29175
+ let newestAssistant = options?.reasoningMutationExemptMessage;
29176
+ if (!newestAssistant) {
29177
+ for (let index = messages.length - 1;index >= 0; index -= 1) {
29178
+ const message = messages[index];
29179
+ if (message.info.role !== "assistant")
29180
+ continue;
29181
+ newestAssistant = message;
29182
+ break;
29183
+ }
29184
+ }
29185
+ const mergedReasoningParts = options?.skipMergedReasoningStrip ? 0 : stripReasoningFromMergedAssistants(messages, resolvedProviderID, {
29186
+ mutationExemptMessage: options?.reasoningMutationExemptMessage,
29187
+ frozenMessageIds: options?.mergedReasoningStrippedIds
28903
29188
  });
29189
+ if (!options?.skipTrailingWhitespaceStrip && modelAcceptsEmptyContent(resolvedProviderID)) {
29190
+ applyFrozenTrailingBlankDecisions(messages, typeof newestAssistant?.info.id === "string" ? newestAssistant.info.id : undefined, options?.trailingBlankDecisions ?? new Map);
29191
+ }
28904
29192
  return { clearedParts, mergedReasoningParts };
28905
29193
  }
28906
29194
  async function runPostTransformPhase(args) {
@@ -28925,7 +29213,7 @@ async function runPostTransformPhase(args) {
28925
29213
  const deferredMaterialize = args.canConsumeDeferredLate && deferredMaterializationWasPending;
28926
29214
  const materializationRequested = isExplicitFlush || deferredMaterialize;
28927
29215
  const m0M1EnabledForFold = args.m0M1 !== undefined && (!!args.m0M1.projectPath || !!args.m0M1.projectDirectory) && (args.fullFeatureMode || compactionOff);
28928
- const m0HardFoldThisPass = m0M1EnabledForFold && args.m0M1 ? mustMaterialize({
29216
+ const foldDueDecision = m0M1EnabledForFold && args.m0M1 ? mustMaterialize({
28929
29217
  db: args.db,
28930
29218
  sessionId: args.sessionId,
28931
29219
  state: args.sessionMeta,
@@ -28936,13 +29224,55 @@ async function runPostTransformPhase(args) {
28936
29224
  memoryInjectionBudgetTokens: args.m0M1.memoryInjectionBudgetTokens,
28937
29225
  historyBudgetTokens: args.m0M1.historyBudgetTokens,
28938
29226
  hardSignals: args.m0M1.hardSignals
28939
- }).value : false;
28940
- const bypassCompartmentGate = forceMaterialization || m0HardFoldThisPass;
28941
- const shouldReadPendingOps = !compactionOff && (materializationRequested || args.schedulerDecision === "execute" || forceMaterialization || m0HardFoldThisPass || compartmentRunning);
29227
+ }) : { value: false, reason: null };
29228
+ let foldExecutedThisPass = false;
29229
+ let m0RematerializedThisPass = false;
29230
+ const m0CoverageBeforeFold = args.sessionMeta.cachedM0Bytes === null ? -1 : args.sessionMeta.cachedM0MaxCompartmentSeq;
29231
+ let m0MaterializeReason = null;
29232
+ if (foldDueDecision.value && args.m0M1) {
29233
+ try {
29234
+ const foldResult = injectM0M1({
29235
+ db: args.db,
29236
+ sessionId: args.sessionId,
29237
+ state: args.sessionMeta,
29238
+ projectPath: args.m0M1.projectPath,
29239
+ projectDirectory: args.m0M1.projectDirectory,
29240
+ injectDocs: args.m0M1.injectDocs,
29241
+ memoryInjectionBudgetTokens: args.m0M1.memoryInjectionBudgetTokens,
29242
+ historyBudgetTokens: args.m0M1.historyBudgetTokens,
29243
+ temporalAwareness: args.m0M1.temporalAwareness,
29244
+ isCacheBustingPass: true,
29245
+ hardSignals: args.m0M1.hardSignals,
29246
+ muralEnabled: args.m0M1.muralEnabled,
29247
+ compactionOff
29248
+ });
29249
+ foldExecutedThisPass = foldExecutesThisPass(foldDueDecision.value, foldResult.m0RematerializedThisPass);
29250
+ m0RematerializedThisPass = foldResult.m0RematerializedThisPass;
29251
+ m0MaterializeReason = foldResult.decision.reason;
29252
+ try {
29253
+ rearmChannel2AfterCoverageAdvancingHardFold({
29254
+ db: args.db,
29255
+ sessionId: args.sessionId,
29256
+ foldExecuted: foldExecutedThisPass,
29257
+ compactionOff,
29258
+ previousCoverage: m0CoverageBeforeFold,
29259
+ currentCoverage: args.sessionMeta.cachedM0MaxCompartmentSeq
29260
+ });
29261
+ } catch (error) {
29262
+ sessionLog(args.sessionId, "channel2 fold-cycle reset failed (ignored):", error);
29263
+ }
29264
+ } catch (error) {
29265
+ args.passOutcome?.record("m0-m1-fold-preexecution-degradation");
29266
+ sessionLog(args.sessionId, "transform: m[0] HARD fold pre-execution failed:", getErrorMessage(error));
29267
+ }
29268
+ sessionLog(args.sessionId, `m[0] HARD fold decision: reason=${foldDueDecision.reason ?? "unknown"} executed=${foldExecutedThisPass}`);
29269
+ }
29270
+ const bypassCompartmentGate = forceMaterialization || foldExecutedThisPass;
29271
+ const shouldReadPendingOps = !compactionOff && (materializationRequested || args.schedulerDecision === "execute" || forceMaterialization || foldExecutedThisPass || compartmentRunning);
28942
29272
  const pendingOps = shouldReadPendingOps ? getPendingOps(args.db, args.sessionId) : [];
28943
29273
  const hasPendingUserOps = pendingOps.length > 0;
28944
- const shouldApplyPendingOps = !compactionOff && (args.schedulerDecision === "execute" || materializationRequested || forceMaterialization || m0HardFoldThisPass) && (!compartmentRunning || bypassCompartmentGate);
28945
- const shouldRunHeuristics = !compactionOff && (!compartmentRunning || bypassCompartmentGate) && (materializationRequested || forceMaterialization || m0HardFoldThisPass || emergencyDropEligible || args.schedulerDecision === "execute" && (!alreadyRanThisTurn || !args.fullFeatureMode));
29274
+ const shouldApplyPendingOps = !compactionOff && (args.schedulerDecision === "execute" || materializationRequested || forceMaterialization || foldExecutedThisPass) && (!compartmentRunning || bypassCompartmentGate);
29275
+ const shouldRunHeuristics = !compactionOff && (!compartmentRunning || bypassCompartmentGate) && (materializationRequested || forceMaterialization || foldExecutedThisPass || emergencyDropEligible || args.schedulerDecision === "execute" && (!alreadyRanThisTurn || !args.fullFeatureMode));
28946
29276
  const isCacheBustingPass = shouldApplyPendingOps || shouldRunHeuristics;
28947
29277
  if (isCacheBustingPass && args.client && args.ctxReduceAvailability.callable && !hasLoggedCtxReducePermissionDeny(args.sessionId)) {
28948
29278
  try {
@@ -28958,7 +29288,7 @@ async function runPostTransformPhase(args) {
28958
29288
  const canUseEmptySentinels = modelAcceptsEmptyContent(args.resolvedProviderID);
28959
29289
  if (shouldRunHeuristics) {
28960
29290
  const subagentRerun = !args.fullFeatureMode && alreadyRanThisTurn && args.schedulerDecision === "execute" && !isExplicitFlush && !forceMaterialization;
28961
- const reason = isExplicitFlush ? "explicit_flush" : deferredMaterialize ? "deferred_materialization" : forceMaterialization ? `force_materialization (${args.contextUsage.percentage.toFixed(1)}% >= ${args.forceMaterializationPercentage}%)` : m0HardFoldThisPass && args.schedulerDecision !== "execute" ? `m0_hard_fold (drain folded into known m[0] bust, scheduler=${args.schedulerDecision})` : subagentRerun ? `scheduler_execute_subagent_rerun (pendingOps=${pendingOps.length}, scheduler=${args.schedulerDecision})` : `scheduler_execute (pendingOps=${pendingOps.length}, scheduler=${args.schedulerDecision})`;
29291
+ const reason = isExplicitFlush ? "explicit_flush" : deferredMaterialize ? "deferred_materialization" : forceMaterialization ? `force_materialization (${args.contextUsage.percentage.toFixed(1)}% >= ${args.forceMaterializationPercentage}%)` : foldExecutedThisPass && args.schedulerDecision !== "execute" ? `m0_hard_fold (drain folded into executed m[0] bust, scheduler=${args.schedulerDecision})` : subagentRerun ? `scheduler_execute_subagent_rerun (pendingOps=${pendingOps.length}, scheduler=${args.schedulerDecision})` : `scheduler_execute (pendingOps=${pendingOps.length}, scheduler=${args.schedulerDecision})`;
28962
29292
  sessionLog(args.sessionId, `heuristics WILL RUN — reason=${reason}, context=${args.contextUsage.percentage.toFixed(1)}%, turn=${args.currentTurnId}`);
28963
29293
  }
28964
29294
  if (alreadyRanThisTurn && args.schedulerDecision === "execute" && !materializationRequested && args.fullFeatureMode) {
@@ -28982,8 +29312,6 @@ async function runPostTransformPhase(args) {
28982
29312
  const droppedTokens = 0;
28983
29313
  let emergencyReclaimedTokens = 0;
28984
29314
  let emergency = false;
28985
- let m0RematerializedThisPass = false;
28986
- let m0MaterializeReason = null;
28987
29315
  let m0M1InjectedThisPass = false;
28988
29316
  let prependedMessageCount = 0;
28989
29317
  const reasoningMutatedMessages = new Set;
@@ -28999,7 +29327,7 @@ async function runPostTransformPhase(args) {
28999
29327
  let autoReclaimDidMutateThisPass = false;
29000
29328
  try {
29001
29329
  if (shouldApplyPendingOps) {
29002
- const applyReason = isExplicitFlush ? "explicit_flush" : deferredMaterialize ? "deferred_materialization" : `scheduler_execute (scheduler=${args.schedulerDecision})`;
29330
+ const applyReason = isExplicitFlush ? "explicit_flush" : deferredMaterialize ? "deferred_materialization" : foldExecutedThisPass && args.schedulerDecision !== "execute" ? `m0_hard_fold (drain folded into executed m[0] bust, scheduler=${args.schedulerDecision})` : `scheduler_execute (scheduler=${args.schedulerDecision})`;
29003
29331
  sessionLog(args.sessionId, `pending ops WILL APPLY — reason=${applyReason}, pendingOps=${pendingOps.length}, context=${args.contextUsage.percentage.toFixed(1)}%`);
29004
29332
  const tApply = performance.now();
29005
29333
  pendingOpsDidMutate = applyPendingOperations(args.sessionId, args.db, args.targets, args.protectedTags, undefined, pendingOps);
@@ -29444,7 +29772,7 @@ async function runPostTransformPhase(args) {
29444
29772
  }
29445
29773
  const materializeReason = m0MaterializeReason ?? (explicitMaterializedSuccessfully ? "explicit_flush" : null);
29446
29774
  const materialized = m0RematerializedThisPass || explicitMaterializedSuccessfully || deferredMaterializedSuccessfully;
29447
- const bustedThisPass = args.didMutateFromFlushedStatuses || pendingOpsDidMutate || heuristicOrReasoningDidMutate || autoReclaimDidMutateThisPass || m0RematerializedThisPass || m0M1InjectedThisPass && historyWasConsumedThisPass || historyWasConsumedThisPass;
29775
+ let bustedThisPass = args.didMutateFromFlushedStatuses || pendingOpsDidMutate || heuristicOrReasoningDidMutate || autoReclaimDidMutateThisPass || m0RematerializedThisPass || m0M1InjectedThisPass && historyWasConsumedThisPass || historyWasConsumedThisPass;
29448
29776
  if (reasoningMutationTargetUnknown) {
29449
29777
  const reasoningCandidates = args.reasoningByMessage.size > 0 ? args.reasoningByMessage.keys() : args.messages;
29450
29778
  for (const message of reasoningCandidates) {
@@ -29460,14 +29788,151 @@ async function runPostTransformPhase(args) {
29460
29788
  reasoningMutatedMessages.add(message);
29461
29789
  }
29462
29790
  }
29791
+ const mergedReasoningStrippedIds = new Set;
29792
+ if (canUseEmptySentinels && !compactionOff) {
29793
+ try {
29794
+ for (const id of getMergedReasoningStrippedIds(args.db, args.sessionId)) {
29795
+ mergedReasoningStrippedIds.add(id);
29796
+ }
29797
+ if (isCacheBustingPass) {
29798
+ const candidates = findMergedReasoningStripCandidateIds(args.messages, args.resolvedProviderID, { mutationExemptMessage: reasoningMutationExemptMessage });
29799
+ const newlyDetectedIds = candidates.filter((id) => !mergedReasoningStrippedIds.has(id));
29800
+ if (newlyDetectedIds.length > 0) {
29801
+ const persisted = addMergedReasoningStrippedIds(args.db, args.sessionId, newlyDetectedIds);
29802
+ if (persisted) {
29803
+ for (const id of newlyDetectedIds)
29804
+ mergedReasoningStrippedIds.add(id);
29805
+ bustedThisPass = true;
29806
+ } else {
29807
+ args.passOutcome?.record("merged-reasoning-strip-persistence-failure");
29808
+ sessionLog(args.sessionId, "merged reasoning strip: persistence failed; leaving newly detected assistants intact");
29809
+ }
29810
+ }
29811
+ }
29812
+ } catch (error) {
29813
+ args.passOutcome?.record("merged-reasoning-strip-exception");
29814
+ sessionLog(args.sessionId, "transform failed freezing merged reasoning strip:", error);
29815
+ }
29816
+ }
29817
+ const trailingBlankDecisions = new Map;
29818
+ if (canUseEmptySentinels && !compactionOff) {
29819
+ try {
29820
+ for (const [id, decision] of getTrailingBlankDecisions(args.db, args.sessionId)) {
29821
+ trailingBlankDecisions.set(id, decision);
29822
+ }
29823
+ } catch (error) {
29824
+ args.passOutcome?.record("trailing-blank-decision-load-exception");
29825
+ sessionLog(args.sessionId, "transform failed loading trailing blank decisions:", error);
29826
+ }
29827
+ }
29828
+ const newestAssistantId = typeof reasoningMutationExemptMessage?.info.id === "string" ? reasoningMutationExemptMessage.info.id : undefined;
29463
29829
  const tFinalRepresentation = performance.now();
29464
29830
  const finalRepresentation = finalizeMessageRepresentation(args.messages, args.resolvedProviderID, {
29465
29831
  prependedMessageCount,
29466
29832
  reasoningMutatedMessages,
29467
- reasoningMutationExemptMessage
29833
+ reasoningMutationExemptMessage,
29834
+ mergedReasoningStrippedIds,
29835
+ trailingBlankDecisions,
29836
+ skipMergedReasoningStrip: compactionOff,
29837
+ skipTrailingWhitespaceStrip: compactionOff
29468
29838
  });
29839
+ if (canUseEmptySentinels && !compactionOff) {
29840
+ const detectedCandidates = findTrailingBlankDecisionCandidates(args.messages, trailingBlankDecisions, { refreshMessageId: newestAssistantId });
29841
+ const candidates = isCacheBustingPass ? detectedCandidates : detectedCandidates.filter(([id]) => id === newestAssistantId);
29842
+ if (candidates.length > 0) {
29843
+ try {
29844
+ const persisted = addTrailingBlankDecisions(args.db, args.sessionId, candidates, {
29845
+ overwriteMessageId: newestAssistantId
29846
+ });
29847
+ if (persisted) {
29848
+ const committed = getTrailingBlankDecisions(args.db, args.sessionId);
29849
+ const newlyFrozen = new Map;
29850
+ for (const [id] of candidates) {
29851
+ const decision = committed.get(id);
29852
+ if (!decision)
29853
+ continue;
29854
+ trailingBlankDecisions.set(id, decision);
29855
+ newlyFrozen.set(id, decision);
29856
+ }
29857
+ applyFrozenTrailingBlankDecisions(args.messages, newestAssistantId, newlyFrozen);
29858
+ if (isCacheBustingPass)
29859
+ bustedThisPass = true;
29860
+ } else {
29861
+ args.passOutcome?.record("trailing-blank-decision-persistence-failure");
29862
+ sessionLog(args.sessionId, "trailing blank decision: persistence failed; leaving newly observed assistants intact");
29863
+ }
29864
+ } catch (error) {
29865
+ args.passOutcome?.record("trailing-blank-decision-exception");
29866
+ sessionLog(args.sessionId, "transform failed freezing trailing blank decision:", error);
29867
+ }
29868
+ }
29869
+ }
29469
29870
  sessionLog(args.sessionId, `final representation: clearedParts=${finalRepresentation.clearedParts} mergedReasoningParts=${finalRepresentation.mergedReasoningParts}`);
29470
29871
  logTransformTiming(args.sessionId, "finalizeMessageRepresentation", tFinalRepresentation, `clearedParts=${finalRepresentation.clearedParts} mergedReasoningParts=${finalRepresentation.mergedReasoningParts}`);
29872
+ let assertedBaseline;
29873
+ if (args.channel1StateBySession) {
29874
+ if (args.ctxReduceAvailability.callable && !compactionOff) {
29875
+ try {
29876
+ const tags = getTailHygieneTags(args.db, args.sessionId);
29877
+ const previous = args.channel1StateBySession.get(args.sessionId);
29878
+ const baseline = refreshTailHygieneBaseline({
29879
+ messages: args.messages,
29880
+ tags,
29881
+ protectedTags: args.protectedTags,
29882
+ cacheBusting: bustedThisPass,
29883
+ previous
29884
+ });
29885
+ const structuralSignature = tailHygieneStructuralSignature(args.messages);
29886
+ args.channel1StateBySession.set(args.sessionId, {
29887
+ ...baseline,
29888
+ reducedSinceRefresh: baseline.baselineGeneration !== previous?.baselineGeneration ? false : previous?.reducedSinceRefresh ?? false,
29889
+ oldestReclaimableToolTags: getOldestActiveUnprotectedToolTags(args.db, args.sessionId, args.protectedTags)
29890
+ });
29891
+ try {
29892
+ rearmChannel2AfterMeasuredCollapse({
29893
+ db: args.db,
29894
+ sessionId: args.sessionId,
29895
+ baseline
29896
+ });
29897
+ } catch (error) {
29898
+ sessionLog(args.sessionId, "channel2 U-collapse reset failed (ignored):", error);
29899
+ }
29900
+ assertedBaseline = {
29901
+ tags,
29902
+ protectedTags: args.protectedTags,
29903
+ contentSignature: baseline.contentSignature,
29904
+ structuralSignature
29905
+ };
29906
+ } catch (error) {
29907
+ const stale = args.channel1StateBySession.get(args.sessionId);
29908
+ if (stale) {
29909
+ stale.evaluable = false;
29910
+ stale.generationInvalidated = true;
29911
+ }
29912
+ sessionLog(args.sessionId, "tail hygiene baseline refresh failed (held):", error);
29913
+ }
29914
+ } else {
29915
+ args.channel1StateBySession.delete(args.sessionId);
29916
+ }
29917
+ }
29918
+ if (assertedBaseline) {
29919
+ try {
29920
+ const servedSignature = tailHygieneStructuralSignature(args.messages);
29921
+ if (!sameTailHygieneStructuralSignature(assertedBaseline.structuralSignature, servedSignature)) {
29922
+ sessionLog(args.sessionId, `ERROR [tail-hygiene-last-writer-mismatch]: served messages changed after tail-hygiene baseline refresh (expected messages=${assertedBaseline.structuralSignature.messageCount}, parts=[${assertedBaseline.structuralSignature.partCounts.join(",")}], bytes=${assertedBaseline.structuralSignature.totalBytes}; actual messages=${servedSignature.messageCount}, parts=[${servedSignature.partCounts.join(",")}], bytes=${servedSignature.totalBytes})`);
29923
+ }
29924
+ } catch (error) {
29925
+ sessionLog(args.sessionId, "ERROR [tail-hygiene-last-writer-check-failed]: structural production guard failed open:", error);
29926
+ }
29927
+ if (true) {
29928
+ assertTailHygieneContentUnchanged({
29929
+ messages: args.messages,
29930
+ tags: assertedBaseline.tags,
29931
+ protectedTags: assertedBaseline.protectedTags,
29932
+ expectedSignature: assertedBaseline.contentSignature
29933
+ });
29934
+ }
29935
+ }
29471
29936
  return {
29472
29937
  explicitMaterializedSuccessfully,
29473
29938
  deferredMaterializedSuccessfully,
@@ -29506,6 +29971,29 @@ var RUST_PARK_RETRY_INTERVAL = 5;
29506
29971
  var RUST_EMERGENCY_WALL_PCT = 95;
29507
29972
  var RUST_PARK_PROBE_PRESSURE_BYPASS_PCT = 90;
29508
29973
  var RUST_SEND_TIMEOUT_MS = 15000;
29974
+ function activeAgentFromMessages(messages) {
29975
+ for (let index = messages.length - 1;index >= 0; index -= 1) {
29976
+ const info = messages[index]?.info;
29977
+ if (info?.role !== "user")
29978
+ continue;
29979
+ return typeof info.agent === "string" && info.agent.length > 0 ? info.agent : undefined;
29980
+ }
29981
+ return;
29982
+ }
29983
+ async function resolveCombinedTodowriteVerdict(deps, sessionId, messages, availability) {
29984
+ if (!availability.frozen || !availability.callable || deps.compactionOff === true)
29985
+ return false;
29986
+ let permissionDenied = cachedToolPermissionDenied(sessionId, "todowrite") ?? getPersistedTodoPermissionDenied(deps.db, sessionId) ?? false;
29987
+ if (deps.client) {
29988
+ try {
29989
+ permissionDenied = await todowritePermissionDenied(deps.client, sessionId, activeAgentFromMessages(messages));
29990
+ setPersistedTodoPermissionDenied(deps.db, sessionId, permissionDenied);
29991
+ } catch (error) {
29992
+ sessionLog(sessionId, "todowrite permission read failed; retaining the last successful verdict:", error);
29993
+ }
29994
+ }
29995
+ return !permissionDenied;
29996
+ }
29509
29997
  var RAW_FALLBACK_BYTES_PER_CONTEXT_TOKEN = 4;
29510
29998
  function rawFallbackSerializedBytes(messages) {
29511
29999
  try {
@@ -29666,10 +30154,10 @@ function messageCacheSignature(message) {
29666
30154
  const parts = Array.isArray(message.parts) ? message.parts : [];
29667
30155
  const serializedParts = JSON.stringify(parts) ?? "null";
29668
30156
  const serializedMessage = JSON.stringify(message) ?? "null";
29669
- return `${messageIdOf(message) ?? ""}:${parts.length}:${Buffer.byteLength(serializedParts)}:${createHash13("sha256").update(serializedMessage).digest("hex")}`;
30157
+ return `${messageIdOf(message) ?? ""}:${parts.length}:${Buffer.byteLength(serializedParts)}:${createHash12("sha256").update(serializedMessage).digest("hex")}`;
29670
30158
  }
29671
30159
  function advanceWireFingerprint(previous, encoded) {
29672
- return createHash13("sha256").update(previous).update("\\0").update(JSON.stringify(encoded) ?? "null").digest("hex");
30160
+ return createHash12("sha256").update(previous).update("\\0").update(JSON.stringify(encoded) ?? "null").digest("hex");
29673
30161
  }
29674
30162
  function buildWireFingerprint(encoded) {
29675
30163
  let fingerprint = "rust-wire-v1";
@@ -29700,7 +30188,9 @@ function emptyRustPassTimings() {
29700
30188
  transportPages: 0,
29701
30189
  transportBytes: 0,
29702
30190
  apply: 0,
29703
- lkgSnapshot: 0
30191
+ lkgSnapshot: 0,
30192
+ mirrorPull: 0,
30193
+ compartmentMirror: 0
29704
30194
  };
29705
30195
  }
29706
30196
  function formatRustPassLog(args) {
@@ -29708,7 +30198,7 @@ function formatRustPassLog(args) {
29708
30198
  const measured = timings.prefixGuard + timings.ordinalResolve + timings.stateSync + timings.clone + timings.wireBuild + timings.transport + timings.apply + timings.lkgSnapshot;
29709
30199
  const unattributed = Math.max(0, args.elapsedMs - measured);
29710
30200
  const rowVersion = Number.isSafeInteger(args.rowVersion) ? args.rowVersion : 0;
29711
- return `rust pass: decision=${args.decision} reason=${args.reason} served_from=${args.servedFrom} in=${args.inputCount} out=${args.outputCount} applied=${args.applied} row_version=${rowVersion} elapsed=${args.elapsedMs.toFixed(1)} ms module=${args.moduleElapsedMs.toFixed(1)} ms stages=prefix_guard:${timings.prefixGuard.toFixed(1)} ordinal_resolve:${timings.ordinalResolve.toFixed(1)} state_sync:${timings.stateSync.toFixed(1)} clone:${timings.clone.toFixed(1)} wire_build:${timings.wireBuild.toFixed(1)} wire_messages:${timings.wireMessages} transport:${timings.transport.toFixed(1)} transport_pages:${timings.transportPages} transport_bytes:${timings.transportBytes} apply:${timings.apply.toFixed(1)} lkg_snapshot:${timings.lkgSnapshot.toFixed(1)} other:${unattributed.toFixed(1)}`;
30201
+ return `rust pass: decision=${args.decision} reason=${args.reason} served_from=${args.servedFrom} in=${args.inputCount} out=${args.outputCount} applied=${args.applied} row_version=${rowVersion} elapsed=${args.elapsedMs.toFixed(1)} ms module=${args.moduleElapsedMs.toFixed(1)} ms stages=prefix_guard:${timings.prefixGuard.toFixed(1)} ordinal_resolve:${timings.ordinalResolve.toFixed(1)} state_sync:${timings.stateSync.toFixed(1)} clone:${timings.clone.toFixed(1)} wire_build:${timings.wireBuild.toFixed(1)} wire_messages:${timings.wireMessages} transport:${timings.transport.toFixed(1)} transport_pages:${timings.transportPages} transport_bytes:${timings.transportBytes} apply:${timings.apply.toFixed(1)} lkg_snapshot:${timings.lkgSnapshot.toFixed(1)} mirror_pull:${timings.mirrorPull.toFixed(1)} compartment_mirror:${timings.compartmentMirror.toFixed(1)} other:${unattributed.toFixed(1)}`;
29712
30202
  }
29713
30203
  function isSyntheticUserMessage(message) {
29714
30204
  if (!message || messageInfo2(message).role !== "user" || !Array.isArray(message.parts)) {
@@ -29738,7 +30228,13 @@ function assertNativeBoundary(output, sessionId, boundaryId) {
29738
30228
  const synthetic = parts.length > 0 && parts.every((part) => isRecord3(part) && part.synthetic === true);
29739
30229
  if (info.role === "user" && info.sessionID === sessionId && synthetic)
29740
30230
  return;
29741
- throw new Error(`rust transform wire invariant failed: boundary=${boundaryId} expected a synthetic m0 user message scoped to session ${sessionId}`);
30231
+ const headSummary = output.slice(0, 3).map((message) => {
30232
+ const mi = messageInfo2(message);
30233
+ const mParts = isRecord3(message) && Array.isArray(message.parts) ? message.parts : [];
30234
+ const partDesc = mParts.slice(0, 5).map((part) => isRecord3(part) ? `${String(part.type)}${part.synthetic === true ? "" : "!"}` : "?").join(",");
30235
+ return `role=${String(mi.role)} sid=${mi.sessionID === sessionId ? "ok" : String(mi.sessionID ?? "absent")} id=${String(mi.id ?? "-").slice(0, 24)} parts=[${partDesc}]`;
30236
+ });
30237
+ throw new Error(`rust transform wire invariant failed: boundary=${boundaryId} expected a synthetic m0 user message scoped to session ${sessionId}; head: ${headSummary.join(" | ")}`);
29742
30238
  }
29743
30239
  function responseValue(response) {
29744
30240
  if (isRecord3(response) && isRecord3(response.result))
@@ -29747,6 +30243,20 @@ function responseValue(response) {
29747
30243
  return response;
29748
30244
  throw new Error("module transform returned a non-object response");
29749
30245
  }
30246
+ function isTransformPageAttemptMismatch(error) {
30247
+ let current = error;
30248
+ const seen = new Set;
30249
+ while (isRecord3(current) && !seen.has(current)) {
30250
+ seen.add(current);
30251
+ const code = typeof current.code === "string" ? current.code : "";
30252
+ const message = typeof current.message === "string" ? current.message : "";
30253
+ if (code === "attempt_mismatch" || code === "authority_transform_page_attempt_mismatch" || /\b(?:authority_transform_page_)?attempt_mismatch\b/.test(message)) {
30254
+ return true;
30255
+ }
30256
+ current = current.cause;
30257
+ }
30258
+ return false;
30259
+ }
29750
30260
  function mirrorRustRenderedMemoryIds(args) {
29751
30261
  if (!("rendered_memory_ids" in args.response))
29752
30262
  return;
@@ -29856,6 +30366,27 @@ function passUsage(usage, limit) {
29856
30366
  context_limit_tokens: limit
29857
30367
  };
29858
30368
  }
30369
+ function transformGeometryForWire(geometry) {
30370
+ if (!geometry)
30371
+ return;
30372
+ const { window, reserve } = geometry.derivation;
30373
+ let derivation;
30374
+ if (geometry.geometry === "separate" && geometry.usableSoft < geometry.usableHard) {
30375
+ derivation = `s1-pre-carve/input=${geometry.usableSoft}`;
30376
+ } else if (geometry.geometry === "separate") {
30377
+ derivation = `s1-separate/context=${window}`;
30378
+ } else {
30379
+ derivation = `s1-shared/context-output/context=${window}/output=${reserve}` + `/mode=${geometry.geometry}/usable-hard=${geometry.usableHard}`;
30380
+ }
30381
+ return {
30382
+ usable_soft: geometry.usableSoft,
30383
+ usable_hard: geometry.usableHard,
30384
+ derivation
30385
+ };
30386
+ }
30387
+ function hardWallUsagePercentage(usage, geometry) {
30388
+ return geometry && geometry.usable_hard > 0 && usage.inputTokens > 0 ? usage.inputTokens / geometry.usable_hard * 100 : usage.percentage;
30389
+ }
29859
30390
  function shouldDisarmRustEmergencyRecovery(input) {
29860
30391
  if (input.finalWireEstimate?.trusted === true && input.providerProvenLimitTokens > 0 && input.finalWireEstimate.tokens < input.providerProvenLimitTokens * 0.8) {
29861
30392
  return "trusted-final-wire";
@@ -29885,7 +30416,7 @@ function canonicalizeForChecksum(value) {
29885
30416
  return Object.fromEntries(Object.keys(value).sort().map((key) => [key, canonicalizeForChecksum(value[key])]));
29886
30417
  }
29887
30418
  function checksumSeedRows(rows) {
29888
- return createHash13("sha256").update(JSON.stringify(rows.map(canonicalizeForChecksum))).digest("hex");
30419
+ return createHash12("sha256").update(JSON.stringify(rows.map(canonicalizeForChecksum))).digest("hex");
29889
30420
  }
29890
30421
  function authoritySeedRows(db, projectPath, domain) {
29891
30422
  const snapshots = domain === "memories" ? db.prepare("SELECT * FROM memories WHERE project_path = ? ORDER BY id ASC").all(projectPath) : db.prepare(`SELECT n.*
@@ -30055,7 +30586,14 @@ function mirrorRustSyntheticTodoAnchor(args) {
30055
30586
  clearPersistedTodoSyntheticAnchor(args.db, args.sessionId);
30056
30587
  }
30057
30588
  }
30058
- function applyNativeMessagesVerbatim(output, response) {
30589
+ function hasNativeResponseContent(response) {
30590
+ if (typeof response.native_messages === "string" || Array.isArray(response.native_messages)) {
30591
+ return true;
30592
+ }
30593
+ const delta = response.native_messages_delta;
30594
+ return isRecord3(delta) && Array.isArray(delta.messages);
30595
+ }
30596
+ function applyNativeMessagesVerbatim(output, response, previous) {
30059
30597
  const nativeMessages = response.native_messages;
30060
30598
  if (typeof nativeMessages === "string") {
30061
30599
  const parsed = JSON.parse(nativeMessages);
@@ -30063,10 +30601,32 @@ function applyNativeMessagesVerbatim(output, response) {
30063
30601
  throw new Error("rust transform native_messages string was not an array");
30064
30602
  return replaceMessagesInPlace(output, parsed);
30065
30603
  }
30066
- if (!Array.isArray(nativeMessages)) {
30604
+ if (Array.isArray(nativeMessages)) {
30605
+ return replaceMessagesInPlace(output, nativeMessages);
30606
+ }
30607
+ const delta = response.native_messages_delta;
30608
+ if (!isRecord3(delta) || !Array.isArray(delta.messages)) {
30067
30609
  throw new Error("rust transform response omitted native_messages");
30068
30610
  }
30069
- return replaceMessagesInPlace(output, nativeMessages);
30611
+ const replaceFrom = delta.replace_from;
30612
+ if (!previous || delta.after !== previous.fingerprint || typeof replaceFrom !== "number" || !Number.isSafeInteger(replaceFrom) || replaceFrom < 0 || replaceFrom > previous.messages.length) {
30613
+ throw new Error("rust transform native_messages_delta did not match the acknowledged output");
30614
+ }
30615
+ return replaceMessagesInPlace(output, [
30616
+ ...previous.messages.slice(0, replaceFrom),
30617
+ ...delta.messages
30618
+ ]);
30619
+ }
30620
+ function muralInputForWire(mural) {
30621
+ if (!mural?.enabled || !mural.supportsVision || typeof mural.dataUrl !== "string" || mural.dataUrl.length === 0) {
30622
+ return;
30623
+ }
30624
+ return {
30625
+ enabled: true,
30626
+ supports_vision: true,
30627
+ data_url: mural.dataUrl,
30628
+ content_hash: mural.contentHash
30629
+ };
30070
30630
  }
30071
30631
  function buildTransformBody(args) {
30072
30632
  return {
@@ -30096,6 +30656,7 @@ function buildTransformBody(args) {
30096
30656
  }
30097
30657
  } : {},
30098
30658
  usage: args.usage,
30659
+ ...args.geometry ? { geometry: args.geometry } : {},
30099
30660
  provider_error: args.passInputs.provider_error,
30100
30661
  mid_turn: args.midTurn,
30101
30662
  prev_response_completed_at_ms: args.prevResponseCompletedAtMs,
@@ -30113,7 +30674,12 @@ function buildTransformBody(args) {
30113
30674
  prompt_surface_model_key: args.passInputs.prompt_surface_model_key,
30114
30675
  prompt_surface_config_identity: args.passInputs.prompt_surface_config_identity,
30115
30676
  prompt_surface_tool_descriptions: args.passInputs.prompt_surface_tool_descriptions ?? {},
30677
+ prompt_surface_guidance_override: args.passInputs.prompt_surface_guidance_override,
30678
+ mural: args.passInputs.mural,
30116
30679
  effective_execute_threshold: args.passInputs.effective_execute_threshold,
30680
+ auto_search_enabled: args.passInputs.auto_search_enabled === true,
30681
+ auto_search_score_threshold: args.passInputs.auto_search_score_threshold,
30682
+ auto_search_min_prompt_chars: args.passInputs.auto_search_min_prompt_chars,
30117
30683
  history_budget_tokens: args.passInputs.history_budget_tokens,
30118
30684
  clear_reasoning_age: args.passInputs.clear_reasoning_age,
30119
30685
  caveman_enabled: args.passInputs.caveman_enabled === true,
@@ -30253,14 +30819,13 @@ function createRustModeTransform(deps, options) {
30253
30819
  sessionLog(sessionId, "lkg_replay_served");
30254
30820
  return true;
30255
30821
  };
30256
- const prepareRustCapture = (state, sessionId, input, inputSnapshots, response, responseRowVersion) => {
30822
+ const prepareRustCapture = (state, sessionId, input, inputSnapshots, nativeMessages, responseRowVersion) => {
30257
30823
  state.lkgCaptureSequence += 1;
30258
30824
  const inputIds = input.map((message) => message.info.id);
30259
30825
  if (inputIds.some((id) => typeof id !== "string") || new Set(inputIds).size !== inputIds.length || inputIds.length === 0 || inputSnapshots.length !== inputIds.length) {
30260
30826
  return null;
30261
30827
  }
30262
- const native = response.native_messages;
30263
- const jsonPrefix = typeof native === "string" ? native : JSON.stringify(native);
30828
+ const jsonPrefix = JSON.stringify(nativeMessages);
30264
30829
  if (typeof jsonPrefix !== "string")
30265
30830
  return null;
30266
30831
  const keys = resolveLkgModelKeys(input);
@@ -30280,11 +30845,22 @@ function createRustModeTransform(deps, options) {
30280
30845
  if (states.get(plan.sessionId) !== state || plan.captureSequence !== state.lkgCaptureSequence || plan.rowVersion < state.lkgLastCapturedRowVersion) {
30281
30846
  return "superseded";
30282
30847
  }
30283
- const inputContentDigests = plan.inputSnapshots.map((snapshot) => lkgContentDigestFromFields(snapshot.fields));
30848
+ const prior = getSlot(plan.sessionId);
30849
+ const inputContentSignatures = plan.inputSnapshots.map((snapshot) => snapshot.signature);
30850
+ const { digests: inputContentDigests } = incrementalLkgContentDigests(plan.inputIds.map((id, index) => ({
30851
+ id,
30852
+ signature: inputContentSignatures[index] ?? "",
30853
+ fields: plan.inputSnapshots[index]?.fields ?? []
30854
+ })), prior?.inputContentSignatures ? {
30855
+ ids: prior.inputIdSeq,
30856
+ signatures: prior.inputContentSignatures,
30857
+ digests: prior.inputContentDigests
30858
+ } : undefined);
30284
30859
  const captured = captureSlot(plan.sessionId, {
30285
30860
  jsonPrefix: plan.jsonPrefix,
30286
30861
  inputIdSeq: plan.inputIds,
30287
30862
  inputContentDigests,
30863
+ inputContentSignatures,
30288
30864
  lastInputMessageId: plan.inputIds[plan.inputIds.length - 1],
30289
30865
  modelKey: plan.modelKey,
30290
30866
  providerKey: plan.providerKey,
@@ -30330,14 +30906,16 @@ function createRustModeTransform(deps, options) {
30330
30906
  preflightError = error;
30331
30907
  }
30332
30908
  }
30333
- const modelKey = model ? resolveModelKey(model.providerID, model.modelID) : null;
30909
+ const modelKey = model ? piModelRefToCanonical(resolveModelKey(model.providerID, model.modelID) ?? "") : null;
30334
30910
  let resolvedContextLimit;
30911
+ let resolvedWindowGeometry;
30335
30912
  if (model) {
30336
30913
  try {
30337
30914
  resolvedContextLimit = resolveTrustedContextLimit(model.providerID, model.modelID, {
30338
30915
  db: deps.db,
30339
30916
  sessionID: sessionId
30340
30917
  });
30918
+ resolvedWindowGeometry = resolveContextWindowGeometry(model.providerID, model.modelID, { db: deps.db, sessionID: sessionId });
30341
30919
  } catch (error) {
30342
30920
  preflightError ??= error;
30343
30921
  }
@@ -30348,14 +30926,16 @@ function createRustModeTransform(deps, options) {
30348
30926
  } catch (error) {
30349
30927
  preflightError ??= error;
30350
30928
  }
30351
- emergencyFailClosed = passUsageSnapshot.percentage >= RUST_EMERGENCY_WALL_PCT && resolvedContextLimit !== undefined && resolvedContextLimit > 0;
30929
+ const transformGeometry = transformGeometryForWire(resolvedWindowGeometry);
30930
+ const hasTrustedEmergencyWall = transformGeometry ? transformGeometry.usable_hard > 0 : resolvedContextLimit !== undefined && resolvedContextLimit > 0;
30931
+ emergencyFailClosed = hardWallUsagePercentage(passUsageSnapshot, transformGeometry) >= RUST_EMERGENCY_WALL_PCT && hasTrustedEmergencyWall;
30352
30932
  if (overflowState) {
30353
- const detectedLimitMatchesModel = overflowState.detectedContextLimitModelKey === null || overflowState.detectedContextLimitModelKey === modelKey;
30933
+ const detectedLimitMatchesModel = overflowState.detectedContextLimitModelKey === null || piModelRefToCanonical(overflowState.detectedContextLimitModelKey) === piModelRefToCanonical(modelKey ?? "");
30354
30934
  const hasProviderProof = overflowState.detectedContextLimit > 0 && detectedLimitMatchesModel || isProviderOverflowReconfirmed(sessionId);
30355
30935
  emergencyFailClosed ||= overflowState.needsEmergencyRecovery && overflowState.emergencyRecoveryOrigin === "provider_overflow" && hasProviderProof;
30356
30936
  }
30357
30937
  const serveRawFallback = (cause) => {
30358
- const contextLimit = resolvedContextLimit ?? (overflowState && overflowState.detectedContextLimit > 0 ? overflowState.detectedContextLimit : undefined);
30938
+ const contextLimit = transformGeometry?.usable_hard ?? resolvedContextLimit ?? (overflowState && overflowState.detectedContextLimit > 0 ? overflowState.detectedContextLimit : undefined);
30359
30939
  if (contextLimit !== undefined) {
30360
30940
  let estimate;
30361
30941
  try {
@@ -30416,7 +30996,7 @@ function createRustModeTransform(deps, options) {
30416
30996
  const value = timings2[name];
30417
30997
  return typeof value === "number" && Number.isFinite(value) ? value.toFixed(1) : "n/a";
30418
30998
  };
30419
- sessionLog(sessionId, `rust module stages: handler=${stage("handler_total")} apply_once=${stage("total")} ` + `request_to_handler=${stage("request_observed_to_handler")} ` + `projection=${stage("projection")} selection=${stage("selection")} ` + `build_output=${stage("build_output")} store_commit=${stage("store_commit")} ` + `post_attach=${stage("post_attach")} response_encode=${stage("response_encode")} ` + `native_cache_reused=${stage("native_cache_reused_messages")} ` + `native_cache_encoded=${stage("native_cache_encoded_messages")}`);
30999
+ sessionLog(sessionId, `rust module stages: handler=${stage("handler_total")} apply_once=${stage("total")} ` + `request_to_handler=${stage("request_observed_to_handler")} delta_expand=${stage("delta_expand")} ` + `projection_cache_lookup=${stage("projection_cache_lookup")} projection=${stage("projection")} ` + `selection=${stage("selection")} build_output=${stage("build_output")} ` + `store_commit=${stage("store_commit")} trigger=${stage("trigger_ms")} ` + `trigger_boundary=${stage("trigger_boundary_build")} trigger_eval=${stage("trigger_eval")} ` + `projection_cache_store=${stage("projection_cache_store")} native_attach=${stage("native_attach")} ` + `retained_size=${stage("retained_size")} snapshot_store=${stage("snapshot_store")} ` + `post_attach=${stage("post_attach")} response_encode=${stage("response_encode")} ` + `response_meta_encode=${stage("response_meta_encode")} response_splice=${stage("response_splice")} ` + `native_cache_reused=${stage("native_cache_reused_messages")} ` + `native_cache_encoded=${stage("native_cache_encoded_messages")}`);
30420
31000
  }
30421
31001
  if (timings2 && moduleElapsedMs >= 1000) {
30422
31002
  const detail = Object.entries(timings2).filter(([key, value]) => key !== "total" && key !== "handler_total" && typeof value === "number").map(([key, value]) => `${key}:${value.toFixed(1)}`).join(" ");
@@ -30448,7 +31028,7 @@ function createRustModeTransform(deps, options) {
30448
31028
  resolveTodowriteAvailabilityFromMessages(sessionId, messages);
30449
31029
  const todoAvailability = resolveTodowriteAvailability(sessionId);
30450
31030
  const toolPresent = reduceAvailability.frozen && reduceAvailability.callable;
30451
- const todoToolPresent = todoAvailability.frozen ? todoAvailability.callable : undefined;
31031
+ const todoToolPresent = await resolveCombinedTodowriteVerdict(deps, sessionId, messages, todoAvailability);
30452
31032
  try {
30453
31033
  if (preflightError)
30454
31034
  throw preflightError;
@@ -30465,13 +31045,20 @@ function createRustModeTransform(deps, options) {
30465
31045
  const midTurn = isMidTurn(deps, sessionId);
30466
31046
  const requestObservedAtMs = Date.now();
30467
31047
  const recoveryNoHeadEscape = overflowState.needsEmergencyRecovery && loadProtectedTailMeta(deps.db, sessionId).recoveryNoEligibleHeadCount >= RECOVERY_NO_HEAD_LIMIT;
30468
- const promptSurface = resolvePromptSurface(deps.promptSurface, modelKey ?? undefined);
31048
+ const promptSurfaceGuidance = deps.promptSurfaceRuntime?.resolveGuidance(deps.promptSurface, modelKey ?? undefined);
31049
+ const promptSurface = promptSurfaceGuidance ?? resolvePromptSurface(deps.promptSurface, modelKey ?? undefined);
31050
+ const resolvedMural = !sessionMeta.isSubagent && deps.muralEnabled === true ? resolveMuralWire(deps.db, deps.projectPath, modelKey ?? undefined, true, deps.memoryConfig?.injectionBudgetTokens) : undefined;
31051
+ const mural = muralInputForWire(resolvedMural);
30469
31052
  const passInputs = {
30470
31053
  now_ms: requestObservedAtMs,
30471
31054
  model_key: modelKey,
30472
31055
  provider_id: model?.providerID ?? null,
30473
31056
  usage: passUsage(usage, contextLimit),
31057
+ geometry: transformGeometry,
30474
31058
  effective_execute_threshold: threshold,
31059
+ auto_search_enabled: deps.autoSearch?.enabled ?? true,
31060
+ auto_search_score_threshold: deps.autoSearch?.scoreThreshold ?? 0.6,
31061
+ auto_search_min_prompt_chars: deps.autoSearch?.minPromptChars ?? 20,
30475
31062
  history_budget_tokens: historyBudgetTokens,
30476
31063
  clear_reasoning_age: deps.clearReasoningAge,
30477
31064
  caveman_enabled: !sessionMeta.isSubagent && deps.cavemanTextCompression?.enabled === true,
@@ -30487,6 +31074,8 @@ function createRustModeTransform(deps, options) {
30487
31074
  prompt_surface_model_key: modelKey,
30488
31075
  prompt_surface_config_identity: promptSurfaceConfigIdentity(deps.promptSurface),
30489
31076
  prompt_surface_tool_descriptions: deps.promptSurface?.tool_descriptions ?? {},
31077
+ prompt_surface_guidance_override: promptSurfaceGuidance?.primaryOverride,
31078
+ mural,
30490
31079
  protected_tags: deps.protectedTags ?? DEFAULT_PROTECTED_TAGS,
30491
31080
  temporal_awareness: deps.experimentalTemporalAwareness === true,
30492
31081
  channel2_nudge_state: getChannel2NudgeState(deps.db, sessionId),
@@ -30702,6 +31291,7 @@ function createRustModeTransform(deps, options) {
30702
31291
  final_wire_input_tokens: finalWireEstimate?.tokens ?? 0,
30703
31292
  final_wire_trusted: finalWireEstimate?.trusted === true
30704
31293
  },
31294
+ geometry: transformGeometry,
30705
31295
  modelKey: modelKey ?? null,
30706
31296
  providerId: model?.providerID ?? null,
30707
31297
  systemPromptHash: sessionMeta.systemPromptHash ?? "",
@@ -30712,27 +31302,84 @@ function createRustModeTransform(deps, options) {
30712
31302
  channel2NudgeState: String(passInputs.channel2_nudge_state ?? ""),
30713
31303
  emergencyRecoveryArmed: passInputs.emergency_recovery_armed === true
30714
31304
  });
30715
- const pages = buildPagedModuleTransformPayloads(body);
30716
31305
  logStage(sessionId, "wireBuild", wireBuildStartedAt, timings, wireDelta ? `mode=tail_delta input=${encodedInput.length}` : "mode=full");
30717
- let response;
31306
+ const sendTransformSeries = async (payload, detail = "") => {
31307
+ const pages = buildPagedModuleTransformPayloads(payload);
31308
+ const paged = pages.some((entry) => typeof entry.page.transform_page_id === "string");
31309
+ let response2;
31310
+ for (const [index, { page, bytes }] of pages.entries()) {
31311
+ const transportStartedAt = performance.now();
31312
+ let moduleResponse;
31313
+ try {
31314
+ moduleResponse = await callModule({
31315
+ sessionId,
31316
+ projectRoot,
31317
+ method: "transform",
31318
+ body: page,
31319
+ generationSensitive: paged && index > 0
31320
+ });
31321
+ } catch (error) {
31322
+ if (paged && isTransformPageAttemptMismatch(error)) {
31323
+ return {
31324
+ restart: {
31325
+ reason: "attempt_mismatch",
31326
+ pages: pages.length,
31327
+ atPage: index
31328
+ }
31329
+ };
31330
+ }
31331
+ throw error;
31332
+ }
31333
+ if (paged && isModuleTransportGenerationChangedResult(moduleResponse)) {
31334
+ return {
31335
+ restart: { reason: "reconnect", pages: pages.length, atPage: index }
31336
+ };
31337
+ }
31338
+ if (paged && isTransformPageAttemptMismatch(moduleResponse)) {
31339
+ return {
31340
+ restart: {
31341
+ reason: "attempt_mismatch",
31342
+ pages: pages.length,
31343
+ atPage: index
31344
+ }
31345
+ };
31346
+ }
31347
+ response2 = responseValue(moduleResponse);
31348
+ timings.transportBytes += bytes;
31349
+ timings.transportPages += 1;
31350
+ logStage(sessionId, "transport", transportStartedAt, timings, `page=${index + 1}/${pages.length}${detail}`);
31351
+ }
31352
+ if (!response2)
31353
+ throw new Error("rust module returned no transform response");
31354
+ return { response: response2 };
31355
+ };
31356
+ let transformSeriesRestarted = false;
31357
+ const sendTransformSeriesWithSingleRestart = async (payload, detail = "") => {
31358
+ let result = await sendTransformSeries(payload, detail);
31359
+ if (!("restart" in result))
31360
+ return result.response;
31361
+ if (transformSeriesRestarted) {
31362
+ throw new Error(`rust transform page series restart exhausted: reason=${result.restart.reason}`);
31363
+ }
31364
+ transformSeriesRestarted = true;
31365
+ sessionLog(sessionId, `transform_series_restart reason=${result.restart.reason} pages=${result.restart.pages} at_page=${result.restart.atPage}`);
31366
+ result = await sendTransformSeries(payload, `${detail} restart=series`);
31367
+ if ("restart" in result) {
31368
+ throw new Error(`rust transform page series restart exhausted: reason=${result.restart.reason}`);
31369
+ }
31370
+ return result.response;
31371
+ };
31372
+ let response = await sendTransformSeriesWithSingleRestart(body);
30718
31373
  let servedFinalWireEstimate;
30719
- for (const [index, page] of pages.entries()) {
30720
- timings.transportBytes += Buffer.byteLength(JSON.stringify(page));
30721
- const transportStartedAt = performance.now();
30722
- response = responseValue(await callModule({
30723
- sessionId,
30724
- projectRoot,
30725
- method: "transform",
30726
- body: page
30727
- }));
30728
- timings.transportPages += 1;
30729
- logStage(sessionId, "transport", transportStartedAt, timings, `page=${index + 1}/${pages.length}`);
30730
- }
30731
- if (!response)
30732
- throw new Error("rust module returned no transform response");
30733
31374
  captureResponseTelemetry(response);
30734
- if (isNeedFullSync(response)) {
30735
- options.moduleClient.invalidateStateSyncCapabilities?.();
31375
+ const needFullSync = isNeedFullSync(response);
31376
+ const nativeContentOmitted = !hasNativeResponseContent(response);
31377
+ if (needFullSync || nativeContentOmitted) {
31378
+ if (needFullSync) {
31379
+ options.moduleClient.invalidateStateSyncCapabilities?.();
31380
+ } else {
31381
+ sessionLog(sessionId, "native_delta_fallback_reason=adapter_response_omitted_native_content retry=full");
31382
+ }
30736
31383
  state.forceFullWire = true;
30737
31384
  if (wireDelta) {
30738
31385
  const retryOrdinalStartedAt = performance.now();
@@ -30798,6 +31445,7 @@ function createRustModeTransform(deps, options) {
30798
31445
  final_wire_input_tokens: finalWireEstimate?.tokens ?? 0,
30799
31446
  final_wire_trusted: finalWireEstimate?.trusted === true
30800
31447
  },
31448
+ geometry: transformGeometry,
30801
31449
  modelKey: modelKey ?? null,
30802
31450
  providerId: model?.providerID ?? null,
30803
31451
  systemPromptHash: sessionMeta.systemPromptHash ?? "",
@@ -30810,28 +31458,16 @@ function createRustModeTransform(deps, options) {
30810
31458
  });
30811
31459
  logStage(sessionId, "wireBuild", retryWireBuildStartedAt2, timings, "retry=full");
30812
31460
  }
30813
- response = undefined;
30814
31461
  const retryWireBuildStartedAt = performance.now();
30815
- const retryPages = buildPagedModuleTransformPayloads(body);
31462
+ response = await sendTransformSeriesWithSingleRestart(body, " retry=full");
30816
31463
  logStage(sessionId, "wireBuild", retryWireBuildStartedAt, timings, "retry=full");
30817
- for (const [index, page] of retryPages.entries()) {
30818
- timings.transportBytes += Buffer.byteLength(JSON.stringify(page));
30819
- const transportStartedAt = performance.now();
30820
- response = responseValue(await callModule({
30821
- sessionId,
30822
- projectRoot,
30823
- method: "transform",
30824
- body: page
30825
- }));
30826
- timings.transportPages += 1;
30827
- logStage(sessionId, "transport", transportStartedAt, timings, `page=${index + 1}/${retryPages.length} retry=full`);
30828
- }
30829
- if (!response)
30830
- throw new Error("rust module returned no retry transform response");
30831
31464
  captureResponseTelemetry(response);
30832
31465
  if (isNeedFullSync(response)) {
30833
31466
  throw new Error("rust module still requires full sync after a full-array send");
30834
31467
  }
31468
+ if (!hasNativeResponseContent(response)) {
31469
+ throw new Error("rust module omitted native content after a full-array retry");
31470
+ }
30835
31471
  }
30836
31472
  const deliveryPassIds = noteDeliveryPassIds(response);
30837
31473
  const sendNoteDeliveryDisposition = async (method) => {
@@ -30855,13 +31491,20 @@ function createRustModeTransform(deps, options) {
30855
31491
  let appliedMessages;
30856
31492
  const applyStartedAt = performance.now();
30857
31493
  try {
30858
- appliedMessages = applyNativeMessagesVerbatim({ messages: [] }, response);
31494
+ appliedMessages = applyNativeMessagesVerbatim({ messages: [] }, response, previousWireCache?.nativeOutput ? {
31495
+ messages: previousWireCache.nativeOutput,
31496
+ fingerprint: previousWireCache.fingerprint
31497
+ } : undefined);
31498
+ pendingWireCache.nativeOutput = appliedMessages;
30859
31499
  runRustModePostprocess({
30860
31500
  db: deps.db,
30861
31501
  sessionId,
30862
31502
  messages: appliedMessages,
30863
31503
  projectPath: memoryProjectPath,
30864
- fullFeatureMode: !sessionMeta.isSubagent
31504
+ fullFeatureMode: !sessionMeta.isSubagent,
31505
+ compactionOff: deps.compactionOff,
31506
+ tagger: deps.tagger,
31507
+ ctxReduceAvailability: reduceAvailability
30865
31508
  });
30866
31509
  const boundaryId = response.boundary_id;
30867
31510
  if (typeof boundaryId === "string" && boundaryId.length > 0) {
@@ -30889,7 +31532,7 @@ function createRustModeTransform(deps, options) {
30889
31532
  if (cacheBustingPass) {
30890
31533
  dropSlot(sessionId, "lkg_cache_bust_pending_capture");
30891
31534
  }
30892
- const capturePlan = prepareRustCapture(state, sessionId, messages, pendingWireCache.rawContentSnapshots, response, rowVersion);
31535
+ const capturePlan = prepareRustCapture(state, sessionId, messages, pendingWireCache.rawContentSnapshots, appliedMessages, rowVersion);
30893
31536
  let captureMode = "async";
30894
31537
  const captureFailed = (mode, error) => {
30895
31538
  if (states.get(sessionId) !== state || capturePlan && capturePlan.captureSequence !== state.lkgCaptureSequence) {
@@ -30983,30 +31626,6 @@ function createRustModeTransform(deps, options) {
30983
31626
  sessionLog(sessionId, "rust channel2 pending-intent CAS failed (ignored):", error);
30984
31627
  }
30985
31628
  }
30986
- if (options.moduleClient.mirrorPull) {
30987
- try {
30988
- await pullMemoryMirrorOnce({
30989
- db: deps.db,
30990
- module: options.moduleClient
30991
- });
30992
- } catch (error) {
30993
- sessionLog(sessionId, "rust memory mirror-back failed (ignored):", error);
30994
- }
30995
- }
30996
- const getCompartmentsAfter = options.moduleClient.getCompartmentsAfter;
30997
- if (getCompartmentsAfter) {
30998
- try {
30999
- await mirrorModuleCompartments({
31000
- db: deps.db,
31001
- sessionId,
31002
- reader: {
31003
- getCompartmentsAfter: (mirroredSessionId, afterSequence) => getCompartmentsAfter.call(options.moduleClient, mirroredSessionId, afterSequence)
31004
- }
31005
- });
31006
- } catch (error) {
31007
- sessionLog(sessionId, "rust compartment mirror-back failed (ignored):", error);
31008
- }
31009
- }
31010
31629
  const currentOverflowState = getOverflowState(deps.db, sessionId, modelKey);
31011
31630
  const disarmEvidence = currentOverflowState.needsEmergencyRecovery ? shouldDisarmRustEmergencyRecovery({
31012
31631
  materialized: materializeReason !== "none",
@@ -31025,6 +31644,40 @@ function createRustModeTransform(deps, options) {
31025
31644
  }
31026
31645
  wireCaches.set(sessionId, pendingWireCache);
31027
31646
  appliedAt = performance.now();
31647
+ const getCompartmentsAfter = options.moduleClient.getCompartmentsAfter;
31648
+ if (options.moduleClient.mirrorPull || getCompartmentsAfter) {
31649
+ (async () => {
31650
+ if (options.moduleClient.mirrorPull) {
31651
+ const mirrorPullStartedAt = performance.now();
31652
+ try {
31653
+ await pullMemoryMirrorOnce({
31654
+ db: deps.db,
31655
+ module: options.moduleClient
31656
+ });
31657
+ } catch (error) {
31658
+ sessionLog(sessionId, "rust memory mirror-back failed (ignored):", error);
31659
+ } finally {
31660
+ logStage(sessionId, "mirrorPull", mirrorPullStartedAt, timings);
31661
+ }
31662
+ }
31663
+ if (getCompartmentsAfter) {
31664
+ const compartmentMirrorStartedAt = performance.now();
31665
+ try {
31666
+ await mirrorModuleCompartments({
31667
+ db: deps.db,
31668
+ sessionId,
31669
+ reader: {
31670
+ getCompartmentsAfter: (mirroredSessionId, afterSequence) => getCompartmentsAfter.call(options.moduleClient, mirroredSessionId, afterSequence)
31671
+ }
31672
+ });
31673
+ } catch (error) {
31674
+ sessionLog(sessionId, "rust compartment mirror-back failed (ignored):", error);
31675
+ } finally {
31676
+ logStage(sessionId, "compartmentMirror", compartmentMirrorStartedAt, timings);
31677
+ }
31678
+ }
31679
+ })();
31680
+ }
31028
31681
  finishPass(true);
31029
31682
  } catch (error) {
31030
31683
  if (error instanceof Error && error.message.startsWith("rust transform wire invariant failed")) {
@@ -31061,6 +31714,7 @@ function createRustModeTransform(deps, options) {
31061
31714
  dropSlot(sessionId, "session-deleted");
31062
31715
  states.delete(sessionId);
31063
31716
  wireCaches.delete(sessionId);
31717
+ clearCompartmentMirrorCursor(sessionId);
31064
31718
  if (projectRoot && options.moduleClient.deleteSession) {
31065
31719
  options.moduleClient.deleteSession(sessionId, projectRoot).catch((error) => {
31066
31720
  sessionLog(sessionId, "rust module session deletion failed:", error);
@@ -31306,7 +31960,7 @@ function clearMessageTokensCache(sessionId, messageId2) {
31306
31960
  cache.delete(messageId2);
31307
31961
  }
31308
31962
  var recordedSessionProjectIdentity = new BoundedSessionMap(MESSAGE_TOKENS_CACHE_MAX);
31309
- function activeAgentFromMessages(messages) {
31963
+ function activeAgentFromMessages2(messages) {
31310
31964
  for (let index = messages.length - 1;index >= 0; index -= 1) {
31311
31965
  const info = messages[index]?.info;
31312
31966
  if (info?.role !== "user")
@@ -31321,7 +31975,7 @@ function deriveTaggerLoadFloor(messages, sessionId, db) {
31321
31975
  yield message.info?.id;
31322
31976
  }());
31323
31977
  }
31324
- function computeHardCacheExpired(cacheTtl, lastResponseTime, now, onInvalid) {
31978
+ function computeHardCacheExpired(cacheTtl, lastResponseTime, now2, onInvalid) {
31325
31979
  let ttlMs;
31326
31980
  try {
31327
31981
  ttlMs = parseCacheTtl(cacheTtl);
@@ -31329,7 +31983,7 @@ function computeHardCacheExpired(cacheTtl, lastResponseTime, now, onInvalid) {
31329
31983
  onInvalid?.(error);
31330
31984
  ttlMs = 5 * 60 * 1000;
31331
31985
  }
31332
- return lastResponseTime > 0 && now - lastResponseTime > ttlMs;
31986
+ return lastResponseTime > 0 && now2 - lastResponseTime > ttlMs;
31333
31987
  }
31334
31988
  function findLastAssistantModel(messages) {
31335
31989
  for (let i = messages.length - 1;i >= 0; i--) {
@@ -31421,6 +32075,8 @@ async function recoverTsAuthorityProject(args) {
31421
32075
  function scheduleTsAuthorityRecovery(args) {
31422
32076
  if (!getAuthorityManagedMarker(args.db, args.projectPath))
31423
32077
  return;
32078
+ if ((args.isLinkedWorktree ?? isLinkedGitWorktree)(args.projectRoot))
32079
+ return;
31424
32080
  if (tsAuthorityRecoveryStateByProject.has(args.projectPath))
31425
32081
  return;
31426
32082
  const module = args.module;
@@ -31483,7 +32139,7 @@ function createTransform(deps) {
31483
32139
  }
31484
32140
  const tUserMsg = performance.now();
31485
32141
  const currentTurnId = findLastUserMessageId(messages);
31486
- const activeAgent = activeAgentFromMessages(messages);
32142
+ const activeAgent = activeAgentFromMessages2(messages);
31487
32143
  logTransformTiming(sessionId, "findLastUserMessageId", tUserMsg);
31488
32144
  const tMeta = performance.now();
31489
32145
  let sessionMeta;
@@ -31541,8 +32197,6 @@ function createTransform(deps) {
31541
32197
  sessionLog(sessionId, "compaction mode transition failed (retrying next pass):", error);
31542
32198
  }
31543
32199
  if (deps.transformMode === "rust") {
31544
- if (compactionOff)
31545
- return;
31546
32200
  if (!rustModeTransform) {
31547
32201
  sessionLog(sessionId, "rust transform unavailable; using raw passthrough");
31548
32202
  return;
@@ -31589,7 +32243,7 @@ function createTransform(deps) {
31589
32243
  deps.liveModelBySession.set(sessionId, currentOutgoingModel);
31590
32244
  const outgoingModelKey = resolveModelKey(currentOutgoingModel.providerID, currentOutgoingModel.modelID);
31591
32245
  const lastUsageModelKey = persistedUsageBeforeResets?.lastObservedModelKey ?? null;
31592
- if (lastUsageModelKey != null && outgoingModelKey != null && lastUsageModelKey !== outgoingModelKey) {
32246
+ if (lastUsageModelKey != null && outgoingModelKey != null && piModelRefToCanonical(lastUsageModelKey) !== piModelRefToCanonical(outgoingModelKey)) {
31593
32247
  dropSlot(sessionId, "model-change");
31594
32248
  sessionLog(sessionId, `transform: model change since last usage (${lastUsageModelKey} -> ${outgoingModelKey}), clearing stale per-model state`);
31595
32249
  updateSessionMeta(db, sessionId, {
@@ -31647,7 +32301,7 @@ function createTransform(deps) {
31647
32301
  const lastMeasuredInput = armSnapshot?.usage.inputTokens ?? sessionMeta?.lastInputTokens ?? 0;
31648
32302
  const lastMeasuredModelKey = armSnapshot?.lastObservedModelKey ?? null;
31649
32303
  const armCatalogLimit = armModel ? getSdkContextLimit(armModel.providerID, armModel.modelID) : undefined;
31650
- if (!sessionMeta?.isSubagent && armModel && typeof armCatalogLimit === "number" && armCatalogLimit > 0 && lastMeasuredInput > armCatalogLimit && lastMeasuredModelKey != null && armModelKey != null && lastMeasuredModelKey !== armModelKey && !getOverflowState(db, sessionId).needsEmergencyRecovery) {
32304
+ if (!sessionMeta?.isSubagent && armModel && typeof armCatalogLimit === "number" && armCatalogLimit > 0 && lastMeasuredInput > armCatalogLimit && lastMeasuredModelKey != null && armModelKey != null && piModelRefToCanonical(lastMeasuredModelKey) !== piModelRefToCanonical(armModelKey) && !getOverflowState(db, sessionId).needsEmergencyRecovery) {
31651
32305
  sessionLog(sessionId, `transform: last input ${lastMeasuredInput} (model ${lastMeasuredModelKey}) exceeds new model ${armModelKey} catalog limit ${armCatalogLimit}; arming overflow recovery proactively for the shrinking switch`);
31652
32306
  dropSlot(sessionId, "overflow-recovery-arm");
31653
32307
  recordOverflowDetected(db, sessionId, undefined, armModelKey, "proactive_model_shrink");
@@ -31691,6 +32345,11 @@ function createTransform(deps) {
31691
32345
  db,
31692
32346
  sessionID: sessionId
31693
32347
  }) : undefined;
32348
+ const windowGeometry = modelForBudget ? resolveContextWindowGeometry(modelForBudget.providerID, modelForBudget.modelID, {
32349
+ db,
32350
+ sessionID: sessionId
32351
+ }) : undefined;
32352
+ const emergencyUsagePercentageEarly = usagePercentageSynthetic ? Math.max(95, contextUsageEarly.percentage) : windowGeometry?.usableHard && contextUsageEarly.inputTokens > 0 ? contextUsageEarly.inputTokens / windowGeometry.usableHard * 100 : contextUsageEarly.percentage;
31694
32353
  const currentModelKeyForBoundary = deps.getModelKey?.(sessionId);
31695
32354
  const thresholdContextLimit = resolvedContextLimit && resolvedContextLimit > 0 ? resolvedContextLimit : contextUsageEarly.percentage > 0 ? contextUsageEarly.inputTokens / (contextUsageEarly.percentage / 100) : undefined;
31696
32355
  const effectiveExecuteThresholdPercentage = resolveExecuteThreshold(deps.executeThresholdPercentage ?? 65, currentModelKeyForBoundary, 65, {
@@ -31699,7 +32358,7 @@ function createTransform(deps) {
31699
32358
  sessionId
31700
32359
  });
31701
32360
  const { forceMaterializationPercentage } = escalationBands(effectiveExecuteThresholdPercentage);
31702
- const persistedUsageFreshForBoundary = persistedUsageBeforeResets && Date.now() - persistedUsageBeforeResets.updatedAt <= 10 * 60 * 1000 && (persistedUsageBeforeResets.lastObservedModelKey === null || currentModelKeyForBoundary === undefined || persistedUsageBeforeResets.lastObservedModelKey === currentModelKeyForBoundary) && (resolvedContextLimit === undefined || persistedUsageBeforeResets.lastUsageContextLimit === 0 || persistedUsageBeforeResets.lastUsageContextLimit === resolvedContextLimit) ? persistedUsageBeforeResets.usage : null;
32361
+ const persistedUsageFreshForBoundary = persistedUsageBeforeResets && Date.now() - persistedUsageBeforeResets.updatedAt <= 10 * 60 * 1000 && (persistedUsageBeforeResets.lastObservedModelKey === null || currentModelKeyForBoundary === undefined || piModelRefToCanonical(persistedUsageBeforeResets.lastObservedModelKey) === piModelRefToCanonical(currentModelKeyForBoundary)) && (resolvedContextLimit === undefined || persistedUsageBeforeResets.lastUsageContextLimit === 0 || persistedUsageBeforeResets.lastUsageContextLimit === resolvedContextLimit) ? persistedUsageBeforeResets.usage : null;
31703
32362
  const boundaryUsageForProtectedTail = persistedUsageFreshForBoundary ?? contextUsageEarly;
31704
32363
  const boundaryUsageSource = persistedUsageFreshForBoundary ? "persisted" : "live";
31705
32364
  const historyBudgetTokens = resolveHistoryBudgetTokens(deps.historyBudgetPercentage, contextUsageEarly, deps.executeThresholdPercentage, deps.getModelKey?.(sessionId), deps.executeThresholdTokens, resolvedContextLimit);
@@ -31776,7 +32435,7 @@ function createTransform(deps) {
31776
32435
  };
31777
32436
  let skipCompartmentAwaitForThisPass = false;
31778
32437
  const startRecoveryRun = () => {
31779
- const scale = contextUsageEarly.percentage >= 95 ? 0.25 : 0.5;
32438
+ const scale = emergencyUsagePercentageEarly >= 95 ? 0.25 : 0.5;
31780
32439
  let boundarySnapshot = getRunnableBoundaryForCompartment();
31781
32440
  if (!boundarySnapshot || !hasRunnableCompartmentWindow(boundarySnapshot)) {
31782
32441
  boundarySnapshot = getRunnableBoundaryForCompartment(scale);
@@ -31817,12 +32476,12 @@ function createTransform(deps) {
31817
32476
  skipCompartmentAwaitForThisPass = true;
31818
32477
  return true;
31819
32478
  };
31820
- if (fullFeatureMode && !compactionOff && historianFailureState.failureCount > 0 && contextUsageEarly.percentage >= 95 && !recoveryNoHeadEscapeActive) {
32479
+ if (fullFeatureMode && !compactionOff && historianFailureState.failureCount > 0 && emergencyUsagePercentageEarly >= 95 && !recoveryNoHeadEscapeActive) {
31821
32480
  skipCompartmentAwaitForThisPass = true;
31822
32481
  const emergencyPercentage = contextUsageEarly.percentage.toFixed(1);
31823
32482
  const recoveryStarted = startRecoveryRun();
31824
32483
  if (!recoveryStarted && !getEligibleHistoryForCompartment()) {
31825
- const noHeadSnapshot = getRunnableBoundaryForCompartment(contextUsageEarly.percentage >= 95 ? 0.25 : 0.5) ?? getRunnableBoundaryForCompartment();
32484
+ const noHeadSnapshot = getRunnableBoundaryForCompartment(emergencyUsagePercentageEarly >= 95 ? 0.25 : 0.5) ?? getRunnableBoundaryForCompartment();
31826
32485
  if (noHeadSnapshot) {
31827
32486
  recordHighPressureNoEligibleHead(db, noHeadSnapshot);
31828
32487
  }
@@ -32076,6 +32735,7 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
32076
32735
  messageTagNumbers,
32077
32736
  tagger: deps.tagger,
32078
32737
  ctxReduceAvailability,
32738
+ channel1StateBySession: deps.channel1StateBySession,
32079
32739
  todowriteAvailability,
32080
32740
  client: deps.client,
32081
32741
  activeAgent,
@@ -32131,7 +32791,8 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
32131
32791
  const finalWireTail = describeFinalWireTail(messages);
32132
32792
  let finalWireEstimate;
32133
32793
  if (!compactionOff) {
32134
- finalWireEstimate = contextUsage.percentage >= 95 ? estimateFinalWireInputTokens({
32794
+ const emergencyUsagePercentage = usagePercentageSynthetic ? Math.max(95, contextUsage.percentage) : windowGeometry?.usableHard && contextUsage.inputTokens > 0 ? contextUsage.inputTokens / windowGeometry.usableHard * 100 : contextUsage.percentage;
32795
+ finalWireEstimate = emergencyUsagePercentage >= 95 ? estimateFinalWireInputTokens({
32135
32796
  messages,
32136
32797
  systemPromptTokens: sessionMeta.systemPromptTokens,
32137
32798
  providerID: modelForBudget?.providerID,
@@ -32143,9 +32804,9 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
32143
32804
  }
32144
32805
  const currentModelKeyForRecovery = deps.getModelKey?.(sessionId);
32145
32806
  const overflowStateForFinalWire = getOverflowState(db, sessionId, currentModelKeyForRecovery);
32146
- const providerProvenLimitTokens = typeof currentModelKeyForRecovery === "string" && currentModelKeyForRecovery.length > 0 && overflowStateForFinalWire.detectedContextLimit > 0 && overflowStateForFinalWire.detectedContextLimitModelKey === currentModelKeyForRecovery ? overflowStateForFinalWire.detectedContextLimit : undefined;
32807
+ const providerProvenLimitTokens = typeof currentModelKeyForRecovery === "string" && currentModelKeyForRecovery.length > 0 && overflowStateForFinalWire.detectedContextLimit > 0 && piModelRefToCanonical(overflowStateForFinalWire.detectedContextLimitModelKey ?? "") === piModelRefToCanonical(currentModelKeyForRecovery) ? overflowStateForFinalWire.detectedContextLimit : undefined;
32147
32808
  const emergencyFailClosed = evaluateEmergencyFailClosed({
32148
- usagePercentage: contextUsage.percentage,
32809
+ usagePercentage: emergencyUsagePercentage,
32149
32810
  emergencyRecoveryArmed,
32150
32811
  emergencyRecoveryOrigin,
32151
32812
  foldMaterializedThisPass: postTransformResult.historianFoldMaterializedThisPass,
@@ -32267,59 +32928,22 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
32267
32928
  sessionLog(sessionId, "conversation_tokens UPDATE failed:", error);
32268
32929
  }
32269
32930
  }
32270
- if (ctxReduceCallable && !compactionOff && deps.channel1StateBySession) {
32271
- try {
32272
- const resolvedExecuteThresholdPct = resolveExecuteThreshold(deps.executeThresholdPercentage ?? 65, deps.getModelKey?.(sessionId), 65, {
32273
- tokensConfig: deps.executeThresholdTokens,
32274
- contextLimit: resolvedContextLimit ?? 0
32275
- });
32276
- let tailToolTokens;
32277
- let liveTailTokens;
32931
+ const channelBaseline = deps.channel1StateBySession?.get(sessionId);
32932
+ if (ctxReduceCallable && !compactionOff && channelBaseline) {
32933
+ const measuredU = Math.min(Math.max(0, channelBaseline.baselineT + channelBaseline.turnDeltaT), Math.max(0, channelBaseline.baselineU + channelBaseline.turnDeltaU));
32934
+ resetLastNudgeCycleIfTailShrank(db, sessionId, measuredU);
32935
+ if (channelBaseline.evaluable && !channelBaseline.generationInvalidated && !channelBaseline.reducedSinceRefresh) {
32936
+ const channel2Evaluation = evaluateChannel2(channelBaseline);
32278
32937
  try {
32279
- const agg = getActiveTagTokenAggregate(db, sessionId, deps.protectedTags);
32280
- tailToolTokens = agg.toolOutput;
32281
- liveTailTokens = agg.conversation + agg.toolCall;
32282
- } catch {
32283
- const estimate = computeTailTokenEstimate(messages);
32284
- tailToolTokens = estimate.tailToolTokens;
32285
- liveTailTokens = estimate.liveTailTokens;
32286
- }
32287
- const executeThresholdTokens = Math.round((resolvedContextLimit ?? 0) * resolvedExecuteThresholdPct / 100);
32288
- const usableTokens = Math.max(0, executeThresholdTokens - contextUsage.inputTokens + liveTailTokens);
32289
- resetLastNudgeCycleIfTailShrank(db, sessionId, tailToolTokens);
32290
- const oldestReclaimableToolTags = getOldestActiveUnprotectedToolTags(db, sessionId, deps.protectedTags);
32291
- deps.channel1StateBySession.set(sessionId, {
32292
- tailToolTokens,
32293
- historyBudgetTokens: historyBudgetTokens ?? 0,
32294
- contextLimit: resolvedContextLimit ?? 0,
32295
- executeThresholdPercentage: resolvedExecuteThresholdPct,
32296
- lastInputTokens: contextUsage.inputTokens,
32297
- turnToolTokens: 0,
32298
- usableTokens,
32299
- reducedSinceRefresh: false,
32300
- oldestReclaimableToolTags
32301
- });
32302
- const channel2MetricsKnown = resolvedContextLimit !== undefined && resolvedContextLimit > 0 && resolvedExecuteThresholdPct > 0;
32303
- if (channel2MetricsKnown) {
32304
- const channel2ShouldTrigger = shouldTriggerChannel2({
32305
- reclaimableTokens: tailToolTokens,
32306
- usableTokens
32307
- });
32308
- try {
32309
- if (channel2ShouldTrigger) {
32310
- casChannel2NudgeState(db, sessionId, "", "pending");
32311
- } else {
32312
- casChannel2NudgeState(db, sessionId, "pending", "");
32313
- }
32314
- } catch (error) {
32315
- sessionLog(sessionId, "channel2 trigger CAS failed (ignored):", error);
32938
+ if (channel2Evaluation.shouldTrigger) {
32939
+ casChannel2NudgeState(db, sessionId, "", "pending");
32940
+ } else {
32941
+ casChannel2NudgeState(db, sessionId, "pending", "");
32316
32942
  }
32943
+ } catch (error) {
32944
+ sessionLog(sessionId, "channel2 trigger CAS failed (ignored):", error);
32317
32945
  }
32318
- } catch (error) {
32319
- sessionLog(sessionId, "channel1 baseline snapshot failed (ignored):", error);
32320
32946
  }
32321
- } else {
32322
- deps.channel1StateBySession?.delete(sessionId);
32323
32947
  }
32324
32948
  const elapsed = (performance.now() - startTime).toFixed(1);
32325
32949
  sessionLog(sessionId, `transform completed in ${elapsed}ms (${messages.length} messages, ${targets.size} targets, watermark: ${watermark})`);
@@ -32361,9 +32985,9 @@ function formatTokens(value) {
32361
32985
  return value.toLocaleString();
32362
32986
  }
32363
32987
  function evictExpiredUsageEntries(contextUsageMap) {
32364
- const now = Date.now();
32988
+ const now2 = Date.now();
32365
32989
  for (const [sessionId, entry] of contextUsageMap) {
32366
- if (now - entry.updatedAt > CONTEXT_USAGE_TTL_MS) {
32990
+ if (now2 - entry.updatedAt > CONTEXT_USAGE_TTL_MS) {
32367
32991
  contextUsageMap.delete(sessionId);
32368
32992
  }
32369
32993
  }
@@ -32377,8 +33001,7 @@ async function deliverChannel2IfPending(deps, sessionId) {
32377
33001
  db: deps.db,
32378
33002
  client: deps.client,
32379
33003
  directiveText: deps.channel2DirectiveTextBySession?.get(sessionId),
32380
- reclaimableTokens: baseline ? baseline.tailToolTokens + baseline.turnToolTokens : undefined,
32381
- usableTokens: baseline?.usableTokens,
33004
+ baseline,
32382
33005
  oldestReclaimableToolTags: baseline?.oldestReclaimableToolTags
32383
33006
  });
32384
33007
  if (delivered || getChannel2NudgeState(deps.db, sessionId) !== "pending") {
@@ -32453,6 +33076,14 @@ function createEventHandler2(deps) {
32453
33076
  if (!detection.isOverflow) {
32454
33077
  return;
32455
33078
  }
33079
+ captureWindowReport({
33080
+ db: deps.db,
33081
+ sessionID: errInfo.sessionID,
33082
+ matchedPattern: detection.matchedPattern,
33083
+ reportedLimit: detection.reportedLimit,
33084
+ reportedLimitProvenance: detection.reportedLimitProvenance,
33085
+ error: errInfo.error
33086
+ });
32456
33087
  const sessionMeta = getOrCreateSessionMeta(deps.db, errInfo.sessionID);
32457
33088
  if (sessionMeta.isSubagent) {
32458
33089
  if (typeof detection.reportedLimit === "number" && detection.reportedLimit > 0) {
@@ -32509,6 +33140,17 @@ function createEventHandler2(deps) {
32509
33140
  if (detection.isOverflow) {
32510
33141
  messageHadOverflowError = true;
32511
33142
  try {
33143
+ captureWindowReport({
33144
+ db: deps.db,
33145
+ sessionID: info.sessionID,
33146
+ providerID: info.providerID,
33147
+ modelID: info.modelID,
33148
+ matchedPattern: detection.matchedPattern,
33149
+ reportedLimit: detection.reportedLimit,
33150
+ reportedLimitProvenance: detection.reportedLimitProvenance,
33151
+ attemptedTokens: (info.tokens?.input ?? 0) + (info.tokens?.cache?.read ?? 0) + (info.tokens?.cache?.write ?? 0),
33152
+ error: info.error
33153
+ });
32512
33154
  const overflowModelKey = resolveModelKey(info.providerID, info.modelID);
32513
33155
  const metaForOverflow = getOrCreateSessionMeta(deps.db, info.sessionID);
32514
33156
  if (metaForOverflow.isSubagent) {
@@ -32532,7 +33174,7 @@ function createEventHandler2(deps) {
32532
33174
  }
32533
33175
  }
32534
33176
  }
32535
- const now = Date.now();
33177
+ const now2 = Date.now();
32536
33178
  const usageTokens = [
32537
33179
  info.tokens?.input,
32538
33180
  info.tokens?.cache?.read,
@@ -32557,7 +33199,7 @@ function createEventHandler2(deps) {
32557
33199
  try {
32558
33200
  const modelKey = resolveModelKey(info.providerID, info.modelID);
32559
33201
  const updates = {
32560
- lastResponseTime: now
33202
+ lastResponseTime: now2
32561
33203
  };
32562
33204
  if (typeof deps.config.cache_ttl === "string") {
32563
33205
  updates.cacheTtl = resolveCacheTtl(deps.config.cache_ttl, modelKey);
@@ -32603,8 +33245,8 @@ function createEventHandler2(deps) {
32603
33245
  percentage,
32604
33246
  inputTokens: totalInputTokens
32605
33247
  },
32606
- updatedAt: now,
32607
- lastResponseTime: now,
33248
+ updatedAt: now2,
33249
+ lastResponseTime: now2,
32608
33250
  hasUsageTokens: true
32609
33251
  });
32610
33252
  updates.lastContextPercentage = percentage;
@@ -32907,6 +33549,7 @@ async function runOneWrapupIteration(args) {
32907
33549
  historianTwoPass: ctx.historianTwoPass,
32908
33550
  memoryEnabled: ctx.memoryEnabled,
32909
33551
  autoPromote: ctx.autoPromote,
33552
+ experimentalUserMemories: ctx.userMemoriesEnabled,
32910
33553
  ensureProjectRegistered: ctx.ensureProjectRegistered,
32911
33554
  getNotificationParams: () => ctx.getNotificationParams(sessionId),
32912
33555
  preserveInjectionCacheUntilConsumed: true,
@@ -33129,16 +33772,16 @@ var MAX_CACHED_SESSIONS = 100;
33129
33772
  var STALE_SNAPSHOT_AGE_MS = 5 * 60 * 1000;
33130
33773
  var cache = new BoundedSessionMap(MAX_CACHED_SESSIONS);
33131
33774
  function applyStickySnapshotCache(sessionId, fresh) {
33132
- const now = Date.now();
33775
+ const now2 = Date.now();
33133
33776
  if (fresh.inputTokens > 0) {
33134
- cache.set(sessionId, { snapshot: fresh, cachedAt: now });
33777
+ cache.set(sessionId, { snapshot: fresh, cachedAt: now2 });
33135
33778
  return fresh;
33136
33779
  }
33137
33780
  const cached = cache.peek(sessionId);
33138
33781
  if (!cached) {
33139
33782
  return fresh;
33140
33783
  }
33141
- if (now - cached.cachedAt > STALE_SNAPSHOT_AGE_MS) {
33784
+ if (now2 - cached.cachedAt > STALE_SNAPSHOT_AGE_MS) {
33142
33785
  cache.delete(sessionId);
33143
33786
  return fresh;
33144
33787
  }
@@ -33300,26 +33943,19 @@ function maybeInjectChannel1Nudge(args, sessionId, tool, output) {
33300
33943
  return;
33301
33944
  if (out.output.includes(CHANNEL1_SENTINEL))
33302
33945
  return;
33303
- const thisTurnTokens = toolOutputTokens(out.output);
33304
- state.turnToolTokens += thisTurnTokens;
33946
+ state.turnDeltaT += toolOutputTokens(out.output);
33305
33947
  if (state.reducedSinceRefresh)
33306
33948
  return;
33307
- const undroppedTokens = state.tailToolTokens + state.turnToolTokens;
33308
- const pressure = computePressure({
33309
- lastInputTokens: state.lastInputTokens,
33310
- turnToolTokens: state.turnToolTokens,
33311
- contextLimit: state.contextLimit,
33312
- executeThresholdPercentage: state.executeThresholdPercentage
33313
- });
33314
- const workingWindowTokens = Math.round(state.contextLimit * state.executeThresholdPercentage / 100);
33315
33949
  const decision = decideChannel1({
33316
- undroppedTokens,
33317
- pressure,
33318
- estimatedInputTokens: state.lastInputTokens + state.turnToolTokens,
33319
- workingWindowTokens,
33950
+ baselineU: state.baselineU,
33951
+ baselineT: state.baselineT,
33952
+ turnDeltaU: state.turnDeltaU,
33953
+ turnDeltaT: state.turnDeltaT,
33320
33954
  lastNudgeUndropped: getLastNudgeUndropped(args.db, sessionId),
33321
33955
  lastNudgeLevel: getLastNudgeLevel(args.db, sessionId),
33322
- hasRecentReduce: false
33956
+ hasRecentReduce: false,
33957
+ evaluable: state.evaluable,
33958
+ generationInvalidated: state.generationInvalidated
33323
33959
  });
33324
33960
  setLastNudgeUndropped(args.db, sessionId, decision.nextLastNudge);
33325
33961
  setLastNudgeLevel(args.db, sessionId, decision.nextLastNudgeLevel);
@@ -33337,8 +33973,11 @@ function createToolExecuteAfterHook(args) {
33337
33973
  await flushIgnoredMessages(typedInput.sessionID);
33338
33974
  if (typedInput.tool === "ctx_reduce") {
33339
33975
  const state = args.channel1StateBySession.get(typedInput.sessionID);
33340
- if (state)
33976
+ if (state) {
33341
33977
  state.reducedSinceRefresh = true;
33978
+ state.evaluable = false;
33979
+ state.generationInvalidated = true;
33980
+ }
33342
33981
  try {
33343
33982
  resetLastNudgeCycle(args.db, typedInput.sessionID);
33344
33983
  } catch (error) {
@@ -33404,7 +34043,7 @@ function createToolExecuteAfterHook(args) {
33404
34043
  }
33405
34044
 
33406
34045
  // src/hooks/magic-context/system-prompt-hash.ts
33407
- import { createHash as createHash14 } from "node:crypto";
34046
+ import { createHash as createHash13 } from "node:crypto";
33408
34047
 
33409
34048
  // src/agents/magic-context-prompt.ts
33410
34049
  var LONG_TERM_PARTNER_FRAME = `### You are the user's long-term partner on this project — not a one-off hire
@@ -33563,6 +34202,9 @@ Prefer many small targeted operations over one large blanket operation, and keep
33563
34202
 
33564
34203
  // src/hooks/magic-context/system-prompt-hash.ts
33565
34204
  var MAGIC_CONTEXT_MARKER = "## Magic Context";
34205
+ var SYSTEM_PROMPT_GUIDANCE_SEPARATOR = `
34206
+
34207
+ `;
33566
34208
  function clearSystemPromptHashSession(sessionId, handleMaps) {
33567
34209
  handleMaps.stickyDateBySession.delete(sessionId);
33568
34210
  handleMaps.cachedDocsBySession.delete(sessionId);
@@ -33618,13 +34260,13 @@ function createSystemPromptHashHandler(deps) {
33618
34260
  const skipGuidanceForDisabledSubagent = isSubagentSession2 && !ctxReduceCallable;
33619
34261
  const inputModel = input.model;
33620
34262
  const liveModel = inputModel?.providerID && inputModel.modelID ? { providerID: inputModel.providerID, modelID: inputModel.modelID } : deps.resolveModel?.(sessionId);
33621
- const modelKey = liveModel?.providerID && liveModel.modelID ? `${liveModel.providerID}/${liveModel.modelID}` : undefined;
34263
+ const modelKey = liveModel?.providerID && liveModel.modelID ? piModelRefToCanonical(`${liveModel.providerID}/${liveModel.modelID}`) : undefined;
33622
34264
  const promptSurface = guidanceEpochs.resolve(sessionId, deps.promptSurface, modelKey);
33623
34265
  const fullPrompt = output.system.join(`
33624
34266
  `);
33625
34267
  if (fullPrompt.length > 0 && !fullPrompt.includes(MAGIC_CONTEXT_MARKER) && !skipGuidanceForDisabledSubagent) {
33626
34268
  const guidance = buildMagicContextSection(null, deps.protectedTags, effectiveCtxReduceEnabled, deps.dreamerEnabled, deps.experimentalTemporalAwareness, deps.experimentalCavemanTextCompression, subagentReduceMode, deps.language, deps.memoryEnabled !== false, promptSurface.preset, promptSurface.primaryOverride);
33627
- output.system.push(guidance);
34269
+ output.system[0] = `${output.system[0]}${SYSTEM_PROMPT_GUIDANCE_SEPARATOR}${guidance}`;
33628
34270
  sessionLog(sessionId, `injected generic guidance into system prompt (ctxReduce=${effectiveCtxReduceEnabled}, subagent=${isSubagentSession2}, subagentReduceMode=${subagentReduceMode})`);
33629
34271
  }
33630
34272
  const isCacheBusting = deps.systemPromptRefreshSessions.has(sessionId);
@@ -33647,7 +34289,7 @@ function createSystemPromptHashHandler(deps) {
33647
34289
  }
33648
34290
  const stickyDate = stickyDateBySession.get(sessionId);
33649
34291
  const stableCandidate = currentDate && stickyDate && currentDate !== stickyDate ? liveSystemContent.replace(DATE_PATTERN_ALL, stickyDate) : liveSystemContent;
33650
- const stableCandidateHash = createHash14("md5").update(promptSurfaceHashMaterial(stableCandidate, promptSurface.preset)).digest("hex");
34292
+ const stableCandidateHash = createHash13("md5").update(promptSurfaceHashMaterial(stableCandidate, promptSurface.preset)).digest("hex");
33651
34293
  const contentOrPresetChanged = hasPersistedHash && stableCandidateHash !== previousHash;
33652
34294
  const dateMayAdvance = isCacheBusting || contentOrPresetChanged;
33653
34295
  if (currentDate && !stickyDate) {
@@ -33667,7 +34309,7 @@ function createSystemPromptHashHandler(deps) {
33667
34309
  `);
33668
34310
  if (!availability.frozen || !modelKey)
33669
34311
  return;
33670
- const currentHash = createHash14("md5").update(promptSurfaceHashMaterial(systemContent, promptSurface.preset)).digest("hex");
34312
+ const currentHash = createHash13("md5").update(promptSurfaceHashMaterial(systemContent, promptSurface.preset)).digest("hex");
33671
34313
  if (!sessionMetaEarly) {
33672
34314
  return;
33673
34315
  }
@@ -33793,8 +34435,8 @@ async function maybeSendUpgradeReminder(deps, sessionId) {
33793
34435
  remindedThisProcess.add(sessionId);
33794
34436
  return;
33795
34437
  }
33796
- const now = Date.now();
33797
- if (meta.upgradeReminderCount >= MAX_UPGRADE_REMINDERS_PER_SESSION || meta.upgradeReminderLastSentAt !== null && now - meta.upgradeReminderLastSentAt < UPGRADE_REMINDER_COOLDOWN_MS) {
34438
+ const now2 = Date.now();
34439
+ if (meta.upgradeReminderCount >= MAX_UPGRADE_REMINDERS_PER_SESSION || meta.upgradeReminderLastSentAt !== null && now2 - meta.upgradeReminderLastSentAt < UPGRADE_REMINDER_COOLDOWN_MS) {
33798
34440
  remindedThisProcess.add(sessionId);
33799
34441
  return;
33800
34442
  }
@@ -33803,7 +34445,7 @@ async function maybeSendUpgradeReminder(deps, sessionId) {
33803
34445
  const recordDelivery = () => {
33804
34446
  try {
33805
34447
  updateSessionMeta(deps.db, sessionId, {
33806
- upgradeReminderLastSentAt: now,
34448
+ upgradeReminderLastSentAt: now2,
33807
34449
  upgradeReminderCount: meta.upgradeReminderCount + 1
33808
34450
  });
33809
34451
  } catch {}
@@ -33886,7 +34528,7 @@ function createMagicContextHook(deps) {
33886
34528
  log("[magic-context] disabling feature because persistent storage is unavailable:", reason);
33887
34529
  notifyMagicContextDisabled(deps.client, reason);
33888
34530
  const migration = getMigrationOnOpenRefusal();
33889
- const blockingProcesses = migration?.serverPids.map((pid) => ({ harness: "OpenCode server", pid })) ?? [];
34531
+ const blockingProcesses = migration?.blockingProcesses ?? migration?.serverPids.map((pid) => ({ kind: "process", pid })) ?? [];
33890
34532
  const fence = getSchemaFenceRejection();
33891
34533
  recordHookInitFailure({
33892
34534
  type: "storage",
@@ -33962,7 +34604,7 @@ function createMagicContextHook(deps) {
33962
34604
  const internalChildSessions = deps.liveSessionState?.internalChildSessions ?? new Set;
33963
34605
  const recompProgressBySession = deps.liveSessionState?.recompProgressBySession ?? new Map;
33964
34606
  const dreamerProgressByProject = deps.liveSessionState?.dreamerProgressByProject ?? new Map;
33965
- const channel1StateBySession = new Map;
34607
+ const channel1StateBySession = deps.liveSessionState?.channel1StateBySession ?? new Map;
33966
34608
  const channel2DirectiveTextBySession = new Map;
33967
34609
  const resolveLiveModel = (sessionId) => {
33968
34610
  const cached = liveModelBySession.get(sessionId);
@@ -33993,6 +34635,7 @@ function createMagicContextHook(deps) {
33993
34635
  db,
33994
34636
  liveSessionState: {
33995
34637
  liveModelBySession,
34638
+ channel1StateBySession,
33996
34639
  variantBySession,
33997
34640
  agentBySession,
33998
34641
  historyRefreshSessions,
@@ -34217,7 +34860,15 @@ function createMagicContextHook(deps) {
34217
34860
  const record = value && typeof value === "object" ? value : {};
34218
34861
  const compartments = "compartments" in record && Array.isArray(record.compartments) ? record.compartments : [];
34219
34862
  const maxSequence = "max_sequence" in record && typeof record.max_sequence === "number" ? record.max_sequence : afterSequence;
34220
- return { max_sequence: maxSequence, compartments };
34863
+ const compartmentCount = "compartment_count" in record && typeof record.compartment_count === "number" ? record.compartment_count : undefined;
34864
+ const revertEpoch = "revert_epoch" in record && typeof record.revert_epoch === "number" ? record.revert_epoch : undefined;
34865
+ return {
34866
+ max_sequence: maxSequence,
34867
+ compartments,
34868
+ ...compartmentCount !== undefined ? { compartment_count: compartmentCount } : {},
34869
+ ...revertEpoch !== undefined ? { revert_epoch: revertEpoch } : {},
34870
+ ..."set_changed" in record && record.set_changed === true ? { set_changed: true } : {}
34871
+ };
34221
34872
  }
34222
34873
  };
34223
34874
  return client;
@@ -34454,13 +35105,13 @@ function createMagicContextHook(deps) {
34454
35105
  historianTwoPass: deps.config.historian?.two_pass === true,
34455
35106
  liveModelBySession,
34456
35107
  sessionDirectoryBySession,
34457
- autoSearch: deps.config.memory?.auto_search?.enabled ? {
34458
- enabled: true,
34459
- scoreThreshold: deps.config.memory?.auto_search.score_threshold,
34460
- minPromptChars: deps.config.memory?.auto_search.min_prompt_chars,
35108
+ autoSearch: {
35109
+ enabled: deps.config.memory?.auto_search?.enabled ?? true,
35110
+ scoreThreshold: deps.config.memory?.auto_search?.score_threshold ?? 0.6,
35111
+ minPromptChars: deps.config.memory?.auto_search?.min_prompt_chars ?? 20,
34461
35112
  directory: deps.directory,
34462
35113
  ensureProjectRegistered: ensureProjectRegisteredFromOpenCodeDirectory
34463
- } : undefined,
35114
+ },
34464
35115
  cavemanTextCompression: compactionOff ? undefined : deps.config.caveman_text_compression?.enabled === true ? {
34465
35116
  enabled: true,
34466
35117
  minChars: deps.config.caveman_text_compression.min_chars ?? 500
@@ -34468,6 +35119,7 @@ function createMagicContextHook(deps) {
34468
35119
  maybeAutoEmbedSession,
34469
35120
  transformMode: deps.config.transform_mode,
34470
35121
  promptSurface: deps.config.prompt_surface,
35122
+ promptSurfaceRuntime: deps.promptSurfaceRuntime,
34471
35123
  rustModeModuleClient,
34472
35124
  tsAuthorityRecoveryModuleClient: authorityRecoveryModuleClient,
34473
35125
  rustMemorySyncRequestedSessions,
@@ -34528,11 +35180,11 @@ function createMagicContextHook(deps) {
34528
35180
  if (!dreaming || dreaming.disable === true) {
34529
35181
  return;
34530
35182
  }
34531
- const now = Date.now();
34532
- if (now - lastScheduleCheckMs < DREAM_SCHEDULE_CHECK_INTERVAL_MS) {
35183
+ const now2 = Date.now();
35184
+ if (now2 - lastScheduleCheckMs < DREAM_SCHEDULE_CHECK_INTERVAL_MS) {
34533
35185
  return;
34534
35186
  }
34535
- lastScheduleCheckMs = now;
35187
+ lastScheduleCheckMs = now2;
34536
35188
  const runtimeConfigs = buildDreamTaskRuntimeConfigs(dreaming, deps.config.language);
34537
35189
  const executor = createDreamTaskExecutor({
34538
35190
  client: deps.client,
@@ -34581,6 +35233,7 @@ function createMagicContextHook(deps) {
34581
35233
  return model ? `${model.providerID}/${model.modelID}` : undefined;
34582
35234
  },
34583
35235
  getDreamerProgress: () => dreamerProgressByProject.get(projectPath) ?? null,
35236
+ getTailHygiene: (sessionId) => channel1StateBySession.get(sessionId),
34584
35237
  getContextLimit: (sessionId) => {
34585
35238
  const model = resolveLiveModel(sessionId);
34586
35239
  if (!model)
@@ -34804,9 +35457,9 @@ async function createSessionHooksAsync(args) {
34804
35457
  }
34805
35458
 
34806
35459
  // src/plugin/instance-disposal.ts
34807
- import path5 from "node:path";
35460
+ import path6 from "node:path";
34808
35461
  function isDisposedInstanceDirectory(ownDirectory, disposedDirectory) {
34809
- return path5.resolve(disposedDirectory) === path5.resolve(ownDirectory);
35462
+ return path6.resolve(disposedDirectory) === path6.resolve(ownDirectory);
34810
35463
  }
34811
35464
 
34812
35465
  // src/plugin/messages-transform.ts
@@ -34815,8 +35468,27 @@ function replaceMessagesInPlace2(output, next) {
34815
35468
  if (output.messages !== next)
34816
35469
  output.messages.splice(0, output.messages.length, ...next);
34817
35470
  }
35471
+ function preserveUserTerminatedTail(messages, inputTail) {
35472
+ if (inputTail?.info.role !== "user" || messages.at(-1)?.info.role !== "assistant")
35473
+ return;
35474
+ let userIndex = messages.lastIndexOf(inputTail);
35475
+ if (userIndex < 0) {
35476
+ const inputId = inputTail.info.id;
35477
+ for (let index = messages.length - 1;index >= 0; index -= 1) {
35478
+ const message = messages[index];
35479
+ if (message.info.role === "user" && message.info.id === inputId) {
35480
+ userIndex = index;
35481
+ break;
35482
+ }
35483
+ }
35484
+ }
35485
+ const trailingUser = userIndex >= 0 ? messages[userIndex] : inputTail;
35486
+ if (userIndex >= 0)
35487
+ messages.splice(userIndex, 1);
35488
+ messages.push(trailingUser);
35489
+ }
34818
35490
  function createMessagesTransformHandler(args) {
34819
- return async (input, output) => {
35491
+ const run = async (input, output) => {
34820
35492
  const sessionId = resolveSessionId2(output);
34821
35493
  const agent = resolveAgentNameFromMessages(output.messages);
34822
35494
  const isInternalChild = typeof sessionId === "string" && sessionId.length > 0 && args.internalChildSessions?.has(sessionId) === true;
@@ -34937,6 +35609,14 @@ function createMessagesTransformHandler(args) {
34937
35609
  restoreCompactionOffInput();
34938
35610
  return output.messages;
34939
35611
  };
35612
+ return async (input, output) => {
35613
+ const inputTail = output.messages.at(-1);
35614
+ try {
35615
+ return await run(input, output);
35616
+ } finally {
35617
+ preserveUserTerminatedTail(output.messages, inputTail);
35618
+ }
35619
+ };
34940
35620
  }
34941
35621
  function resolveSessionId2(output) {
34942
35622
  for (const message of output.messages) {
@@ -35325,6 +36005,7 @@ function buildSidebarSnapshot(db, sessionId, directory, liveSessionState, inject
35325
36005
  }) : contextLimit;
35326
36006
  const nativeContextUsagePercentage = nativeContextLimit > 0 ? effectiveInputTokens / nativeContextLimit * 100 : undefined;
35327
36007
  const calibration = resolveModelCalibration(activeProviderID, activeModelID);
36008
+ const tailHygiene = resolveTailHygieneStatus(liveSessionState?.channel1StateBySession.get(sessionId), moduleStatus?.tail_hygiene);
35328
36009
  const calibrated = calibrateBuckets({
35329
36010
  inputTokens: effectiveInputTokens,
35330
36011
  systemLocal: systemPromptTokens,
@@ -35369,6 +36050,7 @@ function buildSidebarSnapshot(db, sessionId, directory, liveSessionState, inject
35369
36050
  conversationTokens: calibrated.conversationTokens,
35370
36051
  toolCallTokens: calibrated.toolCallTokens,
35371
36052
  toolDefinitionTokens: calibrated.toolDefinitionTokens,
36053
+ ...tailHygiene === undefined ? {} : { tailHygiene },
35372
36054
  executeThreshold,
35373
36055
  executeThresholdClamped,
35374
36056
  boundaryPresent: moduleStatus?.boundary_present,
@@ -35432,6 +36114,7 @@ function buildStatusDetail(db, sessionId, directory, modelKey, config, liveSessi
35432
36114
  compressionUsage: null,
35433
36115
  toastDurationMs: 5000,
35434
36116
  mural: undefined,
36117
+ loggerDiagnostics: getLoggerDiagnostics(),
35435
36118
  storage_versions: {
35436
36119
  context_db_schema_version: null,
35437
36120
  plugin_supported_version: LATEST_SUPPORTED_VERSION
@@ -35470,6 +36153,10 @@ function buildStatusDetail(db, sessionId, directory, modelKey, config, liveSessi
35470
36153
  const ops = db.prepare("SELECT tag_id, operation FROM pending_ops WHERE session_id = ? LIMIT 100").all(sessionId);
35471
36154
  detail.pendingOps = ops.map((o) => ({ tagId: o.tag_id, operation: o.operation }));
35472
36155
  } catch {}
36156
+ const modelSlash = modelKey?.indexOf("/") ?? -1;
36157
+ if (modelKey && modelSlash > 0) {
36158
+ detail.windowGeometry = resolveContextWindowGeometry(modelKey.slice(0, modelSlash), modelKey.slice(modelSlash + 1), { db, sessionID: sessionId });
36159
+ }
35473
36160
  const contextLimitForTokens = base.contextLimit > 0 ? base.contextLimit : base.usagePercentage > 0 ? Math.round(base.inputTokens / (base.usagePercentage / 100)) : 0;
35474
36161
  if (config) {
35475
36162
  const pctCfg = config.execute_threshold_percentage;
@@ -35600,7 +36287,7 @@ function registerRpcHandlers(rpcServer, args) {
35600
36287
  }
35601
36288
  });
35602
36289
  const buildManagedCtx = async (db) => {
35603
- const { deriveHistorianChunkTokens: deriveHistorianChunkTokens2, resolveHistorianContextLimit: resolveHistorianContextLimit2 } = await import("./derive-budgets-88mxk2w1.js");
36290
+ const { deriveHistorianChunkTokens: deriveHistorianChunkTokens2, resolveHistorianContextLimit: resolveHistorianContextLimit2 } = await import("./derive-budgets-da4yg3tz.js");
35604
36291
  const { resolveFallbackChain: resolveFallbackChain2 } = await import("./resolve-fallbacks-5n5tvge1.js");
35605
36292
  const { userMemoryCollectionEnabled: userMemoryCollectionEnabled2 } = await import("./task-config-gbp7r23g.js");
35606
36293
  const DEFAULT_HISTORIAN_TIMEOUT_MS2 = 600000;
@@ -35627,8 +36314,8 @@ function registerRpcHandlers(rpcServer, args) {
35627
36314
  const db = getDb();
35628
36315
  if (!db)
35629
36316
  return { ok: false, error: "db unavailable" };
35630
- const { runManagedRecomp: runManagedRecomp2 } = await import("./recomp-orchestrator-a0g9b52q.js");
35631
- const { sendIgnoredMessage: sendIgnoredMessage2 } = await import("./send-session-notification-bgtf4853.js");
36317
+ const { runManagedRecomp: runManagedRecomp2 } = await import("./recomp-orchestrator-jsde4ygw.js");
36318
+ const { sendIgnoredMessage: sendIgnoredMessage2 } = await import("./send-session-notification-dxske5zm.js");
35632
36319
  log(`[rpc] recomp requested for session ${sessionId}`);
35633
36320
  const ctx = await buildManagedCtx(db);
35634
36321
  runManagedRecomp2(ctx, sessionId).then((message) => {
@@ -35643,8 +36330,8 @@ function registerRpcHandlers(rpcServer, args) {
35643
36330
  const db = getDb();
35644
36331
  if (!db)
35645
36332
  return { ok: false, error: "db unavailable" };
35646
- const { runManagedUpgrade: runManagedUpgrade2 } = await import("./recomp-orchestrator-a0g9b52q.js");
35647
- const { sendIgnoredMessage: sendIgnoredMessage2 } = await import("./send-session-notification-bgtf4853.js");
36333
+ const { runManagedUpgrade: runManagedUpgrade2 } = await import("./recomp-orchestrator-jsde4ygw.js");
36334
+ const { sendIgnoredMessage: sendIgnoredMessage2 } = await import("./send-session-notification-dxske5zm.js");
35648
36335
  log(`[rpc] session-upgrade requested for session ${sessionId}`);
35649
36336
  const ctx = await buildManagedCtx(db);
35650
36337
  runManagedUpgrade2(ctx, sessionId).then((message) => {
@@ -35660,7 +36347,7 @@ function registerRpcHandlers(rpcServer, args) {
35660
36347
  if (!db)
35661
36348
  return { ok: false, error: "db unavailable" };
35662
36349
  try {
35663
- const { updateSessionMeta: updateSessionMeta2 } = await import("./storage-meta-session-df9tstzr.js");
36350
+ const { updateSessionMeta: updateSessionMeta2 } = await import("./storage-meta-session-mk4gsnke.js");
35664
36351
  updateSessionMeta2(db, sessionId, { upgradeRemindedAt: Date.now() });
35665
36352
  return { ok: true };
35666
36353
  } catch (error) {
@@ -36059,13 +36746,22 @@ function normalizeCategory(category) {
36059
36746
  const trimmed = category?.trim();
36060
36747
  return trimmed ? trimmed : undefined;
36061
36748
  }
36062
- function moduleMemoryText(response) {
36749
+ function memoryAuthorityRefusal(args) {
36750
+ const readiness = "Rust memory authority is not ready.";
36751
+ if ((args.action === "write" || args.action === "update" || args.action === "merge") && typeof args.content === "string") {
36752
+ return `Error: ${readiness} Write REFUSED and NOT saved; RESEND after authority is ready.
36753
+ Content to resend:
36754
+ ${args.content}`;
36755
+ }
36756
+ return `Error: ${readiness} Request REFUSED and NOT applied; RESEND after authority is ready.`;
36757
+ }
36758
+ function moduleMemoryText(response, args) {
36063
36759
  let value = response;
36064
36760
  if (value !== null && typeof value === "object" && "result" in value) {
36065
36761
  value = value.result;
36066
36762
  }
36067
36763
  if (isRustAuthorityDrainingError(value)) {
36068
- return "Error: Rust memory authority is not ready; TypeScript fallback is disabled.";
36764
+ return memoryAuthorityRefusal(args);
36069
36765
  }
36070
36766
  if (typeof value === "string")
36071
36767
  return value;
@@ -36298,17 +36994,17 @@ function createCtxMemoryTool(deps) {
36298
36994
  category: args.category,
36299
36995
  ids: args.ids,
36300
36996
  reason: args.reason
36301
- }));
36997
+ }), args);
36302
36998
  return text ?? "Error: Rust module returned an invalid ctx_memory response.";
36303
36999
  } catch (error) {
36304
37000
  if (isRustAuthorityDrainingError(error)) {
36305
- return "Error: Rust memory authority is not ready; TypeScript fallback is disabled.";
37001
+ return memoryAuthorityRefusal(args);
36306
37002
  }
36307
37003
  return `Error: Rust module ctx_memory failed. ${error instanceof Error ? error.message : String(error)}`;
36308
37004
  }
36309
37005
  }
36310
37006
  if (marker || authorityState === "PREPARING" || authorityState === "DRAINING") {
36311
- return "Error: Rust memory authority is not ready; TypeScript fallback is disabled.";
37007
+ return memoryAuthorityRefusal(args);
36312
37008
  }
36313
37009
  }
36314
37010
  const workspaceIdentitySet = resolveWorkspaceIdentitySet(deps.db, projectPath);
@@ -36618,13 +37314,13 @@ Example: ctx_note(action="write", content="Re-run the perf benchmark once the bo
36618
37314
  import { tool as tool3 } from "@opencode-ai/plugin";
36619
37315
 
36620
37316
  // src/features/magic-context/smart-notes/condition-compiler.ts
36621
- import { existsSync as existsSync11 } from "node:fs";
37317
+ import { existsSync as existsSync12 } from "node:fs";
36622
37318
  import { isAbsolute as isAbsolute4 } from "node:path";
36623
37319
 
36624
37320
  // ../retina-local-fs/src/path-fence.ts
36625
37321
  import { lstat as lstat2, readlink, realpath as realpath2 } from "node:fs/promises";
36626
37322
  import { homedir as homedir4 } from "node:os";
36627
- import { basename, dirname as dirname4, isAbsolute as isAbsolute3, join as join6, relative, resolve as resolve3, sep } from "node:path";
37323
+ import { basename, dirname as dirname5, isAbsolute as isAbsolute3, join as join8, relative, resolve as resolve3, sep } from "node:path";
36628
37324
 
36629
37325
  // ../retina-local-fs/src/errors.ts
36630
37326
  class ProviderError extends Error {
@@ -36639,7 +37335,7 @@ class ProviderError extends Error {
36639
37335
  // ../retina-local-fs/src/path-fence.ts
36640
37336
  async function resolveAndFenceProviderPath(configuredPath, options) {
36641
37337
  const { home, dataDirectory } = await resolveFenceRoots(options);
36642
- const expanded = configuredPath.startsWith("~/") ? join6(home, configuredPath.slice(2)) : configuredPath === "~" ? home : configuredPath;
37338
+ const expanded = configuredPath.startsWith("~/") ? join8(home, configuredPath.slice(2)) : configuredPath === "~" ? home : configuredPath;
36643
37339
  const absolute = isAbsolute3(expanded) ? resolve3(expanded) : resolve3(options.cwd ?? process.cwd(), expanded);
36644
37340
  const canonical = await canonicalPath(absolute, options.allowMissing);
36645
37341
  if (isFencedPath(canonical, home, dataDirectory)) {
@@ -36655,50 +37351,50 @@ async function resolveFenceRoots(options) {
36655
37351
  } catch (error) {
36656
37352
  throw fsError(configuredHomePath, error);
36657
37353
  }
36658
- const configuredDataDirectory = resolve3(options.dataDirectory ?? process.env.XDG_DATA_HOME ?? join6(home, ".local", "share"));
37354
+ const configuredDataDirectory = resolve3(options.dataDirectory ?? process.env.XDG_DATA_HOME ?? join8(home, ".local", "share"));
36659
37355
  const dataDirectory = await canonicalPath(configuredDataDirectory, true);
36660
37356
  return { home, dataDirectory };
36661
37357
  }
36662
- async function canonicalPath(path6, allowMissing) {
37358
+ async function canonicalPath(path7, allowMissing) {
36663
37359
  try {
36664
- return await realpath2(path6);
37360
+ return await realpath2(path7);
36665
37361
  } catch (error) {
36666
37362
  if (!allowMissing || !isMissingError(error)) {
36667
- throw fsError(path6, error);
37363
+ throw fsError(path7, error);
36668
37364
  }
36669
37365
  const suffix = [];
36670
- let candidate = path6;
37366
+ let candidate = path7;
36671
37367
  while (true) {
36672
37368
  try {
36673
37369
  const metadata = await lstat2(candidate);
36674
37370
  if (metadata.isSymbolicLink()) {
36675
37371
  const target = await readlink(candidate);
36676
- const resolvedTarget = resolve3(dirname4(candidate), target);
36677
- return canonicalPath(join6(resolvedTarget, ...suffix), true);
37372
+ const resolvedTarget = resolve3(dirname5(candidate), target);
37373
+ return canonicalPath(join8(resolvedTarget, ...suffix), true);
36678
37374
  }
36679
37375
  } catch (candidateError) {
36680
37376
  if (!isMissingError(candidateError)) {
36681
- throw fsError(path6, candidateError);
37377
+ throw fsError(path7, candidateError);
36682
37378
  }
36683
37379
  }
36684
- const parent = dirname4(candidate);
37380
+ const parent = dirname5(candidate);
36685
37381
  if (parent === candidate) {
36686
- throw fsError(path6, error);
37382
+ throw fsError(path7, error);
36687
37383
  }
36688
37384
  suffix.unshift(basename(candidate));
36689
37385
  candidate = parent;
36690
37386
  try {
36691
- return join6(await realpath2(candidate), ...suffix);
37387
+ return join8(await realpath2(candidate), ...suffix);
36692
37388
  } catch (parentError) {
36693
37389
  if (!isMissingError(parentError)) {
36694
- throw fsError(path6, parentError);
37390
+ throw fsError(path7, parentError);
36695
37391
  }
36696
37392
  }
36697
37393
  }
36698
37394
  }
36699
37395
  }
36700
- function isFencedPath(canonicalPath2, homeDirectory, dataDirectory = process.env.XDG_DATA_HOME ?? join6(resolve3(homeDirectory), ".local", "share")) {
36701
- const cortexkitRoot = join6(resolve3(dataDirectory), "cortexkit");
37396
+ function isFencedPath(canonicalPath2, homeDirectory, dataDirectory = process.env.XDG_DATA_HOME ?? join8(resolve3(homeDirectory), ".local", "share")) {
37397
+ const cortexkitRoot = join8(resolve3(dataDirectory), "cortexkit");
36702
37398
  const relativeToCortexkit = relative(cortexkitRoot, canonicalPath2);
36703
37399
  const insideCortexkit = relativeToCortexkit !== "" && relativeToCortexkit !== ".." && !relativeToCortexkit.startsWith(`..${sep}`) && !isAbsolute3(relativeToCortexkit);
36704
37400
  const parts = insideCortexkit ? relativeToCortexkit.split(sep) : [];
@@ -36716,9 +37412,9 @@ function isFencedPath(canonicalPath2, homeDirectory, dataDirectory = process.env
36716
37412
  const plexusStore = insideCortexkit && parts[0] === "plexus" && name.startsWith("store.db");
36717
37413
  return inFencedRoot || fencedBasename || plexusStore;
36718
37414
  }
36719
- function fsError(path6, error) {
37415
+ function fsError(path7, error) {
36720
37416
  const message = error instanceof Error ? error.message : String(error);
36721
- return new ProviderError("unreadable_path", `Could not read ${path6}: ${message}`);
37417
+ return new ProviderError("unreadable_path", `Could not read ${path7}: ${message}`);
36722
37418
  }
36723
37419
  function isMissingError(error) {
36724
37420
  return error !== null && typeof error === "object" && "code" in error && (error.code === "ENOENT" || error.code === "ENOTDIR");
@@ -36867,20 +37563,20 @@ async function compileSurfaceCondition(surfaceCondition, options) {
36867
37563
  const parsed = parseCondition(surfaceCondition, options.projectPath);
36868
37564
  if (parsed === null)
36869
37565
  return { status: "plain" };
36870
- const now = (options.now ?? Date.now)();
36871
- const resolvePath = options.resolvePath ?? (async (path6) => {
36872
- const resolved = await resolveAndFenceProviderPath(path6, {
37566
+ const now2 = (options.now ?? Date.now)();
37567
+ const resolvePath = options.resolvePath ?? (async (path7) => {
37568
+ const resolved = await resolveAndFenceProviderPath(path7, {
36873
37569
  allowMissing: true,
36874
37570
  homeDirectory: options.homeDirectory,
36875
37571
  cwd: options.projectPath
36876
37572
  });
36877
- return { path: resolved, exists: existsSync11(resolved) };
37573
+ return { path: resolved, exists: existsSync12(resolved) };
36878
37574
  });
36879
37575
  let predicates;
36880
37576
  try {
36881
37577
  predicates = [];
36882
37578
  for (const predicate of parsed) {
36883
- predicates.push(await resolvePredicate(predicate, resolvePath, now));
37579
+ predicates.push(await resolvePredicate(predicate, resolvePath, now2));
36884
37580
  }
36885
37581
  } catch (error) {
36886
37582
  const code = error !== null && typeof error === "object" && "code" in error ? error.code : undefined;
@@ -36901,7 +37597,7 @@ async function compileSurfaceCondition(surfaceCondition, options) {
36901
37597
  status: "compiled",
36902
37598
  provider: RETINA_LOCAL_FS_PROVIDER,
36903
37599
  config: validation.config,
36904
- compiledAt: now
37600
+ compiledAt: now2
36905
37601
  };
36906
37602
  }
36907
37603
  function conditionCompileStorageFields(result) {
@@ -36947,13 +37643,13 @@ function parseCondition(surfaceCondition, projectPath) {
36947
37643
  function parseAtomicCondition(text, projectPath) {
36948
37644
  const fileContains = text.match(new RegExp(`^(?:when\\s+)?file\\s+(${VALUE})\\s+(no longer contains|contains)\\s+(${VALUE})$`, "i"));
36949
37645
  if (fileContains) {
36950
- const path6 = unquote(fileContains[1]);
37646
+ const path7 = unquote(fileContains[1]);
36951
37647
  const needle = unquote(fileContains[3].trim());
36952
- if (path6 === null || needle === null)
37648
+ if (path7 === null || needle === null)
36953
37649
  return null;
36954
37650
  return {
36955
37651
  kind: "file_contains",
36956
- path: path6,
37652
+ path: path7,
36957
37653
  needle,
36958
37654
  ...fileContains[2].toLowerCase() === "no longer contains" ? { absent: true } : {}
36959
37655
  };
@@ -36985,28 +37681,28 @@ function parseAtomicCondition(text, projectPath) {
36985
37681
  }
36986
37682
  const mtime = text.match(new RegExp(`^(?:when\\s+)?(?:file\\s+)?(${VALUE})\\s+(changes|is rebuilt|mtime moves)$`, "i"));
36987
37683
  if (mtime) {
36988
- const path6 = unquote(mtime[1]);
36989
- if (path6 === null)
37684
+ const path7 = unquote(mtime[1]);
37685
+ if (path7 === null)
36990
37686
  return null;
36991
37687
  return {
36992
37688
  kind: "mtime_after",
36993
- path: path6
37689
+ path: path7
36994
37690
  };
36995
37691
  }
36996
37692
  const pathExists = text.match(new RegExp(`^(?:when\\s+)?(?:path\\s+)?(${VALUE})\\s+(exists|is gone)$`, "i"));
36997
37693
  if (pathExists) {
36998
- const path6 = unquote(pathExists[1]);
36999
- if (path6 === null)
37694
+ const path7 = unquote(pathExists[1]);
37695
+ if (path7 === null)
37000
37696
  return null;
37001
37697
  return {
37002
37698
  kind: "path_exists",
37003
- path: path6,
37699
+ path: path7,
37004
37700
  ...pathExists[2].toLowerCase() === "is gone" ? { gone: true } : {}
37005
37701
  };
37006
37702
  }
37007
37703
  return null;
37008
37704
  }
37009
- async function resolvePredicate(predicate, resolvePath, now) {
37705
+ async function resolvePredicate(predicate, resolvePath, now2) {
37010
37706
  const configuredPath = "repo_path" in predicate ? predicate.repo_path : predicate.path;
37011
37707
  const resolved = await resolvePath(configuredPath);
37012
37708
  const sourceIsResolvable = isAbsolute4(configuredPath) || configuredPath === "~" || configuredPath.startsWith("~/");
@@ -37017,7 +37713,7 @@ async function resolvePredicate(predicate, resolvePath, now) {
37017
37713
  case "path_exists":
37018
37714
  return { ...predicate, path: resolved.path, ...audit };
37019
37715
  case "mtime_after":
37020
- return { kind: predicate.kind, path: resolved.path, since_ms: now, ...audit };
37716
+ return { kind: predicate.kind, path: resolved.path, since_ms: now2, ...audit };
37021
37717
  case "git_commit_after":
37022
37718
  return { ...predicate, repo_path: resolved.path, ...audit };
37023
37719
  case "git_tag_matching":
@@ -37207,13 +37903,22 @@ ${footer}` : ""}`);
37207
37903
  }
37208
37904
  return sections;
37209
37905
  }
37210
- function moduleNoteText(response) {
37906
+ function noteAuthorityRefusal(args, action) {
37907
+ const readiness = "Rust notes authority is not ready.";
37908
+ if ((action === "write" || action === "update") && typeof args.content === "string") {
37909
+ return `Error: ${readiness} Write REFUSED and NOT saved; RESEND after authority is ready.
37910
+ Content to resend:
37911
+ ${args.content}`;
37912
+ }
37913
+ return `Error: ${readiness} Request REFUSED and NOT applied; RESEND after authority is ready.`;
37914
+ }
37915
+ function moduleNoteText(response, args, action) {
37211
37916
  let value = response;
37212
37917
  if (value !== null && typeof value === "object" && "result" in value) {
37213
37918
  value = value.result;
37214
37919
  }
37215
37920
  if (isRustAuthorityDrainingError(value)) {
37216
- return "Error: Rust notes authority is not ready; TypeScript fallback is disabled.";
37921
+ return noteAuthorityRefusal(args, action);
37217
37922
  }
37218
37923
  if (typeof value === "string")
37219
37924
  return value;
@@ -37264,6 +37969,8 @@ function createCtxNoteTool(deps) {
37264
37969
  });
37265
37970
  const sessionId = toolContext.sessionID;
37266
37971
  const action = args.action ?? (args.content?.trim() ? "write" : "read");
37972
+ const wakePlaneActive = action === "write" && Boolean(args.surface_condition?.trim()) && await wakePlaneStatus() === "present";
37973
+ const surfaceCondition = wakePlaneActive ? undefined : args.surface_condition?.trim();
37267
37974
  const projectIdentity = deps.resolveProjectPath?.(toolContext.directory);
37268
37975
  const marker = projectIdentity ? getAuthorityManagedMarker(deps.db, projectIdentity) : null;
37269
37976
  let notesAuthority = null;
@@ -37285,7 +37992,6 @@ function createCtxNoteTool(deps) {
37285
37992
  if (!rustNote || !projectIdentity) {
37286
37993
  return "Error: Rust notes authority is active, but this module transport does not support ctx_note.";
37287
37994
  }
37288
- const surfaceCondition = args.surface_condition?.trim();
37289
37995
  let compilation;
37290
37996
  if ((action === "write" || action === "update") && surfaceCondition) {
37291
37997
  if (deps.rustToolBackends?.noteEvaluationAvailable?.(projectIdentity) !== true) {
@@ -37312,23 +38018,28 @@ function createCtxNoteTool(deps) {
37312
38018
  noteId: args.note_id
37313
38019
  };
37314
38020
  try {
37315
- const text = moduleNoteText(await rustNote(request2));
38021
+ const text = moduleNoteText(await rustNote(request2), args, action);
37316
38022
  if (text === null) {
37317
38023
  return "Error: Rust module returned an invalid ctx_note response.";
37318
38024
  }
37319
- if (compilation && !text.startsWith("Error:")) {
37320
- return text + conditionCompileReplySuffix(compilation);
38025
+ if (text.startsWith("Error:"))
38026
+ return text;
38027
+ if (wakePlaneActive) {
38028
+ return `${text}
38029
+ wake plane active — create a scheduled wake instead; stored as a plain note.`;
37321
38030
  }
38031
+ if (compilation)
38032
+ return text + conditionCompileReplySuffix(compilation);
37322
38033
  return text;
37323
38034
  } catch (error) {
37324
38035
  if (isRustAuthorityDrainingError(error)) {
37325
- return "Error: Rust notes authority is not ready; TypeScript fallback is disabled.";
38036
+ return noteAuthorityRefusal(args, action);
37326
38037
  }
37327
38038
  return `Error: Rust module ctx_note failed. ${error instanceof Error ? error.message : String(error)}`;
37328
38039
  }
37329
38040
  }
37330
38041
  if (marker || notesAuthority === "PREPARING" || notesAuthority === "DRAINING") {
37331
- return "Error: Rust notes authority is not ready; TypeScript fallback is disabled.";
38042
+ return noteAuthorityRefusal(args, action);
37332
38043
  }
37333
38044
  if (action === "write") {
37334
38045
  const content = args.content?.trim();
@@ -37337,27 +38048,36 @@ function createCtxNoteTool(deps) {
37337
38048
  }
37338
38049
  const anchorOrdinal = captureAnchorOrdinal(deps.db, sessionId);
37339
38050
  if (args.surface_condition?.trim()) {
38051
+ if (wakePlaneActive) {
38052
+ const note3 = addNote(deps.db, "session", {
38053
+ sessionId,
38054
+ content,
38055
+ anchorOrdinal
38056
+ });
38057
+ return `Saved session note #${note3.id}.
38058
+ wake plane active — create a scheduled wake instead; stored as a plain note.`;
38059
+ }
37340
38060
  if (!deps.dreamerEnabled) {
37341
38061
  return "Error: Smart notes require dreamer to be enabled. Enable dreamer in magic-context.jsonc to use surface_condition.";
37342
38062
  }
37343
38063
  if (!projectIdentity) {
37344
38064
  return "Error: Could not resolve project identity for smart note.";
37345
38065
  }
37346
- const surfaceCondition = args.surface_condition.trim();
37347
- const compilation = await compileSurfaceCondition(surfaceCondition, {
38066
+ const smartSurfaceCondition = args.surface_condition.trim();
38067
+ const compilation = await compileSurfaceCondition(smartSurfaceCondition, {
37348
38068
  projectPath: toolContext.directory
37349
38069
  });
37350
38070
  const note2 = addNote(deps.db, "smart", {
37351
38071
  content,
37352
38072
  projectPath: projectIdentity,
37353
38073
  sessionId,
37354
- surfaceCondition,
38074
+ surfaceCondition: smartSurfaceCondition,
37355
38075
  anchorOrdinal,
37356
38076
  ...conditionCompileStorageFields(compilation)
37357
38077
  });
37358
38078
  return `Created smart note #${note2.id}. Dreamer will evaluate the condition during nightly runs:
37359
38079
  - Content: ${content}
37360
- - Condition: ${surfaceCondition}${conditionCompileReplySuffix(compilation)}`;
38080
+ - Condition: ${smartSurfaceCondition}${conditionCompileReplySuffix(compilation)}`;
37361
38081
  }
37362
38082
  const note = addNote(deps.db, "session", { sessionId, content, anchorOrdinal });
37363
38083
  return `Saved session note #${note.id}.`;
@@ -37386,9 +38106,9 @@ function createCtxNoteTool(deps) {
37386
38106
  updates.content = args.content.trim();
37387
38107
  let compilation;
37388
38108
  if (args.surface_condition?.trim()) {
37389
- const surfaceCondition = args.surface_condition.trim();
37390
- updates.surfaceCondition = surfaceCondition;
37391
- compilation = await compileSurfaceCondition(surfaceCondition, {
38109
+ const surfaceCondition2 = args.surface_condition.trim();
38110
+ updates.surfaceCondition = surfaceCondition2;
38111
+ compilation = await compileSurfaceCondition(surfaceCondition2, {
37392
38112
  projectPath: toolContext.directory
37393
38113
  });
37394
38114
  Object.assign(updates, conditionCompileStorageFields(compilation));
@@ -37460,7 +38180,7 @@ Mark discardable once processed: large outputs you've summarized, repeated or re
37460
38180
  Keep: user messages, unresolved errors, raw evidence you haven't extracted yet, and outputs whose exact wording may matter later.
37461
38181
  Never blanket-mark large ranges (e.g. "1-50") — review what each tag holds first.`;
37462
38182
  // src/tools/ctx-reduce/tools.ts
37463
- import { createHash as createHash15 } from "node:crypto";
38183
+ import { createHash as createHash14 } from "node:crypto";
37464
38184
  import { tool as tool4 } from "@opencode-ai/plugin";
37465
38185
 
37466
38186
  // src/features/magic-context/range-parser.ts
@@ -37530,11 +38250,11 @@ function createCtxReduceTool(deps) {
37530
38250
  const stableId = `oc-${sessionId}-${callId}`;
37531
38251
  if (Buffer.byteLength(stableId) <= 128)
37532
38252
  return stableId;
37533
- return `oc-${createHash15("sha256").update(stableId).digest("hex")}`;
38253
+ return `oc-${createHash14("sha256").update(stableId).digest("hex")}`;
37534
38254
  }
37535
38255
  fallbackCommandSequence += 1;
37536
38256
  const monotonicId = `oc-${sessionId}-${fallbackCommandSequence}`;
37537
- return Buffer.byteLength(monotonicId) <= 128 ? monotonicId : `oc-${createHash15("sha256").update(monotonicId).digest("hex")}`;
38257
+ return Buffer.byteLength(monotonicId) <= 128 ? monotonicId : `oc-${createHash14("sha256").update(monotonicId).digest("hex")}`;
37538
38258
  };
37539
38259
  return tool4({
37540
38260
  description: CTX_REDUCE_DESCRIPTION,
@@ -37609,9 +38329,9 @@ function createCtxReduceTool(deps) {
37609
38329
  }
37610
38330
  try {
37611
38331
  deps.db.transaction(() => {
37612
- const now = Date.now();
38332
+ const now2 = Date.now();
37613
38333
  for (const id of dropIds) {
37614
- queuePendingOp(deps.db, sessionId, id, "drop", now);
38334
+ queuePendingOp(deps.db, sessionId, id, "drop", now2);
37615
38335
  }
37616
38336
  })();
37617
38337
  } catch (error) {
@@ -37974,15 +38694,15 @@ function unregisterExitAbort(controller) {
37974
38694
  import { randomBytes, timingSafeEqual } from "node:crypto";
37975
38695
  import {
37976
38696
  chmodSync,
37977
- mkdirSync as mkdirSync2,
38697
+ mkdirSync as mkdirSync3,
37978
38698
  readdirSync,
37979
38699
  readFileSync as readFileSync6,
37980
- renameSync as renameSync3,
37981
- rmSync as rmSync2,
38700
+ renameSync as renameSync4,
38701
+ rmSync as rmSync3,
37982
38702
  unlinkSync,
37983
38703
  writeFileSync as writeFileSync4
37984
38704
  } from "node:fs";
37985
- import { dirname as dirname5 } from "node:path";
38705
+ import { dirname as dirname6 } from "node:path";
37986
38706
  var MAX_BODY_BYTES = 1048576;
37987
38707
  var WS_AUTH_TIMEOUT_MS = 5000;
37988
38708
  var WS_CLOSE_UNAUTHORIZED = 4401;
@@ -38056,28 +38776,29 @@ class MagicContextRpcServer {
38056
38776
  this.port = server.port ?? 0;
38057
38777
  try {
38058
38778
  this.warnIfOtherLiveInstance();
38059
- const dir = dirname5(this.portFilePath);
38779
+ const dir = dirname6(this.portFilePath);
38060
38780
  const enforcePrivatePermissions = shouldEnforcePrivateStoragePermissions();
38061
38781
  if (enforcePrivatePermissions) {
38062
- mkdirSync2(dir, { recursive: true, mode: 448 });
38782
+ mkdirSync3(dir, { recursive: true, mode: 448 });
38063
38783
  try {
38064
38784
  chmodSync(dir, 448);
38065
38785
  } catch {}
38066
38786
  } else {
38067
- mkdirSync2(dir, { recursive: true });
38787
+ mkdirSync3(dir, { recursive: true });
38068
38788
  }
38069
38789
  const tmpPath = `${this.portFilePath}.tmp`;
38070
38790
  try {
38071
- rmSync2(tmpPath, { force: true });
38791
+ rmSync3(tmpPath, { force: true });
38072
38792
  } catch {}
38073
38793
  writeFileSync4(tmpPath, JSON.stringify({
38074
38794
  port: this.port,
38075
38795
  pid: process.pid,
38076
38796
  started_at: this.startedAt,
38797
+ kind: "OpenCode server",
38077
38798
  token: this.token,
38078
38799
  instance_id: this.instanceId
38079
38800
  }), enforcePrivatePermissions ? { encoding: "utf-8", mode: 384 } : { encoding: "utf-8" });
38080
- renameSync3(tmpPath, this.portFilePath);
38801
+ renameSync4(tmpPath, this.portFilePath);
38081
38802
  if (enforcePrivatePermissions) {
38082
38803
  try {
38083
38804
  chmodSync(this.portFilePath, 384);
@@ -38289,7 +39010,7 @@ var server = async (ctx) => {
38289
39010
  `);
38290
39011
  setTimeout(async () => {
38291
39012
  try {
38292
- const { sendIgnoredMessage: sendIgnoredMessage2 } = await import("./send-session-notification-bgtf4853.js");
39013
+ const { sendIgnoredMessage: sendIgnoredMessage2 } = await import("./send-session-notification-dxske5zm.js");
38293
39014
  const clientWithSessions = ctx.client;
38294
39015
  const sessions = await Promise.resolve(clientWithSessions.session?.list?.()).catch(() => null);
38295
39016
  const sessionList = Array.isArray(sessions) ? sessions : sessions?.data;
@@ -38302,8 +39023,13 @@ var server = async (ctx) => {
38302
39023
  }
38303
39024
  let conflictResult = null;
38304
39025
  if (pluginConfig.enabled) {
39026
+ const resolvedCompaction = await resolveCompactionForBoot(ctx.client);
39027
+ if (resolvedCompaction === null) {
39028
+ log("[magic-context] resolved-config fetch failed; using file-based compaction detection (the running server's resolved config may differ — `opencode debug config` is authoritative)");
39029
+ }
38305
39030
  conflictResult = detectConflicts(ctx.directory, {
38306
- compactionEnabled: isCompactionEnabled(pluginConfig)
39031
+ compactionEnabled: isCompactionEnabled(pluginConfig),
39032
+ resolvedCompaction: resolvedCompaction ?? undefined
38307
39033
  });
38308
39034
  if (conflictResult.hasConflict) {
38309
39035
  pluginConfig.enabled = false;
@@ -38471,7 +39197,7 @@ var server = async (ctx) => {
38471
39197
  {
38472
39198
  const fence = getSchemaFenceRejection();
38473
39199
  if (fence) {
38474
- import("./conflict-warning-hook-mt0ttc4x.js").then(({ sendSchemaFenceWarning }) => sendSchemaFenceWarning(ctx.client, ctx.directory, fence));
39200
+ import("./conflict-warning-hook-an4fxhwf.js").then(({ sendSchemaFenceWarning }) => sendSchemaFenceWarning(ctx.client, ctx.directory, fence));
38475
39201
  }
38476
39202
  }
38477
39203
  if (conflictResult?.hasConflict) {
@@ -38492,7 +39218,7 @@ var server = async (ctx) => {
38492
39218
  } = await import("./announcement-6c1g4es4.js");
38493
39219
  if (shouldShowAnnouncement2()) {
38494
39220
  setTimeout(() => {
38495
- import("./conflict-warning-hook-mt0ttc4x.js").then(({ sendStartupAnnouncement }) => sendStartupAnnouncement(ctx.client, ctx.directory, ANNOUNCEMENT_VERSION2, ANNOUNCEMENT_FEATURES2, ANNOUNCEMENT_FOOTER2, markAnnouncementSeen2)).catch(() => {});
39221
+ import("./conflict-warning-hook-an4fxhwf.js").then(({ sendStartupAnnouncement }) => sendStartupAnnouncement(ctx.client, ctx.directory, ANNOUNCEMENT_VERSION2, ANNOUNCEMENT_FEATURES2, ANNOUNCEMENT_FOOTER2, markAnnouncementSeen2)).catch(() => {});
38496
39222
  }, 8000);
38497
39223
  }
38498
39224
  } catch {}