@cortexkit/opencode-magic-context 0.49.12 → 0.49.14

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 (141) hide show
  1. package/dist/auto-search-worker.js +3 -3
  2. package/dist/chunk-embedding-write-worker.js +89 -0
  3. package/dist/config/schema/agent-overrides.d.ts +12 -12
  4. package/dist/config/schema/magic-context.d.ts +88 -88
  5. package/dist/{conflict-warning-hook-f4x5wed7.js → conflict-warning-hook-mgq17yr3.js} +3 -3
  6. package/dist/{context-dam8p201.js → context-cpxqpkzv.js} +55 -71
  7. package/dist/{derive-budgets-5306b1jt.js → derive-budgets-zn7yzd2d.js} +1 -1
  8. package/dist/{embedding-backfill-qbfcbp87.js → embedding-backfill-5e1t5wha.js} +6 -5
  9. package/dist/embedding-worker.js +1 -1
  10. package/dist/features/magic-context/chunk-embedding-write-worker.d.ts +2 -0
  11. package/dist/features/magic-context/chunk-embedding-write-worker.d.ts.map +1 -0
  12. package/dist/features/magic-context/chunk-embedding-writer.d.ts +48 -0
  13. package/dist/features/magic-context/chunk-embedding-writer.d.ts.map +1 -0
  14. package/dist/features/magic-context/compartment-chunk-embedding.d.ts +1 -1
  15. package/dist/features/magic-context/compartment-chunk-embedding.d.ts.map +1 -1
  16. package/dist/features/magic-context/dreamer/hidden-single-shot.d.ts +3 -2
  17. package/dist/features/magic-context/dreamer/hidden-single-shot.d.ts.map +1 -1
  18. package/dist/features/magic-context/dreamer/map-memories.d.ts +8 -1
  19. package/dist/features/magic-context/dreamer/map-memories.d.ts.map +1 -1
  20. package/dist/features/magic-context/dreamer/retrospective-raw-provider.d.ts +2 -0
  21. package/dist/features/magic-context/dreamer/retrospective-raw-provider.d.ts.map +1 -1
  22. package/dist/features/magic-context/dreamer/storage-dream-runs.d.ts +5 -0
  23. package/dist/features/magic-context/dreamer/storage-dream-runs.d.ts.map +1 -1
  24. package/dist/features/magic-context/dreamer/task-executor.d.ts.map +1 -1
  25. package/dist/features/magic-context/dreamer/verify-prompt.d.ts +6 -1
  26. package/dist/features/magic-context/dreamer/verify-prompt.d.ts.map +1 -1
  27. package/dist/features/magic-context/dreamer/verify.d.ts +25 -11
  28. package/dist/features/magic-context/dreamer/verify.d.ts.map +1 -1
  29. package/dist/features/magic-context/mural/compress-cues.d.ts +3 -0
  30. package/dist/features/magic-context/mural/compress-cues.d.ts.map +1 -1
  31. package/dist/features/magic-context/project-embedding-registry.d.ts +5 -0
  32. package/dist/features/magic-context/project-embedding-registry.d.ts.map +1 -1
  33. package/dist/features/magic-context/storage-tags.d.ts +2 -0
  34. package/dist/features/magic-context/storage-tags.d.ts.map +1 -1
  35. package/dist/hooks/magic-context/apply-operations.d.ts +3 -1
  36. package/dist/hooks/magic-context/apply-operations.d.ts.map +1 -1
  37. package/dist/hooks/magic-context/auto-embed-session.d.ts +10 -0
  38. package/dist/hooks/magic-context/auto-embed-session.d.ts.map +1 -0
  39. package/dist/hooks/magic-context/compartment-runner.d.ts +4 -0
  40. package/dist/hooks/magic-context/compartment-runner.d.ts.map +1 -1
  41. package/dist/hooks/magic-context/compartment-trigger.d.ts +1 -1
  42. package/dist/hooks/magic-context/compartment-trigger.d.ts.map +1 -1
  43. package/dist/hooks/magic-context/degraded-pass-refusal.d.ts +2 -0
  44. package/dist/hooks/magic-context/degraded-pass-refusal.d.ts.map +1 -1
  45. package/dist/hooks/magic-context/embed-session-state.d.ts +8 -1
  46. package/dist/hooks/magic-context/embed-session-state.d.ts.map +1 -1
  47. package/dist/hooks/magic-context/hook.d.ts +3 -1
  48. package/dist/hooks/magic-context/hook.d.ts.map +1 -1
  49. package/dist/hooks/magic-context/pending-drop-eligibility.d.ts +14 -0
  50. package/dist/hooks/magic-context/pending-drop-eligibility.d.ts.map +1 -0
  51. package/dist/hooks/magic-context/transform-compartment-phase.d.ts.map +1 -1
  52. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts +1 -0
  53. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
  54. package/dist/hooks/magic-context/transform.d.ts.map +1 -1
  55. package/dist/{index-fx90bvjd.js → index-3kdm78zp.js} +2 -2
  56. package/dist/{index-gf0psee3.js → index-3kx0kg0f.js} +60 -3
  57. package/dist/{index-1wwh38fk.js → index-5591fg8y.js} +471 -139
  58. package/dist/{index-b16gpywn.js → index-944w16m0.js} +2 -2
  59. package/dist/{index-6sz25c3s.js → index-bxdg2nbt.js} +2 -2
  60. package/dist/{index-7h8a1xpc.js → index-e4dsjj1p.js} +1 -1
  61. package/dist/{index-05n6ykca.js → index-kf4epshg.js} +3 -3
  62. package/dist/index-saews2s3.js +229 -0
  63. package/dist/{index-yx5kgp2x.js → index-t4q9zbbf.js} +95 -73
  64. package/dist/{index-wqs4q74r.js → index-thvnpfsv.js} +8 -8
  65. package/dist/{index-95s8xaj1.js → index-tyckte5c.js} +4 -4
  66. package/dist/{index-qtbdx42g.js → index-w900fbhd.js} +110 -25
  67. package/dist/{index-6sytd5w3.js → index-xn6q9pg6.js} +7 -7
  68. package/dist/{index-7zd5asz9.js → index-y1qysm3q.js} +196 -243
  69. package/dist/{index-x2xjyq8f.js → index-yxycg7fs.js} +9 -9
  70. package/dist/index.js +54 -92
  71. package/dist/{message-index-df7swgy1.js → message-index-a6gztaqx.js} +7 -7
  72. package/dist/{message-index-bounded-nq6rp8xa.js → message-index-bounded-vtgpq6b4.js} +4 -4
  73. package/dist/migration-worker.js +2 -2
  74. package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
  75. package/dist/{project-embedding-registry-q0ysjyzc.js → project-embedding-registry-x45bv3qr.js} +5 -4
  76. package/dist/raw-ordinal-warmup-worker.js +3 -3
  77. package/dist/{read-session-chunk-ax05f7gr.js → read-session-chunk-3ae3nfdn.js} +2 -2
  78. package/dist/{recomp-orchestrator-a0mvby4e.js → recomp-orchestrator-xqb9gwgm.js} +21 -20
  79. package/dist/{search-fm002702.js → search-deajrd90.js} +16 -15
  80. package/dist/{send-session-notification-y2wg3fkh.js → send-session-notification-24r4esbh.js} +2 -2
  81. package/dist/shared/model-suggestion-retry.d.ts +2 -0
  82. package/dist/shared/model-suggestion-retry.d.ts.map +1 -1
  83. package/dist/shared/prompt-async-transport.d.ts.map +1 -1
  84. package/dist/{storage-tags-yygfb9c8.js → storage-tags-s5bg1ahx.js} +1 -1
  85. package/dist/{transform-postprocess-phase-s84rdf32.js → transform-postprocess-phase-k5t63qm5.js} +21 -20
  86. package/dist/v2/auto-search-worker.js +3 -3
  87. package/dist/v2/chunk-embedding-write-worker.js +88 -0
  88. package/dist/v2/{context-x60fa16g.js → context-k4jrq71s.js} +611 -210
  89. package/dist/v2/{derive-budgets-z25jw3py.js → derive-budgets-2zh4gm2c.js} +2 -2
  90. package/dist/v2/{embedding-backfill-mbjyza2a.js → embedding-backfill-jmaf8zrr.js} +6 -5
  91. package/dist/v2/embedding-worker.js +1 -1
  92. package/dist/v2/hidden-completion.d.ts +3 -2
  93. package/dist/v2/hidden-completion.d.ts.map +1 -1
  94. package/dist/v2/hooks/hidden-child.d.ts.map +1 -1
  95. package/dist/v2/hooks/transform-features.d.ts +2 -2
  96. package/dist/v2/hooks/transform-features.d.ts.map +1 -1
  97. package/dist/v2/{message-index-bounded-pgv1ndpb.js → message-index-bounded-rxxznd34.js} +4 -4
  98. package/dist/v2/{message-index-5nayhm1r.js → message-index-f947qtbz.js} +7 -7
  99. package/dist/v2/migration-worker.js +2 -2
  100. package/dist/v2/{project-embedding-registry-jbmjc0p4.js → project-embedding-registry-0msp56p8.js} +5 -4
  101. package/dist/v2/raw-ordinal-warmup-worker.js +3 -3
  102. package/dist/v2/{read-session-chunk-hr3w5bjk.js → read-session-chunk-rq9nx1nn.js} +2 -2
  103. package/dist/v2/{recomp-orchestrator-8w3449eb.js → recomp-orchestrator-1j1nqrrr.js} +21 -20
  104. package/dist/v2/retrospective-raw-provider.d.ts.map +1 -1
  105. package/dist/v2/{search-mhmxgq0e.js → search-n8wqxb1j.js} +16 -15
  106. package/dist/v2/{send-session-notification-jevgj9fe.js → send-session-notification-8ghn9tnv.js} +2 -2
  107. package/dist/v2/{server-f7jfmrrz.js → server-34kwfsr4.js} +1 -1
  108. package/dist/v2/server-4gn3z5an.js +229 -0
  109. package/dist/v2/{server-4c10404h.js → server-6cdy4rc0.js} +2 -2
  110. package/dist/v2/{server-25tg45b4.js → server-cfbr1s2x.js} +7 -7
  111. package/dist/v2/{server-nmrm2rjy.js → server-e298hswg.js} +8 -8
  112. package/dist/v2/{server-9ewkzqgd.js → server-ef89gdsx.js} +2 -2
  113. package/dist/v2/{server-m97brnat.js → server-ehyava47.js} +2 -2
  114. package/dist/v2/{server-5gvkzzrf.js → server-fnqxt9j6.js} +95 -71
  115. package/dist/v2/{server-sz8jj92q.js → server-hek6z3w6.js} +194 -241
  116. package/dist/v2/{server-50mkkhy1.js → server-kmbarfmn.js} +9 -9
  117. package/dist/v2/{server-vknbt0gq.js → server-qhfvvfxj.js} +60 -3
  118. package/dist/v2/{server-37ngj8qw.js → server-zc3e54vy.js} +1 -1
  119. package/dist/v2/server.js +9 -8
  120. package/dist/v2/{storage-tags-a2gq6dw7.js → storage-tags-hcc2adpf.js} +1 -1
  121. package/dist/v2/store-reader.d.ts +1 -0
  122. package/dist/v2/store-reader.d.ts.map +1 -1
  123. package/dist/v2/{wrapup-orchestrator-r82y780v.js → wrapup-orchestrator-hkv8apcc.js} +16 -15
  124. package/dist/{wrapup-orchestrator-vmt6z3q5.js → wrapup-orchestrator-kxqj4rwh.js} +22 -21
  125. package/package.json +6 -5
  126. package/src/shared/model-suggestion-retry.test.ts +34 -0
  127. package/src/shared/model-suggestion-retry.ts +23 -3
  128. package/src/shared/prompt-async-transport.test.ts +1 -1
  129. package/src/shared/prompt-async-transport.ts +16 -3
  130. package/dist/{index-e6xnpach.js → index-b7p25tm0.js} +0 -0
  131. package/dist/{index-2pgxcncf.js → index-dgs16axy.js} +0 -0
  132. package/dist/{index-9vqb5p1s.js → index-e20m7284.js} +0 -0
  133. package/dist/{index-fwefky9w.js → index-mht7bq0z.js} +0 -0
  134. package/dist/{index-8ketfacn.js → index-v10f1rjv.js} +3 -3
  135. package/dist/{index-tdn0zkw4.js → index-wk0n1cgt.js} +0 -0
  136. package/dist/v2/{index-e6xnpach.js → index-b7p25tm0.js} +0 -0
  137. package/dist/v2/{server-bxpwy6fy.js → server-atbc19ab.js} +0 -0
  138. package/dist/v2/{server-2x42esxd.js → server-g10mdym6.js} +0 -0
  139. package/dist/v2/{server-fa75w6gp.js → server-k2bzedxk.js} +0 -0
  140. package/dist/v2/{server-kn9n2qgd.js → server-tbe1femw.js} +3 -3
  141. /package/dist/v2/{server-83ygfha2.js → server-vbe4se57.js} +0 -0
@@ -6,7 +6,7 @@ import {
6
6
  resolveLegacyConfigSources,
7
7
  getProtectedTokensTierOverrides,
8
8
  loadPluginConfigDetailed
9
- } from "./server-37ngj8qw.js";
9
+ } from "./server-zc3e54vy.js";
10
10
  import {
11
11
  getHarness2,
12
12
  harnessOwnsOpenCodeStore2
@@ -33,7 +33,7 @@ import {
33
33
  getSdkContextLimit,
34
34
  getSdkOutputLimit,
35
35
  getModelsDevCacheState
36
- } from "./server-kn9n2qgd.js";
36
+ } from "./server-tbe1femw.js";
37
37
  import {
38
38
  isValidLanguageCode,
39
39
  withContentLanguageDirective,
@@ -71,13 +71,6 @@ import {
71
71
  pluginConfigReader,
72
72
  currentPluginConfigReader,
73
73
  withLiveDreamerOutputCap,
74
- embedPauseBySession,
75
- embedRunStateBySession,
76
- autoEmbedAttemptedBySession,
77
- autoEmbedIdentityBySession,
78
- invalidateAutoEmbedSession,
79
- getEmbedDrainUiStatus,
80
- clearEmbedSessionState,
81
74
  acquireCompartmentLease,
82
75
  releaseCompartmentLeaseBestEffort,
83
76
  isCompartmentLeaseHeld,
@@ -214,9 +207,11 @@ import {
214
207
  toModelEntry,
215
208
  isPromptTimeoutError,
216
209
  getPromptFailureDetail,
210
+ raceWithSignal,
217
211
  promptSyncWithValidatedOutputRetry,
218
212
  normalizeSDKResponse,
219
213
  failedInvocationStatus,
214
+ sumTokensFromChildMessages,
220
215
  recordChildInvocation,
221
216
  createPromptAsyncTransport,
222
217
  CTX_NOTE_LIGHT_DESCRIPTION,
@@ -286,7 +281,7 @@ import {
286
281
  startCompartmentAgent,
287
282
  setRecompStarting2,
288
283
  setRecompTerminal2
289
- } from "./server-5gvkzzrf.js";
284
+ } from "./server-fnqxt9j6.js";
290
285
  import {
291
286
  resolveHistorianModel2
292
287
  } from "./server-8cd2j99z.js";
@@ -311,7 +306,7 @@ import {
311
306
  openDatabaseAsync,
312
307
  isDatabasePersisted,
313
308
  getDatabasePersistenceError
314
- } from "./server-50mkkhy1.js";
309
+ } from "./server-kmbarfmn.js";
315
310
  import {
316
311
  setHomeProjectPermission,
317
312
  shouldSkipHomeProjectMemory,
@@ -356,6 +351,7 @@ import {
356
351
  HYGIENE_PROVIDER_UNITS_VERSION,
357
352
  sessionDecisionCalibration,
358
353
  transitionSessionHygieneUnits,
354
+ readEpochFloorSnapshot,
359
355
  getProtectionWindowForSession,
360
356
  withReplayEnvelopeSnapshot,
361
357
  invalidateReplayEnvelopeSnapshot,
@@ -514,7 +510,36 @@ import {
514
510
  readRawSessionMessageById2,
515
511
  readSessionChunk2,
516
512
  readRawSessionSeedTail2
517
- } from "./server-m97brnat.js";
513
+ } from "./server-ehyava47.js";
514
+ import {
515
+ embedPauseBySession,
516
+ embedRunStateBySession,
517
+ activeEmbeddingSessions,
518
+ autoEmbedAttemptedBySession,
519
+ autoEmbedIdentityBySession,
520
+ autoEmbedRetryAfterBySession,
521
+ invalidateAutoEmbedSession,
522
+ getEmbedDrainUiStatus,
523
+ clearEmbedSessionState,
524
+ describeShadowBackfillWriteRefusal2,
525
+ markProjectLoadUntrusted2,
526
+ drainProjectEmbeddingIdentityMaintenance2,
527
+ drainStaleEmbeddingIdentitiesForProject2,
528
+ registerProjectEmbedding2,
529
+ registerProjectShadowEmbedding2,
530
+ enqueueShadowEmbeddingItems2,
531
+ registerProjectInObservationMode2,
532
+ unregisterProjectShadowEmbedding2,
533
+ getProjectEmbeddingSnapshot2,
534
+ embedTextForProject2,
535
+ embedBatchForProject2,
536
+ embedUnembeddedMemoriesForProject2,
537
+ embedUnembeddedMemoriesForProjectOutcome2,
538
+ drainCommitBacklogForProject2,
539
+ embedSessionCompartmentChunks2,
540
+ getEmbeddingCoverageStatus2,
541
+ getAutoEmbeddingSessionCoverage2
542
+ } from "./server-hek6z3w6.js";
518
543
  import {
519
544
  textMentionsRecentCommit,
520
545
  hasMeaningfulUserText2,
@@ -551,7 +576,7 @@ import {
551
576
  import"./server-yrvqaswb.js";
552
577
  import {
553
578
  deleteChunkEmbedBackoffForSession
554
- } from "./server-vknbt0gq.js";
579
+ } from "./server-qhfvvfxj.js";
555
580
  import {
556
581
  registerOwnRpcServerInstance,
557
582
  rpcPortDir,
@@ -577,12 +602,13 @@ import {
577
602
  isMessageIndexReconciledThrough2,
578
603
  indexMessagesAfterOrdinal2,
579
604
  sweepOrphanedOpenCodeMessageIndexes2
580
- } from "./server-nmrm2rjy.js";
605
+ } from "./server-e298hswg.js";
581
606
  import {
582
607
  stableStringify,
583
608
  getTemporalDecisions,
584
609
  observeTemporalDecisions,
585
610
  freezeTemporalDecisions,
611
+ tagRevisionKey,
586
612
  tagIdentityRevisionKey
587
613
  } from "./server-pwv4ezb0.js";
588
614
  import {
@@ -677,7 +703,7 @@ import {
677
703
  adoptNullOwnerToolTag2,
678
704
  getCandidateToolOwners2,
679
705
  pickNearestPriorOwner2
680
- } from "./server-bxpwy6fy.js";
706
+ } from "./server-atbc19ab.js";
681
707
  import"./server-51779zs2.js";
682
708
  import {
683
709
  isRawCompactionSummaryInfo2,
@@ -719,35 +745,7 @@ import {
719
745
  resolveStoredPathWorkspaceIdentity,
720
746
  storedPathBelongsToWorkspace,
721
747
  computeWorkspaceEpochFingerprint
722
- } from "./server-fa75w6gp.js";
723
- import {
724
- GIT_SWEEP_LEASE_RENEWAL_MS,
725
- acquireGitSweepLease,
726
- renewGitSweepLease,
727
- markGitSweepSuccessAndRelease,
728
- parkGitSweepNonIndexable,
729
- releaseGitSweepLease,
730
- recordSessionProjectIdentity,
731
- hasRecordedSessionProjectIdentity,
732
- describeShadowBackfillWriteRefusal2,
733
- markProjectLoadUntrusted2,
734
- drainProjectEmbeddingIdentityMaintenance2,
735
- drainStaleEmbeddingIdentitiesForProject2,
736
- registerProjectEmbedding2,
737
- registerProjectShadowEmbedding2,
738
- enqueueShadowEmbeddingItems2,
739
- registerProjectInObservationMode2,
740
- unregisterProjectShadowEmbedding2,
741
- getProjectEmbeddingSnapshot2,
742
- embedTextForProject2,
743
- embedBatchForProject2,
744
- embedUnembeddedMemoriesForProject2,
745
- embedUnembeddedMemoriesForProjectOutcome2,
746
- drainCommitBacklogForProject2,
747
- embedSessionCompartmentChunks2,
748
- getEmbeddingCoverageStatus2,
749
- getAutoEmbeddingSessionCoverage2
750
- } from "./server-sz8jj92q.js";
748
+ } from "./server-k2bzedxk.js";
751
749
  import {
752
750
  configureContextDatabasePragmas2
753
751
  } from "./server-fb3zxn06.js";
@@ -793,18 +791,28 @@ import {
793
791
  readGitFileChangeTimesSince,
794
792
  verificationFileExists,
795
793
  normalizeVerificationFiles
796
- } from "./server-4c10404h.js";
794
+ } from "./server-6cdy4rc0.js";
797
795
  import {
798
796
  deriveTriggerBudget2,
799
797
  deriveHistorianChunkTokens2,
800
798
  resolveKnownHistorianContextLimit2,
801
799
  resolveHistorianProducerLimits2,
802
800
  resolveHistorianContextLimit2
803
- } from "./server-f7jfmrrz.js";
801
+ } from "./server-34kwfsr4.js";
804
802
  import"./server-05xjtq6c.js";
805
803
  import {
806
804
  isEmbeddingHostBusy2
807
805
  } from "./server-qt1qqasc.js";
806
+ import {
807
+ GIT_SWEEP_LEASE_RENEWAL_MS,
808
+ acquireGitSweepLease,
809
+ renewGitSweepLease,
810
+ markGitSweepSuccessAndRelease,
811
+ parkGitSweepNonIndexable,
812
+ releaseGitSweepLease,
813
+ recordSessionProjectIdentity,
814
+ hasRecordedSessionProjectIdentity
815
+ } from "./server-4gn3z5an.js";
808
816
  import {
809
817
  saveEmbeddingIfHashMatches,
810
818
  invalidateProject2,
@@ -812,10 +820,10 @@ import {
812
820
  } from "./server-4dhv7mqz.js";
813
821
  import {
814
822
  getLocalEmbeddingNativeMemoryStats
815
- } from "./server-2x42esxd.js";
823
+ } from "./server-g10mdym6.js";
816
824
  import {
817
825
  cosineSimilarity
818
- } from "./server-9ewkzqgd.js";
826
+ } from "./server-ef89gdsx.js";
819
827
  import {
820
828
  computeCueContentHash,
821
829
  hasMuralCueColumns,
@@ -852,7 +860,7 @@ import"./server-h0410h0v.js";
852
860
  import {
853
861
  flushIgnoredMessages2,
854
862
  sendStatusNotification2
855
- } from "./server-83ygfha2.js";
863
+ } from "./server-vbe4se57.js";
856
864
  import {
857
865
  renderSingleStoreMigrationRequiredRefusal,
858
866
  SingleStoreMigrationRequiredError,
@@ -873,7 +881,7 @@ import {
873
881
  resolveMemoriesByIdsForSearch2,
874
882
  unifiedSearch2,
875
883
  formatSearchResults2
876
- } from "./server-25tg45b4.js";
884
+ } from "./server-cfbr1s2x.js";
877
885
  import {
878
886
  resolvePromptContext2
879
887
  } from "./server-fmsr7v69.js";
@@ -893,21 +901,6 @@ import {
893
901
  import {
894
902
  computeNormalizedHash
895
903
  } from "./server-2bvekkfy.js";
896
- import {
897
- sameProjectDirectory,
898
- canonicalProjectDirectory
899
- } from "./server-knvkbfvh.js";
900
- import {
901
- getErrorMessage,
902
- describeError
903
- } from "./server-y8v6yerm.js";
904
- import {
905
- shouldEnforcePrivateStoragePermissions,
906
- ensureStorageDirectorySync,
907
- writeStorageFileAtomicSync,
908
- writeStorageFileAsync,
909
- createStorageWriteStream
910
- } from "./server-fvnzcnww.js";
911
904
  import {
912
905
  normalizeProtectedToolName,
913
906
  mergeProtectedTools
@@ -917,6 +910,14 @@ import {
917
910
  piModelRefToCanonical,
918
911
  modelRefLookupOrder
919
912
  } from "./server-avwt563y.js";
913
+ import {
914
+ sameProjectDirectory,
915
+ canonicalProjectDirectory
916
+ } from "./server-knvkbfvh.js";
917
+ import {
918
+ getErrorMessage,
919
+ describeError
920
+ } from "./server-y8v6yerm.js";
920
921
  import {
921
922
  closeQuietly,
922
923
  isKnownAutocommit
@@ -924,6 +925,13 @@ import {
924
925
  import {
925
926
  logSlowWriteTransaction
926
927
  } from "./server-6pmqg9m4.js";
928
+ import {
929
+ shouldEnforcePrivateStoragePermissions,
930
+ ensureStorageDirectorySync,
931
+ writeStorageFileAtomicSync,
932
+ writeStorageFileAsync,
933
+ createStorageWriteStream
934
+ } from "./server-fvnzcnww.js";
927
935
 
928
936
  // ../../node_modules/.bun/zod@4.1.8/node_modules/zod/v4/classic/external.js
929
937
  var exports_external = {};
@@ -3018,6 +3026,20 @@ function resolveTodowriteAvailability(sessionId) {
3018
3026
  }
3019
3027
 
3020
3028
  // src/hooks/magic-context/degraded-pass-refusal.ts
3029
+ function describeDegradedPassFailure(site, cause) {
3030
+ const details = [site];
3031
+ const seen = new Set;
3032
+ while (cause !== undefined && cause !== null && !seen.has(cause)) {
3033
+ seen.add(cause);
3034
+ const current = cause;
3035
+ const detail = typeof current.site === "string" ? current.site : typeof current.message === "string" ? current.message : String(cause);
3036
+ if (!details.includes(detail))
3037
+ details.push(detail);
3038
+ cause = current.cause;
3039
+ }
3040
+ return `Magic Context could not safely prepare this turn [${userFacingFailureCode("transform_pass_degraded")}] (${details.join(": ")}). This request was not sent.`;
3041
+ }
3042
+
3021
3043
  class DegradedPassRefusalError extends Error {
3022
3044
  site;
3023
3045
  code = "DEGRADED_PASS_REFUSAL";
@@ -3025,7 +3047,7 @@ class DegradedPassRefusalError extends Error {
3025
3047
  estimatedTokens;
3026
3048
  contextLimitTokens;
3027
3049
  constructor(site, options) {
3028
- super(renderUserFacingFailure("transform_pass_degraded", "plain"), {
3050
+ super(describeDegradedPassFailure(site, options?.cause), {
3029
3051
  cause: options?.cause
3030
3052
  });
3031
3053
  this.site = site;
@@ -5727,12 +5749,12 @@ function buildTriggerInMemoryTail(db, sessionId, messages) {
5727
5749
  function getProactiveCompartmentTriggerPercentage(executeThresholdPercentage) {
5728
5750
  return Math.max(0, executeThresholdPercentage - PROACTIVE_TRIGGER_OFFSET_PERCENTAGE);
5729
5751
  }
5730
- function estimateProjectedPostDropPercentage(db, sessionId, usage, activeTags, keepReasoningTokens, clearedReasoningThroughTag, canClearReasoning, liveBudgetCutoff) {
5752
+ function estimateProjectedPostDropPercentage(db, sessionId, usage, activeTags, keepReasoningTokens, clearedReasoningThroughTag, canClearReasoning, liveBudgetCutoff, eligiblePendingDropTagIds) {
5731
5753
  const totalActiveBytes = activeTags.reduce((sum, tag) => sum + tag.byteSize + tag.reasoningByteSize, 0);
5732
5754
  if (totalActiveBytes === 0)
5733
5755
  return null;
5734
5756
  let droppableBytes = 0;
5735
- const pendingDrops = getPendingOps(db, sessionId).filter((op) => op.operation === "drop");
5757
+ const pendingDrops = getPendingOps(db, sessionId).filter((op) => op.operation === "drop" && eligiblePendingDropTagIds?.has(op.tagId) === true);
5736
5758
  const pendingDropTagIds = new Set(pendingDrops.map((op) => op.tagId));
5737
5759
  if (pendingDrops.length > 0) {
5738
5760
  droppableBytes += activeTags.filter((tag) => pendingDropTagIds.has(tag.tagNumber)).reduce((sum, tag) => sum + tag.byteSize + tag.reasoningByteSize, 0);
@@ -5861,7 +5883,7 @@ function getUnsummarizedTailInfo(db, sessionId, triggerBudget, usage, executeThr
5861
5883
  function formatProjectedPostDropPercentage(value) {
5862
5884
  return value === null ? "none" : `${value.toFixed(1)}%`;
5863
5885
  }
5864
- function checkCompartmentTrigger(db, sessionId, sessionMeta, usage, _previousPercentage, executeThresholdPercentage, triggerBudget, keepReasoningTokens, commitClusterTrigger, preloadedActiveTags, contextLimit, inMemoryTail, taggerFloorOverride, reasoningProjection, reclaimRide) {
5886
+ function checkCompartmentTrigger(db, sessionId, sessionMeta, usage, _previousPercentage, executeThresholdPercentage, triggerBudget, keepReasoningTokens, commitClusterTrigger, preloadedActiveTags, contextLimit, inMemoryTail, taggerFloorOverride, reasoningProjection, reclaimRide, eligiblePendingDropTagIds) {
5865
5887
  if (sessionMeta.compartmentInProgress) {
5866
5888
  sessionLog2(sessionId, `compartment trigger: skipped — historian already in progress (usage=${usage.percentage.toFixed(1)}%)`);
5867
5889
  return { shouldFire: false };
@@ -5925,7 +5947,7 @@ function checkCompartmentTrigger(db, sessionId, sessionMeta, usage, _previousPer
5925
5947
  return { shouldFire: false };
5926
5948
  }
5927
5949
  const canClearReasoning = reasoningProjection?.canClearReasoning ?? modelAcceptsEmptyContent(reasoningProjection?.providerID);
5928
- const projectedPostDropPercentage = estimateProjectedPostDropPercentage(db, sessionId, usage, preloadedActiveTags ?? getActiveTagsBySession2(db, sessionId), keepReasoningTokens, sessionMeta.clearedReasoningThroughTag, canClearReasoning, reasoningProjection?.budgetCutoff);
5950
+ const projectedPostDropPercentage = estimateProjectedPostDropPercentage(db, sessionId, usage, preloadedActiveTags ?? getActiveTagsBySession2(db, sessionId), keepReasoningTokens, sessionMeta.clearedReasoningThroughTag, canClearReasoning, reasoningProjection?.budgetCutoff, eligiblePendingDropTagIds);
5929
5951
  const relativePostDropTarget = executeThresholdPercentage * POST_DROP_TARGET_RATIO;
5930
5952
  const rideLabel = reclaimRide ? reclaimRideLabel(reclaimRide) : "ride=none";
5931
5953
  const dropsCanLand = reclaimRide !== undefined && hasReclaimRide(reclaimRide);
@@ -6851,6 +6873,76 @@ function resolveHistoryBudgetTokens(historyBudgetPercentage, contextUsage, execu
6851
6873
  }) / 100) * historyBudgetPercentage);
6852
6874
  }
6853
6875
 
6876
+ // src/hooks/magic-context/pending-drop-eligibility.ts
6877
+ function pendingDropVeto(tagNumber, target, protectedTagIds) {
6878
+ if (protectedTagIds.has(tagNumber))
6879
+ return "protected";
6880
+ if (target?.thinkingDropProtected)
6881
+ return "active_thinking";
6882
+ return null;
6883
+ }
6884
+ function capturePendingDropEligibility(targets, protectedTagIds) {
6885
+ const eligible = new Set;
6886
+ for (const [number, target] of targets) {
6887
+ if (pendingDropVeto(number, target, protectedTagIds))
6888
+ continue;
6889
+ if (target.drop) {
6890
+ if (target.canDrop?.() === true)
6891
+ eligible.add(number);
6892
+ } else {
6893
+ const content = target.getContent?.();
6894
+ if (typeof content === "string" && content.length > `[dropped §${number}§]`.length)
6895
+ eligible.add(number);
6896
+ }
6897
+ }
6898
+ return eligible;
6899
+ }
6900
+ function pendingDropEligibilityKey(db, sessionId, input, protectionInputs) {
6901
+ const digests = input.map((message) => message.contentDigest?.() ?? null);
6902
+ if (digests.some((digest) => digest === null))
6903
+ return null;
6904
+ const revision = db.prepare("SELECT value FROM schema_migrations_meta WHERE key = ?").get(tagRevisionKey(sessionId));
6905
+ if (!revision?.value)
6906
+ return null;
6907
+ return JSON.stringify([
6908
+ input.map((message, index) => [
6909
+ message.id,
6910
+ message.role,
6911
+ message.synthetic,
6912
+ digests[index]
6913
+ ]),
6914
+ revision.value,
6915
+ readEpochFloorSnapshot(db, sessionId),
6916
+ sessionDecisionCalibration(db, sessionId).toolsRatio,
6917
+ loadProtectedTailMeta(db, sessionId),
6918
+ [...getMergedReasoningStrippedIds(db, sessionId)].sort(),
6919
+ [...getReasoningRemovalState(db, sessionId).messageIds].sort(),
6920
+ protectionInputs
6921
+ ]);
6922
+ }
6923
+ function createPendingDropEligibilityCache() {
6924
+ const sessions = new Map;
6925
+ return {
6926
+ read(sessionId, key) {
6927
+ const previous = sessions.get(sessionId);
6928
+ if (key === null || previous?.key !== key) {
6929
+ sessions.delete(sessionId);
6930
+ return;
6931
+ }
6932
+ return previous.eligible;
6933
+ },
6934
+ record(sessionId, key, eligible) {
6935
+ sessions.delete(sessionId);
6936
+ if (key === null)
6937
+ return;
6938
+ const oldest = sessions.keys().next().value;
6939
+ if (sessions.size >= 64 && oldest !== undefined)
6940
+ sessions.delete(oldest);
6941
+ sessions.set(sessionId, { key, eligible: new Set(eligible) });
6942
+ }
6943
+ };
6944
+ }
6945
+
6854
6946
  // src/hooks/magic-context/apply-operations.ts
6855
6947
  var RECENT_TOOL_SKELETON_WINDOW = 20;
6856
6948
  function buildReplacementContent(tagId) {
@@ -6971,7 +7063,7 @@ function renderConvertedToolSkeletons(targets, converted) {
6971
7063
  }
6972
7064
  return didMutate;
6973
7065
  }
6974
- function applyPendingOperations(sessionId, db, targets, protectedTagIds, preloadedTags, preloadedPendingOps, syntheticPendingOps = [], editMarkerTagIds = new Set, onTagReduced, onBatchComplete) {
7066
+ function applyPendingOperations(sessionId, db, targets, protectedTagIds, preloadedTags, preloadedPendingOps, syntheticPendingOps = [], editMarkerTagIds = new Set, onTagReduced, onBatchComplete, onEligibilitySnapshot) {
6975
7067
  let didMutateMessage = false;
6976
7068
  let diagnostics;
6977
7069
  const reject = (reason) => {
@@ -6986,6 +7078,7 @@ function applyPendingOperations(sessionId, db, targets, protectedTagIds, preload
6986
7078
  }).immediate();
6987
7079
  {
6988
7080
  const pendingOps = preloadedPendingOps ?? getPendingOps(db, sessionId);
7081
+ onEligibilitySnapshot?.(capturePendingDropEligibility(targets, protectedTagIds));
6989
7082
  const tags = preloadedTags ?? getTagsByNumbers2(db, sessionId, [
6990
7083
  ...new Set([
6991
7084
  ...pendingOps.map((op) => op.tagId),
@@ -7016,13 +7109,10 @@ function applyPendingOperations(sessionId, db, targets, protectedTagIds, preload
7016
7109
  removePendingOp(db, sessionId, pendingOp.tagId);
7017
7110
  continue;
7018
7111
  }
7019
- if (protectedTagIds.has(pendingOp.tagId)) {
7020
- reject("protected");
7021
- continue;
7022
- }
7023
7112
  const target = targets.get(pendingOp.tagId);
7024
- if (target?.thinkingDropProtected) {
7025
- reject("active_thinking");
7113
+ const veto = pendingDropVeto(pendingOp.tagId, target, protectedTagIds);
7114
+ if (veto) {
7115
+ reject(veto);
7026
7116
  continue;
7027
7117
  }
7028
7118
  const isToolTag = tagTypeById.get(pendingOp.tagId) === "tool";
@@ -9809,11 +9899,6 @@ async function runPostTransformPhase(args) {
9809
9899
  }
9810
9900
  sessionLog2(args.sessionId, `m[0] HARD fold decision: reason=${m0MaterializeReason ?? foldDueDecision.reason ?? (foldExecutedThisPass ? "drift" : "soft_refresh")} executed=${foldExecutedThisPass} bustsServedPrefix=${foldBustsServedPrefixThisPass}`);
9811
9901
  }
9812
- if (args.normalizeRecoveryTail && (foldBustsServedPrefixThisPass || firstRenderBust)) {
9813
- args.normalizeRecoveryTail();
9814
- args.tags = getTagsBySession2(args.db, args.sessionId);
9815
- newTargets = protectNewTagMutations(args.messages, args.targets, retainedThinking, args.thinkingBindingRecoveryEnabledForModel === true);
9816
- }
9817
9902
  logTransformTiming(args.sessionId, "pp.prefixPreflight", tPostprocessSetup, `foldExecuted=${foldExecutedThisPass} m1Refreshed=${publishedM1RefreshedThisPass}`);
9818
9903
  const tPassDecisions = performance.now();
9819
9904
  const frontToolCandidates = args.tags.filter((tag) => tag.type === "tool" && tag.status === "active" && args.targets.get(tag.tagNumber)?.canDrop?.());
@@ -9847,6 +9932,11 @@ async function runPostTransformPhase(args) {
9847
9932
  const shouldApplyPendingOps = publishedWorkDrainAllowed;
9848
9933
  const shouldRunHeuristics = publishedWorkDrainAllowed && (rideSignals.publishedHistory || materializationRequested || forceMaterialization || foldBustsServedPrefixThisPass || firstRenderBust || heldIdleExpiryRebuild || emergencyDropEligible || args.schedulerDecision === "execute" && (!alreadyRanThisTurn || !args.fullFeatureMode));
9849
9934
  const isCacheBustingPass = publishedWorkDrainAllowed;
9935
+ if (args.normalizeRecoveryTail && isCacheBustingPass) {
9936
+ args.normalizeRecoveryTail();
9937
+ args.tags = getTagsBySession2(args.db, args.sessionId);
9938
+ newTargets = protectNewTagMutations(args.messages, args.targets, retainedThinking, args.thinkingBindingRecoveryEnabledForModel === true);
9939
+ }
9850
9940
  const reclaimDistance = isCacheBustingPass ? toolReclaimDistanceEntries(args.messages, args.targets) : [];
9851
9941
  const canEditWholePrefix = isCacheBustingPass && !activeThinkingPrefixHold;
9852
9942
  const previousTemporalDecisions = args.temporalCandidates && !compactionOff ? new Map([
@@ -9990,7 +10080,7 @@ async function runPostTransformPhase(args) {
9990
10080
  pendingOpsDidMutate = applyPendingOperations(args.sessionId, args.db, newTargets, new Set([
9991
10081
  ...args.contextUsage.percentage >= 95 ? [] : args.protectedTagIds,
9992
10082
  ...protectedToolTags
9993
- ]), undefined, pendingOps, [], new Set, (reduction) => droppedTokenReductions.push(reduction));
10083
+ ]), undefined, pendingOps, [], new Set, (reduction) => droppedTokenReductions.push(reduction), undefined, args.onPendingDropEligibility);
9994
10084
  if (pendingOpsDidMutate) {
9995
10085
  droppedCount += pendingOps.length;
9996
10086
  for (const pendingOp of pendingOps) {
@@ -17753,6 +17843,13 @@ async function runCompartmentPhaseImpl(args) {
17753
17843
  return snapshot !== null && hasRunnableCompartmentWindow(snapshot);
17754
17844
  }
17755
17845
  async function awaitCompartmentRun(activeRun, reason) {
17846
+ await Promise.resolve();
17847
+ if (activeRun.inlineJoinTimedOutBudgetMs !== undefined && !activeRun.settled) {
17848
+ historianJoinTimedOut = true;
17849
+ historianJoinBudgetMs = activeRun.inlineJoinTimedOutBudgetMs;
17850
+ sessionLog2(args.sessionId, "transform: compartment inline join budget already exhausted for this run — not waiting again");
17851
+ return "timed_out";
17852
+ }
17756
17853
  sessionLog2(args.sessionId, reason);
17757
17854
  const timeoutMs = resolveHistorianInlineJoinBudget(args.historianTimeoutMs);
17758
17855
  historianJoinBudgetMs = timeoutMs;
@@ -17768,6 +17865,7 @@ async function runCompartmentPhaseImpl(args) {
17768
17865
  clearTimeout(timer);
17769
17866
  }
17770
17867
  if (result === "timeout") {
17868
+ activeRun.inlineJoinTimedOutBudgetMs = timeoutMs;
17771
17869
  historianJoinTimedOut = true;
17772
17870
  sessionLog2(args.sessionId, `transform: compartment await timed out after ${timeoutMs}ms — proceeding without waiting`);
17773
17871
  return "timed_out";
@@ -18046,6 +18144,7 @@ function createTransform(deps) {
18046
18144
  memorySyncRequestedSessions: deps.rustMemorySyncRequestedSessions
18047
18145
  }) : undefined;
18048
18146
  let entryReuse;
18147
+ const pendingDropEligibility = createPendingDropEligibilityCache();
18049
18148
  const projectEntry = createLkgEntryProjector({
18050
18149
  onReuse: (stats) => {
18051
18150
  entryReuse = stats;
@@ -18616,6 +18715,18 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
18616
18715
  prewarmTagOwners(db, sessionId, ownerRatio);
18617
18716
  const tagOwnersReady = isTagOwnerSummaryReady2(db, sessionId, ownerRatio);
18618
18717
  let triggerBoundarySnapshot;
18718
+ let dropProjectionEmergency = contextUsageEarly.percentage >= 95;
18719
+ const dropProjectionKey = () => pendingDropEligibilityKey(db, sessionId, lkgInput, {
18720
+ currentTurnId,
18721
+ model: modelForBudget,
18722
+ protectedTokens: deps.protectedTokens,
18723
+ protectedTokenTierOverrides: deps.protectedTokenTierOverrides,
18724
+ protectedTools: deps.protectedTools,
18725
+ keepReasoningTokens: deps.keepReasoningTokens,
18726
+ usableSoft: windowGeometry?.usableSoft ?? boundaryContextLimit,
18727
+ emergency: dropProjectionEmergency,
18728
+ clearedReasoningThroughTag: sessionMeta?.clearedReasoningThroughTag
18729
+ });
18619
18730
  if (fullFeatureMode && !compactionOff && historianRunnable && tagOwnersReady && !sessionMeta.compartmentInProgress) {
18620
18731
  const tTrigger = performance.now();
18621
18732
  try {
@@ -18628,7 +18739,7 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
18628
18739
  force: contextUsageEarly.percentage >= forceMaterializationPercentage && (contextUsageEarly.percentage >= 95 || getEmergencyInputSample(db, sessionId) === 0),
18629
18740
  explicitFlush: deps.pendingMaterializationSessions.has(sessionId),
18630
18741
  publishedHistory: isCacheBusting
18631
- });
18742
+ }, pendingDropEligibility.read(sessionId, dropProjectionKey()));
18632
18743
  if (triggerResult.shouldFire) {
18633
18744
  sessionLog2(sessionId, `compartment trigger: firing (reason=${triggerResult.reason})`);
18634
18745
  updateSessionMeta(db, sessionId, { compartmentInProgress: true });
@@ -18934,6 +19045,7 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
18934
19045
  const protectedTagIds = protectedTagNumbers;
18935
19046
  const protectedCutoff = protectionWindow.cutoff;
18936
19047
  const tPostProcess = performance.now();
19048
+ dropProjectionEmergency = thinkingFitRetries.has(sessionId) || contextUsage.percentage >= 95;
18937
19049
  const postTransformResult = await runPostTransformPhase({
18938
19050
  opencode2: deps.storeGeneration === "v2",
18939
19051
  normalizeRecoveryTail,
@@ -18991,6 +19103,7 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
18991
19103
  lastHeuristicsTurnId: deps.lastHeuristicsTurnId,
18992
19104
  keepReasoningTokens: resolveKeepReasoningTokens(deps.keepReasoningTokens, currentModelKeyForBoundary),
18993
19105
  protectedTagIds,
19106
+ onPendingDropEligibility: (eligible) => pendingDropEligibility.record(sessionId, dropProjectionKey(), eligible),
18994
19107
  protectedTagNumbers,
18995
19108
  protectedCutoff,
18996
19109
  protectedCount: protectionWindow.status.protectedCount,
@@ -20533,7 +20646,7 @@ function getAsyncModule() {
20533
20646
  await beforeModuleLoad();
20534
20647
  const [{ default: singlefileAsyncifyVariant }, { newQuickJSAsyncWASMModuleFromVariant }] = await importPluginModule(() => Promise.all([
20535
20648
  import("./index-6e4mwffh.js").then((m)=>__toESM(m.default,1)),
20536
- import("./index-e6xnpach.js")
20649
+ import("./index-b7p25tm0.js")
20537
20650
  ]));
20538
20651
  const module = await newQuickJSAsyncWASMModuleFromVariant(singlefileAsyncifyVariant);
20539
20652
  return module;
@@ -22559,7 +22672,7 @@ function registerRpcHandlers(rpcServer, args) {
22559
22672
  return { count: buildCompartmentCount(db, sessionId, moduleStatus) };
22560
22673
  });
22561
22674
  const buildManagedCtx = async (db) => {
22562
- const { deriveHistorianChunkTokens, resolveHistorianContextLimit } = await importPluginModule(() => import("./derive-budgets-z25jw3py.js"));
22675
+ const { deriveHistorianChunkTokens, resolveHistorianContextLimit } = await importPluginModule(() => import("./derive-budgets-2zh4gm2c.js"));
22563
22676
  const { resolveHistorianModel } = await importPluginModule(() => import("./model-resolution-nx97z3x7.js"));
22564
22677
  const { userObservationCollectionEnabled, userObservationsRequested } = await importPluginModule(() => import("./task-config-nvz8mapa.js"));
22565
22678
  const DEFAULT_HISTORIAN_TIMEOUT_MS = 10 * 60 * 1000;
@@ -22611,8 +22724,8 @@ function registerRpcHandlers(rpcServer, args) {
22611
22724
  const db = readDatabase();
22612
22725
  if (!db)
22613
22726
  return { ok: false, error: "db unavailable" };
22614
- const { runManagedRecomp } = await importPluginModule(() => import("./recomp-orchestrator-8w3449eb.js"));
22615
- const { sendIgnoredMessage } = await importPluginModule(() => import("./send-session-notification-jevgj9fe.js"));
22727
+ const { runManagedRecomp } = await importPluginModule(() => import("./recomp-orchestrator-1j1nqrrr.js"));
22728
+ const { sendIgnoredMessage } = await importPluginModule(() => import("./send-session-notification-8ghn9tnv.js"));
22616
22729
  log2(`[rpc] recomp requested for session ${sessionId}`);
22617
22730
  if (!args.client && !args.hiddenCompletionExecutor) {
22618
22731
  return {
@@ -22696,7 +22809,7 @@ function registerRpcHandlers(rpcServer, args) {
22696
22809
  const db = readDatabase();
22697
22810
  if (!db)
22698
22811
  return { ok: false, error: "db unavailable" };
22699
- const { runManagedWrapup } = await importPluginModule(() => import("./wrapup-orchestrator-r82y780v.js"));
22812
+ const { runManagedWrapup } = await importPluginModule(() => import("./wrapup-orchestrator-hkv8apcc.js"));
22700
22813
  const model = liveSessionState.liveModelBySession.get(sessionId);
22701
22814
  const contextLimit = model ? resolveContextLimit(model.providerID, model.modelID, { db, sessionID: sessionId }) : 128000;
22702
22815
  const ctx = {
@@ -25547,7 +25660,7 @@ function toolResultText(result) {
25547
25660
  `);
25548
25661
  return text.length > 0 ? text : undefined;
25549
25662
  }
25550
- function toolLoopMessages(attempt) {
25663
+ function toolLoopMessages(attempt, rows) {
25551
25664
  const messages = attempt.observedMessages ?? [];
25552
25665
  const results = new Map;
25553
25666
  for (const message of messages) {
@@ -25565,10 +25678,28 @@ function toolLoopMessages(attempt) {
25565
25678
  });
25566
25679
  }
25567
25680
  }
25568
- return messages.flatMap((message) => {
25681
+ const transcript = rows ? rows.map((row) => ({ role: "assistant", content: row.data.content ?? [] })) : messages;
25682
+ return transcript.flatMap((message) => {
25569
25683
  if (message.role !== "assistant")
25570
25684
  return [];
25571
25685
  const parts = message.content.flatMap((part) => {
25686
+ if (part.type === "text" && typeof part.text === "string")
25687
+ return [{ type: "text", text: part.text }];
25688
+ if (part.type === "tool" && typeof part.name === "string" && typeof part.state === "object" && part.state !== null) {
25689
+ const state = part.state;
25690
+ const output = state.status === "completed" ? toolResultText({ value: state.content }) : undefined;
25691
+ return [
25692
+ {
25693
+ type: "tool",
25694
+ tool: part.name,
25695
+ state: {
25696
+ status: state.status,
25697
+ input: state.input,
25698
+ ...output === undefined ? {} : { output }
25699
+ }
25700
+ }
25701
+ ];
25702
+ }
25572
25703
  if (part.type !== "tool-call" || typeof part.id !== "string" || typeof part.name !== "string")
25573
25704
  return [];
25574
25705
  const result = results.get(part.id);
@@ -25756,7 +25887,7 @@ async function createV2HiddenCompletionExecutor(host, options) {
25756
25887
  const entry = rows.find((row) => row && typeof row === "object" && row.providerID === model.providerID && row.id === model.modelID);
25757
25888
  if (!entry)
25758
25889
  return model;
25759
- if (entry.variants && typeof entry.variants === "object" && Object.hasOwn(entry.variants, model.variant))
25890
+ if (Array.isArray(entry.variants) ? entry.variants.some((variant) => variant?.id === model.variant) : entry.variants && typeof entry.variants === "object" && Object.hasOwn(entry.variants, model.variant))
25760
25891
  return model;
25761
25892
  const key = `${model.providerID}/${model.modelID}:${model.variant}`;
25762
25893
  if (!warnedVariants.has(key)) {
@@ -26002,7 +26133,7 @@ async function createV2HiddenCompletionExecutor(host, options) {
26002
26133
  run.completion = {
26003
26134
  text,
26004
26135
  tokenLog: runTokenLog(tokens, run.identity.maxOutputTokens, row.data.finish),
26005
- ...hiddenToolLoop(run.identity) ? { messages: toolLoopMessages(attempt) } : {},
26136
+ ...hiddenToolLoop(run.identity) ? { messages: toolLoopMessages(attempt, steps) } : {},
26006
26137
  reasoning: text ? null : assistantReasoning(row),
26007
26138
  usage: reportedUsage ? usage : meter(system, promptText(request), text ?? ""),
26008
26139
  lengthCapped: ["length", "max_tokens"].includes(row.data.finish ?? ""),
@@ -26804,9 +26935,12 @@ async function runCompressCues(args) {
26804
26935
  let timeoutStreakElapsedMs = [];
26805
26936
  for (let i = 0;i < chunks.length; i += 1) {
26806
26937
  const remainingMs = Math.max(0, args.deadline - Date.now());
26807
- if (remainingMs <= 0)
26938
+ if (remainingMs <= 0) {
26939
+ result.stopReason = "deadline";
26808
26940
  break;
26941
+ }
26809
26942
  if (remainingMs < CHUNK_TIMEOUT_FLOOR_MS) {
26943
+ result.stopReason = "deadline";
26810
26944
  log2(`[dreamer] compress-cues: stopping before chunk ${i + 1}/${chunks.length} — remaining budget ${remainingMs}ms is below the ${CHUNK_TIMEOUT_FLOOR_MS}ms chunk floor; banking ${result.compressed} compressed cue(s)`);
26811
26945
  break;
26812
26946
  }
@@ -26815,6 +26949,10 @@ async function runCompressCues(args) {
26815
26949
  if (!chunk)
26816
26950
  break;
26817
26951
  const outcome = await compressOneChunk(args, chunk, sliceMs, abortController.signal);
26952
+ if (outcome.failure) {
26953
+ result.failure = outcome.failure.error;
26954
+ result.failureStage = outcome.failure.stage;
26955
+ }
26818
26956
  result.compressed += outcome.compressed;
26819
26957
  result.skipped += outcome.skipped;
26820
26958
  result.remaining -= outcome.compressed;
@@ -26824,6 +26962,7 @@ async function runCompressCues(args) {
26824
26962
  consecutiveTimeouts += 1;
26825
26963
  timeoutStreakElapsedMs.push(outcome.failure.elapsedMs);
26826
26964
  if (consecutiveTimeouts >= CONSECUTIVE_TIMEOUT_LIMIT) {
26965
+ result.stopReason = "timeout-circuit-breaker";
26827
26966
  log2(`[dreamer] compress-cues: circuit breaker tripped — ${consecutiveTimeouts} consecutive chunk timeouts (model too slow for its time slice); per-chunk elapsed [${timeoutStreakElapsedMs.join("ms, ")}ms] vs ${sliceMs}ms slice; stopping run incomplete with ${chunks.length - i - 1} chunk(s) unattempted`);
26828
26967
  break;
26829
26968
  }
@@ -26840,7 +26979,7 @@ async function runCompressCues(args) {
26840
26979
  }
26841
26980
  }
26842
26981
  function isTimeoutClassError(error) {
26843
- return error instanceof Error && /^prompt timed out after \d+ms$/.test(error.message);
26982
+ return isPromptTimeoutError(error) || getPromptFailureDetail(error)?.failureClass === "provider_timeout";
26844
26983
  }
26845
26984
  async function compressOneChunk(args, chunk, sliceMs, signal) {
26846
26985
  let agentSessionId = null;
@@ -26848,6 +26987,7 @@ async function compressOneChunk(args, chunk, sliceMs, signal) {
26848
26987
  const executor = resolveHiddenCompletionExecutor(args.hiddenCompletionExecutor, args.client, args.db, args.sessionDirectory, "compress-cues");
26849
26988
  let promptSettled = false;
26850
26989
  const startedAt = Date.now();
26990
+ let stage = "child-start";
26851
26991
  try {
26852
26992
  const prompt = buildCompressCuesPrompt({
26853
26993
  projectPath: args.projectIdentity,
@@ -26868,6 +27008,7 @@ async function compressOneChunk(args, chunk, sliceMs, signal) {
26868
27008
  agentSessionId = handle.id || null;
26869
27009
  if (!agentSessionId)
26870
27010
  throw new Error("Could not create compress-cues session.");
27011
+ stage = "prompt";
26871
27012
  const opened = handle;
26872
27013
  const run = await promptSyncWithValidatedOutputRetry(args.client, {
26873
27014
  path: { id: agentSessionId },
@@ -26919,16 +27060,19 @@ async function compressOneChunk(args, chunk, sliceMs, signal) {
26919
27060
  modelId: run.output.modelId
26920
27061
  });
26921
27062
  }
27063
+ stage = "apply";
26922
27064
  return args.moduleRoute ? await applyCuesThroughModule(args, chunk, run.validated, signal) : applyCues(args, chunk, run.validated);
26923
27065
  } catch (error) {
26924
27066
  const desc = describeError(error);
26925
27067
  log2(`[dreamer] compress-cues chunk failed: ${desc.brief}`, desc.stackHead ? { stackHead: desc.stackHead } : undefined);
26926
- if (signal.aborted || error instanceof HiddenCompletionRefusal || error instanceof DreamerProviderOutputFailureError)
27068
+ if (signal.aborted || error instanceof DreamerModuleFailureError || error instanceof HiddenCompletionRefusal || error instanceof DreamerProviderOutputFailureError)
26927
27069
  throw error;
26928
27070
  return {
26929
27071
  compressed: 0,
26930
27072
  skipped: 0,
26931
27073
  failure: {
27074
+ error,
27075
+ stage,
26932
27076
  class: isTimeoutClassError(error) ? "timeout" : "other",
26933
27077
  brief: desc.brief,
26934
27078
  elapsedMs: Date.now() - startedAt
@@ -27082,7 +27226,7 @@ async function applyCuesThroughModule(args, chunk, manifestText, signal) {
27082
27226
  // src/features/magic-context/dreamer/hidden-single-shot.ts
27083
27227
  async function runHiddenSingleShotPrompt(args) {
27084
27228
  const system = withContentLanguageDirective(args.system, args.language);
27085
- const handle = await args.executor.open({
27229
+ const opening = args.executor.open({
27086
27230
  parentSessionId: args.parentSessionId,
27087
27231
  agent: args.agent,
27088
27232
  kind: "dreamer-task",
@@ -27094,6 +27238,17 @@ async function runHiddenSingleShotPrompt(args) {
27094
27238
  directory: args.sessionDirectory,
27095
27239
  ...args.metadata ? { metadata: args.metadata } : {}
27096
27240
  });
27241
+ opening.then((handle) => {
27242
+ if (args.signal?.aborted)
27243
+ return args.executor.close(handle, {
27244
+ promptSettled: false,
27245
+ privacySensitive: args.privacySensitive ?? true,
27246
+ context: `[dreamer] ${args.callContext}`,
27247
+ log: log2
27248
+ });
27249
+ }).catch(() => {});
27250
+ const handle = await raceWithSignal(opening, args.signal);
27251
+ args.onOpened?.(handle.id);
27097
27252
  let promptSettled = false;
27098
27253
  try {
27099
27254
  if (!handle.id)
@@ -27148,12 +27303,16 @@ async function runHiddenSingleShotPrompt(args) {
27148
27303
  }
27149
27304
  throw error;
27150
27305
  } finally {
27151
- await args.executor.close(handle, {
27306
+ const close = args.executor.close(handle, {
27152
27307
  promptSettled,
27153
27308
  privacySensitive: args.privacySensitive ?? true,
27154
27309
  context: `[dreamer] ${args.callContext}`,
27155
27310
  log: log2
27156
27311
  });
27312
+ if (args.signal?.aborted)
27313
+ close.catch(() => {});
27314
+ else
27315
+ await raceWithSignal(close, args.signal);
27157
27316
  }
27158
27317
  }
27159
27318
 
@@ -30228,14 +30387,29 @@ function isDeferred(memory, retries) {
30228
30387
  return !!retry && retry.content === contentKey2(memory) && retry.deferUntil > Date.now();
30229
30388
  }
30230
30389
  function assistantText2(messages) {
30231
- return messages.filter((message) => isRecord(message) && (message.role === "assistant" || isRecord(message.info) && message.info.role === "assistant")).map((message) => extractLatestAssistantText([message]) ?? (isRecord(message) && Array.isArray(message.content) ? message.content.filter(isRecord).filter((part) => part.type === "text" && typeof part.text === "string").map((part) => part.text).join(`
30390
+ const joined = messages.filter((message) => isRecord(message) && (message.role === "assistant" || isRecord(message.info) && message.info.role === "assistant")).map((message) => extractLatestAssistantText([message]) ?? (isRecord(message) && Array.isArray(message.content) ? message.content.filter(isRecord).filter((part) => part.type === "text" && typeof part.text === "string").map((part) => part.text).join(`
30232
30391
  `) : "")).join(`
30233
30392
  `);
30393
+ return joined.trim() ? joined : null;
30234
30394
  }
30235
30395
  function currentManifest(text) {
30236
30396
  const start = text.lastIndexOf("<mappings>");
30237
30397
  return start < 0 ? text : text.slice(start);
30238
30398
  }
30399
+ function parseMapMemoriesCompletion(text, completion, expectedIds) {
30400
+ const source = /<mappings\b/i.test(text) ? text : assistantText2(completion.messages ?? []) || text;
30401
+ return validateMapMemoriesManifest(currentManifest(source), expectedIds);
30402
+ }
30403
+ function validateClientMapMemories(messages, expectedIds) {
30404
+ if (hasLengthCappedOutput(messages)) {
30405
+ throw new Error("map-memories returned length-capped output");
30406
+ }
30407
+ const raw = assistantText2(messages);
30408
+ if (raw == null) {
30409
+ throw new Error("map-memories returned no output");
30410
+ }
30411
+ return validateMapMemoriesManifest(currentManifest(raw), expectedIds);
30412
+ }
30239
30413
  function logBatchUsage(messages, committed, startedAt) {
30240
30414
  const steps = messages.filter((message) => isRecord(message) && (message.role === "assistant" || isRecord(message.info) && message.info.role === "assistant")).length;
30241
30415
  log2(`[dreamer] map-memories batch: steps=${steps} committed=${committed} steps_per_memory=${committed ? (steps / committed).toFixed(2) : "n/a"} elapsed_ms=${Date.now() - startedAt}`);
@@ -30300,8 +30474,11 @@ async function mapMemories(args) {
30300
30474
  const inputs = allInputs.filter((memory) => !isDeferred(memory, retries));
30301
30475
  result.remaining = allInputs.length;
30302
30476
  result.complete = result.remaining === 0;
30303
- if (inputs.length === 0)
30477
+ if (inputs.length === 0) {
30478
+ if (allInputs.length > 0)
30479
+ result.deferred = true;
30304
30480
  return result;
30481
+ }
30305
30482
  const batches = [];
30306
30483
  for (let i = 0;i < inputs.length; i += MAP_BATCH_SIZE) {
30307
30484
  batches.push({ inputs: inputs.slice(i, i + MAP_BATCH_SIZE), isOmissionRetry: false });
@@ -30327,6 +30504,10 @@ async function mapMemories(args) {
30327
30504
  if (!batch)
30328
30505
  break;
30329
30506
  const outcome = await mapOneBatch(args, batch.inputs, sliceMs, abortController.signal);
30507
+ if (outcome.failure) {
30508
+ result.failure = outcome.failure.error;
30509
+ result.failureStage = outcome.failure.stage;
30510
+ }
30330
30511
  const committed = outcome.mapped + outcome.independent;
30331
30512
  runLeaseGuardedWrite(args.db, args.holderId, args.leaseKey, () => {
30332
30513
  const committedIds = new Set(outcome.committedIds);
@@ -30390,6 +30571,7 @@ async function mapOneBatch(args, batch, sliceMs, signal) {
30390
30571
  const startedAt = Date.now();
30391
30572
  let budgetFinalized = false;
30392
30573
  let failedCompletion;
30574
+ let stage = "child-start";
30393
30575
  const onBudgetUpdate = (state) => {
30394
30576
  budgetFinalized ||= state.finalizeFired;
30395
30577
  args.onBudgetUpdate?.(state);
@@ -30411,15 +30593,19 @@ async function mapOneBatch(args, batch, sliceMs, signal) {
30411
30593
  fallbackModels: args.fallbackModels,
30412
30594
  timeoutMs: sliceMs,
30413
30595
  signal,
30596
+ onOpened: () => {
30597
+ stage = "prompt";
30598
+ },
30414
30599
  onFailureOutput: (completion) => {
30415
30600
  failedCompletion = completion;
30416
30601
  },
30417
- parse: (text, completion) => validateMapMemoriesManifest(currentManifest(assistantText2(completion.messages ?? []) || text), new Set(batch.map((memory) => memory.id)))
30602
+ parse: (text, completion) => parseMapMemoriesCompletion(text, completion, new Set(batch.map((memory) => memory.id)))
30418
30603
  });
30419
30604
  recordInvocation2(args, startedAt, {
30420
30605
  status: "completed",
30421
30606
  messages: run.completion.messages ?? []
30422
30607
  });
30608
+ stage = "apply";
30423
30609
  const outcome = await applyParsedBatchMappings(args, batch, run.validated, budgetFinalized, true);
30424
30610
  logBatchUsage(run.completion.messages ?? [], outcome.mapped + outcome.independent, startedAt);
30425
30611
  const returnedIds = new Set(outcome.committedIds);
@@ -30444,6 +30630,7 @@ async function mapOneBatch(args, batch, sliceMs, signal) {
30444
30630
  agentSessionId = typeof created?.id === "string" ? created.id : null;
30445
30631
  if (!agentSessionId)
30446
30632
  throw new Error("Could not create map-memories session.");
30633
+ stage = "prompt";
30447
30634
  const run = await promptSyncWithValidatedOutputRetry(client, {
30448
30635
  path: { id: agentSessionId },
30449
30636
  query: { directory: args.sessionDirectory },
@@ -30471,18 +30658,11 @@ async function mapOneBatch(args, batch, sliceMs, signal) {
30471
30658
  preferResponseOnMissingData: true
30472
30659
  });
30473
30660
  },
30474
- validateOutput: (messages) => {
30475
- if (hasLengthCappedOutput(messages)) {
30476
- throw new Error("map-memories returned length-capped output");
30477
- }
30478
- const text = currentManifest(assistantText2(messages));
30479
- if (!text)
30480
- throw new Error("map-memories returned no output");
30481
- return validateMapMemoriesManifest(text, new Set(batch.map((memory) => memory.id)));
30482
- }
30661
+ validateOutput: (messages) => validateClientMapMemories(messages, new Set(batch.map((memory) => memory.id)))
30483
30662
  });
30484
30663
  promptSettled = true;
30485
30664
  recordInvocation2(args, startedAt, { status: "completed", messages: run.output });
30665
+ stage = "apply";
30486
30666
  const outcome = await applyParsedBatchMappings(args, batch, run.validated, budgetFinalized, true);
30487
30667
  logBatchUsage(run.output, outcome.mapped + outcome.independent, startedAt);
30488
30668
  const returnedIds = new Set(outcome.committedIds);
@@ -30511,6 +30691,8 @@ async function mapOneBatch(args, batch, sliceMs, signal) {
30511
30691
  return {
30512
30692
  ...outcome,
30513
30693
  failure: {
30694
+ error,
30695
+ stage,
30514
30696
  class: isTimeoutClassError2(error) ? "timeout" : "other",
30515
30697
  elapsedMs: Date.now() - startedAt
30516
30698
  }
@@ -31667,10 +31849,28 @@ async function readRetrospectiveScanWindow(provider, projectIdentity, watermarkM
31667
31849
  }
31668
31850
  function readOpenCodeMessagesSince(db, sessionId, sinceMs, capPerSession) {
31669
31851
  const limit = Math.max(1, Math.floor(capPerSession));
31670
- const rows = db.prepare(`SELECT id, data, time_created
31671
- FROM message
31672
- WHERE session_id = ? AND time_created > ?
31673
- ORDER BY time_created ASC, id ASC
31852
+ const rows = db.prepare(`SELECT current.id, current.data, current.time_created,
31853
+ EXISTS (
31854
+ SELECT 1 FROM message assistant_reply
31855
+ WHERE assistant_reply.session_id = current.session_id
31856
+ AND json_valid(assistant_reply.data)
31857
+ AND json_extract(assistant_reply.data, '$.role') = 'assistant'
31858
+ AND (assistant_reply.time_created < current.time_created
31859
+ OR (assistant_reply.time_created = current.time_created
31860
+ AND assistant_reply.id < current.id))
31861
+ AND EXISTS (
31862
+ SELECT 1 FROM message prior_user
31863
+ WHERE prior_user.session_id = current.session_id
31864
+ AND json_valid(prior_user.data)
31865
+ AND json_extract(prior_user.data, '$.role') = 'user'
31866
+ AND (prior_user.time_created < assistant_reply.time_created
31867
+ OR (prior_user.time_created = assistant_reply.time_created
31868
+ AND prior_user.id < assistant_reply.id))
31869
+ )
31870
+ ) AS has_prior_assistant_reply
31871
+ FROM message current
31872
+ WHERE current.session_id = ? AND current.time_created > ?
31873
+ ORDER BY current.time_created ASC, current.id ASC
31674
31874
  LIMIT ?`).all(sessionId, sinceMs, limit + 1);
31675
31875
  const truncated = rows.length > limit;
31676
31876
  const kept = truncated ? rows.slice(0, limit) : rows;
@@ -31774,7 +31974,8 @@ function normalizeOpenCodeRows(db, sessionId, rows) {
31774
31974
  ordinal,
31775
31975
  role,
31776
31976
  parts,
31777
- ts: row.time_created
31977
+ ts: row.time_created,
31978
+ followsAssistantReply: row.has_prior_assistant_reply === 1
31778
31979
  });
31779
31980
  });
31780
31981
  }
@@ -31788,7 +31989,8 @@ function normalizeOpenCodeMessage(args) {
31788
31989
  ordinal: args.ordinal,
31789
31990
  role: "user",
31790
31991
  text,
31791
- ts: args.ts
31992
+ ts: args.ts,
31993
+ ...args.followsAssistantReply ? { followsAssistantReply: true } : {}
31792
31994
  });
31793
31995
  }
31794
31996
  }
@@ -32154,7 +32356,7 @@ var VERIFY_SYSTEM_PROMPT = `You are a memory verifier for the magic-context syst
32154
32356
 
32155
32357
  Each memory below comes with its backing file(s) — the code it makes a claim about. For EACH memory: use the provided git diff as evidence when present. If no diff is supplied, read its backing files (you may read more if needed) and decide whether the memory is still accurate.
32156
32358
 
32157
- Tools (read-only): read, grep, glob. Request line ranges and keep reads short. You read code only when the evidence requires it; you change nothing.
32359
+ Tools (read-only): read, grep, glob, plus any available AFT navigation tools. Use at most 3 tool calls per memory, including searches and reads. Start with the backing files and likely identifier matches. Never read the same file twice in a batch; reuse evidence. Request short useful line ranges unless the claim concerns the file as a whole. If evidence is insufficient when the call budget runs out, SKIP that memory; uncertainty never justifies archival. You change nothing.
32158
32360
 
32159
32361
  Decide ONE of four outcomes per memory:
32160
32362
  - VERIFIED — still accurate. Keep it as-is.
@@ -32166,7 +32368,7 @@ UPDATE and ARCHIVE are ONLY for claims a repository file can falsify, such as an
32166
32368
 
32167
32369
  BE CONSERVATIVE ABOUT ARCHIVING. Wrong archival of a TRUE memory is the worst possible outcome — far worse than leaving a slightly-stale memory. If you cannot find the code, or you are unsure, or it might still be true somewhere you didn't look: mark it VERIFIED or SKIPPED, never archived. Archive ONLY when you have positive evidence the code contradicts a code fact.
32168
32370
 
32169
- Output ONE XML manifest at the very end and NOTHING else — no narration, no per-memory commentary, no reasoning:
32371
+ Output ONE XML manifest and NOTHING else — no narration or reasoning. Open <verify> before investigating and emit each complete verdict immediately before investigating the next memory, so interruption preserves finished work. Close </verify> when done:
32170
32372
  <verify>
32171
32373
  <verified id="N" files="path/a.ts,path/b.ts"/>
32172
32374
  <update id="M" files="path/c.ts">corrected present-tense content</update>
@@ -32179,17 +32381,24 @@ Rules:
32179
32381
  - Every input memory id MUST appear exactly once, in exactly one of verified/update/archive/skip.
32180
32382
  - files = the COMPLETE current backing set (repo-relative, comma-separated). It may differ from the given mapping if a file moved — record what you actually verified against.
32181
32383
  - Default to VERIFIED. skip when code cannot decide the claim. update and archive are the exceptions, not the norm.`;
32384
+ async function seedVerifyCandidates(memories, directory) {
32385
+ const seeded = await seedIdentifierCandidates(memories.map((m) => ({ ...m, candidates: [] })), directory);
32386
+ return memories.map((m, i) => ({ ...m, candidates: seeded[i].candidates }));
32387
+ }
32182
32388
  function buildVerifyPrompt(projectPath, memories, evidence) {
32183
32389
  const list = memories.map((m) => `[${m.id}] ${m.category}
32184
32390
  Content: ${m.content}
32185
- Backing files: ${m.mappedFiles.join(", ")}`).join(`
32391
+ Backing files: ${m.mappedFiles.join(", ")}${m.candidates?.length ? `
32392
+ Likely files (identifier matches, confirm before using): ${m.candidates.join(", ")}` : ""}`).join(`
32186
32393
 
32187
32394
  `);
32188
32395
  return `## Verify these memories against the code
32189
32396
 
32190
32397
  Project: ${projectPath}
32191
32398
 
32192
- ${evidence ? "The git diff below is the evidence. If changed hunks do not touch a claim, mark it verified without opening files. Open files only when a diff suggests the claim may have changed. A rename or deletion requires an update or archive when positively supported; do not archive on uncertainty." : "Read each memory's backing files to check its claims."} Decide verified / update / archive / skip (default verified; behavioral directives only permit verified or skip), then output ONE <verify> manifest covering every id.
32399
+ When available in this session, use aft_outline to outline the backing file and aft_zoom on the claimed symbol (or aft_search to locate it), instead of paging through whole files. Read a whole file only when the claim is about the file as a whole. Otherwise use the available read-only tools.
32400
+
32401
+ ${evidence ? "The git diff below is the evidence. If changed hunks do not touch a claim, mark it verified without opening files. Open files only when a diff suggests the claim may have changed. A rename or deletion requires an update or archive when positively supported; do not archive on uncertainty." : "Check each memory's claim against its backing files."} Decide verified / update / archive / skip (default verified; behavioral directives only permit verified or skip), then output ONE <verify> manifest covering every id.
32193
32402
 
32194
32403
  <memories>
32195
32404
  ${list}
@@ -32266,13 +32475,57 @@ function validateVerifyManifest(text, expectedIds) {
32266
32475
  assertNoDuplicateManifestIds(ids.filter((id) => expectedIds.has(id)), "verify");
32267
32476
  return parsed;
32268
32477
  }
32478
+ function parsePartialVerifyManifest(text, expectedIds) {
32479
+ const out = { verified: [], updated: [], archived: [], skipped: [] };
32480
+ const start = text.lastIndexOf("<verify>");
32481
+ if (start < 0)
32482
+ return out;
32483
+ const entries = new Map;
32484
+ const conflicts = new Set;
32485
+ for (const match of text.slice(start).matchAll(/<(?:verified|archive|skip)\b[^<>]*\/>|<update\b[^<>]*>[\s\S]*?<\/update>/g)) {
32486
+ try {
32487
+ const parsed = parseVerifyManifest(`<verify>${match[0]}</verify>`);
32488
+ const id = verifyIds(parsed)[0];
32489
+ if (!expectedIds.has(id) || conflicts.has(id))
32490
+ continue;
32491
+ const previous = entries.get(id);
32492
+ if (previous && JSON.stringify(previous) !== JSON.stringify(parsed)) {
32493
+ entries.delete(id);
32494
+ conflicts.add(id);
32495
+ } else
32496
+ entries.set(id, parsed);
32497
+ } catch {}
32498
+ }
32499
+ for (const parsed of entries.values()) {
32500
+ out.verified.push(...parsed.verified);
32501
+ out.updated.push(...parsed.updated);
32502
+ out.archived.push(...parsed.archived);
32503
+ out.skipped.push(...parsed.skipped);
32504
+ }
32505
+ return out;
32506
+ }
32269
32507
 
32270
32508
  // src/features/magic-context/dreamer/verify.ts
32271
- var VERIFY_BATCH_SIZE = 20;
32509
+ var VERIFY_BATCH_SIZE = 5;
32510
+ var VERIFY_TOKENS_PER_MEMORY = 1e5;
32511
+ var VERIFY_RUN_TOKEN_BUDGET = 2500000;
32512
+ var VERIFY_RUN_SLICE_MS = 240000;
32513
+ function verifyBatchTokenBudget(size, configured) {
32514
+ return Math.min(configured ?? Number.MAX_SAFE_INTEGER, size * VERIFY_TOKENS_PER_MEMORY);
32515
+ }
32516
+ function verifyAssistantText(messages) {
32517
+ const text = messages.filter((m) => isRecord(m) && (m.role === "assistant" || isRecord(m.info) && m.info.role === "assistant")).map((m) => extractLatestAssistantText([m]) || (isRecord(m) && Array.isArray(m.content) ? m.content.filter(isRecord).filter((p) => p.type === "text").map((p) => p.text).join(`
32518
+ `) : "")).join(`
32519
+ `);
32520
+ if (!text.trim())
32521
+ return null;
32522
+ const start = text.lastIndexOf("<verify>");
32523
+ return start >= 0 ? text.slice(start) : text;
32524
+ }
32272
32525
  var IDENTICAL_PROVIDER_FAILURE_BATCH_LIMIT = 2;
32273
- var VERIFY_BATCH_FLOOR_MS = 240000;
32274
- function computeVerifyBatchSliceMs(remainingMs, batchesRemaining) {
32275
- return Math.min(remainingMs, Math.max(VERIFY_BATCH_FLOOR_MS, Math.floor(remainingMs / batchesRemaining)));
32526
+ var VERIFY_BATCH_FLOOR_MS = 30000;
32527
+ function computeVerifyBatchSliceMs(remainingMs, _batchesRemaining) {
32528
+ return Math.min(remainingMs, VERIFY_RUN_SLICE_MS);
32276
32529
  }
32277
32530
  function closeBroadCycle(args, cycleStartAt) {
32278
32531
  if (!args.forceBroad || cycleStartAt === undefined)
@@ -32296,6 +32549,7 @@ async function runVerify(args) {
32296
32549
  }
32297
32550
  async function runVerifyWithCooldown(args) {
32298
32551
  const runStartedAt = Date.now();
32552
+ const sliceDeadline = runStartedAt + VERIFY_RUN_SLICE_MS;
32299
32553
  const result = {
32300
32554
  verified: 0,
32301
32555
  updated: 0,
@@ -32338,16 +32592,31 @@ async function runVerifyWithCooldown(args) {
32338
32592
  let consecutiveProviderFailures = 0;
32339
32593
  let priorProviderFailureFingerprint = null;
32340
32594
  let lastProviderFailure = null;
32595
+ let runSpent = 0;
32596
+ const runTokenBudget = Math.min(args.tokenBudget ?? VERIFY_RUN_TOKEN_BUDGET, VERIFY_RUN_TOKEN_BUDGET);
32341
32597
  try {
32342
32598
  for (let i = 0;i < batches.length; i += 1) {
32343
- const remainingMs = Math.max(0, args.deadline - Date.now());
32599
+ const remainingMs = Math.max(0, Math.min(args.deadline, sliceDeadline) - Date.now());
32344
32600
  if (remainingMs < VERIFY_BATCH_FLOOR_MS) {
32345
32601
  result.stopReason = "deadline";
32346
32602
  log2(`[dreamer] ${args.forceBroad ? "verify-broad" : "verify"}: stopping before batch ${i + 1}/${batches.length} — remaining budget ${remainingMs}ms is below the ${VERIFY_BATCH_FLOOR_MS}ms batch floor`);
32347
32603
  break;
32348
32604
  }
32349
32605
  const sliceMs = computeVerifyBatchSliceMs(remainingMs, batches.length - i);
32350
- const counts = await verifyOneBatch(args, batches[i], sliceMs, abortController.signal);
32606
+ if (runSpent >= runTokenBudget) {
32607
+ result.stopReason = "token-budget";
32608
+ break;
32609
+ }
32610
+ let batchSpent = 0;
32611
+ const counts = await verifyOneBatch({
32612
+ ...args,
32613
+ tokenBudget: runTokenBudget - runSpent,
32614
+ onBudgetUpdate: (state) => {
32615
+ runSpent += Math.max(0, state.spent - batchSpent);
32616
+ batchSpent = Math.max(batchSpent, state.spent);
32617
+ args.onBudgetUpdate?.(state);
32618
+ }
32619
+ }, batches[i], sliceMs, abortController.signal);
32351
32620
  result.verified += counts.verified;
32352
32621
  result.updated += counts.updated;
32353
32622
  result.archived += counts.archived;
@@ -32357,6 +32626,10 @@ async function runVerifyWithCooldown(args) {
32357
32626
  result.remaining -= batchProcessed;
32358
32627
  result.batches += 1;
32359
32628
  args.onProgress?.(result.verified + result.updated + result.archived + result.skipped + result.refused, result.refused);
32629
+ if (counts.tokenLimited) {
32630
+ result.stopReason = "token-budget";
32631
+ break;
32632
+ }
32360
32633
  if (counts.timedOut) {
32361
32634
  result.stopReason = "batch-timeout";
32362
32635
  log2(`[dreamer] ${args.forceBroad ? "verify-broad" : "verify"}: batch ${i + 1}/${batches.length} timed out after its ${sliceMs}ms slice; stopping with ${result.remaining} remaining`);
@@ -32391,18 +32664,41 @@ async function runVerifyWithCooldown(args) {
32391
32664
  }
32392
32665
  }
32393
32666
  async function verifyOneBatch(args, batch, sliceMs, signal) {
32667
+ const batchController = new AbortController;
32668
+ const abort = () => batchController.abort(signal.reason);
32669
+ signal.addEventListener("abort", abort, { once: true });
32670
+ if (signal.aborted)
32671
+ abort();
32672
+ const timer = setTimeout(() => batchController.abort(new Error(`verify slice timed out after ${sliceMs}ms`)), sliceMs);
32673
+ const batchSignal = batchController.signal;
32674
+ const tokenBudget = verifyBatchTokenBudget(batch.length, args.tokenBudget);
32394
32675
  let agentSessionId = null;
32676
+ let hiddenSessionId = null;
32395
32677
  let promptSettled = false;
32396
32678
  const startedAt = Date.now();
32397
32679
  let budgetFinalized = false;
32680
+ let failedCompletion;
32681
+ let headAtPrompt = null;
32398
32682
  const onBudgetUpdate = (state) => {
32399
32683
  budgetFinalized ||= state.finalizeFired;
32400
- args.onBudgetUpdate?.(state);
32684
+ args.onBudgetUpdate?.({
32685
+ ...state,
32686
+ ...hiddenSessionId ? { sessionId: hiddenSessionId } : {}
32687
+ });
32688
+ };
32689
+ const reportUsage = (messages, sessionId, fallbackSpent = 0) => {
32690
+ const usage = sumTokensFromChildMessages(messages);
32691
+ onBudgetUpdate({
32692
+ spent: Math.max(fallbackSpent, usage.input + usage.cacheRead + usage.cacheWrite),
32693
+ finalizeFired: budgetFinalized,
32694
+ ...sessionId ? { sessionId } : {}
32695
+ });
32401
32696
  };
32402
32697
  try {
32403
- const headAtPrompt = await readGitHead(args.sessionDirectory);
32404
- const evidence = !args.forceBroad && batch.every((m) => m.verifiedAt) ? await buildVerifyDiffEvidence(args.sessionDirectory, batch) : null;
32405
- const prompt = buildVerifyPrompt(args.projectIdentity, batch, evidence);
32698
+ headAtPrompt = await raceWithSignal(readGitHead(args.sessionDirectory), batchSignal);
32699
+ const evidence = !args.forceBroad && batch.every((m) => m.verifiedAt) ? await raceWithSignal(buildVerifyDiffEvidence(args.sessionDirectory, batch), batchSignal) : null;
32700
+ const prompt = buildVerifyPrompt(args.projectIdentity, await raceWithSignal(seedVerifyCandidates(batch, args.sessionDirectory), batchSignal), evidence);
32701
+ batchSignal.throwIfAborted();
32406
32702
  if (args.hiddenCompletionExecutor) {
32407
32703
  const run = await runHiddenSingleShotPrompt({
32408
32704
  executor: args.hiddenCompletionExecutor,
@@ -32413,41 +32709,53 @@ async function verifyOneBatch(args, batch, sliceMs, signal) {
32413
32709
  prompt,
32414
32710
  title: "magic-context-dream-verify",
32415
32711
  callContext: "dreamer:verify",
32416
- metadata: { tokenBudget: args.tokenBudget, onBudgetUpdate },
32712
+ metadata: { tokenBudget, onBudgetUpdate },
32417
32713
  model: args.model,
32418
32714
  fallbackModels: args.fallbackModels,
32419
32715
  language: args.language,
32420
32716
  timeoutMs: sliceMs,
32421
- signal,
32717
+ signal: batchSignal,
32718
+ onFailureOutput: (completion) => {
32719
+ failedCompletion = completion;
32720
+ },
32721
+ onOpened: (sessionId) => {
32722
+ hiddenSessionId = sessionId;
32723
+ onBudgetUpdate({ spent: 0, finalizeFired: false, sessionId });
32724
+ },
32422
32725
  parse: (text, completion) => {
32423
32726
  const providerFailure = providerOutputFailureFromInvalidManifest(completion.messages ?? [], text);
32424
32727
  if (providerFailure)
32425
32728
  throw providerFailure;
32426
- return validateVerifyManifest(text, new Set(batch.map((memory) => memory.id)));
32729
+ const manifest = verifyAssistantText(completion.messages ?? []) ?? (text.trim() ? text : null);
32730
+ if (!manifest)
32731
+ throw new Error("verify returned no output");
32732
+ return validateVerifyManifest(manifest, new Set(batch.map((memory) => memory.id)));
32427
32733
  }
32428
32734
  });
32429
32735
  recordInvocation4(args, startedAt, {
32430
32736
  status: "completed",
32431
32737
  messages: run.completion.messages ?? []
32432
32738
  });
32433
- return applyParsedVerifyManifest(args, batch, run.validated, evidence?.head ?? headAtPrompt, budgetFinalized);
32739
+ reportUsage(run.completion.messages ?? [], run.childSessionId, run.completion.usage.input + (run.completion.usage.cacheRead ?? 0) + (run.completion.usage.cacheWrite ?? 0));
32740
+ return await applyParsedVerifyManifest(args, batch, run.validated, evidence?.head ?? headAtPrompt, budgetFinalized);
32434
32741
  }
32435
32742
  const client = args.client;
32436
32743
  if (!client)
32437
32744
  throw new Error("verify requires a client or hidden completion executor");
32438
- const createResponse = await createChildSessionWithFence({
32745
+ const createResponse = await raceWithSignal(createChildSessionWithFence({
32439
32746
  client,
32440
32747
  db: args.db,
32441
32748
  parentSessionId: args.parentSessionId,
32442
32749
  title: args.forceBroad ? "magic-context-dream-verify-broad" : "magic-context-dream-verify",
32443
32750
  directory: args.sessionDirectory
32444
- });
32751
+ }), batchSignal);
32445
32752
  const created = normalizeSDKResponse(createResponse, null, {
32446
32753
  preferResponseOnMissingData: true
32447
32754
  });
32448
32755
  agentSessionId = typeof created?.id === "string" ? created.id : null;
32449
32756
  if (!agentSessionId)
32450
32757
  throw new Error("Could not create verify session.");
32758
+ onBudgetUpdate({ spent: 0, finalizeFired: false, sessionId: agentSessionId });
32451
32759
  const run = await promptSyncWithValidatedOutputRetry(client, {
32452
32760
  path: { id: agentSessionId },
32453
32761
  query: { directory: args.sessionDirectory },
@@ -32459,11 +32767,11 @@ async function verifyOneBatch(args, batch, sliceMs, signal) {
32459
32767
  }
32460
32768
  }, {
32461
32769
  transport: createPromptAsyncTransport(client, agentSessionId, {
32462
- tokenBudget: args.tokenBudget,
32770
+ tokenBudget,
32463
32771
  onBudgetUpdate
32464
32772
  }),
32465
32773
  timeoutMs: sliceMs,
32466
- signal,
32774
+ signal: batchSignal,
32467
32775
  fallbackModels: args.fallbackModels,
32468
32776
  callContext: "dreamer:verify",
32469
32777
  fetchOutput: async () => {
@@ -32479,7 +32787,7 @@ async function verifyOneBatch(args, batch, sliceMs, signal) {
32479
32787
  if (hasLengthCappedOutput(messages)) {
32480
32788
  throw new Error("verify returned length-capped output");
32481
32789
  }
32482
- const text = extractLatestAssistantText(messages);
32790
+ const text = verifyAssistantText(messages);
32483
32791
  if (!text)
32484
32792
  throw new Error("verify returned no output");
32485
32793
  const providerFailure = providerOutputFailureFromInvalidManifest(messages, text);
@@ -32490,27 +32798,31 @@ async function verifyOneBatch(args, batch, sliceMs, signal) {
32490
32798
  });
32491
32799
  promptSettled = true;
32492
32800
  recordInvocation4(args, startedAt, { status: "completed", messages: run.output });
32801
+ reportUsage(run.output, agentSessionId);
32493
32802
  return await applyParsedVerifyManifest(args, batch, run.validated, evidence?.head ?? headAtPrompt, budgetFinalized);
32494
32803
  } catch (error) {
32495
32804
  const desc = describeError(error);
32496
32805
  const providerFailure = error instanceof DreamerProviderOutputFailureError ? error : undefined;
32497
32806
  const promptFailure = getPromptFailureDetail(error);
32498
32807
  log2(`[dreamer] verify batch ${providerFailure ? "provider failure" : "failed"}: ${desc.brief}`, desc.stackHead ? { stackHead: desc.stackHead } : undefined);
32808
+ const messages = failedCompletion?.messages ?? await readFailedChildMessages(args.client, agentSessionId, args.sessionDirectory) ?? [];
32809
+ reportUsage(messages, hiddenSessionId ?? agentSessionId, failedCompletion?.usage.input ?? 0);
32499
32810
  recordInvocation4(args, startedAt, {
32500
32811
  status: failedInvocationStatus(error),
32501
32812
  error,
32502
- messages: await readFailedChildMessages(args.client, agentSessionId, args.sessionDirectory)
32813
+ messages
32503
32814
  });
32504
- if (error instanceof DreamerModuleFailureError || error instanceof DreamTokenBudgetExceeded || signal.aborted)
32815
+ if (error instanceof DreamerModuleFailureError || signal.aborted)
32505
32816
  throw error;
32506
- if (promptFailure?.failureClass === "provider_timeout" || isPromptTimeoutError(error)) {
32817
+ const interrupted = batchSignal.aborted || error instanceof DreamTokenBudgetExceeded || promptFailure?.failureClass === "provider_timeout" || isPromptTimeoutError(error);
32818
+ if (interrupted) {
32819
+ const text = verifyAssistantText(messages) ?? failedCompletion?.text ?? "";
32820
+ const recovered = parsePartialVerifyManifest(text, new Set(batch.map((m) => m.id)));
32821
+ const counts = await applyParsedVerifyManifest(args, batch, recovered, headAtPrompt, true);
32507
32822
  return {
32508
- verified: 0,
32509
- updated: 0,
32510
- archived: 0,
32511
- skipped: 0,
32512
- refused: 0,
32513
- timedOut: true
32823
+ ...counts,
32824
+ timedOut: !(error instanceof DreamTokenBudgetExceeded),
32825
+ tokenLimited: error instanceof DreamTokenBudgetExceeded
32514
32826
  };
32515
32827
  }
32516
32828
  if (promptFailure !== null && promptFailure.failureClass !== "parse_failed" && !providerFailure)
@@ -32525,7 +32837,7 @@ async function verifyOneBatch(args, batch, sliceMs, signal) {
32525
32837
  };
32526
32838
  } finally {
32527
32839
  if (agentSessionId && args.client)
32528
- await teardownChildSession({
32840
+ await raceWithSignal(teardownChildSession({
32529
32841
  client: args.client,
32530
32842
  sessionId: agentSessionId,
32531
32843
  sessionDirectory: args.sessionDirectory,
@@ -32533,7 +32845,9 @@ async function verifyOneBatch(args, batch, sliceMs, signal) {
32533
32845
  privacySensitive: true,
32534
32846
  context: "[dreamer] verify",
32535
32847
  log: log2
32536
- });
32848
+ }), batchSignal).catch(() => {});
32849
+ clearTimeout(timer);
32850
+ signal.removeEventListener("abort", abort);
32537
32851
  }
32538
32852
  }
32539
32853
  async function applyParsedVerifyManifest(args, batch, parsed, headAtPrompt, budgetFinalized = false) {
@@ -32560,7 +32874,7 @@ async function applyParsedVerifyManifest(args, batch, parsed, headAtPrompt, budg
32560
32874
  throw new Error(`verify manifest covers ${validIds.length}/${batch.length} batch ids after filtering unknown entries; rejecting mostly-wrong manifest`);
32561
32875
  }
32562
32876
  if (budgetFinalized && validIds.length < batch.length) {
32563
- log2(`[dreamer] verify: accepted partial manifest after token budget: ${validIds.length}/${batch.length}`);
32877
+ log2(`[dreamer] verify: accepted partial manifest after investigation stop: ${validIds.length}/${batch.length}`);
32564
32878
  }
32565
32879
  if (validIds.length === 0) {
32566
32880
  return { verified: 0, updated: 0, archived: 0, skipped: 0, refused: 0 };
@@ -32795,10 +33109,10 @@ function dreamRunFailureDetail(error) {
32795
33109
  child_session_id: null
32796
33110
  };
32797
33111
  }
32798
- const localRefusal = error instanceof HiddenCompletionRefusal;
33112
+ const localRefusal = error instanceof HiddenCompletionRefusal || error instanceof DreamerModuleFailureError;
32799
33113
  const providerFailure = error instanceof Error && error.name === "DreamerProviderOutputFailureError";
32800
33114
  return {
32801
- failure_class: localRefusal ? "local_refusal" : providerFailure ? "provider_error" : /no models?|model chain is empty/i.test(message) ? "no_models" : "unknown",
33115
+ failure_class: localRefusal ? "local_refusal" : providerFailure ? "provider_error" : /lease_(?:lost|expired)|Dream lease (?:lost|unavailable)/i.test(message) ? "child_aborted" : /no models?|model chain is empty/i.test(message) ? "no_models" : "unknown",
32802
33116
  model_attempted: null,
32803
33117
  models_tried: [],
32804
33118
  provider_error: providerFailure ? sanitizeDiagnosticText(message).slice(0, 500) : null,
@@ -32809,6 +33123,10 @@ function dreamRunFailureDetail(error) {
32809
33123
  } : {}
32810
33124
  };
32811
33125
  }
33126
+ function incompleteFailure(error, fallback = "parse_failed") {
33127
+ const detail = dreamRunFailureDetail(error);
33128
+ return detail.failure_class === "unknown" ? { ...detail, failure_class: fallback } : detail;
33129
+ }
32812
33130
  function classifyFailure(error) {
32813
33131
  const described = describeError(error);
32814
33132
  const brief = described.brief;
@@ -32968,6 +33286,7 @@ function createDreamTaskExecutor(deps) {
32968
33286
  const { db, projectIdentity, holderId, leaseKey } = ctx;
32969
33287
  deps.client?.resetDreamTokenBudget?.(config.task);
32970
33288
  const startedAt = Date.now();
33289
+ const effectiveTokenBudget = config.task === "verify" || config.task === "verify-broad" ? Math.min(config.tokenBudget ?? VERIFY_RUN_TOKEN_BUDGET, VERIFY_RUN_TOKEN_BUDGET) : config.tokenBudget;
32971
33290
  const leaseAcquisition = ctx.leaseAcquisition ?? acquireLeaseWithAcquisition(db, holderId, leaseKey) ?? (() => {
32972
33291
  throw new Error("Dream lease unavailable during executor setup");
32973
33292
  })();
@@ -33015,7 +33334,7 @@ function createDreamTaskExecutor(deps) {
33015
33334
  if (state.sessionId) {
33016
33335
  const previous = childSpending.get(state.sessionId) ?? 0;
33017
33336
  budgetSpent += Math.max(0, state.spent - previous);
33018
- childSpending.set(state.sessionId, state.spent);
33337
+ childSpending.set(state.sessionId, Math.max(previous, state.spent));
33019
33338
  } else
33020
33339
  budgetSpent = Math.max(budgetSpent, state.spent);
33021
33340
  budgetFinalized ||= state.finalizeFired;
@@ -33042,9 +33361,15 @@ function createDreamTaskExecutor(deps) {
33042
33361
  failure: extra?.failure ?? dreamRunFailureDetail(error ?? "unknown dreamer failure")
33043
33362
  } : {},
33044
33363
  ...extra?.progress ? { progress: extra.progress } : {},
33045
- ...config.tokenBudget ? {
33364
+ ...childSpending.size ? {
33365
+ children: [...childSpending].map(([sessionId, promptTokens]) => ({
33366
+ sessionId,
33367
+ promptTokens
33368
+ }))
33369
+ } : {},
33370
+ ...effectiveTokenBudget ? {
33046
33371
  tokenBudget: {
33047
- budget: config.tokenBudget,
33372
+ budget: effectiveTokenBudget,
33048
33373
  spent: budgetSpent,
33049
33374
  finalizeFired: budgetFinalized,
33050
33375
  banked: extra?.banked ?? processedDreamTaskItems(backlogAtStart.pending, (extra?.backlogAfter ?? getDreamTaskBacklog(db, projectIdentity, config.task)).pending)
@@ -33133,8 +33458,13 @@ function createDreamTaskExecutor(deps) {
33133
33458
  });
33134
33459
  log2(`[dreamer] compress-cues: compressed=${result.compressed} skipped=${result.skipped} chunks=${result.chunks} remaining=${result.remaining}`);
33135
33460
  if (!result.complete) {
33136
- const error = incompleteMessage(result.remaining);
33137
- recordRun("failed", error);
33461
+ if (result.stopReason === "deadline" && result.chunks === 0)
33462
+ return skip("compress-cues: insufficient time to start a chunk");
33463
+ const error = `${incompleteMessage(result.remaining)}; ${result.failureStage ? `${result.failureStage}: ` : ""}${result.failure ? describeError(result.failure).brief : `${result.skipped} cues rejected by validation`}`;
33464
+ recordRun("failed", error, {
33465
+ banked: result.compressed,
33466
+ failure: incompleteFailure(result.failure, result.failureStage === "child-start" ? "local_refusal" : result.stopReason === "timeout-circuit-breaker" ? "provider_timeout" : "parse_failed")
33467
+ });
33138
33468
  return { status: "failed", transient: true, error };
33139
33469
  }
33140
33470
  recordRun("completed", null);
@@ -33180,9 +33510,15 @@ function createDreamTaskExecutor(deps) {
33180
33510
  });
33181
33511
  log2(`[dreamer] map-memories: committed=${result.mapped + result.independent} mapped=${result.mapped} independent=${result.independent} batches=${result.batches} remaining=${result.remaining} complete=${result.complete}${result.stopReason ? ` stop_reason=${result.stopReason}` : ""}`);
33182
33512
  if (!result.complete) {
33513
+ if (result.deferred)
33514
+ return skip("map-memories: all pending mappings are in content-keyed retry backoff; no child started");
33515
+ if (result.stopReason === "deadline" && result.batches === 0 && !result.failure)
33516
+ return skip("map-memories: insufficient time to start a batch");
33183
33517
  if (result.stopReason === "timeout-circuit-breaker") {
33184
33518
  const error = `map-memories starvation: timeout circuit breaker stopped the run with ${result.remaining} remain`;
33185
- recordRun("failed", error);
33519
+ recordRun("failed", error, {
33520
+ failure: incompleteFailure(result.failure, "provider_timeout")
33521
+ });
33186
33522
  return { status: "failed", transient: true, error };
33187
33523
  }
33188
33524
  const processed = result.mapped + result.independent;
@@ -33191,8 +33527,10 @@ function createDreamTaskExecutor(deps) {
33191
33527
  recordRun("completed", null, { progress });
33192
33528
  return { status: "completed" };
33193
33529
  }
33194
- const error = incompleteMessage(result.remaining);
33195
- recordRun("failed", error);
33530
+ const error = `${incompleteMessage(result.remaining)}; ${result.failureStage ? `${result.failureStage}: ` : ""}${result.failure ? describeError(result.failure).brief : "manifest returned no accepted mapping decisions"}`;
33531
+ recordRun("failed", error, {
33532
+ failure: incompleteFailure(result.failure, result.failureStage === "child-start" ? "local_refusal" : "parse_failed")
33533
+ });
33196
33534
  return { status: "failed", transient: true, error };
33197
33535
  }
33198
33536
  recordRun("completed", null);
@@ -33222,25 +33560,27 @@ function createDreamTaskExecutor(deps) {
33222
33560
  });
33223
33561
  const processed = result.verified + result.updated + result.archived + result.skipped + result.refused;
33224
33562
  const verificationProgress = `${config.task}${config.task === "verify-broad" ? ` cycle ${result.broadCycleStartAt ?? "open"}` : ""}: processed ${processed} (verified ${result.verified}, updated ${result.updated}, archived ${result.archived}, skipped ${result.skipped}, refused ${result.refused}); ${result.remaining} remain`;
33225
- const broadProgress = config.task === "verify-broad" ? verificationProgress : null;
33226
33563
  const backlogAfter = config.task === "verify-broad" ? { pending: result.remaining, total: backlogAtStart.total } : undefined;
33227
33564
  if (!result.complete) {
33228
- if (broadProgress && processed > 0) {
33565
+ if (processed > 0) {
33229
33566
  recordRun("completed", null, {
33230
- progress: broadProgress,
33567
+ progress: verificationProgress,
33231
33568
  memoryChanges: computeMemoryDelta(memoryBefore),
33232
33569
  backlogAfter,
33233
33570
  banked: result.verified + result.updated + result.archived
33234
33571
  });
33235
33572
  return { status: "completed" };
33236
33573
  }
33574
+ if (result.stopReason === "deadline")
33575
+ return skip(`${config.task}: insufficient time to start a batch`);
33237
33576
  const batchTimedOut = result.stopReason === "batch-timeout";
33238
33577
  const error = batchTimedOut ? `${config.task}: a batch timed out within its time slice; ${result.remaining} remain` : incompleteMessage(result.remaining);
33239
33578
  recordRun("failed", error, {
33240
33579
  progress: verificationProgress,
33241
33580
  memoryChanges: computeMemoryDelta(memoryBefore),
33242
33581
  backlogAfter,
33243
- banked: result.verified + result.updated + result.archived
33582
+ banked: result.verified + result.updated + result.archived,
33583
+ failure: incompleteFailure(error, batchTimedOut ? "provider_timeout" : result.stopReason === "token-budget" ? "token_budget" : "parse_failed")
33244
33584
  });
33245
33585
  return { status: "failed", transient: !batchTimedOut, error };
33246
33586
  }
@@ -33364,6 +33704,7 @@ function createDreamTaskExecutor(deps) {
33364
33704
  if (retro.skipReason)
33365
33705
  return skip(retro.skipReason);
33366
33706
  recordRun("completed", null, {
33707
+ progress: retro.noOpReason,
33367
33708
  memoryChanges: computeMemoryDelta(memoryBefore),
33368
33709
  backlogAfter: retro.retrospectiveWatermarkMs == null ? undefined : getDreamTaskBacklog(db, projectIdentity, "retrospective", {
33369
33710
  retrospectiveWatermarkMs: retro.retrospectiveWatermarkMs
@@ -33371,6 +33712,7 @@ function createDreamTaskExecutor(deps) {
33371
33712
  });
33372
33713
  return {
33373
33714
  status: "completed",
33715
+ ...retro.noOpReason ? { detail: retro.noOpReason } : {},
33374
33716
  schedulePatch: retro.retrospectiveWatermarkMs != null || retro.taskStateJson !== undefined ? {
33375
33717
  ...retro.retrospectiveWatermarkMs != null ? {
33376
33718
  retrospectiveWatermarkMs: retro.retrospectiveWatermarkMs
@@ -33570,20 +33912,28 @@ async function runRetrospectiveTask(config, ctx, helpers) {
33570
33912
  const recencyCutoffMs = helpers.invocationStartedAt - recencyDays * RETROSPECTIVE_DAY_MS;
33571
33913
  const scan = await readRetrospectiveScanWindow(provider, projectIdentity, watermarkMs, RETROSPECTIVE_OVERLAP_USER_LINES, { usableInputTokens, recencyCutoffMs });
33572
33914
  const clearedTaskStateJson = activeOverflow ? writeRetrospectiveOverflowState(taskState.root, null) : undefined;
33573
- const completedWindow = (retrospectiveWatermarkMs) => ({
33915
+ const completedWindow = (retrospectiveWatermarkMs, noOpReason) => ({
33574
33916
  retrospectiveWatermarkMs,
33575
- ...clearedTaskStateJson ? { taskStateJson: clearedTaskStateJson } : {}
33917
+ ...clearedTaskStateJson ? { taskStateJson: clearedTaskStateJson } : {},
33918
+ ...noOpReason ? { noOpReason } : {}
33576
33919
  });
33577
33920
  const messages = withGlobalOrdinals(scan.messages);
33578
33921
  const userMessages = messages.filter((message) => message.role === "user" && message.text.trim().length > 0);
33579
33922
  if (userMessages.length === 0) {
33580
- log2("[dreamer] retrospective: no user messages in window");
33581
- return completedWindow(scan.maxScannedTs);
33923
+ const noOpReason = "no reply-following user lines";
33924
+ log2(`[dreamer] retrospective: ${noOpReason}`);
33925
+ return completedWindow(scan.maxScannedTs, noOpReason);
33582
33926
  }
33583
- const postWatermarkOrdinals = new Set(userMessages.filter((message) => message.ts > watermarkMs).map((message) => message.ordinal));
33584
- if (postWatermarkOrdinals.size === 0) {
33927
+ const newUserOrdinals = new Set(userMessages.filter((message) => message.ts > watermarkMs).map((message) => message.ordinal));
33928
+ if (newUserOrdinals.size === 0) {
33585
33929
  log2("[dreamer] retrospective: only overlap lines, nothing new");
33586
- return completedWindow(scan.maxScannedTs);
33930
+ return completedWindow(scan.maxScannedTs, "only overlap lines, nothing new");
33931
+ }
33932
+ const postWatermarkOrdinals = new Set(userMessages.filter((message) => message.ts > watermarkMs && message.followsAssistantReply === true).map((message) => message.ordinal));
33933
+ if (postWatermarkOrdinals.size === 0) {
33934
+ const noOpReason = "no reply-following user lines";
33935
+ log2(`[dreamer] retrospective: ${noOpReason}`);
33936
+ return completedWindow(scan.maxScannedTs, noOpReason);
33587
33937
  }
33588
33938
  const abortController = new AbortController;
33589
33939
  let leaseLost = false;
@@ -34537,7 +34887,8 @@ class V2RetrospectiveRawProvider {
34537
34887
  ordinal: row.seq,
34538
34888
  role: "user",
34539
34889
  text: cleanUserText2(row.text),
34540
- ts: row.time_created
34890
+ ts: row.time_created,
34891
+ ...row.follows_assistant_reply === 1 ? { followsAssistantReply: true } : {}
34541
34892
  }));
34542
34893
  }
34543
34894
  readUserMessagesSince(sessionId, sinceMs, capPerSession) {
@@ -50533,6 +50884,85 @@ function bindV2TransformDecision(args) {
50533
50884
  }
50534
50885
  }
50535
50886
 
50887
+ // src/hooks/magic-context/auto-embed-session.ts
50888
+ function embeddingIdentity(projectIdentity) {
50889
+ const snapshot = getProjectEmbeddingSnapshot2(projectIdentity);
50890
+ return JSON.stringify([
50891
+ projectIdentity,
50892
+ snapshot?.providerIdentity,
50893
+ snapshot?.chunkModelId,
50894
+ snapshot?.runtimeFingerprint
50895
+ ]);
50896
+ }
50897
+ function maybeAutoEmbedSessionBackfill(deps, sessionId) {
50898
+ const markActive = () => activeEmbeddingSessions.set(sessionId, {
50899
+ project: deps.projectIdentity,
50900
+ model: getProjectEmbeddingSnapshot2(deps.projectIdentity)?.chunkModelId ?? "off"
50901
+ });
50902
+ markActive();
50903
+ const identity = embeddingIdentity(deps.projectIdentity);
50904
+ if (autoEmbedIdentityBySession.get(sessionId) !== identity) {
50905
+ invalidateAutoEmbedSession(sessionId);
50906
+ autoEmbedIdentityBySession.set(sessionId, identity);
50907
+ }
50908
+ if (autoEmbedAttemptedBySession.has(sessionId) || embedPauseBySession.has(sessionId) || embedRunStateBySession.has(sessionId) || Date.now() < (autoEmbedRetryAfterBySession.get(sessionId) ?? 0))
50909
+ return;
50910
+ const controller = new AbortController;
50911
+ embedRunStateBySession.set(sessionId, controller);
50912
+ (async () => {
50913
+ let complete = false;
50914
+ let retryDelay = 1000;
50915
+ let started = false;
50916
+ let reason = "error";
50917
+ let registeredIdentity = identity;
50918
+ try {
50919
+ await new Promise((resolve) => setTimeout(resolve, 0));
50920
+ if (controller.signal.aborted)
50921
+ return;
50922
+ await deps.ensureRegistered();
50923
+ if (controller.signal.aborted)
50924
+ return;
50925
+ markActive();
50926
+ registeredIdentity = embeddingIdentity(deps.projectIdentity);
50927
+ autoEmbedIdentityBySession.set(sessionId, registeredIdentity);
50928
+ const coverage = await getAutoEmbeddingSessionCoverage2(deps.db, deps.projectIdentity, sessionId);
50929
+ if (controller.signal.aborted || !coverage.enabled)
50930
+ return;
50931
+ if (coverage.embedded === coverage.total) {
50932
+ complete = true;
50933
+ return;
50934
+ }
50935
+ const model = getProjectEmbeddingSnapshot2(deps.projectIdentity)?.model;
50936
+ log2(`[magic-context] session backfill start session=${sessionId} missing=${coverage.total - coverage.embedded} model=${model}`);
50937
+ started = true;
50938
+ const outcome = await embedSessionCompartmentChunks2(deps.db, deps.projectIdentity, sessionId, { signal: controller.signal, automatic: true });
50939
+ reason = outcome.status;
50940
+ const after = await getAutoEmbeddingSessionCoverage2(deps.db, deps.projectIdentity, sessionId);
50941
+ complete = after.enabled && after.embedded === after.total;
50942
+ if (!complete && outcome.status !== "busy" && outcome.status !== "aborted") {
50943
+ retryDelay = 60000;
50944
+ if (outcome.status === "nothing" || outcome.status === "done")
50945
+ reason = "deferred";
50946
+ }
50947
+ } catch (error) {
50948
+ log2("[magic-context] auto-embed drain failed:", error);
50949
+ retryDelay = 60000;
50950
+ } finally {
50951
+ if (started)
50952
+ log2(`[magic-context] session backfill ${complete ? "complete" : "stop"} session=${sessionId} reason=${reason}`);
50953
+ if (embedRunStateBySession.get(sessionId) === controller) {
50954
+ embedRunStateBySession.delete(sessionId);
50955
+ }
50956
+ if (!controller.signal.aborted && autoEmbedIdentityBySession.get(sessionId) === registeredIdentity && embeddingIdentity(deps.projectIdentity) === registeredIdentity) {
50957
+ if (complete)
50958
+ autoEmbedAttemptedBySession.add(sessionId);
50959
+ else
50960
+ autoEmbedRetryAfterBySession.set(sessionId, Date.now() + retryDelay);
50961
+ }
50962
+ }
50963
+ })();
50964
+ }
50965
+
50536
50966
  // src/v2/hooks/transform-features.ts
50537
50967
  function createV2TransformFeatureDeps(config, compactionOff, directory) {
50538
50968
  return {
@@ -50568,47 +50998,18 @@ function createV2TransformFeatureDeps(config, compactionOff, directory) {
50568
50998
  }
50569
50999
  function createV2AutoEmbedSession(deps) {
50570
51000
  return (sessionId) => {
50571
- if (isEmbeddingHostBusy2())
50572
- return;
50573
51001
  const directory = deps.resolveDirectory(sessionId);
50574
- const identity = resolveProjectIdentityForSession(directory, deps.allowHomeProject);
50575
- const snapshot = identity ? getProjectEmbeddingSnapshot2(identity) : undefined;
50576
- const embedIdentity = snapshot ? JSON.stringify([
50577
- snapshot.providerIdentity,
50578
- snapshot.chunkModelId,
50579
- snapshot.runtimeFingerprint
50580
- ]) : "off";
50581
- if (autoEmbedIdentityBySession.get(sessionId) !== embedIdentity)
50582
- invalidateAutoEmbedSession(sessionId);
50583
- if (autoEmbedAttemptedBySession.has(sessionId) || embedPauseBySession.has(sessionId))
51002
+ const projectIdentity = resolveProjectIdentityForSession(directory, deps.allowHomeProject);
51003
+ if (!projectIdentity)
50584
51004
  return;
50585
- autoEmbedAttemptedBySession.add(sessionId);
50586
- autoEmbedIdentityBySession.set(sessionId, embedIdentity);
50587
- (async () => {
50588
- try {
50589
- await new Promise((resolve) => setTimeout(resolve, 0));
50590
- if (isEmbeddingHostBusy2()) {
50591
- invalidateAutoEmbedSession(sessionId);
50592
- return;
50593
- }
51005
+ maybeAutoEmbedSessionBackfill({
51006
+ db: deps.db,
51007
+ projectIdentity,
51008
+ ensureRegistered: async () => {
50594
51009
  await ensureProjectRegisteredFromOpenCodeDirectory(directory, deps.db);
50595
- const project = resolveProjectIdentityForSession(directory, deps.allowHomeProject);
50596
- if (!project) {
50597
- invalidateAutoEmbedSession(sessionId);
50598
- return;
50599
- }
50600
- const coverage = await getAutoEmbeddingSessionCoverage2(deps.db, project, sessionId);
50601
- if (!coverage.enabled) {
50602
- invalidateAutoEmbedSession(sessionId);
50603
- return;
50604
- }
50605
- if (coverage.total <= coverage.embedded)
50606
- return;
50607
- await runEmbedHistoryDrain(deps, sessionId, { silent: true });
50608
- } catch (error) {
50609
- log2("[magic-context] auto-embed drain failed:", error);
51010
+ deps.onDirectoryResolved?.(sessionId, directory);
50610
51011
  }
50611
- })();
51012
+ }, sessionId);
50612
51013
  };
50613
51014
  }
50614
51015