@cortexkit/opencode-magic-context 0.36.0 → 0.37.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (192) hide show
  1. package/dist/config/index.d.ts.map +1 -1
  2. package/dist/config/project-security.d.ts +2 -1
  3. package/dist/config/project-security.d.ts.map +1 -1
  4. package/dist/config/schema/magic-context.d.ts +10 -0
  5. package/dist/config/schema/magic-context.d.ts.map +1 -1
  6. package/dist/{conflict-warning-hook-dw9fs934.js → conflict-warning-hook-an4fxhwf.js} +4 -4
  7. package/dist/{derive-budgets-88mxk2w1.js → derive-budgets-0f8xpyw2.js} +3 -2
  8. package/dist/features/magic-context/context-authority.d.ts +12 -0
  9. package/dist/features/magic-context/context-authority.d.ts.map +1 -1
  10. package/dist/features/magic-context/dreamer/classify.d.ts +2 -0
  11. package/dist/features/magic-context/dreamer/classify.d.ts.map +1 -1
  12. package/dist/features/magic-context/dreamer/evaluate-smart-notes.d.ts +2 -0
  13. package/dist/features/magic-context/dreamer/evaluate-smart-notes.d.ts.map +1 -1
  14. package/dist/features/magic-context/dreamer/lease.d.ts +10 -3
  15. package/dist/features/magic-context/dreamer/lease.d.ts.map +1 -1
  16. package/dist/features/magic-context/dreamer/map-memories.d.ts +2 -0
  17. package/dist/features/magic-context/dreamer/map-memories.d.ts.map +1 -1
  18. package/dist/features/magic-context/dreamer/module-apply.d.ts +5 -0
  19. package/dist/features/magic-context/dreamer/module-apply.d.ts.map +1 -1
  20. package/dist/features/magic-context/dreamer/promote-primers.d.ts +2 -0
  21. package/dist/features/magic-context/dreamer/promote-primers.d.ts.map +1 -1
  22. package/dist/features/magic-context/dreamer/refresh-primers.d.ts +2 -0
  23. package/dist/features/magic-context/dreamer/refresh-primers.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/task-scheduler.d.ts +5 -2
  26. package/dist/features/magic-context/dreamer/task-scheduler.d.ts.map +1 -1
  27. package/dist/features/magic-context/dreamer/verify.d.ts +2 -0
  28. package/dist/features/magic-context/dreamer/verify.d.ts.map +1 -1
  29. package/dist/features/magic-context/memory/embedding-openai.d.ts +3 -1
  30. package/dist/features/magic-context/memory/embedding-openai.d.ts.map +1 -1
  31. package/dist/features/magic-context/memory/project-identity.d.ts +6 -0
  32. package/dist/features/magic-context/memory/project-identity.d.ts.map +1 -1
  33. package/dist/features/magic-context/message-index-async.d.ts.map +1 -1
  34. package/dist/features/magic-context/migrations.d.ts.map +1 -1
  35. package/dist/features/magic-context/mural/compress-cues.d.ts +2 -0
  36. package/dist/features/magic-context/mural/compress-cues.d.ts.map +1 -1
  37. package/dist/features/magic-context/overflow-detection.d.ts.map +1 -1
  38. package/dist/features/magic-context/project-embedding-registry.d.ts.map +1 -1
  39. package/dist/features/magic-context/schema-fence-probe.d.ts +1 -0
  40. package/dist/features/magic-context/schema-fence-probe.d.ts.map +1 -1
  41. package/dist/features/magic-context/smart-notes/condition-compiler.d.ts +1 -0
  42. package/dist/features/magic-context/smart-notes/condition-compiler.d.ts.map +1 -1
  43. package/dist/features/magic-context/smart-notes/runner.d.ts.map +1 -1
  44. package/dist/features/magic-context/smart-notes/wake-plane.d.ts +21 -0
  45. package/dist/features/magic-context/smart-notes/wake-plane.d.ts.map +1 -0
  46. package/dist/features/magic-context/storage-clone.d.ts +6 -0
  47. package/dist/features/magic-context/storage-clone.d.ts.map +1 -1
  48. package/dist/features/magic-context/storage-db.d.ts +14 -3
  49. package/dist/features/magic-context/storage-db.d.ts.map +1 -1
  50. package/dist/features/magic-context/storage-identity-merge.d.ts.map +1 -1
  51. package/dist/features/magic-context/storage-meta-persisted.d.ts +22 -0
  52. package/dist/features/magic-context/storage-meta-persisted.d.ts.map +1 -1
  53. package/dist/features/magic-context/storage-meta-session.d.ts.map +1 -1
  54. package/dist/features/magic-context/storage-meta-shared.d.ts.map +1 -1
  55. package/dist/features/magic-context/storage-primers.d.ts +11 -0
  56. package/dist/features/magic-context/storage-primers.d.ts.map +1 -1
  57. package/dist/features/magic-context/storage-schema-helpers.d.ts.map +1 -1
  58. package/dist/features/magic-context/storage-tags.d.ts +2 -0
  59. package/dist/features/magic-context/storage-tags.d.ts.map +1 -1
  60. package/dist/features/magic-context/storage.d.ts +1 -1
  61. package/dist/features/magic-context/storage.d.ts.map +1 -1
  62. package/dist/features/magic-context/user-memory/review-user-memories.d.ts +2 -0
  63. package/dist/features/magic-context/user-memory/review-user-memories.d.ts.map +1 -1
  64. package/dist/features/magic-context/user-memory/storage-user-memory.d.ts +7 -0
  65. package/dist/features/magic-context/user-memory/storage-user-memory.d.ts.map +1 -1
  66. package/dist/features/magic-context/window-report-ledger.d.ts +70 -0
  67. package/dist/features/magic-context/window-report-ledger.d.ts.map +1 -0
  68. package/dist/hooks/magic-context/child-session-spawn.d.ts +1 -0
  69. package/dist/hooks/magic-context/child-session-spawn.d.ts.map +1 -1
  70. package/dist/hooks/magic-context/command-handler.d.ts.map +1 -1
  71. package/dist/hooks/magic-context/compaction-off-transition.d.ts.map +1 -1
  72. package/dist/hooks/magic-context/compartment-render-epoch.d.ts +5 -3
  73. package/dist/hooks/magic-context/compartment-render-epoch.d.ts.map +1 -1
  74. package/dist/hooks/magic-context/embed-session-state.d.ts +1 -1
  75. package/dist/hooks/magic-context/embed-session-state.d.ts.map +1 -1
  76. package/dist/hooks/magic-context/event-handler.d.ts.map +1 -1
  77. package/dist/hooks/magic-context/event-resolvers.d.ts +4 -0
  78. package/dist/hooks/magic-context/event-resolvers.d.ts.map +1 -1
  79. package/dist/hooks/magic-context/execute-status.d.ts +2 -1
  80. package/dist/hooks/magic-context/execute-status.d.ts.map +1 -1
  81. package/dist/hooks/magic-context/hook.d.ts.map +1 -1
  82. package/dist/hooks/magic-context/inject-compartments.d.ts +8 -0
  83. package/dist/hooks/magic-context/inject-compartments.d.ts.map +1 -1
  84. package/dist/hooks/magic-context/lkg-replay.d.ts +5 -2
  85. package/dist/hooks/magic-context/lkg-replay.d.ts.map +1 -1
  86. package/dist/hooks/magic-context/lkg-slot.d.ts +20 -0
  87. package/dist/hooks/magic-context/lkg-slot.d.ts.map +1 -1
  88. package/dist/hooks/magic-context/module-state-sync.d.ts +9 -0
  89. package/dist/hooks/magic-context/module-state-sync.d.ts.map +1 -1
  90. package/dist/hooks/magic-context/module-transport.d.ts +20 -3
  91. package/dist/hooks/magic-context/module-transport.d.ts.map +1 -1
  92. package/dist/hooks/magic-context/module-wire.d.ts +6 -1
  93. package/dist/hooks/magic-context/module-wire.d.ts.map +1 -1
  94. package/dist/hooks/magic-context/read-session-formatting.d.ts +1 -0
  95. package/dist/hooks/magic-context/read-session-formatting.d.ts.map +1 -1
  96. package/dist/hooks/magic-context/rust-mode-transform.d.ts +20 -0
  97. package/dist/hooks/magic-context/rust-mode-transform.d.ts.map +1 -1
  98. package/dist/hooks/magic-context/strip-content.d.ts +31 -1
  99. package/dist/hooks/magic-context/strip-content.d.ts.map +1 -1
  100. package/dist/hooks/magic-context/system-prompt-hash.d.ts.map +1 -1
  101. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts +12 -3
  102. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
  103. package/dist/hooks/magic-context/transform.d.ts +10 -0
  104. package/dist/hooks/magic-context/transform.d.ts.map +1 -1
  105. package/dist/hooks/magic-context/wrapup-orchestrator.d.ts.map +1 -1
  106. package/dist/{index-3nfgbsp4.js → index-0ze9p983.js} +897 -114
  107. package/dist/{index-nsx2n9eg.js → index-4cz5nfxf.js} +3 -3
  108. package/dist/{index-0c9dmw9m.js → index-8mtsfhyg.js} +33 -3
  109. package/dist/{index-f1tnb3vm.js → index-8pqfcghm.js} +21 -9
  110. package/dist/{index-37rt2bka.js → index-cae89eas.js} +26 -7
  111. package/dist/index-cgyfn1s2.js +53 -0
  112. package/dist/{index-z8v31d85.js → index-crke4z5j.js} +144 -14
  113. package/dist/{index-tsgs7td8.js → index-pck9vadr.js} +1 -1
  114. package/dist/index-q0t189ay.js +741 -0
  115. package/dist/{index-3tnkymva.js → index-sw8gnq34.js} +1 -1
  116. package/dist/index.d.ts.map +1 -1
  117. package/dist/index.js +1952 -795
  118. package/dist/plugin/hooks/create-session-hooks.d.ts +3 -0
  119. package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
  120. package/dist/plugin/rpc-handlers.d.ts.map +1 -1
  121. package/dist/plugin/rust-tool-backends.d.ts +4 -0
  122. package/dist/plugin/rust-tool-backends.d.ts.map +1 -1
  123. package/dist/{recomp-orchestrator-7wbbvf87.js → recomp-orchestrator-c3ff16k7.js} +8 -7
  124. package/dist/{safe-notification-target-c11fdda2.js → safe-notification-target-b693f9x3.js} +2 -2
  125. package/dist/{send-session-notification-bgtf4853.js → send-session-notification-dxske5zm.js} +3 -3
  126. package/dist/shared/conflict-detector.d.ts +63 -0
  127. package/dist/shared/conflict-detector.d.ts.map +1 -1
  128. package/dist/shared/conflict-fixer.d.ts.map +1 -1
  129. package/dist/shared/harness-provider-map.d.ts +8 -0
  130. package/dist/shared/harness-provider-map.d.ts.map +1 -1
  131. package/dist/shared/jsonc-edit.d.ts +18 -0
  132. package/dist/shared/jsonc-edit.d.ts.map +1 -0
  133. package/dist/shared/jsonc-parser.d.ts +11 -1
  134. package/dist/shared/jsonc-parser.d.ts.map +1 -1
  135. package/dist/shared/logger.d.ts +8 -0
  136. package/dist/shared/logger.d.ts.map +1 -1
  137. package/dist/shared/models-dev-cache.d.ts +5 -0
  138. package/dist/shared/models-dev-cache.d.ts.map +1 -1
  139. package/dist/shared/prompt-surface-runtime.d.ts.map +1 -1
  140. package/dist/shared/prompt-surface.d.ts +7 -3
  141. package/dist/shared/prompt-surface.d.ts.map +1 -1
  142. package/dist/shared/rpc-client.d.ts.map +1 -1
  143. package/dist/shared/rpc-types.d.ts +14 -0
  144. package/dist/shared/rpc-types.d.ts.map +1 -1
  145. package/dist/shared/rpc-utils.d.ts +32 -6
  146. package/dist/shared/rpc-utils.d.ts.map +1 -1
  147. package/dist/shared/tui-preferences.d.ts +9 -0
  148. package/dist/shared/tui-preferences.d.ts.map +1 -1
  149. package/dist/shared/window-geometry.d.ts +89 -0
  150. package/dist/shared/window-geometry.d.ts.map +1 -0
  151. package/dist/{storage-meta-session-kh5egr11.js → storage-meta-session-mk4gsnke.js} +4 -3
  152. package/dist/tools/ctx-memory/tools.d.ts.map +1 -1
  153. package/dist/tools/ctx-note/tools.d.ts.map +1 -1
  154. package/dist/tui/data/context-db.d.ts.map +1 -1
  155. package/dist/tui-compiled/data/context-db.d.ts.map +1 -1
  156. package/package.json +2 -1
  157. package/src/config/index.test.ts +23 -0
  158. package/src/config/index.ts +43 -9
  159. package/src/config/latch-permanence-guard.test.ts +218 -0
  160. package/src/config/project-security.ts +10 -1
  161. package/src/config/schema/magic-context.test.ts +2 -1
  162. package/src/config/schema/magic-context.ts +13 -3
  163. package/src/shared/__fixtures__/window-overlay.v1.json +337 -0
  164. package/src/shared/conflict-detector.test.ts +176 -1
  165. package/src/shared/conflict-detector.ts +126 -3
  166. package/src/shared/conflict-fixer.test.ts +174 -0
  167. package/src/shared/conflict-fixer.ts +66 -70
  168. package/src/shared/harness-provider-map.test.ts +20 -0
  169. package/src/shared/harness-provider-map.ts +19 -0
  170. package/src/shared/jsonc-edit.ts +295 -0
  171. package/src/shared/jsonc-parser.test.ts +33 -0
  172. package/src/shared/jsonc-parser.ts +54 -2
  173. package/src/shared/logger.test.ts +119 -0
  174. package/src/shared/logger.ts +33 -15
  175. package/src/shared/models-dev-cache.test.ts +17 -0
  176. package/src/shared/models-dev-cache.ts +58 -6
  177. package/src/shared/prompt-surface-runtime.ts +5 -3
  178. package/src/shared/prompt-surface.test.ts +91 -2
  179. package/src/shared/prompt-surface.ts +35 -11
  180. package/src/shared/rpc-client.ts +4 -2
  181. package/src/shared/rpc-types.ts +14 -0
  182. package/src/shared/rpc-utils.test.ts +173 -13
  183. package/src/shared/rpc-utils.ts +202 -18
  184. package/src/shared/tui-preferences.test.ts +52 -2
  185. package/src/shared/tui-preferences.ts +42 -17
  186. package/src/shared/window-geometry.test.ts +309 -0
  187. package/src/shared/window-geometry.ts +629 -0
  188. package/src/tui/data/context-db.ts +5 -0
  189. package/src/tui/index.tsx +22 -0
  190. package/src/tui-compiled/data/context-db.ts +5 -0
  191. package/src/tui-compiled/index.tsx +319 -255
  192. package/dist/index-wgvxkqpx.js +0 -342
@@ -1,9 +1,8 @@
1
1
  import {
2
2
  deriveTriggerBudget,
3
3
  modelSupportsVision,
4
- piModelRefToCanonical,
5
4
  shouldEnforcePrivateStoragePermissions
6
- } from "./index-wgvxkqpx.js";
5
+ } from "./index-q0t189ay.js";
7
6
  import {
8
7
  parseProviderModel
9
8
  } from "./index-td9depx5.js";
@@ -11,7 +10,7 @@ import {
11
10
  describeError,
12
11
  getErrorMessage,
13
12
  sendIgnoredMessage
14
- } from "./index-nsx2n9eg.js";
13
+ } from "./index-4cz5nfxf.js";
15
14
  import {
16
15
  buildToolArcs,
17
16
  buildTrueRawTokenIndex,
@@ -35,23 +34,27 @@ import {
35
34
  readSessionChunk,
36
35
  stableStringify,
37
36
  updateSessionMeta
38
- } from "./index-z8v31d85.js";
37
+ } from "./index-crke4z5j.js";
38
+ import {
39
+ modelRefLookupOrder,
40
+ piModelRefToCanonical
41
+ } from "./index-cgyfn1s2.js";
39
42
  import {
40
43
  Database,
41
44
  closeQuietly,
42
45
  getMessageTimesFromOpenCodeDb,
43
46
  withPrivilegedWriter
44
- } from "./index-3tnkymva.js";
47
+ } from "./index-sw8gnq34.js";
45
48
  import {
46
49
  detectConfigFile
47
- } from "./index-0c9dmw9m.js";
50
+ } from "./index-8mtsfhyg.js";
48
51
  import {
49
52
  pushNotification
50
53
  } from "./index-d62ypazr.js";
51
54
  import {
52
55
  log,
53
56
  sessionLog
54
- } from "./index-f1tnb3vm.js";
57
+ } from "./index-8pqfcghm.js";
55
58
  import {
56
59
  ensureCortexKitArtifactGitignore,
57
60
  getDataDir,
@@ -389,6 +392,171 @@ function buildPrimaryLanguageDirective(language) {
389
392
  return `Use ${target} for your natural-language replies to the user unless the user explicitly asks for another language. Keep code, identifiers, file paths, commands, logs, and quoted text verbatim.`;
390
393
  }
391
394
 
395
+ // src/features/magic-context/fail-closed-block.ts
396
+ var FAIL_CLOSED_DOCTOR_COMMAND = "npx @cortexkit/magic-context@latest doctor";
397
+ var FAIL_CLOSED_REPROBE_EVERY_N = 5;
398
+
399
+ class FailClosedBlockingError extends Error {
400
+ code = "FAIL_CLOSED_BLOCKING";
401
+ reason;
402
+ constructor(message, reason, options) {
403
+ super(message, options);
404
+ this.name = "FailClosedBlockingError";
405
+ this.reason = reason;
406
+ }
407
+ }
408
+ var OPENCODE_INTERNAL_AGENT_NAMES = new Set(["title", "summary", "compaction"]);
409
+ function isMagicContextHiddenAgentName(agent) {
410
+ if (agent === "sidekick" || agent === "smart-note-compiler" || agent.startsWith("smart-note-")) {
411
+ return true;
412
+ }
413
+ if (agent === "historian" || agent.startsWith("historian-"))
414
+ return true;
415
+ if (agent === "dreamer" || agent.startsWith("dreamer-"))
416
+ return true;
417
+ return false;
418
+ }
419
+ var MAX_FORMATTED_BLOCKING_PROCESSES = 8;
420
+ function formatFailClosedBlockingProcesses(processes) {
421
+ const uniqueProcesses = new Map;
422
+ for (const process2 of processes) {
423
+ if (!process2.harness.trim() || !Number.isInteger(process2.pid) || process2.pid <= 0)
424
+ continue;
425
+ uniqueProcesses.set(`${process2.harness}\x00${process2.pid}`, {
426
+ harness: process2.harness.trim(),
427
+ pid: process2.pid
428
+ });
429
+ }
430
+ const entries = [...uniqueProcesses.values()];
431
+ const visible = entries.slice(0, MAX_FORMATTED_BLOCKING_PROCESSES);
432
+ const rendered = visible.map(({ harness, pid }) => `${harness} (PID ${pid})`);
433
+ const omitted = entries.length - visible.length;
434
+ if (omitted > 0)
435
+ rendered.push(`${omitted} more blocking process(es)`);
436
+ if (rendered.length === 0)
437
+ return "a live harness process";
438
+ if (rendered.length === 1)
439
+ return rendered[0];
440
+ const last = rendered.pop();
441
+ return `${rendered.join(", ")}, and ${last}`;
442
+ }
443
+ function formatFailClosedBlockingMessage(reason) {
444
+ if (reason.kind === "migration_guard") {
445
+ if (reason.unreadableFile) {
446
+ const arm = reason.unreadableArm ?? "io";
447
+ const recovery = arm === "io" ? `If no OpenCode server is running, it is safe to delete ${reason.unreadableFile} and retry.` : `The file may be a recent incomplete write; retry after the file is older than the ten-minute grace window, or stop OpenCode before deleting it.`;
448
+ return [
449
+ `Magic Context cannot migrate the shared database because RPC discovery file ${reason.unreadableFile} is uncertain (${arm} arm), so the absence of a live OpenCode server cannot be proven.`,
450
+ recovery,
451
+ `Recovery: ${FAIL_CLOSED_DOCTOR_COMMAND}`
452
+ ].join(" ");
453
+ }
454
+ return [
455
+ `Magic Context cannot migrate the shared database because ${formatFailClosedBlockingProcesses(reason.blockingProcesses)} may be running an older Magic Context build that would fail against the migrated database.`,
456
+ "Restart the blocking process (it will pick up the new build and migrate on start), or shut it down and retry.",
457
+ `Recovery: ${FAIL_CLOSED_DOCTOR_COMMAND}`
458
+ ].join(" ");
459
+ }
460
+ if (reason.kind === "schema_fence") {
461
+ return [
462
+ `Magic Context cannot operate: this Magic Context build is older than the database; upgrade/restart this harness (upstream migration lane v${reason.persistedVersion}, build supports through v${reason.supportedVersion}).`,
463
+ `Recovery: ${FAIL_CLOSED_DOCTOR_COMMAND}`
464
+ ].join(" ");
465
+ }
466
+ const cause = reason.cause.trim().length > 0 ? reason.cause.trim() : "unknown storage error";
467
+ return [
468
+ `Magic Context cannot operate: persistent storage failed (${cause}).`,
469
+ "The plugin will not silently degrade to native compaction while enabled.",
470
+ `Recovery: ${FAIL_CLOSED_DOCTOR_COMMAND}`
471
+ ].join(" ");
472
+ }
473
+ function createFailClosedBlockingError(reason, options) {
474
+ return new FailClosedBlockingError(formatFailClosedBlockingMessage(reason), reason, options);
475
+ }
476
+ function isFailClosedBlockingError(error) {
477
+ return error instanceof FailClosedBlockingError || typeof error === "object" && error !== null && error.name === "FailClosedBlockingError" && error.code === "FAIL_CLOSED_BLOCKING";
478
+ }
479
+ function shouldBypassFailClosedBlock(input) {
480
+ if (input.isPiSubagentEnv === true)
481
+ return true;
482
+ if (input.isInternalChildSession === true)
483
+ return true;
484
+ const agent = typeof input.agent === "string" ? input.agent.trim() : "";
485
+ if (agent.length === 0)
486
+ return false;
487
+ if (OPENCODE_INTERNAL_AGENT_NAMES.has(agent))
488
+ return true;
489
+ if (isMagicContextHiddenAgentName(agent))
490
+ return true;
491
+ return false;
492
+ }
493
+ function resolveAgentNameFromMessages(messages) {
494
+ for (let i = messages.length - 1;i >= 0; i -= 1) {
495
+ const info = messages[i]?.info;
496
+ if (!info || typeof info !== "object")
497
+ continue;
498
+ const agent = info.agent;
499
+ if (typeof agent === "string" && agent.length > 0)
500
+ return agent;
501
+ }
502
+ return;
503
+ }
504
+ function createFailClosedController(options) {
505
+ const reprobeEveryN = Math.max(1, options?.reprobeEveryN ?? FAIL_CLOSED_REPROBE_EVERY_N);
506
+ let reason = null;
507
+ let blockedPassCount = 0;
508
+ return {
509
+ arm(next) {
510
+ reason = next;
511
+ blockedPassCount = 0;
512
+ },
513
+ clear() {
514
+ reason = null;
515
+ blockedPassCount = 0;
516
+ },
517
+ isArmed() {
518
+ return reason !== null;
519
+ },
520
+ getReason() {
521
+ return reason;
522
+ },
523
+ async enforce(input) {
524
+ if (!reason)
525
+ return;
526
+ if (!input.blockingEnabled)
527
+ return;
528
+ if (input.exempt)
529
+ return;
530
+ blockedPassCount += 1;
531
+ const shouldReprobe = typeof input.tryReopen === "function" && (blockedPassCount === 1 || blockedPassCount % reprobeEveryN === 0);
532
+ if (shouldReprobe) {
533
+ try {
534
+ const healed = await input.tryReopen?.();
535
+ if (healed) {
536
+ reason = null;
537
+ blockedPassCount = 0;
538
+ return;
539
+ }
540
+ } catch {}
541
+ }
542
+ const blockedReason = reason;
543
+ if (!blockedReason)
544
+ return;
545
+ throw createFailClosedBlockingError(blockedReason);
546
+ }
547
+ };
548
+ }
549
+ var lastHookInitFailure = null;
550
+ function recordHookInitFailure(failure) {
551
+ lastHookInitFailure = failure;
552
+ }
553
+ function clearHookInitFailure() {
554
+ lastHookInitFailure = null;
555
+ }
556
+ function getLastHookInitFailure() {
557
+ return lastHookInitFailure;
558
+ }
559
+
392
560
  // src/features/magic-context/storage-db.ts
393
561
  import {
394
562
  chmodSync,
@@ -437,20 +605,25 @@ function rpcPortFilePath(storageDir, directory, pid = process.pid, instanceId) {
437
605
  }
438
606
  function isPidAlive(pid) {
439
607
  if (!Number.isInteger(pid) || pid <= 0)
440
- return false;
608
+ return "dead";
609
+ if (rpcIdentityPlatform === "win32")
610
+ return readWindowsProcess(pid).state;
441
611
  try {
442
- process.kill(pid, 0);
443
- return true;
444
- } catch (err) {
445
- return err.code === "EPERM";
612
+ rpcIdentityProcessKill(pid, 0);
613
+ return "alive";
614
+ } catch (error) {
615
+ return error.code === "ESRCH" ? "dead" : "inconclusive";
446
616
  }
447
617
  }
448
618
  var RPC_IDENTITY_SKEW_TOLERANCE_MS = 120000;
449
619
  var LINUX_CLOCK_TICKS_PER_SECOND = 100;
450
620
  var PS_PROBE_TIMEOUT_MS = 1000;
451
621
  var OPEN_CODE_COMMAND_MARKERS = ["opencode", "node", "bun", "electron"];
622
+ var TASKLIST_NO_TASKS_PATTERN = /^INFO:\s+No tasks are running which match the specified criteria\.?$/im;
452
623
  var rpcIdentityReadFileSync = readFileSync;
453
624
  var rpcIdentityExecFileSync = execFileSync;
625
+ var rpcIdentityProcessKill = process.kill;
626
+ var rpcProcessListExecFileSync = execFileSync;
454
627
  var rpcIdentityPlatform = process.platform;
455
628
  var rpcIdentityNowMs = () => Date.now();
456
629
  function parseLinuxProcessStartTime(statContent, uptimeContent) {
@@ -479,7 +652,8 @@ function readPsProcessStartTime(pid) {
479
652
  try {
480
653
  const output = rpcIdentityExecFileSync("ps", ["-p", String(pid), "-o", "lstart="], {
481
654
  encoding: "utf8",
482
- timeout: PS_PROBE_TIMEOUT_MS
655
+ timeout: PS_PROBE_TIMEOUT_MS,
656
+ stdio: ["ignore", "pipe", "pipe"]
483
657
  });
484
658
  const processStartTime = Date.parse(String(output).trim());
485
659
  return Number.isFinite(processStartTime) ? processStartTime : null;
@@ -487,6 +661,70 @@ function readPsProcessStartTime(pid) {
487
661
  return null;
488
662
  }
489
663
  }
664
+ function parseCsvLine(line) {
665
+ const fields = [];
666
+ let field = "";
667
+ let quoted = false;
668
+ for (let index = 0;index < line.length; index += 1) {
669
+ const character = line[index];
670
+ if (character === '"') {
671
+ if (quoted && line[index + 1] === '"') {
672
+ field += '"';
673
+ index += 1;
674
+ } else {
675
+ quoted = !quoted;
676
+ }
677
+ } else if (character === "," && !quoted) {
678
+ fields.push(field);
679
+ field = "";
680
+ } else {
681
+ field += character;
682
+ }
683
+ }
684
+ if (quoted)
685
+ return null;
686
+ fields.push(field);
687
+ return fields;
688
+ }
689
+ function parseTasklistOutput(output) {
690
+ const entries = [];
691
+ let sawHeader = false;
692
+ for (const rawLine of output.split(/\r?\n/)) {
693
+ const line = rawLine.trim();
694
+ if (!line)
695
+ continue;
696
+ if (TASKLIST_NO_TASKS_PATTERN.test(line))
697
+ return [];
698
+ const fields = parseCsvLine(line);
699
+ if (!fields)
700
+ continue;
701
+ if (fields[1]?.trim().toLowerCase() === "pid") {
702
+ sawHeader = true;
703
+ continue;
704
+ }
705
+ const pid = Number(fields[1]);
706
+ if (!Number.isInteger(pid) || pid <= 0 || !fields[0])
707
+ continue;
708
+ entries.push({ pid, command: fields[0] });
709
+ }
710
+ return entries.length > 0 || sawHeader ? entries : null;
711
+ }
712
+ function readWindowsProcess(pid) {
713
+ try {
714
+ const output = rpcIdentityExecFileSync("tasklist", ["/FO", "CSV", "/FI", `PID eq ${pid}`], {
715
+ encoding: "utf8",
716
+ timeout: PS_PROBE_TIMEOUT_MS,
717
+ stdio: ["ignore", "pipe", "pipe"]
718
+ });
719
+ const entries = parseTasklistOutput(String(output));
720
+ if (entries === null)
721
+ return { state: "inconclusive" };
722
+ const process2 = entries.find((entry) => entry.pid === pid);
723
+ return process2 ? { state: "alive", command: process2.command } : { state: "dead" };
724
+ } catch {
725
+ return { state: "inconclusive" };
726
+ }
727
+ }
490
728
  function readLinuxProcessCommand(pid) {
491
729
  try {
492
730
  return String(rpcIdentityReadFileSync(`/proc/${pid}/cmdline`, "utf8"));
@@ -498,7 +736,8 @@ function readPsProcessCommand(pid) {
498
736
  try {
499
737
  const output = rpcIdentityExecFileSync("ps", ["-p", String(pid), "-o", "command="], {
500
738
  encoding: "utf8",
501
- timeout: PS_PROBE_TIMEOUT_MS
739
+ timeout: PS_PROBE_TIMEOUT_MS,
740
+ stdio: ["ignore", "pipe", "pipe"]
502
741
  });
503
742
  return String(output);
504
743
  } catch {
@@ -511,17 +750,76 @@ function commandLooksLikeOpenCode(command) {
511
750
  }
512
751
  function isPidIdentityPlausible(record) {
513
752
  if (!Number.isInteger(record.pid) || record.pid <= 0)
514
- return false;
753
+ return "implausible";
515
754
  if (Number.isFinite(record.started_at) && record.started_at > 0) {
516
- const processStartTime = rpcIdentityPlatform === "linux" ? readLinuxProcessStartTime(record.pid) : readPsProcessStartTime(record.pid);
755
+ const processStartTime = rpcIdentityPlatform === "linux" ? readLinuxProcessStartTime(record.pid) : rpcIdentityPlatform === "win32" ? null : readPsProcessStartTime(record.pid);
517
756
  if (processStartTime === null)
518
- return true;
519
- return processStartTime <= record.started_at + RPC_IDENTITY_SKEW_TOLERANCE_MS;
757
+ return "inconclusive";
758
+ return processStartTime <= record.started_at + RPC_IDENTITY_SKEW_TOLERANCE_MS ? "plausible" : "implausible";
520
759
  }
521
- const command = rpcIdentityPlatform === "linux" ? readLinuxProcessCommand(record.pid) : readPsProcessCommand(record.pid);
760
+ const command = rpcIdentityPlatform === "linux" ? readLinuxProcessCommand(record.pid) : rpcIdentityPlatform === "win32" ? readWindowsProcess(record.pid).command ?? null : readPsProcessCommand(record.pid);
522
761
  if (command === null)
762
+ return "inconclusive";
763
+ return commandLooksLikeOpenCode(command) ? "plausible" : "implausible";
764
+ }
765
+ function commandLooksLikePi(command) {
766
+ const normalized = command.trim().toLowerCase().replaceAll("\\", "/");
767
+ const tokens = normalized.split(/\s+/).filter(Boolean);
768
+ const executableName = (token) => (token ?? "").split("/").at(-1) ?? "";
769
+ const first = executableName(tokens[0]).replace(/\.exe$/, "");
770
+ if (["pi", "pi.cmd", "omp", "oh-my-pi"].includes(first))
523
771
  return true;
524
- return commandLooksLikeOpenCode(command);
772
+ if (["node", "bun", "deno"].includes(first)) {
773
+ const script = executableName(tokens[1]);
774
+ return ["pi", "pi.js", "pi.mjs", "pi.cjs"].includes(script) || normalized.includes("pi-coding-agent");
775
+ }
776
+ return false;
777
+ }
778
+ function inspectLivePiProcesses() {
779
+ if (false) {}
780
+ try {
781
+ const isWindows = rpcIdentityPlatform === "win32";
782
+ const output = String(rpcProcessListExecFileSync(isWindows ? "tasklist" : "ps", isWindows ? ["/FO", "CSV"] : ["-axo", "pid=,command="], {
783
+ encoding: "utf8",
784
+ timeout: PS_PROBE_TIMEOUT_MS,
785
+ stdio: ["ignore", "pipe", "pipe"]
786
+ }));
787
+ const pids = new Set;
788
+ if (isWindows) {
789
+ const entries = parseTasklistOutput(output);
790
+ if (entries === null) {
791
+ return {
792
+ state: "unreadable",
793
+ processIds: [],
794
+ error: "tasklist output unavailable"
795
+ };
796
+ }
797
+ for (const entry of entries) {
798
+ if (entry.pid === process.pid)
799
+ continue;
800
+ if (commandLooksLikePi(entry.command))
801
+ pids.add(entry.pid);
802
+ }
803
+ } else {
804
+ for (const line of output.split(/\r?\n/)) {
805
+ const match = /^\s*(\d+)\s+(.+)$/.exec(line);
806
+ if (!match)
807
+ continue;
808
+ const pid = Number(match[1]);
809
+ if (!Number.isInteger(pid) || pid <= 0 || pid === process.pid)
810
+ continue;
811
+ if (commandLooksLikePi(match[2]))
812
+ pids.add(pid);
813
+ }
814
+ }
815
+ return { state: "known", processIds: [...pids].sort((left, right) => left - right) };
816
+ } catch (error) {
817
+ return {
818
+ state: "unreadable",
819
+ processIds: [],
820
+ error: error instanceof Error ? error.message : String(error)
821
+ };
822
+ }
525
823
  }
526
824
  function parseRpcPortFile(content, fallbackPid = 0) {
527
825
  const trimmed = content.trim();
@@ -1206,6 +1504,7 @@ function prepareMirrorPageStatements(db) {
1206
1504
  return {
1207
1505
  identityByModule: db.prepare("SELECT context_row_id FROM mirror_identity WHERE domain = ? AND module_project = ? AND module_row_id = ?"),
1208
1506
  insertIdentity: db.prepare("INSERT OR IGNORE INTO mirror_identity(domain, module_project, module_row_id, context_row_id) VALUES (?, ?, ?, ?)"),
1507
+ deleteIdentityByContext: db.prepare("DELETE FROM mirror_identity WHERE domain = ? AND context_row_id = ?"),
1209
1508
  deleteLiveMemory: db.prepare("DELETE FROM mirror_live_memory_rows WHERE module_project = ? AND module_row_id = ?"),
1210
1509
  deletePendingReferencesForMemory: db.prepare("DELETE FROM mirror_pending_references WHERE domain = ? AND module_project = ? AND (module_row_id = ? OR target_module_row_id = ?)"),
1211
1510
  deleteIdentity: db.prepare("DELETE FROM mirror_identity WHERE domain = ? AND module_project = ? AND module_row_id = ?"),
@@ -1251,12 +1550,13 @@ function prepareMirrorPageStatements(db) {
1251
1550
  deleteNote: db.prepare("DELETE FROM notes WHERE id = ?"),
1252
1551
  deleteNoteRevisions: db.prepare("DELETE FROM mirror_note_revisions WHERE module_project = ? AND module_row_id = ?"),
1253
1552
  updateNote: db.prepare(`UPDATE notes SET type = ?, status = ?, project_path = ?, session_id = ?, content = ?,
1254
- surface_condition = ?, ready_at = ?, ready_reason = ?, manifest_json = ?, compiled_check = ?,
1553
+ surface_condition = ?, compiled_provider = ?, compiled_config = ?, compiled_at = ?, compile_status = ?,
1554
+ ready_at = ?, ready_reason = ?, manifest_json = ?, compiled_check = ?,
1255
1555
  check_hash = ?, check_cron = ?, check_failure_count = ?, check_network_failure_count = ?,
1256
1556
  check_quarantined_until = ?, check_next_due_at = ?, check_compiled_at = ?, check_false_since_at = ?,
1257
1557
  check_last_liveness_at = ?, last_checked_at = ?, check_status = ?, check_version = ?,
1258
1558
  policy_version = ?, anchor_block_id = ?, anchor_ordinal = ?, created_at = ?, updated_at = ? WHERE id = ?`),
1259
- upsertNoteRevision: db.prepare("INSERT INTO mirror_note_revisions(module_project, module_row_id, context_row_id, status_version) VALUES (?, ?, ?, ?) ON CONFLICT(module_project, module_row_id) DO UPDATE SET context_row_id = excluded.context_row_id, status_version = excluded.status_version"),
1559
+ upsertNoteRevision: db.prepare("INSERT OR REPLACE INTO mirror_note_revisions(module_project, module_row_id, context_row_id, status_version) VALUES (?, ?, ?, ?)"),
1260
1560
  translateMemoryReferences: db.prepare(`UPDATE memories
1261
1561
  SET superseded_by_memory_id = (
1262
1562
  SELECT target.context_row_id
@@ -1325,10 +1625,25 @@ function prepareMirrorPageStatements(db) {
1325
1625
  function mirrorIdentity(db, domain, moduleProject, moduleRowId, statements) {
1326
1626
  return (statements?.identityByModule ?? db.prepare("SELECT context_row_id FROM mirror_identity WHERE domain = ? AND module_project = ? AND module_row_id = ?")).get(domain, moduleProject, moduleRowId) ?? null;
1327
1627
  }
1628
+ function applyMirroredNoteCompileFields(args) {
1629
+ return withPrivilegedWriter(args.db, () => {
1630
+ const result = args.db.prepare(`UPDATE notes
1631
+ SET compiled_provider = ?, compiled_config = ?, compiled_at = ?, compile_status = ?
1632
+ WHERE id = (
1633
+ SELECT context_row_id
1634
+ FROM mirror_identity
1635
+ WHERE domain = 'notes' AND module_project = ? AND module_row_id = ?
1636
+ )`).run(args.fields.compiledProvider, args.fields.compiledConfig, args.fields.compiledAt, args.fields.compileStatus, args.moduleProject, args.moduleRowId);
1637
+ return result.changes === 1;
1638
+ });
1639
+ }
1328
1640
  function rememberIdentity(db, domain, moduleProject, moduleRowId, contextRowId, statements) {
1329
1641
  const existing = mirrorIdentity(db, domain, moduleProject, moduleRowId, statements);
1330
1642
  if (existing)
1331
1643
  return;
1644
+ if (domain === "notes") {
1645
+ (statements?.deleteIdentityByContext ?? db.prepare("DELETE FROM mirror_identity WHERE domain = ? AND context_row_id = ?")).run(domain, contextRowId);
1646
+ }
1332
1647
  (statements?.insertIdentity ?? db.prepare("INSERT OR IGNORE INTO mirror_identity(domain, module_project, module_row_id, context_row_id) VALUES (?, ?, ?, ?)")).run(domain, moduleProject, moduleRowId, contextRowId);
1333
1648
  }
1334
1649
  function contextMemoryId(db, domain, moduleProject, row, moduleRowId, statements) {
@@ -1507,7 +1822,7 @@ function applyNoteRow(db, feed, statements) {
1507
1822
  }
1508
1823
  const moduleStatus = rowString(effectiveRow, "status", "active");
1509
1824
  const contextStatus = moduleStatus === "surfaced" || moduleStatus === "surfacing" ? "ready" : moduleStatus;
1510
- statements.updateNote.run(rowString(effectiveRow, "type", "smart"), contextStatus, moduleProject, rowNullableString(effectiveRow, "session_id"), rowString(effectiveRow, "content"), rowNullableString(effectiveRow, "surface_condition"), typeof effectiveRow.ready_at === "number" ? effectiveRow.ready_at : null, rowNullableString(effectiveRow, "ready_reason"), rowNullableString(effectiveRow, "manifest_json"), rowNullableString(effectiveRow, "compiled_check"), rowNullableString(effectiveRow, "check_hash"), rowNullableString(effectiveRow, "check_cron"), rowNumber(effectiveRow, "check_failure_count"), rowNumber(effectiveRow, "check_network_failure_count"), typeof effectiveRow.check_quarantined_until === "number" ? effectiveRow.check_quarantined_until : null, typeof effectiveRow.check_next_due_at === "number" ? effectiveRow.check_next_due_at : null, typeof effectiveRow.check_compiled_at === "number" ? effectiveRow.check_compiled_at : null, typeof effectiveRow.check_false_since_at === "number" ? effectiveRow.check_false_since_at : null, typeof effectiveRow.check_last_liveness_at === "number" ? effectiveRow.check_last_liveness_at : null, typeof effectiveRow.last_checked_at === "number" ? effectiveRow.last_checked_at : null, rowString(effectiveRow, "check_status", "uncompiled"), rowNumber(effectiveRow, "check_version"), rowNumber(effectiveRow, "policy_version", 1), rowNullableString(effectiveRow, "anchor_block_id"), typeof effectiveRow.anchor_ordinal === "number" ? effectiveRow.anchor_ordinal : null, rowNumber(effectiveRow, "created_at_ms"), rowNumber(effectiveRow, "updated_at_ms"), contextId);
1825
+ statements.updateNote.run(rowString(effectiveRow, "type", "smart"), contextStatus, moduleProject, rowNullableString(effectiveRow, "session_id"), rowString(effectiveRow, "content"), rowNullableString(effectiveRow, "surface_condition"), rowNullableString(effectiveRow, "compiled_provider"), rowNullableString(effectiveRow, "compiled_config"), typeof effectiveRow.compiled_at === "number" ? effectiveRow.compiled_at : null, rowNullableString(effectiveRow, "compile_status"), typeof effectiveRow.ready_at === "number" ? effectiveRow.ready_at : null, rowNullableString(effectiveRow, "ready_reason"), rowNullableString(effectiveRow, "manifest_json"), rowNullableString(effectiveRow, "compiled_check"), rowNullableString(effectiveRow, "check_hash"), rowNullableString(effectiveRow, "check_cron"), rowNumber(effectiveRow, "check_failure_count"), rowNumber(effectiveRow, "check_network_failure_count"), typeof effectiveRow.check_quarantined_until === "number" ? effectiveRow.check_quarantined_until : null, typeof effectiveRow.check_next_due_at === "number" ? effectiveRow.check_next_due_at : null, typeof effectiveRow.check_compiled_at === "number" ? effectiveRow.check_compiled_at : null, typeof effectiveRow.check_false_since_at === "number" ? effectiveRow.check_false_since_at : null, typeof effectiveRow.check_last_liveness_at === "number" ? effectiveRow.check_last_liveness_at : null, typeof effectiveRow.last_checked_at === "number" ? effectiveRow.last_checked_at : null, rowString(effectiveRow, "check_status", "uncompiled"), rowNumber(effectiveRow, "check_version"), rowNumber(effectiveRow, "policy_version", 1), rowNullableString(effectiveRow, "anchor_block_id"), typeof effectiveRow.anchor_ordinal === "number" ? effectiveRow.anchor_ordinal : null, rowNumber(effectiveRow, "created_at_ms"), rowNumber(effectiveRow, "updated_at_ms"), contextId);
1511
1826
  statements.upsertNoteRevision.run(moduleProject, feed.module_row_id, contextId, rowNumber(effectiveRow, "status_version"));
1512
1827
  }
1513
1828
  function applyMirrorPage(args) {
@@ -1911,6 +2226,8 @@ function healAllNullColumns(db) {
1911
2226
  ["stripped_placeholder_ids", ""],
1912
2227
  ["stale_reduce_stripped_ids", ""],
1913
2228
  ["processed_image_stripped_ids", ""],
2229
+ ["merged_reasoning_stripped_ids", ""],
2230
+ ["trailing_blank_decisions", ""],
1914
2231
  ["memory_block_cache", ""],
1915
2232
  ["memory_block_ids", ""],
1916
2233
  ["compaction_marker_state", ""],
@@ -2022,6 +2339,7 @@ import path from "node:path";
2022
2339
  var GIT_TIMEOUT_MS = 5000;
2023
2340
  var TRANSIENT_FAILURE_COOLDOWN_MS = 5 * 60 * 1000;
2024
2341
  var identityCache = new Map;
2342
+ var linkedGitWorktreeCache = new Map;
2025
2343
  var lastKnownGitIdentityCache = new Map;
2026
2344
  var directoryFallbackCache = new Map;
2027
2345
  var transientFailureCooldown = new Map;
@@ -2236,7 +2554,12 @@ function takeDubiousOwnershipProjectIdentityWarning(directory) {
2236
2554
  return formatDubiousOwnershipWarning(canonical);
2237
2555
  }
2238
2556
  function canonicalUserHomeDirectory() {
2239
- return realpathSync.native(userHomeDirectoryForIdentity());
2557
+ const homeDirectory = userHomeDirectoryForIdentity();
2558
+ try {
2559
+ return realpathSync.native(homeDirectory);
2560
+ } catch {
2561
+ return homeDirectory;
2562
+ }
2240
2563
  }
2241
2564
  function isUserHomeDirectory(directory) {
2242
2565
  try {
@@ -2370,6 +2693,27 @@ function normalizeStoredProjectPath(rawOrStored) {
2370
2693
  function storedPathBelongsToIdentity(storedProjectPath, projectIdentity) {
2371
2694
  return storedProjectPath === projectIdentity || normalizeStoredProjectPath(storedProjectPath) === projectIdentity;
2372
2695
  }
2696
+ function isLinkedGitWorktree(directory) {
2697
+ const resolvedDirectory = path.resolve(directory);
2698
+ const cached = linkedGitWorktreeCache.get(resolvedDirectory);
2699
+ if (cached !== undefined)
2700
+ return cached;
2701
+ let linked = false;
2702
+ try {
2703
+ const output = execFileSyncForIdentity("git", ["rev-parse", "--path-format=absolute", "--git-dir", "--git-common-dir"], {
2704
+ cwd: resolvedDirectory,
2705
+ encoding: "utf8",
2706
+ timeout: GIT_TIMEOUT_MS,
2707
+ windowsHide: true
2708
+ });
2709
+ const [gitDir, commonDir] = String(output).split(/\r?\n/u).map((line) => line.trim()).filter(Boolean);
2710
+ linked = Boolean(gitDir && commonDir && path.resolve(gitDir) !== path.resolve(commonDir));
2711
+ } catch {
2712
+ linked = hasGitDir(resolvedDirectory);
2713
+ }
2714
+ linkedGitWorktreeCache.set(resolvedDirectory, linked);
2715
+ return linked;
2716
+ }
2373
2717
  // src/features/magic-context/workspaces.ts
2374
2718
  var VALID_SHARE_CATEGORIES = new Set(V2_MEMORY_CATEGORIES);
2375
2719
  var DEFAULT_WORKSPACE_SHARE_CATEGORIES = ["CONSTRAINTS"];
@@ -2861,6 +3205,7 @@ var MIGRATIONS = [
2861
3205
  status TEXT NOT NULL DEFAULT 'active',
2862
3206
  promoted_at INTEGER NOT NULL,
2863
3207
  source_candidate_ids TEXT DEFAULT '[]',
3208
+ source_candidate_provenance TEXT,
2864
3209
  created_at INTEGER NOT NULL,
2865
3210
  updated_at INTEGER NOT NULL
2866
3211
  );
@@ -3887,6 +4232,7 @@ var MIGRATIONS = [
3887
4232
  last_observed_at INTEGER,
3888
4233
  answer_refreshed_at INTEGER,
3889
4234
  source_candidate_ids TEXT NOT NULL DEFAULT '[]',
4235
+ source_candidate_provenance TEXT,
3890
4236
  created_at INTEGER NOT NULL,
3891
4237
  updated_at INTEGER NOT NULL
3892
4238
  );
@@ -4696,6 +5042,37 @@ var MIGRATIONS = [
4696
5042
  ensureColumn(db, "notes", "compiled_at", "INTEGER");
4697
5043
  ensureColumn(db, "notes", "compile_status", "TEXT CHECK(compile_status IN ('compiled', 'plain', 'refused'))");
4698
5044
  }
5045
+ },
5046
+ {
5047
+ version: 77,
5048
+ description: "persist scoped provenance for promoted user memories and primers",
5049
+ up(db) {
5050
+ if (tableExists2(db, "user_memories")) {
5051
+ ensureColumn(db, "user_memories", "source_candidate_provenance", "TEXT");
5052
+ }
5053
+ if (tableExists2(db, "primers")) {
5054
+ ensureColumn(db, "primers", "source_candidate_provenance", "TEXT");
5055
+ }
5056
+ }
5057
+ },
5058
+ {
5059
+ version: 78,
5060
+ description: "add migration_pending journal for crash-safe cross-harness session migration",
5061
+ up(db) {
5062
+ db.exec(`
5063
+ CREATE TABLE IF NOT EXISTS migration_pending (
5064
+ migration_key TEXT PRIMARY KEY,
5065
+ source_session_id TEXT NOT NULL,
5066
+ target_harness TEXT NOT NULL,
5067
+ pi_session_id TEXT NOT NULL,
5068
+ final_path TEXT NOT NULL,
5069
+ stage_path TEXT NOT NULL,
5070
+ content_sha256 TEXT NOT NULL,
5071
+ phase TEXT NOT NULL CHECK (phase IN ('staged', 'db_committed')),
5072
+ created_at INTEGER NOT NULL
5073
+ );
5074
+ `);
5075
+ }
4699
5076
  }
4700
5077
  ];
4701
5078
  var LATEST_MIGRATION_VERSION = MIGRATIONS.reduce((max, m) => Math.max(max, m.version), 0);
@@ -5163,7 +5540,7 @@ function getSchemaFenceRejection() {
5163
5540
  function getMigrationOnOpenRefusal() {
5164
5541
  return lastMigrationOnOpenRefusal;
5165
5542
  }
5166
- var LATEST_SUPPORTED_VERSION = 76;
5543
+ var LATEST_SUPPORTED_VERSION = 78;
5167
5544
  var PERMISSIONS_ENFORCEABLE = process.platform !== "win32";
5168
5545
  var defaultStoragePermissionFs = { chmodSync, mkdirSync };
5169
5546
  var storagePermissionFs = defaultStoragePermissionFs;
@@ -5363,6 +5740,7 @@ function inspectRpcServerDiscovery(storageDir) {
5363
5740
  }
5364
5741
  const pids = new Set;
5365
5742
  const staleFiles = [];
5743
+ const inconclusivePids = new Set;
5366
5744
  for (const portFile of portFiles) {
5367
5745
  let raw;
5368
5746
  try {
@@ -5382,10 +5760,15 @@ function inspectRpcServerDiscovery(storageDir) {
5382
5760
  return junk;
5383
5761
  continue;
5384
5762
  }
5385
- if (isPidAlive(record.pid) && isPidIdentityPlausible(record))
5763
+ const liveness = isPidAlive(record.pid);
5764
+ const identity = liveness === "dead" ? "implausible" : isPidIdentityPlausible(record);
5765
+ if (liveness === "alive" && identity === "plausible") {
5386
5766
  pids.add(record.pid);
5387
- else
5767
+ } else if (liveness === "dead" || identity === "implausible") {
5388
5768
  staleFiles.push(portFile);
5769
+ } else {
5770
+ inconclusivePids.add(record.pid);
5771
+ }
5389
5772
  }
5390
5773
  for (const staleFile of staleFiles) {
5391
5774
  try {
@@ -5398,8 +5781,29 @@ function inspectRpcServerDiscovery(storageDir) {
5398
5781
  if (serverPids.length > 0) {
5399
5782
  return { state: "live", serverPids, staleFiles };
5400
5783
  }
5784
+ const uncertainPids = [...inconclusivePids].sort((a, b) => a - b);
5785
+ if (uncertainPids.length > 0) {
5786
+ return {
5787
+ state: "inconclusive",
5788
+ serverPids: [],
5789
+ staleFiles,
5790
+ inconclusivePids: uncertainPids
5791
+ };
5792
+ }
5401
5793
  return { state: "stale", serverPids: [], staleFiles };
5402
5794
  }
5795
+ function formatInconclusiveOpenCodeMigrationWarning(dbPath, pids) {
5796
+ return `[magic-context] storage warning: continuing migration for ${dbPath}; OpenCode server PID ${pids.join(", ")} was not confirmed because its liveness or identity check could not run. This commonly means an OS sandbox denied kill(0) or ps. No live OpenCode server was confirmed.`;
5797
+ }
5798
+ function logInconclusiveMigrationProbes(dbPath, discovery, piProbeState) {
5799
+ const uncertainPids = discovery.inconclusivePids ?? [];
5800
+ if (uncertainPids.length > 0) {
5801
+ log(formatInconclusiveOpenCodeMigrationWarning(dbPath, uncertainPids));
5802
+ }
5803
+ if (piProbeState === "unreadable") {
5804
+ log(`[magic-context] storage warning: continuing migration for ${dbPath}; the Pi/OMP process-list probe could not run, which commonly means an OS sandbox denied ps. No live Pi harness was confirmed.`);
5805
+ }
5806
+ }
5403
5807
  function enforceMigrationOnOpenGuard(db, dbPath, dbDir, latestSupportedVersion) {
5404
5808
  const persistedVersion = getPersistedSchemaVersion(db);
5405
5809
  if (persistedVersion >= latestSupportedVersion) {
@@ -5407,14 +5811,18 @@ function enforceMigrationOnOpenGuard(db, dbPath, dbDir, latestSupportedVersion)
5407
5811
  return true;
5408
5812
  }
5409
5813
  const discovery = inspectRpcServerDiscovery(dbDir);
5410
- if (discovery.state === "absent" || discovery.state === "stale") {
5814
+ const piDiscovery = inspectLivePiProcesses();
5815
+ const piPids = piDiscovery.processIds;
5816
+ if ((discovery.state === "absent" || discovery.state === "stale" || discovery.state === "inconclusive") && piPids.length === 0) {
5411
5817
  lastMigrationOnOpenRefusal = null;
5818
+ logInconclusiveMigrationProbes(dbPath, discovery, piDiscovery.state);
5412
5819
  return true;
5413
5820
  }
5821
+ const blockingPids = [...new Set([...discovery.serverPids, ...piPids])].sort((left, right) => left - right);
5414
5822
  lastMigrationOnOpenRefusal = {
5415
5823
  persistedVersion,
5416
5824
  supportedVersion: latestSupportedVersion,
5417
- serverPids: discovery.serverPids,
5825
+ serverPids: blockingPids,
5418
5826
  ...discovery.unreadableFile ? { unreadableFile: discovery.unreadableFile } : {},
5419
5827
  ...discovery.unreadableArm ? { unreadableArm: discovery.unreadableArm } : {}
5420
5828
  };
@@ -5424,7 +5832,11 @@ function enforceMigrationOnOpenGuard(db, dbPath, dbDir, latestSupportedVersion)
5424
5832
  const recovery = arm === "io" ? `If no OpenCode server is running, it is safe to delete ${unreadableFile} and retry.` : `Retry after the file is older than the ten-minute grace window, or stop OpenCode before deleting it.`;
5425
5833
  log(`[magic-context] storage fatal: refusing to migrate ${dbPath} from upstream migration v${persistedVersion} to v${latestSupportedVersion} because RPC discovery file ${unreadableFile} is uncertain (${arm} arm), so the absence of a live OpenCode server cannot be proven. ${recovery}`);
5426
5834
  } else {
5427
- log(`[magic-context] storage fatal: refusing to migrate ${dbPath} from upstream migration v${persistedVersion} to v${latestSupportedVersion} while live OpenCode server PID(s) ${discovery.serverPids.join(", ")} may still use the old plugin build. Restart OpenCode, then retry this process.`);
5835
+ const blockers = [
5836
+ ...discovery.serverPids.map((pid) => `confirmed OpenCode server PID ${pid}`),
5837
+ ...piPids.map((pid) => `confirmed Pi harness PID ${pid}`)
5838
+ ];
5839
+ log(`[magic-context] storage fatal: refusing to migrate ${dbPath} from upstream migration v${persistedVersion} to v${latestSupportedVersion} while ${blockers.join(", ")} still use the old plugin build. Restart the blocking harness, then retry this process.`);
5428
5840
  }
5429
5841
  return false;
5430
5842
  }
@@ -5648,6 +6060,7 @@ function initializeDatabase(db) {
5648
6060
  last_observed_at INTEGER,
5649
6061
  answer_refreshed_at INTEGER,
5650
6062
  source_candidate_ids TEXT NOT NULL DEFAULT '[]',
6063
+ source_candidate_provenance TEXT,
5651
6064
  created_at INTEGER NOT NULL,
5652
6065
  updated_at INTEGER NOT NULL
5653
6066
  );
@@ -6283,6 +6696,11 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
6283
6696
  ensureColumn(db, "primer_candidates", "question_embedding", "BLOB");
6284
6697
  ensureColumn(db, "primer_candidates", "question_embedding_model_id", "TEXT");
6285
6698
  ensureColumn(db, "primers", "question_embedding_model_id", "TEXT");
6699
+ ensureColumn(db, "primers", "source_candidate_provenance", "TEXT");
6700
+ const hasUserMemoriesTable = db.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'user_memories'").get();
6701
+ if (hasUserMemoriesTable) {
6702
+ ensureColumn(db, "user_memories", "source_candidate_provenance", "TEXT");
6703
+ }
6286
6704
  db.exec(`
6287
6705
  CREATE UNIQUE INDEX IF NOT EXISTS idx_primer_candidates_occurrence
6288
6706
  ON primer_candidates(project_path, harness, session_id, source_start_message_id, source_end_message_id);
@@ -6356,6 +6774,8 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
6356
6774
  ensureColumn(db, "session_meta", "stripped_placeholder_ids", "TEXT DEFAULT ''");
6357
6775
  ensureColumn(db, "session_meta", "stale_reduce_stripped_ids", "TEXT DEFAULT ''");
6358
6776
  ensureColumn(db, "session_meta", "processed_image_stripped_ids", "TEXT DEFAULT ''");
6777
+ ensureColumn(db, "session_meta", "merged_reasoning_stripped_ids", "TEXT DEFAULT ''");
6778
+ ensureColumn(db, "session_meta", "trailing_blank_decisions", "TEXT DEFAULT ''");
6359
6779
  ensureColumn(db, "compartments", "start_message_id", "TEXT DEFAULT ''");
6360
6780
  ensureColumn(db, "compartments", "end_message_id", "TEXT DEFAULT ''");
6361
6781
  ensureColumn(db, "memory_embeddings", "model_id", "TEXT");
@@ -6698,13 +7118,14 @@ var state = {
6698
7118
  noticeEmitted: false,
6699
7119
  failure: null
6700
7120
  };
6701
- function recordStaleFence(persistedVersion, supportedVersion) {
7121
+ function recordStaleFence(persistedVersion, supportedVersion, reason = "newer_schema") {
6702
7122
  state.consecutiveFailures += 1;
6703
7123
  state.totalFailures += 1;
6704
7124
  const latched = state.consecutiveFailures >= STALE_CHILD_SPAWN_LATCH_THRESHOLD;
6705
7125
  state.latched ||= latched;
6706
7126
  const failure = {
6707
7127
  failureClass: STALE_CHILD_SPAWN_FAILURE,
7128
+ reason,
6708
7129
  persistedVersion,
6709
7130
  supportedVersion,
6710
7131
  consecutiveFailures: state.consecutiveFailures,
@@ -6731,7 +7152,7 @@ function probeChildSpawnFence(db) {
6731
7152
  return recordStaleFence(persistedVersion, LATEST_SUPPORTED_VERSION);
6732
7153
  }
6733
7154
  } catch {
6734
- return { allowSpawn: true };
7155
+ return recordStaleFence(LATEST_SUPPORTED_VERSION, LATEST_SUPPORTED_VERSION, "read_error");
6735
7156
  }
6736
7157
  state.consecutiveFailures = 0;
6737
7158
  state.latched = false;
@@ -7976,7 +8397,7 @@ function clearHistorianFailureState(db, sessionId) {
7976
8397
  })();
7977
8398
  }
7978
8399
  function normalizeDetectedLimitModelKey(modelKey) {
7979
- return typeof modelKey === "string" && modelKey.length > 0 ? modelKey : null;
8400
+ return typeof modelKey === "string" && modelKey.length > 0 ? piModelRefToCanonical(modelKey) : null;
7980
8401
  }
7981
8402
  function normalizeEmergencyRecoveryOrigin(value) {
7982
8403
  return value === "provider_overflow" || value === "proactive_model_shrink" ? value : null;
@@ -8127,6 +8548,84 @@ function removeStrippedPlaceholderId(db, sessionId, messageId) {
8127
8548
  applyStrippedPlaceholderDelta(db, sessionId, { remove: [messageId] });
8128
8549
  return true;
8129
8550
  }
8551
+ function getMergedReasoningStrippedIds(db, sessionId) {
8552
+ const row = db.prepare("SELECT merged_reasoning_stripped_ids FROM session_meta WHERE session_id = ?").get(sessionId);
8553
+ return new Set(parseStrippedBlob(row?.merged_reasoning_stripped_ids));
8554
+ }
8555
+ function addMergedReasoningStrippedIds(db, sessionId, ids) {
8556
+ const add = [...ids];
8557
+ if (add.length === 0)
8558
+ return true;
8559
+ ensureSessionMetaRow(db, sessionId);
8560
+ for (let attempt = 0;attempt < CAS_RETRY_LIMIT; attempt += 1) {
8561
+ const row = db.prepare("SELECT merged_reasoning_stripped_ids FROM session_meta WHERE session_id = ?").get(sessionId);
8562
+ const rawStored = row ? row.merged_reasoning_stripped_ids ?? null : null;
8563
+ const current = new Set(parseStrippedBlob(rawStored));
8564
+ let changed = false;
8565
+ for (const id of add) {
8566
+ if (!current.has(id)) {
8567
+ current.add(id);
8568
+ changed = true;
8569
+ }
8570
+ }
8571
+ if (!changed)
8572
+ return true;
8573
+ const nextBlob = JSON.stringify([...current]);
8574
+ const result = db.prepare("UPDATE session_meta SET merged_reasoning_stripped_ids = ? WHERE session_id = ? AND merged_reasoning_stripped_ids IS ?").run(nextBlob, sessionId, rawStored);
8575
+ if (result.changes > 0)
8576
+ return true;
8577
+ }
8578
+ sessionLog(sessionId, `merged_reasoning_stripped_ids CAS: ${CAS_RETRY_LIMIT} retries exhausted`);
8579
+ return false;
8580
+ }
8581
+ function parseTrailingBlankDecisions(raw) {
8582
+ if (!raw)
8583
+ return new Map;
8584
+ try {
8585
+ const parsed = JSON.parse(raw);
8586
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
8587
+ return new Map;
8588
+ const decisions = new Map;
8589
+ for (const [id, decision] of Object.entries(parsed)) {
8590
+ if (id.length > 0 && (decision === "keep" || decision === "strip")) {
8591
+ decisions.set(id, decision);
8592
+ }
8593
+ }
8594
+ return decisions;
8595
+ } catch {
8596
+ return new Map;
8597
+ }
8598
+ }
8599
+ function getTrailingBlankDecisions(db, sessionId) {
8600
+ const row = db.prepare("SELECT trailing_blank_decisions FROM session_meta WHERE session_id = ?").get(sessionId);
8601
+ return parseTrailingBlankDecisions(row?.trailing_blank_decisions);
8602
+ }
8603
+ function addTrailingBlankDecisions(db, sessionId, additions) {
8604
+ const add = [...additions];
8605
+ if (add.length === 0)
8606
+ return true;
8607
+ ensureSessionMetaRow(db, sessionId);
8608
+ for (let attempt = 0;attempt < CAS_RETRY_LIMIT; attempt += 1) {
8609
+ const row = db.prepare("SELECT trailing_blank_decisions FROM session_meta WHERE session_id = ?").get(sessionId);
8610
+ const rawStored = row ? row.trailing_blank_decisions ?? null : null;
8611
+ const current = parseTrailingBlankDecisions(rawStored);
8612
+ let changed = false;
8613
+ for (const [id, decision] of add) {
8614
+ if (!current.has(id)) {
8615
+ current.set(id, decision);
8616
+ changed = true;
8617
+ }
8618
+ }
8619
+ if (!changed)
8620
+ return true;
8621
+ const nextBlob = JSON.stringify(Object.fromEntries(current));
8622
+ const result = db.prepare("UPDATE session_meta SET trailing_blank_decisions = ? WHERE session_id = ? AND trailing_blank_decisions IS ?").run(nextBlob, sessionId, rawStored);
8623
+ if (result.changes > 0)
8624
+ return true;
8625
+ }
8626
+ sessionLog(sessionId, `trailing_blank_decisions CAS: ${CAS_RETRY_LIMIT} retries exhausted`);
8627
+ return false;
8628
+ }
8130
8629
  function getStaleReduceStrippedIds(db, sessionId) {
8131
8630
  const row = db.prepare("SELECT stale_reduce_stripped_ids FROM session_meta WHERE session_id = ?").get(sessionId);
8132
8631
  return new Set(parseStrippedBlob(row?.stale_reduce_stripped_ids));
@@ -8574,6 +9073,76 @@ function parseCandidateIds(raw) {
8574
9073
  return [];
8575
9074
  }
8576
9075
  }
9076
+ function parsePrimerSourceProvenance(raw) {
9077
+ if (raw === null)
9078
+ return null;
9079
+ try {
9080
+ const parsed = JSON.parse(raw);
9081
+ if (!Array.isArray(parsed))
9082
+ return null;
9083
+ const provenance = [];
9084
+ for (const value of parsed) {
9085
+ if (!value || typeof value !== "object")
9086
+ return null;
9087
+ const source = value;
9088
+ if (typeof source.candidate_id !== "number" || !Number.isFinite(source.candidate_id) || typeof source.project_path !== "string" || typeof source.harness !== "string" || typeof source.session_id !== "string" || source.source_compartment_start !== null && typeof source.source_compartment_start !== "number" || source.source_compartment_end !== null && typeof source.source_compartment_end !== "number" || typeof source.source_start_message_id !== "string" || typeof source.source_end_message_id !== "string") {
9089
+ return null;
9090
+ }
9091
+ provenance.push({
9092
+ candidateId: source.candidate_id,
9093
+ projectPath: source.project_path,
9094
+ harness: source.harness,
9095
+ sessionId: source.session_id,
9096
+ sourceCompartmentStart: source.source_compartment_start,
9097
+ sourceCompartmentEnd: source.source_compartment_end,
9098
+ sourceStartMessageId: source.source_start_message_id,
9099
+ sourceEndMessageId: source.source_end_message_id
9100
+ });
9101
+ }
9102
+ return provenance;
9103
+ } catch {
9104
+ return null;
9105
+ }
9106
+ }
9107
+ function loadPrimerSourceProvenance(db, candidateIds) {
9108
+ const ids = [...new Set(candidateIds)].sort((a, b) => a - b);
9109
+ if (ids.length === 0)
9110
+ return [];
9111
+ const placeholders3 = ids.map(() => "?").join(",");
9112
+ const rows = db.prepare(`SELECT id, project_path, harness, session_id,
9113
+ source_compartment_start, source_compartment_end,
9114
+ source_start_message_id, source_end_message_id
9115
+ FROM primer_candidates
9116
+ WHERE id IN (${placeholders3})
9117
+ ORDER BY id ASC`).all(...ids);
9118
+ return rows.map((row) => ({
9119
+ candidateId: row.id,
9120
+ projectPath: row.project_path,
9121
+ harness: row.harness,
9122
+ sessionId: row.session_id,
9123
+ sourceCompartmentStart: row.source_compartment_start,
9124
+ sourceCompartmentEnd: row.source_compartment_end,
9125
+ sourceStartMessageId: row.source_start_message_id,
9126
+ sourceEndMessageId: row.source_end_message_id
9127
+ }));
9128
+ }
9129
+ function serializePrimerSourceProvenance(provenance, sourceCandidateIds) {
9130
+ if (provenance.length === 0 && sourceCandidateIds.length > 0)
9131
+ return null;
9132
+ return JSON.stringify(provenance.map((source) => ({
9133
+ candidate_id: source.candidateId,
9134
+ project_path: source.projectPath,
9135
+ harness: source.harness,
9136
+ session_id: source.sessionId,
9137
+ source_compartment_start: source.sourceCompartmentStart,
9138
+ source_compartment_end: source.sourceCompartmentEnd,
9139
+ source_start_message_id: source.sourceStartMessageId,
9140
+ source_end_message_id: source.sourceEndMessageId
9141
+ })));
9142
+ }
9143
+ function normalizedCandidateIds(candidateIds) {
9144
+ return [...new Set(candidateIds)].sort((a, b) => a - b);
9145
+ }
8577
9146
  function toCandidate(row) {
8578
9147
  return {
8579
9148
  id: row.id,
@@ -8606,6 +9175,7 @@ function toPrimer(row) {
8606
9175
  lastObservedAt: row.last_observed_at,
8607
9176
  answerRefreshedAt: row.answer_refreshed_at,
8608
9177
  sourceCandidateIds: parseCandidateIds(row.source_candidate_ids),
9178
+ sourceProvenance: parsePrimerSourceProvenance(row.source_candidate_provenance),
8609
9179
  createdAt: row.created_at,
8610
9180
  updatedAt: row.updated_at
8611
9181
  };
@@ -8677,23 +9247,43 @@ function getActivePrimers(db, projectPath) {
8677
9247
  return rows.map(toPrimer);
8678
9248
  }
8679
9249
  function createPrimer(db, input) {
8680
- const now = input.now ?? Date.now();
8681
- const info = db.prepare(`INSERT INTO primers (
8682
- project_path, question, question_embedding, question_embedding_model_id, answer,
8683
- status, total_support, last_observed_at, answer_refreshed_at,
8684
- source_candidate_ids, created_at, updated_at
8685
- ) VALUES (?, ?, ?, ?, ?, 'active', ?, ?, NULL, ?, ?, ?)`).run(input.projectPath, input.question, vectorBlob(input.questionEmbedding), input.questionEmbeddingModelId ?? null, input.answer ?? "", input.totalSupport, input.lastObservedAt, JSON.stringify([...new Set(input.sourceCandidateIds)].sort((a, b) => a - b)), now, now);
8686
- return Number(info.lastInsertRowid);
9250
+ return db.transaction(() => {
9251
+ const now = input.now ?? Date.now();
9252
+ const sourceCandidateIds = normalizedCandidateIds(input.sourceCandidateIds);
9253
+ const sourceProvenance = loadPrimerSourceProvenance(db, sourceCandidateIds);
9254
+ const info = db.prepare(`INSERT INTO primers (
9255
+ project_path, question, question_embedding, question_embedding_model_id, answer,
9256
+ status, total_support, last_observed_at, answer_refreshed_at,
9257
+ source_candidate_ids, source_candidate_provenance, created_at, updated_at
9258
+ ) VALUES (?, ?, ?, ?, ?, 'active', ?, ?, NULL, ?, ?, ?, ?)`).run(input.projectPath, input.question, vectorBlob(input.questionEmbedding), input.questionEmbeddingModelId ?? null, input.answer ?? "", input.totalSupport, input.lastObservedAt, JSON.stringify(sourceCandidateIds), serializePrimerSourceProvenance(sourceProvenance, sourceCandidateIds), now, now);
9259
+ return Number(info.lastInsertRowid);
9260
+ })();
8687
9261
  }
8688
9262
  function updatePrimerSupport(db, input) {
8689
- db.prepare(`UPDATE primers
8690
- SET question_embedding = COALESCE(?, question_embedding),
8691
- question_embedding_model_id = COALESCE(?, question_embedding_model_id),
8692
- total_support = ?,
8693
- last_observed_at = ?,
8694
- source_candidate_ids = ?,
8695
- updated_at = ?
8696
- WHERE id = ?`).run(vectorBlob(input.questionEmbedding), input.questionEmbeddingModelId ?? null, input.totalSupport, input.lastObservedAt, JSON.stringify([...new Set(input.sourceCandidateIds)].sort((a, b) => a - b)), input.now ?? Date.now(), input.primerId);
9263
+ db.transaction(() => {
9264
+ const sourceCandidateIds = normalizedCandidateIds(input.sourceCandidateIds);
9265
+ const allowedIds = new Set(sourceCandidateIds);
9266
+ const existingRow = db.prepare("SELECT source_candidate_provenance FROM primers WHERE id = ?").get(input.primerId);
9267
+ const provenanceByCandidateId = new Map;
9268
+ for (const source of parsePrimerSourceProvenance(existingRow?.source_candidate_provenance ?? null) ?? []) {
9269
+ if (allowedIds.has(source.candidateId)) {
9270
+ provenanceByCandidateId.set(source.candidateId, source);
9271
+ }
9272
+ }
9273
+ for (const source of loadPrimerSourceProvenance(db, sourceCandidateIds)) {
9274
+ provenanceByCandidateId.set(source.candidateId, source);
9275
+ }
9276
+ const sourceProvenance = [...provenanceByCandidateId.values()].sort((a, b) => a.candidateId - b.candidateId);
9277
+ db.prepare(`UPDATE primers
9278
+ SET question_embedding = COALESCE(?, question_embedding),
9279
+ question_embedding_model_id = COALESCE(?, question_embedding_model_id),
9280
+ total_support = ?,
9281
+ last_observed_at = ?,
9282
+ source_candidate_ids = ?,
9283
+ source_candidate_provenance = ?,
9284
+ updated_at = ?
9285
+ WHERE id = ?`).run(vectorBlob(input.questionEmbedding), input.questionEmbeddingModelId ?? null, input.totalSupport, input.lastObservedAt, JSON.stringify(sourceCandidateIds), serializePrimerSourceProvenance(sourceProvenance, sourceCandidateIds), input.now ?? Date.now(), input.primerId);
9286
+ })();
8697
9287
  }
8698
9288
  function updatePrimerAnswer(db, primerId, answer, refreshedAt = Date.now()) {
8699
9289
  db.prepare("UPDATE primers SET answer = ?, answer_refreshed_at = ?, updated_at = ? WHERE id = ?").run(answer, refreshedAt, refreshedAt, primerId);
@@ -9336,25 +9926,31 @@ var ERROR_CLASSES = new Set([
9336
9926
  ]);
9337
9927
  // src/hooks/magic-context/child-session-spawn.ts
9338
9928
  var STALE_PLUGIN_RESTART_NOTICE = "Magic Context: plugin build is older than its database — restart OpenCode";
9339
- async function surfaceStalePluginBuild(args) {
9929
+ var SCHEMA_PROBE_FAILURE_NOTICE = `Magic Context: unable to verify the database schema before spawning a child — run ${FAIL_CLOSED_DOCTOR_COMMAND}`;
9930
+ async function surfaceSchemaFenceFailure(args, failure) {
9340
9931
  if (!args.parentSessionId)
9341
9932
  return;
9342
- try {
9343
- if (args.db) {
9933
+ const notice = failure.reason === "read_error" ? SCHEMA_PROBE_FAILURE_NOTICE : STALE_PLUGIN_RESTART_NOTICE;
9934
+ if (args.db) {
9935
+ try {
9344
9936
  updateSessionMeta(args.db, args.parentSessionId, {
9345
- lastTransformError: STALE_PLUGIN_RESTART_NOTICE
9937
+ lastTransformError: notice
9346
9938
  });
9939
+ } catch (error) {
9940
+ sessionLog(args.parentSessionId, `schema-fence warning persistence failed: ${error instanceof Error ? error.message : String(error)}`);
9347
9941
  }
9942
+ }
9943
+ try {
9348
9944
  pushNotification("toast", {
9349
9945
  title: "Magic Context",
9350
- message: STALE_PLUGIN_RESTART_NOTICE,
9946
+ message: notice,
9351
9947
  variant: "error",
9352
9948
  duration: 1e4
9353
9949
  }, args.parentSessionId);
9354
9950
  pushNotification("action", { action: "refresh-sidebar" }, args.parentSessionId);
9355
- await sendIgnoredMessage(args.client, args.parentSessionId, STALE_PLUGIN_RESTART_NOTICE, args.notificationParams ?? {}, true);
9951
+ await sendIgnoredMessage(args.client, args.parentSessionId, notice, args.notificationParams ?? {}, true);
9356
9952
  } catch (error) {
9357
- sessionLog(args.parentSessionId, `stale plugin-build warning delivery failed: ${error instanceof Error ? error.message : String(error)}`);
9953
+ sessionLog(args.parentSessionId, `schema-fence warning delivery failed: ${error instanceof Error ? error.message : String(error)}`);
9358
9954
  }
9359
9955
  }
9360
9956
  async function createChildSessionWithFence(args) {
@@ -9367,7 +9963,7 @@ async function createChildSessionWithFence(args) {
9367
9963
  if (args.onFenceLatched)
9368
9964
  await args.onFenceLatched(verdict.failure);
9369
9965
  else
9370
- await surfaceStalePluginBuild(args);
9966
+ await surfaceSchemaFenceFailure(args, verdict.failure);
9371
9967
  }
9372
9968
  return null;
9373
9969
  }
@@ -9416,7 +10012,7 @@ var LIMIT_EXTRACTION_PATTERNS = [
9416
10012
  pattern: /too large for model with (\d+) maximum context length/i,
9417
10013
  provenance: "combined"
9418
10014
  },
9419
- { pattern: /context size.*(\d+) tokens?/i, provenance: "combined" },
10015
+ { pattern: /context size[^0-9]{0,40}(\d{4,})\s*tokens?/i, provenance: "combined" },
9420
10016
  { pattern: /exceeds? the context length of (\d+)/i, provenance: "combined" },
9421
10017
  {
9422
10018
  pattern: />\s*(\d+)\s*(?:tokens?\s*)?(?:maximum|max|limit)\b/i,
@@ -9784,11 +10380,21 @@ function normalizeSDKResponse(response, fallback, options) {
9784
10380
  return fallback;
9785
10381
  }
9786
10382
  // src/shared/prompt-surface.ts
10383
+ function promptSurfaceConfigIdentity(config) {
10384
+ return JSON.stringify({
10385
+ default: config?.default ?? "full",
10386
+ models: Object.entries(config?.models ?? {}).sort(([left], [right]) => left < right ? -1 : left > right ? 1 : 0),
10387
+ guidanceOverridePath: config?.guidance_override_path ?? null,
10388
+ toolDescriptions: Object.entries(config?.tool_descriptions ?? {}).sort(([left], [right]) => left < right ? -1 : left > right ? 1 : 0)
10389
+ });
10390
+ }
9787
10391
  function isValidPromptSurfaceModelKey(key) {
9788
10392
  if (key.length === 0 || key.trim() !== key)
9789
10393
  return false;
9790
10394
  const slash = key.indexOf("/");
9791
- if (slash <= 0 || slash === key.length - 1)
10395
+ if (slash < 0)
10396
+ return !key.includes("*");
10397
+ if (slash === 0 || slash === key.length - 1)
9792
10398
  return false;
9793
10399
  const provider = key.slice(0, slash);
9794
10400
  const modelID = key.slice(slash + 1);
@@ -9807,16 +10413,25 @@ function modelKeyLookupOrder(modelKey) {
9807
10413
  return [];
9808
10414
  const provider = modelKey.slice(0, slash);
9809
10415
  let modelID = modelKey.slice(slash + 1);
10416
+ const providerRefs = modelRefLookupOrder(`${provider}/${modelID}`);
9810
10417
  const candidates = [];
9811
10418
  while (modelID.length > 0) {
9812
- candidates.push({ key: `${provider}/${modelID}`, source: "exact" });
10419
+ for (const providerRef of providerRefs) {
10420
+ const providerSlash = providerRef.indexOf("/");
10421
+ const providerPrefix = providerRef.slice(0, providerSlash);
10422
+ candidates.push({ key: `${providerPrefix}/${modelID}`, source: "exact" });
10423
+ }
9813
10424
  candidates.push({ key: modelID, source: "bare" });
9814
10425
  const lastDash = modelID.lastIndexOf("-");
9815
10426
  if (lastDash <= 0)
9816
10427
  break;
9817
10428
  modelID = modelID.slice(0, lastDash);
9818
10429
  }
9819
- candidates.push({ key: `${provider}/*`, source: "wildcard" });
10430
+ for (const providerRef of providerRefs) {
10431
+ const providerSlash = providerRef.indexOf("/");
10432
+ const providerPrefix = providerRef.slice(0, providerSlash);
10433
+ candidates.push({ key: `${providerPrefix}/*`, source: "wildcard" });
10434
+ }
9820
10435
  const seen = new Set;
9821
10436
  return candidates.filter((candidate) => {
9822
10437
  if (seen.has(candidate.key))
@@ -9839,7 +10454,7 @@ function resolveModelConfigValue(values, modelKey) {
9839
10454
  function resolvePromptSurface(config, modelKey) {
9840
10455
  const fallback = config?.default ?? "full";
9841
10456
  const match = resolveModelConfigValue(config?.models, modelKey);
9842
- if (match && match.source !== "bare") {
10457
+ if (match) {
9843
10458
  return { preset: match.value, source: match.source };
9844
10459
  }
9845
10460
  return { preset: fallback, source: "default" };
@@ -10347,12 +10962,13 @@ function createPromptSurfaceGuidanceEpochCache(runtime) {
10347
10962
  const epochs = new Map;
10348
10963
  return {
10349
10964
  resolve(sessionId, config, modelKey) {
10965
+ const canonicalModelKey = modelKey ? piModelRefToCanonical(modelKey) : undefined;
10350
10966
  const cached = epochs.get(sessionId);
10351
- if (cached && cached.config === config && cached.modelKey === modelKey) {
10967
+ if (cached && cached.config === config && cached.modelKey === canonicalModelKey) {
10352
10968
  return cached.selection;
10353
10969
  }
10354
- const selection = runtime.resolveGuidance(config, modelKey);
10355
- epochs.set(sessionId, { config, modelKey, selection });
10970
+ const selection = runtime.resolveGuidance(config, canonicalModelKey);
10971
+ epochs.set(sessionId, { config, modelKey: canonicalModelKey, selection });
10356
10972
  return selection;
10357
10973
  },
10358
10974
  clear(sessionId) {
@@ -10458,13 +11074,44 @@ function pruneExpiredUserMemoryCandidates(db, ttlMs, now = Date.now()) {
10458
11074
  const result = db.prepare("DELETE FROM user_memory_candidates WHERE created_at < ?").run(cutoff);
10459
11075
  return Number(result.changes ?? 0);
10460
11076
  }
11077
+ function loadUserMemorySourceProvenance(db, candidateIds) {
11078
+ const ids = [...new Set(candidateIds)].sort((a, b) => a - b);
11079
+ if (ids.length === 0)
11080
+ return [];
11081
+ const placeholders3 = ids.map(() => "?").join(",");
11082
+ const rows = db.prepare(`SELECT id, session_id, source_compartment_start, source_compartment_end
11083
+ FROM user_memory_candidates
11084
+ WHERE id IN (${placeholders3})
11085
+ ORDER BY id ASC`).all(...ids);
11086
+ return rows.map((row) => ({
11087
+ candidateId: row.id,
11088
+ sessionId: row.session_id,
11089
+ sourceCompartmentStart: row.source_compartment_start,
11090
+ sourceCompartmentEnd: row.source_compartment_end
11091
+ }));
11092
+ }
11093
+ function serializeUserMemorySourceProvenance(provenance, sourceCandidateIds) {
11094
+ if (provenance.length === 0 && sourceCandidateIds.length > 0)
11095
+ return null;
11096
+ return JSON.stringify(provenance.map((source) => ({
11097
+ candidate_id: source.candidateId,
11098
+ session_id: source.sessionId,
11099
+ source_compartment_start: source.sourceCompartmentStart,
11100
+ source_compartment_end: source.sourceCompartmentEnd
11101
+ })));
11102
+ }
10461
11103
  function insertUserMemory(db, content, sourceCandidateIds) {
10462
- const now = Date.now();
10463
- const result = db.prepare("INSERT INTO user_memories (content, status, promoted_at, source_candidate_ids, created_at, updated_at) VALUES (?, 'active', ?, ?, ?, ?)").run(content, now, JSON.stringify(sourceCandidateIds), now, now);
10464
- return Number(result.lastInsertRowid);
11104
+ return db.transaction(() => {
11105
+ const now = Date.now();
11106
+ const sourceProvenance = loadUserMemorySourceProvenance(db, sourceCandidateIds);
11107
+ const result = db.prepare(`INSERT INTO user_memories
11108
+ (content, status, promoted_at, source_candidate_ids, source_candidate_provenance, created_at, updated_at)
11109
+ VALUES (?, 'active', ?, ?, ?, ?, ?)`).run(content, now, JSON.stringify(sourceCandidateIds), serializeUserMemorySourceProvenance(sourceProvenance, sourceCandidateIds), now, now);
11110
+ return Number(result.lastInsertRowid);
11111
+ })();
10465
11112
  }
10466
11113
  function getActiveUserMemories(db) {
10467
- const rows = db.prepare("SELECT id, content, status, promoted_at, source_candidate_ids, created_at, updated_at FROM user_memories WHERE status = 'active' ORDER BY promoted_at ASC, id ASC").all();
11114
+ const rows = db.prepare("SELECT id, content, status, promoted_at, source_candidate_ids, source_candidate_provenance, created_at, updated_at FROM user_memories WHERE status = 'active' ORDER BY promoted_at ASC, id ASC").all();
10468
11115
  return rows.map(parseUserMemoryRow);
10469
11116
  }
10470
11117
  function updateUserMemoryContent(db, id, content) {
@@ -10473,17 +11120,49 @@ function updateUserMemoryContent(db, id, content) {
10473
11120
  function dismissUserMemory(db, id) {
10474
11121
  db.prepare("UPDATE user_memories SET status = 'dismissed', updated_at = ? WHERE id = ?").run(Date.now(), id);
10475
11122
  }
10476
- function parseUserMemoryRow(row) {
10477
- let candidateIds = [];
11123
+ function parseCandidateIds2(raw) {
10478
11124
  try {
10479
- candidateIds = JSON.parse(row.source_candidate_ids);
10480
- } catch {}
11125
+ const parsed = JSON.parse(raw);
11126
+ return Array.isArray(parsed) ? parsed.filter((id) => typeof id === "number" && Number.isFinite(id)) : [];
11127
+ } catch {
11128
+ return [];
11129
+ }
11130
+ }
11131
+ function parseUserMemorySourceProvenance(raw) {
11132
+ if (raw === null)
11133
+ return null;
11134
+ try {
11135
+ const parsed = JSON.parse(raw);
11136
+ if (!Array.isArray(parsed))
11137
+ return null;
11138
+ const provenance = [];
11139
+ for (const value of parsed) {
11140
+ if (!value || typeof value !== "object")
11141
+ return null;
11142
+ const source = value;
11143
+ if (typeof source.candidate_id !== "number" || !Number.isFinite(source.candidate_id) || typeof source.session_id !== "string" || source.source_compartment_start !== null && typeof source.source_compartment_start !== "number" || source.source_compartment_end !== null && typeof source.source_compartment_end !== "number") {
11144
+ return null;
11145
+ }
11146
+ provenance.push({
11147
+ candidateId: source.candidate_id,
11148
+ sessionId: source.session_id,
11149
+ sourceCompartmentStart: source.source_compartment_start,
11150
+ sourceCompartmentEnd: source.source_compartment_end
11151
+ });
11152
+ }
11153
+ return provenance;
11154
+ } catch {
11155
+ return null;
11156
+ }
11157
+ }
11158
+ function parseUserMemoryRow(row) {
10481
11159
  return {
10482
11160
  id: row.id,
10483
11161
  content: row.content,
10484
11162
  status: row.status === "dismissed" ? "dismissed" : "active",
10485
11163
  promotedAt: row.promoted_at,
10486
- sourceCandidateIds: candidateIds,
11164
+ sourceCandidateIds: parseCandidateIds2(row.source_candidate_ids),
11165
+ sourceProvenance: parseUserMemorySourceProvenance(row.source_candidate_provenance),
10487
11166
  createdAt: row.created_at,
10488
11167
  updatedAt: row.updated_at
10489
11168
  };
@@ -26803,14 +27482,14 @@ var PiConfigSchema = exports_external.object({
26803
27482
  }).optional();
26804
27483
  var PromptSurfacePresetSchema = exports_external.enum(["full", "light"]);
26805
27484
  var PromptSurfaceModelKeySchema = exports_external.string().refine(isValidPromptSurfaceModelKey, {
26806
- message: "Use a non-empty provider/model key or the literal provider/* wildcard; model IDs may contain additional slashes and matching is case-sensitive."
27485
+ message: "Use a non-empty bare model key, provider/model key, or the literal provider/* wildcard; model IDs may contain additional slashes and matching is case-sensitive."
26807
27486
  });
26808
27487
  var PromptSurfaceToolKeySchema = exports_external.string().refine((value) => value.trim().length > 0, {
26809
27488
  message: "tool description keys must not be empty or whitespace-only"
26810
27489
  });
26811
27490
  var PromptSurfaceConfigSchema = exports_external.object({
26812
27491
  default: PromptSurfacePresetSchema.default("full").describe('Fallback prompt-surface preset ("full" or "light").'),
26813
- models: exports_external.record(PromptSurfaceModelKeySchema, PromptSurfacePresetSchema).optional().describe("Literal per-model routing. Keys are provider/model or provider/*; matching is case-sensitive and preserves additional slashes in model IDs."),
27492
+ models: exports_external.record(PromptSurfaceModelKeySchema, PromptSurfacePresetSchema).optional().describe("Literal per-model routing. Keys are bare model IDs, provider/model, or provider/*; matching is case-sensitive and preserves additional slashes in model IDs."),
26814
27493
  guidance_override_path: exports_external.string().refine((value) => value.trim().length > 0, {
26815
27494
  message: "guidance_override_path must not be empty or whitespace-only"
26816
27495
  }).optional().describe("USER-LEVEL ONLY path to a complete primary guidance section. Relative paths resolve from the user config file."),
@@ -27003,11 +27682,14 @@ var MagicContextConfigSchema = exports_external.object({
27003
27682
  retina_handoff: exports_external.boolean().default(false).describe("When true, dreamer skips smart notes whose surface conditions compiled to retina provider configs at authoring time. Default false keeps both paths active until the retina consumer is deployed.")
27004
27683
  }).default({ retina_handoff: false }).describe("Smart-note ownership transition controls."),
27005
27684
  cache_ttl: exports_external.union([exports_external.string(), exports_external.object({ default: exports_external.string() }).catchall(exports_external.string())]).default("5m").describe('Cache TTL: string (e.g. "5m", "1h", "30s") or per-model object ({ default: "5m", "model-id": "10m" }). Set to "never" for lanes kept warm by an external keepwarm proxy — disables the idle-TTL heuristic so MC never initiates a rebuild based on elapsed time.'),
27006
- prompt_surface: PromptSurfaceConfigSchema.default({ default: "full" }).describe("Prompt-surface presets: default is full; models use the literal provider/model or provider/* routing grammar. Guidance and tool-description overrides are user-level only. On OpenCode and Pi, per-model routing applies to the guidance block only: tool descriptions are registered once per process, so they follow the default preset (a v1 plugin-surface limitation; per-model tool descriptions are planned for the OpenCode v2 plugin API once the SDK stabilizes)."),
27685
+ prompt_surface: PromptSurfaceConfigSchema.default({ default: "full" }).describe("Prompt-surface presets: default is full; models use bare model IDs, provider/model, or provider/* routing keys. Guidance and tool-description overrides are user-level only. On OpenCode and Pi, per-model routing applies to the guidance block only: tool descriptions are registered once per process, so they follow the default preset (a v1 plugin-surface limitation; per-model tool descriptions are planned for the OpenCode v2 plugin API once the SDK stabilizes)."),
27007
27686
  output_reserve: exports_external.union([
27008
27687
  exports_external.number().min(0),
27009
27688
  exports_external.object({ default: exports_external.number().min(0) }).catchall(exports_external.number().min(0))
27010
27689
  ]).optional().describe('User-only output-token reservation override. Number or per-model object ({ default: 16384, "provider/model": 8192 }); 0 disables reservation. When unset, Magic Context reserves the catalog output limit (capped at 25% of context) for shared-window providers and keeps proven separate-quota Google/Gemini windows unchanged.'),
27690
+ models: exports_external.object({
27691
+ window_overlay_path: exports_external.string().trim().min(1).optional()
27692
+ }).optional().describe("User-only Fusiform window-overlay settings. The path defaults to <dataDir>/fusiform/window-overlay.json."),
27011
27693
  toast_duration_ms: exports_external.number().min(0).max(60000).default(5000).describe("TUI toast lifetime in milliseconds for Magic Context notifications. Set to 0 to disable Magic Context toasts entirely (min: 0, max: 60000, default: 5000)"),
27012
27694
  execute_threshold_percentage: exports_external.union([
27013
27695
  exports_external.number().min(20).max(90, EXECUTE_THRESHOLD_CAP_MESSAGE),
@@ -30524,9 +31206,14 @@ function blockedEmbeddingEndpointReason(endpoint) {
30524
31206
  function normalizeEndpoint2(endpoint) {
30525
31207
  return endpoint?.trim().replace(/\/+$/, "") ?? "";
30526
31208
  }
30527
- function embeddingModelsMatch(served, requested) {
30528
- const a = served.trim().toLowerCase();
30529
- const b = requested.trim().toLowerCase();
31209
+ function parseEmbeddingModel(model) {
31210
+ const lastColon = model.lastIndexOf(":");
31211
+ if (lastColon > model.lastIndexOf("/")) {
31212
+ return { base: model.slice(0, lastColon), tag: model.slice(lastColon + 1) };
31213
+ }
31214
+ return { base: model };
31215
+ }
31216
+ function matchNormalizedEmbeddingModels(a, b) {
30530
31217
  if (a.length === 0 || b.length === 0)
30531
31218
  return true;
30532
31219
  if (a === b)
@@ -30540,6 +31227,16 @@ function embeddingModelsMatch(served, requested) {
30540
31227
  return true;
30541
31228
  return false;
30542
31229
  }
31230
+ function embeddingModelsMatch(served, requested) {
31231
+ const a = served.trim().toLowerCase();
31232
+ const b = requested.trim().toLowerCase();
31233
+ const servedModel = parseEmbeddingModel(a);
31234
+ const requestedModel = parseEmbeddingModel(b);
31235
+ if (servedModel.tag !== undefined && requestedModel.tag !== undefined && servedModel.tag !== requestedModel.tag) {
31236
+ return false;
31237
+ }
31238
+ return matchNormalizedEmbeddingModels(servedModel.base, requestedModel.base);
31239
+ }
30543
31240
  var FAILURE_THRESHOLD = 3;
30544
31241
  var FAILURE_WINDOW_MS = 60000;
30545
31242
  var OPEN_DURATION_MS = 5 * 60000;
@@ -30670,7 +31367,7 @@ class OpenAICompatibleEmbeddingProvider {
30670
31367
  const servedModel = typeof body.model === "string" ? body.model : "";
30671
31368
  if (this.model && servedModel && !embeddingModelsMatch(servedModel, this.model)) {
30672
31369
  if (!this.modelMismatchLogged) {
30673
- log(`[magic-context] embedding endpoint served a DIFFERENT model than requested — refusing the substituted vectors (they have the wrong dimensions/space). requested="${this.model}" served="${servedModel}". The endpoint likely substituted a loaded model; load/select "${this.model}" on the endpoint, or set embedding.model to the served model.`);
31370
+ log(`[magic-context] embedding endpoint served a DIFFERENT model than requested — refusing the substituted vectors (they have the wrong dimensions/space). requested="${this.model}" served="${servedModel}". Check that the endpoint serves the requested model; variant suffixes and vendor prefixes are matched automatically.`);
30674
31371
  this.modelMismatchLogged = true;
30675
31372
  }
30676
31373
  this.recordFailure(isProbe);
@@ -31379,7 +32076,11 @@ function registerProjectShadowEmbedding(db, projectIdentity, config2, sourceDire
31379
32076
  const prior = shadowRegistrations.get(projectIdentity);
31380
32077
  if (prior && prior.providerIdentity === providerIdentity) {
31381
32078
  provider.dispose();
32079
+ dbForShadowQueue.set(projectIdentity, db);
31382
32080
  persistShadowDescriptor(db, prior);
32081
+ const backfillAlreadyArmed = hasPendingShadowBackfill(projectIdentity) || shadowQueue.some((item) => item.projectIdentity === projectIdentity);
32082
+ if (!backfillAlreadyArmed)
32083
+ maybeArmShadowBackfill(db, projectIdentity, prior);
31383
32084
  return {
31384
32085
  ...snapshotFor({
31385
32086
  projectIdentity,
@@ -35999,24 +36700,52 @@ class BoundedSessionMap {
35999
36700
  // src/hooks/magic-context/compartment-render-epoch.ts
36000
36701
  var COMPARTMENT_RENDER_EPOCH = "cre2";
36001
36702
  var EPOCH_COMPONENT_PREFIX = "|compartment-render:";
36002
- function encodeCachedM0UpgradeIdentity(upgradeState, compartmentRenderEpoch = COMPARTMENT_RENDER_EPOCH) {
36003
- if (compartmentRenderEpoch === null)
36004
- return upgradeState;
36005
- return `${upgradeState ?? ""}${EPOCH_COMPONENT_PREFIX}${compartmentRenderEpoch}`;
36703
+ var MURAL_COMPONENT_PREFIX = "|mural-enabled:";
36704
+ var BUDGET_COMPONENT_PREFIX = "|render-budgets:";
36705
+ function encodeCachedM0UpgradeIdentity(upgradeState, compartmentRenderEpoch = COMPARTMENT_RENDER_EPOCH, muralEnabled = null, renderBudgetIdentity = null) {
36706
+ let encoded = upgradeState ?? "";
36707
+ if (compartmentRenderEpoch !== null) {
36708
+ encoded += `${EPOCH_COMPONENT_PREFIX}${compartmentRenderEpoch}`;
36709
+ }
36710
+ if (muralEnabled !== null) {
36711
+ encoded += `${MURAL_COMPONENT_PREFIX}${muralEnabled ? "1" : "0"}`;
36712
+ }
36713
+ if (renderBudgetIdentity !== null) {
36714
+ encoded += `${BUDGET_COMPONENT_PREFIX}${renderBudgetIdentity}`;
36715
+ }
36716
+ return encoded.length > 0 ? encoded : null;
36717
+ }
36718
+ function component(value, prefix) {
36719
+ const start = value.lastIndexOf(prefix);
36720
+ if (start < 0)
36721
+ return null;
36722
+ const valueStart = start + prefix.length;
36723
+ const end = value.indexOf("|", valueStart);
36724
+ const result = value.slice(valueStart, end < 0 ? value.length : end);
36725
+ return result.length > 0 ? result : null;
36006
36726
  }
36007
36727
  function decodeCachedM0UpgradeIdentity(value) {
36008
36728
  if (value === null) {
36009
- return { upgradeState: null, compartmentRenderEpoch: null };
36010
- }
36011
- const componentIndex = value.lastIndexOf(EPOCH_COMPONENT_PREFIX);
36012
- if (componentIndex < 0) {
36013
- return { upgradeState: value, compartmentRenderEpoch: null };
36729
+ return {
36730
+ upgradeState: null,
36731
+ compartmentRenderEpoch: null,
36732
+ muralEnabled: null,
36733
+ renderBudgetIdentity: null
36734
+ };
36014
36735
  }
36015
- const upgradeState = value.slice(0, componentIndex);
36016
- const compartmentRenderEpoch = value.slice(componentIndex + EPOCH_COMPONENT_PREFIX.length);
36736
+ const componentIndexes = [
36737
+ value.indexOf(EPOCH_COMPONENT_PREFIX),
36738
+ value.indexOf(MURAL_COMPONENT_PREFIX),
36739
+ value.indexOf(BUDGET_COMPONENT_PREFIX)
36740
+ ].filter((index) => index >= 0);
36741
+ const identityEnd = componentIndexes.length > 0 ? Math.min(...componentIndexes) : value.length;
36742
+ const upgradeState = value.slice(0, identityEnd);
36743
+ const muralComponent = component(value, MURAL_COMPONENT_PREFIX);
36017
36744
  return {
36018
36745
  upgradeState: upgradeState.length > 0 ? upgradeState : null,
36019
- compartmentRenderEpoch: compartmentRenderEpoch.length > 0 ? compartmentRenderEpoch : null
36746
+ compartmentRenderEpoch: component(value, EPOCH_COMPONENT_PREFIX),
36747
+ muralEnabled: muralComponent === "1" ? true : muralComponent === "0" ? false : null,
36748
+ renderBudgetIdentity: component(value, BUDGET_COMPONENT_PREFIX)
36020
36749
  };
36021
36750
  }
36022
36751
 
@@ -36433,11 +37162,15 @@ function trimMemoriesToBudget(sessionId, memories, budgetTokens) {
36433
37162
  }
36434
37163
  function prepareCompartmentInjection(db, sessionId, messages, isCacheBusting, projectPath, injectionBudgetTokens, temporalAwareness) {
36435
37164
  const cached2 = injectionCache.get(sessionId);
36436
- if (!isCacheBusting && cached2) {
36437
- if (cached2.kind === "empty") {
37165
+ if (cached2 && cached2.db !== db) {
37166
+ clearInjectionCache(sessionId);
37167
+ }
37168
+ const usableCached = cached2?.db === db ? cached2 : undefined;
37169
+ if (!isCacheBusting && usableCached) {
37170
+ if (usableCached.kind === "empty") {
36438
37171
  return null;
36439
37172
  }
36440
- const prepared = cached2.injection;
37173
+ const prepared = usableCached.injection;
36441
37174
  if (prepared.compartmentEndMessageId === null) {
36442
37175
  sessionLog(sessionId, "compartment injection cache in degraded mode (null boundary), forcing rebuild");
36443
37176
  } else {
@@ -36484,6 +37217,7 @@ function prepareCompartmentInjection(db, sessionId, messages, isCacheBusting, pr
36484
37217
  }
36485
37218
  if (compartments.length === 0 && facts.length === 0 && !memoryBlock) {
36486
37219
  injectionCache.set(sessionId, {
37220
+ db,
36487
37221
  kind: "empty",
36488
37222
  compartmentEndMessageId: "",
36489
37223
  renderedBytes: 0
@@ -36523,7 +37257,7 @@ function prepareCompartmentInjection(db, sessionId, messages, isCacheBusting, pr
36523
37257
  memoryCount,
36524
37258
  rebuiltFromDb: true
36525
37259
  };
36526
- injectionCache.set(sessionId, { kind: "populated", injection: result2 });
37260
+ injectionCache.set(sessionId, { db, kind: "populated", injection: result2 });
36527
37261
  return result2;
36528
37262
  }
36529
37263
  const lastCompartment = compartments[compartments.length - 1];
@@ -36555,7 +37289,7 @@ function prepareCompartmentInjection(db, sessionId, messages, isCacheBusting, pr
36555
37289
  memoryCount,
36556
37290
  rebuiltFromDb: true
36557
37291
  };
36558
- injectionCache.set(sessionId, { kind: "populated", injection: result2 });
37292
+ injectionCache.set(sessionId, { db, kind: "populated", injection: result2 });
36559
37293
  return result2;
36560
37294
  }
36561
37295
  let skippedVisibleMessages = 0;
@@ -36616,7 +37350,7 @@ function prepareCompartmentInjection(db, sessionId, messages, isCacheBusting, pr
36616
37350
  if (needsFreshMaterialization) {
36617
37351
  result.needsFreshMaterialization = true;
36618
37352
  }
36619
- injectionCache.set(sessionId, { kind: "populated", injection: result });
37353
+ injectionCache.set(sessionId, { db, kind: "populated", injection: result });
36620
37354
  return result;
36621
37355
  }
36622
37356
  function readCachedBaselineState(db, sessionId) {
@@ -36703,6 +37437,9 @@ function lastCompartmentBoundaryId(compartments) {
36703
37437
  }
36704
37438
  var DEFAULT_HISTORY_BUDGET_TOKENS = 60000;
36705
37439
  var DEFAULT_MEMORY_BUDGET_TOKENS = 8000;
37440
+ function renderBudgetIdentity(memoryBudget, historyBudget) {
37441
+ return `m${memoryBudget ?? DEFAULT_MEMORY_BUDGET_TOKENS}-h${historyBudget ?? DEFAULT_HISTORY_BUDGET_TOKENS}`;
37442
+ }
36706
37443
  var DEFAULT_USER_PROFILE_BUDGET_TOKENS = 4000;
36707
37444
  var MAX_FORCED_MEMORIES_PER_DELTA = 10;
36708
37445
  var M0_EMPTY_BODY = "<session-history></session-history>";
@@ -36975,8 +37712,10 @@ function readCurrentM0SnapshotMarkersUncached(args) {
36975
37712
  upgradeState: getUpgradeState(args.db, args.sessionId),
36976
37713
  compartmentRenderEpoch: COMPARTMENT_RENDER_EPOCH,
36977
37714
  systemHash: hard.systemHash,
36978
- modelKey: hard.modelKey,
36979
- projectIdentity: args.projectPath ?? null
37715
+ modelKey: piModelRefToCanonical(hard.modelKey),
37716
+ projectIdentity: args.projectPath ?? null,
37717
+ muralEnabled: args.muralEnabled === true,
37718
+ renderBudgetIdentity: renderBudgetIdentity(args.memoryInjectionBudgetTokens, args.historyBudgetTokens)
36980
37719
  }
36981
37720
  };
36982
37721
  }
@@ -36989,7 +37728,9 @@ function refreshVolatileMarkerInputs(markers, args) {
36989
37728
  materializedAt: Date.now(),
36990
37729
  systemHash: hard.systemHash,
36991
37730
  modelKey: hard.modelKey,
36992
- projectIdentity: args.projectPath ?? null
37731
+ projectIdentity: args.projectPath ?? null,
37732
+ muralEnabled: args.muralEnabled === true,
37733
+ renderBudgetIdentity: renderBudgetIdentity(args.memoryInjectionBudgetTokens, args.historyBudgetTokens)
36993
37734
  };
36994
37735
  }
36995
37736
  function readCurrentM0SnapshotMarkers(args) {
@@ -37055,7 +37796,9 @@ function snapshotMarkersFromCachedM0(state2) {
37055
37796
  systemHash: state2.cachedM0SystemHash ?? "",
37056
37797
  modelKey: state2.cachedM0ModelKey ?? "",
37057
37798
  projectIdentity: state2.cachedM0ProjectIdentity ?? null,
37058
- muralHash: state2.cachedM0MuralHash ?? null
37799
+ muralHash: state2.cachedM0MuralHash ?? null,
37800
+ muralEnabled: cachedUpgradeIdentity.muralEnabled,
37801
+ renderBudgetIdentity: cachedUpgradeIdentity.renderBudgetIdentity
37059
37802
  };
37060
37803
  }
37061
37804
  function mustMaterialize(args) {
@@ -37069,7 +37812,12 @@ function mustMaterialize(args) {
37069
37812
  if (cachedUpgradeIdentity.compartmentRenderEpoch !== current.compartmentRenderEpoch) {
37070
37813
  return { value: true, reason: "compartment_render_epoch" };
37071
37814
  }
37072
- if (hard.modelKey !== "" && hard.modelKey !== (args.state.cachedM0ModelKey ?? "")) {
37815
+ if (cachedUpgradeIdentity.muralEnabled !== null && cachedUpgradeIdentity.muralEnabled !== current.muralEnabled || cachedUpgradeIdentity.renderBudgetIdentity !== null && cachedUpgradeIdentity.renderBudgetIdentity !== current.renderBudgetIdentity) {
37816
+ return { value: true, reason: "render_config" };
37817
+ }
37818
+ const canonicalHardModelKey = piModelRefToCanonical(hard.modelKey);
37819
+ const canonicalCachedModelKey = piModelRefToCanonical(args.state.cachedM0ModelKey ?? "");
37820
+ if (canonicalHardModelKey !== "" && canonicalHardModelKey !== canonicalCachedModelKey) {
37073
37821
  return { value: true, reason: "model_change" };
37074
37822
  }
37075
37823
  if (hard.systemHash !== "" && hard.systemHash !== (args.state.cachedM0SystemHash ?? "")) {
@@ -37385,7 +38133,7 @@ function applyMarkersToState(state2, m0Bytes, markers, m1Bytes) {
37385
38133
  state2.cachedM0ProjectDocsHash = markers.projectDocsHash;
37386
38134
  state2.cachedM0MaterializedAt = markers.materializedAt;
37387
38135
  state2.cachedM0SessionFactsVersion = markers.sessionFactsVersion;
37388
- state2.cachedM0UpgradeState = encodeCachedM0UpgradeIdentity(markers.upgradeState, markers.compartmentRenderEpoch);
38136
+ state2.cachedM0UpgradeState = encodeCachedM0UpgradeIdentity(markers.upgradeState, markers.compartmentRenderEpoch, markers.muralEnabled, markers.renderBudgetIdentity);
37389
38137
  state2.cachedM0SystemHash = markers.systemHash;
37390
38138
  state2.cachedM0ModelKey = markers.modelKey;
37391
38139
  state2.cachedM0ProjectIdentity = markers.projectIdentity;
@@ -37432,6 +38180,9 @@ function materializeM0(options) {
37432
38180
  projectPath,
37433
38181
  projectDirectory,
37434
38182
  injectDocs: options.injectDocs,
38183
+ muralEnabled: options.muralEnabled,
38184
+ memoryInjectionBudgetTokens: options.memoryInjectionBudgetTokens,
38185
+ historyBudgetTokens: options.historyBudgetTokens,
37435
38186
  hardSignals: options.hardSignals,
37436
38187
  workspaceIdentitySet: {
37437
38188
  identities: workspace.identities,
@@ -37527,7 +38278,9 @@ function materializeM0(options) {
37527
38278
  compartmentRenderEpoch: COMPARTMENT_RENDER_EPOCH,
37528
38279
  systemHash: snapshotMarkers.systemHash,
37529
38280
  modelKey: snapshotMarkers.modelKey,
37530
- projectIdentity: projectPath ?? null
38281
+ projectIdentity: projectPath ?? null,
38282
+ muralEnabled: snapshotMarkers.muralEnabled,
38283
+ renderBudgetIdentity: snapshotMarkers.renderBudgetIdentity
37531
38284
  };
37532
38285
  const memoryEpochStale = current.workspaceFingerprint !== null || snapshotMarkers.workspaceFingerprint !== null ? current.workspaceFingerprint !== snapshotMarkers.workspaceFingerprint : current.projectMemoryEpoch !== snapshotMarkers.projectMemoryEpoch;
37533
38286
  const stale = memoryEpochStale || current.projectUserProfileVersion !== snapshotMarkers.projectUserProfileVersion || current.maxCompartmentSeq !== snapshotMarkers.maxCompartmentSeq || current.maxMutationId !== snapshotMarkers.maxMutationId || current.maxMemoryMutationId !== snapshotMarkers.maxMemoryMutationId || current.sessionFactsVersion !== snapshotMarkers.sessionFactsVersion || current.upgradeState !== snapshotMarkers.upgradeState || (current.projectIdentity ?? null) !== (snapshotMarkers.projectIdentity ?? null);
@@ -37562,7 +38315,7 @@ function materializeM0(options) {
37562
38315
  projectDocsHash: snapshotMarkers.projectDocsHash,
37563
38316
  materializedAt: snapshotMarkers.materializedAt,
37564
38317
  sessionFactsVersion: snapshotMarkers.sessionFactsVersion,
37565
- upgradeState: encodeCachedM0UpgradeIdentity(snapshotMarkers.upgradeState, snapshotMarkers.compartmentRenderEpoch),
38318
+ upgradeState: encodeCachedM0UpgradeIdentity(snapshotMarkers.upgradeState, snapshotMarkers.compartmentRenderEpoch, snapshotMarkers.muralEnabled, snapshotMarkers.renderBudgetIdentity),
37566
38319
  systemHash: snapshotMarkers.systemHash,
37567
38320
  modelKey: snapshotMarkers.modelKey,
37568
38321
  projectIdentity: snapshotMarkers.projectIdentity
@@ -37802,11 +38555,13 @@ function markersFromCachedRow(row) {
37802
38555
  systemHash: row.cached_m0_system_hash ?? "",
37803
38556
  modelKey: row.cached_m0_model_key ?? "",
37804
38557
  projectIdentity: row.cached_m0_project_identity ?? null,
37805
- muralHash: row.cached_m0_mural_hash ?? null
38558
+ muralHash: row.cached_m0_mural_hash ?? null,
38559
+ muralEnabled: cachedUpgradeIdentity.muralEnabled,
38560
+ renderBudgetIdentity: cachedUpgradeIdentity.renderBudgetIdentity
37806
38561
  };
37807
38562
  }
37808
38563
  function cachedRowMatchesState(row, state2) {
37809
- return bufferEqualsNullable(row.cached_m0_bytes, state2.cachedM0Bytes) && (row.cached_m0_mural_data_url ?? null) === (state2.cachedM0MuralDataUrl ?? null) && (row.cached_m0_mural_hash ?? null) === (state2.cachedM0MuralHash ?? null) && row.cached_m0_project_memory_epoch === state2.cachedM0ProjectMemoryEpoch && (row.cached_m0_workspace_fingerprint ?? null) === (state2.cachedM0WorkspaceFingerprint ?? null) && row.cached_m0_project_user_profile_version === state2.cachedM0ProjectUserProfileVersion && row.cached_m0_max_compartment_seq === state2.cachedM0MaxCompartmentSeq && row.cached_m0_max_memory_id === state2.cachedM0MaxMemoryId && row.cached_m0_max_mutation_id === state2.cachedM0MaxMutationId && row.cached_m0_max_memory_mutation_id === state2.cachedM0MaxMemoryMutationId && row.cached_m0_materialized_at === state2.cachedM0MaterializedAt && row.cached_m0_session_facts_version === state2.cachedM0SessionFactsVersion && (row.cached_m0_upgrade_state ?? null) === (state2.cachedM0UpgradeState ?? null) && (row.cached_m0_system_hash ?? "") === (state2.cachedM0SystemHash ?? "") && (row.cached_m0_model_key ?? "") === (state2.cachedM0ModelKey ?? "") && (row.cached_m0_project_identity ?? null) === (state2.cachedM0ProjectIdentity ?? null);
38564
+ return bufferEqualsNullable(row.cached_m0_bytes, state2.cachedM0Bytes) && (row.cached_m0_mural_data_url ?? null) === (state2.cachedM0MuralDataUrl ?? null) && (row.cached_m0_mural_hash ?? null) === (state2.cachedM0MuralHash ?? null) && row.cached_m0_project_memory_epoch === state2.cachedM0ProjectMemoryEpoch && (row.cached_m0_workspace_fingerprint ?? null) === (state2.cachedM0WorkspaceFingerprint ?? null) && row.cached_m0_project_user_profile_version === state2.cachedM0ProjectUserProfileVersion && row.cached_m0_max_compartment_seq === state2.cachedM0MaxCompartmentSeq && row.cached_m0_max_memory_id === state2.cachedM0MaxMemoryId && row.cached_m0_max_mutation_id === state2.cachedM0MaxMutationId && row.cached_m0_max_memory_mutation_id === state2.cachedM0MaxMemoryMutationId && row.cached_m0_materialized_at === state2.cachedM0MaterializedAt && row.cached_m0_session_facts_version === state2.cachedM0SessionFactsVersion && (row.cached_m0_upgrade_state ?? null) === (state2.cachedM0UpgradeState ?? null) && (row.cached_m0_system_hash ?? "") === (state2.cachedM0SystemHash ?? "") && piModelRefToCanonical(row.cached_m0_model_key ?? "") === piModelRefToCanonical(state2.cachedM0ModelKey ?? "") && (row.cached_m0_project_identity ?? null) === (state2.cachedM0ProjectIdentity ?? null);
37810
38565
  }
37811
38566
  function applyCachedRowToState(state2, row) {
37812
38567
  const markers = markersFromCachedRow(row);
@@ -37827,7 +38582,7 @@ function applyCachedRowToState(state2, row) {
37827
38582
  state2.cachedM0ProjectDocsHash = markers.projectDocsHash;
37828
38583
  state2.cachedM0MaterializedAt = markers.materializedAt;
37829
38584
  state2.cachedM0SessionFactsVersion = markers.sessionFactsVersion;
37830
- state2.cachedM0UpgradeState = encodeCachedM0UpgradeIdentity(markers.upgradeState, markers.compartmentRenderEpoch);
38585
+ state2.cachedM0UpgradeState = encodeCachedM0UpgradeIdentity(markers.upgradeState, markers.compartmentRenderEpoch, markers.muralEnabled, markers.renderBudgetIdentity);
37831
38586
  state2.cachedM0SystemHash = markers.systemHash;
37832
38587
  state2.cachedM0ModelKey = markers.modelKey;
37833
38588
  state2.cachedM0ProjectIdentity = markers.projectIdentity;
@@ -37913,6 +38668,10 @@ function renderFreshM0NonPersisted(options) {
37913
38668
  projectPath,
37914
38669
  projectDirectory,
37915
38670
  injectDocs: options.injectDocs,
38671
+ muralEnabled: options.muralEnabled,
38672
+ memoryInjectionBudgetTokens: options.memoryInjectionBudgetTokens,
38673
+ historyBudgetTokens: options.historyBudgetTokens,
38674
+ hardSignals: options.hardSignals,
37916
38675
  workspaceIdentitySet: {
37917
38676
  identities: workspace.identities,
37918
38677
  namesByIdentity: workspace.namesByIdentity
@@ -38009,7 +38768,10 @@ function injectM0M1(options) {
38009
38768
  projectDirectory: options.projectDirectory,
38010
38769
  hardSignals: options.hardSignals,
38011
38770
  workspaceIdentitySet: options.workspaceIdentitySet,
38012
- injectDocs: options.injectDocs
38771
+ injectDocs: options.injectDocs,
38772
+ muralEnabled: options.muralEnabled,
38773
+ memoryInjectionBudgetTokens: options.memoryInjectionBudgetTokens,
38774
+ historyBudgetTokens: options.historyBudgetTokens
38013
38775
  });
38014
38776
  let rematerialized = false;
38015
38777
  let contentionExhausted = false;
@@ -42023,6 +42785,25 @@ function lkgContentDigestFromFields(fields) {
42023
42785
  }
42024
42786
  return hash2.digest("base64url");
42025
42787
  }
42788
+ function incrementalLkgContentDigests(entries, prior) {
42789
+ const aligned = prior !== undefined && prior.ids.length === prior.signatures.length && prior.signatures.length === prior.digests.length;
42790
+ let reusedPrefix = 0;
42791
+ if (aligned && prior) {
42792
+ while (reusedPrefix < entries.length && reusedPrefix < prior.ids.length && entries[reusedPrefix]?.id === prior.ids[reusedPrefix] && entries[reusedPrefix]?.signature === prior.signatures[reusedPrefix]) {
42793
+ reusedPrefix += 1;
42794
+ }
42795
+ }
42796
+ const digests = [];
42797
+ if (aligned && prior) {
42798
+ for (let index = 0;index < reusedPrefix; index += 1) {
42799
+ digests.push(prior.digests[index]);
42800
+ }
42801
+ }
42802
+ for (let index = reusedPrefix;index < entries.length; index += 1) {
42803
+ digests.push(lkgContentDigestFromFields(entries[index]?.fields ?? []));
42804
+ }
42805
+ return { digests, reusedPrefix };
42806
+ }
42026
42807
  function lkgContentDigest(message) {
42027
42808
  const fields = lkgContentFields(message);
42028
42809
  return fields ? lkgContentDigestFromFields(fields) : null;
@@ -42032,7 +42813,7 @@ function touch(sessionId, entry) {
42032
42813
  slots.set(sessionId, entry);
42033
42814
  }
42034
42815
  function captureSlot(sessionId, slot) {
42035
- if (slot.inputContentDigests.length !== slot.inputIdSeq.length || slot.inputContentDigests.some((digest) => digest.length === 0)) {
42816
+ if (slot.inputContentDigests.length !== slot.inputIdSeq.length || slot.inputContentDigests.some((digest) => digest.length === 0) || slot.inputContentSignatures !== undefined && (slot.inputContentSignatures.length !== slot.inputIdSeq.length || slot.inputContentSignatures.some((signature) => signature.length === 0))) {
42036
42817
  return false;
42037
42818
  }
42038
42819
  const bytes = slotBytes(slot);
@@ -42065,7 +42846,8 @@ function captureSlot(sessionId, slot) {
42065
42846
  slot: {
42066
42847
  ...slot,
42067
42848
  inputIdSeq: [...slot.inputIdSeq],
42068
- inputContentDigests: [...slot.inputContentDigests]
42849
+ inputContentDigests: [...slot.inputContentDigests],
42850
+ inputContentSignatures: slot.inputContentSignatures ? [...slot.inputContentSignatures] : undefined
42069
42851
  },
42070
42852
  bytes
42071
42853
  };
@@ -42081,7 +42863,8 @@ function getSlot(sessionId) {
42081
42863
  return {
42082
42864
  ...entry.slot,
42083
42865
  inputIdSeq: [...entry.slot.inputIdSeq],
42084
- inputContentDigests: [...entry.slot.inputContentDigests]
42866
+ inputContentDigests: [...entry.slot.inputContentDigests],
42867
+ inputContentSignatures: entry.slot.inputContentSignatures ? [...entry.slot.inputContentSignatures] : undefined
42085
42868
  };
42086
42869
  }
42087
42870
  function dropSlot(sessionId, _reason) {
@@ -42351,4 +43134,4 @@ async function runUpgradeMemoryMigration(ctx, sessionId, migrationDirectory) {
42351
43134
  }
42352
43135
  }
42353
43136
 
42354
- export { withContentLanguageDirective, buildPrimaryLanguageDirective, cortexKitUserConfigBasePath, cortexKitProjectConfigBasePath, resolveLegacyConfigSources, resolveLegacyConfigSourcesForHarness, migrateMagicContextConfigLocations, exports_external, DEFAULT_PROTECTED_TAGS, parseCron, nextOccurrence, nextDueAtMs, resolvePromptSurface, resolveModelConfigOrDefault, DEFAULT_EXECUTE_THRESHOLD_PERCENTAGE, DEFAULT_HISTORIAN_TIMEOUT_MS, DEFAULT_LOCAL_EMBEDDING_MODEL, MagicContextConfigSchema, getOpenCodeDbPath, removeMcOwnedCompactionMarkers, ProjectIdentityError, resolveProjectIdentityStrict, takeDubiousOwnershipProjectIdentityWarning, resolveProjectIdentity, resolveProjectIdentityForSession, normalizeStoredProjectPath, storedPathBelongsToIdentity, recordSessionProjectIdentity, beginBootQuietPeriod, bootQuietRemainingMs, scheduleAfterBootQuiet, rpcPortDir, rpcPortFilePath, isPidAlive, parseRpcPortFile, registerModuleNoteEvaluationBridge, getModuleNoteEvaluationBridge, getContextStoreUuid, ensureContextStoreUuid, getAuthorityManagedMarker, reconcileAuthorityProject, checksumAuthoritySeedRows, prepareAuthority, drainAuthority, getMirrorCursor, applyMirrorPage, pullMemoryMirrorOnce, V2_MEMORY_CATEGORIES, CATEGORY_PRIORITY, resolveWorkspaceShareCategories, resolveWorkspaceIdentitySet, expandWorkspaceIdentitySetWithAliases, resolveStoredPathWorkspaceIdentity, storedPathBelongsToWorkspace, sourceNameForMemory, computeWorkspaceEpochFingerprint, recordToolDefinition, getMeasuredToolDefinitionTokens, getSchemaFenceRejection, getMigrationOnOpenRefusal, LATEST_SUPPORTED_VERSION, getDatabasePath, getPersistedSchemaVersion, setSqlitePragmaConfig, runSqliteOptimize, openDatabase, openDatabaseAsync, isDatabasePersisted, getDatabasePersistenceError, COMPARTMENT_LEASE_RENEWAL_MS, acquireCompartmentLease, renewCompartmentLease, releaseCompartmentLease, getCompartments, getLastCompartmentEndMessage, getLastCompartmentEndMessageId, clearRecompStaging, recordEmbeddingMeasurement, getMaxM0MutationId, queueMemoryMutation, getMemoryMutationsForRenderByProjects, getMaxMemoryMutationIdForProjects, MAX_EXECUTE_THRESHOLD, escalationBands, isEmergencyRecoveryArmed, isProviderOverflowReconfirmed, getEmergencyRecoveryArmedAt, loadPersistedUsage, loadProtectedTailMeta, resetProtectedTailNoEligibleHead, getWrapupInProgressState, acquireWrapupInProgress, updateWrapupInProgress, releaseWrapupInProgress, resolveCompactionModeRecord, getCompactionModeRecord, setCompactionModeRecord, getPersistedReasoningWatermark, setPersistedReasoningWatermark, clearPersistedReasoningWatermark, getEmergencyInputSample, setEmergencyDropSample, clearEmergencyDropSample, getLastNudgeUndropped, setLastNudgeUndropped, getLastNudgeLevel, setLastNudgeLevel, resetLastNudgeCycle, resetLastNudgeCycleIfTailShrank, getChannel2NudgeState, getChannel2NudgeClaim, setChannel2NudgeState, casChannel2NudgeState, claimChannel2NudgeState, casChannel2NudgeClaim, getPersistedNoteNudge, getNoteNudgeAnchors, getAutoSearchHintDecisions, appendAutoSearchHintDecision, pruneNoteNudgeAnchors, pruneAutoSearchHintDecisions, removeNoteNudgeAnchorByMessageId, removeAutoSearchHintDecisionByMessageId, getPersistedTodoPermissionDenied, setPersistedTodoPermissionDenied, getPersistedTodoSyntheticAnchor, setPersistedTodoSyntheticAnchor, clearPersistedTodoSyntheticAnchor, setNoteLastReadAt, getHistorianFailureState, clearHistorianFailureState, getOverflowState, recordOverflowDetected, recordDetectedContextLimit, clearEmergencyRecovery, clearDetectedContextLimit, getPersistedCompactionMarkerState, setPersistedCompactionMarkerState, getStrippedPlaceholderIds, applyStrippedPlaceholderDelta, removeStrippedPlaceholderId, getStaleReduceStrippedIds, addStaleReduceStrippedIds, getProcessedImageStrippedIds, addProcessedImageStrippedIds, getPendingCompactionMarkerState, clearPendingCompactionMarkerStateIf, peekDeferredExecutePending, setDeferredExecutePendingIfAbsent, clearDeferredExecutePendingIfMatches, getSessionsWithPendingMarker, setSessionWorkMetrics, getNotes, addNote, getSessionNotes, getPendingSmartNotes, getReadySmartNotes, updateNote, dismissNote, markNoteReady, markNoteChecked, queuePendingOp, getPendingOps, clearPendingOps, removePendingOp, PRIMER_CANDIDATE_TTL_MS, PRIMER_CANDIDATE_MAX_AGE_MS, primerOccurrenceKey, primerOccurrenceUtcDay, updatePrimerCandidateEmbedding, getPrimerCandidatesByIds, getPrimerCandidatesForPromotion, countPrimerCandidatesForProject, getActivePrimers, createPrimer, updatePrimerSupport, updatePrimerAnswer, GLOBAL_USER_PROFILE_PROJECT_PATH, getProjectState, bumpProjectMemoryEpoch, bumpProjectUserProfileVersion, saveSourceContent, replaceSourceContent, getSourceContents, getActiveTagTokenAggregate, AGE_RECLAIM_MIN_TOKENS, getOldestActiveUnprotectedToolTags, getActiveToolTagsForAgeReclaim, getTriggerTagTokenUpperBound, getActiveTagTokenTotalsByMessage, tagTokenCountIsNull, backfillTagTokenCounts, insertTag, updateTagStatus, updateTagDropMode, updateCavemanDepth, updateTagMessageId, deleteTagsByMessageId, getMaxTagNumberBySession, getTagNumberByMessageId, deriveTagLoadFloor, getTagsBySession, getActiveTagsBySession, getDroppedTagsBySession, getTagsByNumbers, getMaxDroppedTagNumber, getToolTagNumberByOwner, getNullOwnerToolTag, adoptNullOwnerToolTag, getCandidateToolOwners, pickNearestPriorOwner, createChildSessionWithFence, detectOverflow, promptSyncWithValidatedOutputRetry, normalizeSDKResponse, promptSurfaceHashMaterial, createPromptSurfaceRuntime, createPromptSurfaceGuidanceEpochCache, extractLatestAssistantText, hasLengthCappedOutput, setKeepSubagents, shouldKeepSubagents, recordChildInvocation, COMPARTMENT_AGENT_SYSTEM_PROMPT, HISTORIAN_EDITOR_SYSTEM_PROMPT, COMPARTMENT_STRUCTURAL_SYSTEM_PROMPT, Priority, AdmissionClass, StaleRouteHandleError, SocketClosedError, SocketTimeoutError, SubcClient, isConsumerReconnectTransient, getCompartmentEvents, loadCompartmentChunkEmbeddingsForSearch, cosineSimilarity, SYNAPSE_DEFAULT_MODEL, SynapseEmbeddingProvider, computeNormalizedHash, saveCommitEmbedding, loadProjectCommitEmbeddings, loadUnembeddedCommits, countEmbeddedCommits, upsertCommits, getLatestIndexedCommitTimeMs, enforceProjectCap, GIT_SWEEP_LEASE_RENEWAL_MS, acquireGitSweepLease, renewGitSweepLease, markGitSweepSuccessAndRelease, parkGitSweepNonIndexable, releaseGitSweepLease, saveEmbeddingIfHashMatches, getProjectEmbeddings, peekProjectEmbeddings, invalidateProject, invalidateMemory, markProjectLoadUntrusted, contentSha256, sweepStaleEmbeddingIdentitiesForProject, registerProjectEmbedding, registerProjectShadowEmbedding, getShadowEmbeddingMeasurementCohort, getPrimaryEmbeddingMeasurementCohort, embedShadowTextForProject, enqueueShadowEmbeddingItems, registerProjectInObservationMode, getProjectEmbeddingSnapshot, embedTextForProject, embedBatchForProject, embedItemsForProject, embedUnembeddedMemoriesForProject, drainCommitBacklogForProject, embedSessionCompartmentChunks, getEmbeddingCoverageStatus, isEmbeddingEnabled, embedText, ensureMemoryEmbeddings, computeCueContentHash, hasMuralCueColumns, getMuralCueState, memoryNeedsCue, setMuralCue, recordMuralCueRejection, hasMemoryShareableColumn, hasMemoryClassifiedAtColumn, getUnclassifiedMemoryIds, ModuleMemoryAuthorityError, insertMemory, insertMemoryIdempotent, getMemoryByHash, getMemoriesByProject, buildWorkspaceMemorySqlFilter, getMemoriesByProjects, getMaxMemoryIdForProjects, readNewMemoriesForM1Union, getMemoryById, getMemoriesByIds, updateMemorySeenCount, updateMemoryRetrievalCount, setMemoryClassification, supersededMemory, mergeMemoryStats, archiveMemory, getMemoryCountsByStatus, sanitizeFtsQuery, searchMemoriesFTS, searchMemoriesFTSUnion, recordMemoryMapping, recordMemoryVerifications, getUnmappedMemoryIds, clearMemoryVerifications, getMemoryVerifications, resolveGitTopLevel, readGitHead, readGitChangedFilesSince, readGitFileChangeTimesSince, verificationFileExists, normalizeVerificationFiles, USER_MEMORY_CANDIDATE_TTL_MS, insertUserMemoryCandidates, getUserMemoryCandidates, deleteUserMemoryCandidates, pruneExpiredUserMemoryCandidates, insertUserMemory, getActiveUserMemories, updateUserMemoryContent, dismissUserMemory, MARKER_SUMMARY_TEXT, applyDeferredCompactionMarker, removeCompactionMarkerForSession, checkCompactionMarkerConsistency, getMural, BoundedSessionMap, extractM0Block, formatDate, injectTemporalMarkers, clearInjectionCache, getVisibleMemoryIds, prepareCompartmentInjection, renderCompartmentInjection, mustMaterialize, trimMemoriesToBudgetV2, renderMemoryBlockV2, injectM0M1, onNoteTrigger, peekNoteNudgeText, markNoteNudgeDelivered, clearNoteNudgeTriggerAndCooldown, resetNoteNudgeCooldownOnly, clearNoteNudgeTriggerOnly, RECOVERY_NO_HEAD_LIMIT, resolveOpenCodeProtectedTailBoundary, resolveWrapupProtectedTailBoundary, getRawHistoryEligibility, hasRunnableCompartmentWindow, recordHighPressureNoEligibleHead, runCompartmentAgent, snapRangeToCompartments, LKG_SNAPSHOT_ARRAY, LKG_SNAPSHOT_OBJECT, LKG_SNAPSHOT_KEY, LKG_SNAPSHOT_STRING, LKG_SNAPSHOT_NUMBER, LKG_SNAPSHOT_BOOLEAN, LKG_SNAPSHOT_NULL, LKG_SNAPSHOT_UNDEFINED, lkgContentDigestFromFields, lkgContentDigest, captureSlot, getSlot, dropSlot, noteEntry, getActiveCompartmentRun, markActiveCompartmentRunPublished, registerActiveCompartmentRun, startCompartmentAgent, isRecompFailure, isRecompSkip, isRecompComplete, extractRecompReason, contextualizeUpgradeReason, setRecompStarting, setRecompNote, setRecompTerminal, runManagedRecomp, runManagedUpgrade };
43137
+ export { withContentLanguageDirective, buildPrimaryLanguageDirective, cortexKitUserConfigBasePath, cortexKitProjectConfigBasePath, resolveLegacyConfigSources, resolveLegacyConfigSourcesForHarness, migrateMagicContextConfigLocations, exports_external, DEFAULT_PROTECTED_TAGS, parseCron, nextOccurrence, nextDueAtMs, promptSurfaceConfigIdentity, resolvePromptSurface, resolveModelConfigOrDefault, DEFAULT_EXECUTE_THRESHOLD_PERCENTAGE, DEFAULT_HISTORIAN_TIMEOUT_MS, DEFAULT_LOCAL_EMBEDDING_MODEL, MagicContextConfigSchema, getOpenCodeDbPath, removeMcOwnedCompactionMarkers, isFailClosedBlockingError, shouldBypassFailClosedBlock, resolveAgentNameFromMessages, createFailClosedController, recordHookInitFailure, clearHookInitFailure, getLastHookInitFailure, ProjectIdentityError, resolveProjectIdentityStrict, takeDubiousOwnershipProjectIdentityWarning, resolveProjectIdentity, resolveProjectIdentityForSession, normalizeStoredProjectPath, storedPathBelongsToIdentity, isLinkedGitWorktree, recordSessionProjectIdentity, beginBootQuietPeriod, bootQuietRemainingMs, scheduleAfterBootQuiet, rpcPortDir, rpcPortFilePath, isPidAlive, parseRpcPortFile, registerModuleNoteEvaluationBridge, getModuleNoteEvaluationBridge, getContextStoreUuid, ensureContextStoreUuid, getAuthorityManagedMarker, reconcileAuthorityProject, checksumAuthoritySeedRows, prepareAuthority, drainAuthority, getMirrorCursor, applyMirroredNoteCompileFields, applyMirrorPage, pullMemoryMirrorOnce, V2_MEMORY_CATEGORIES, CATEGORY_PRIORITY, resolveWorkspaceShareCategories, resolveWorkspaceIdentitySet, expandWorkspaceIdentitySetWithAliases, resolveStoredPathWorkspaceIdentity, storedPathBelongsToWorkspace, sourceNameForMemory, computeWorkspaceEpochFingerprint, recordToolDefinition, getMeasuredToolDefinitionTokens, getSchemaFenceRejection, getMigrationOnOpenRefusal, LATEST_SUPPORTED_VERSION, getDatabasePath, getPersistedSchemaVersion, setSqlitePragmaConfig, runSqliteOptimize, openDatabase, openDatabaseAsync, isDatabasePersisted, getDatabasePersistenceError, COMPARTMENT_LEASE_RENEWAL_MS, acquireCompartmentLease, renewCompartmentLease, releaseCompartmentLease, getCompartments, getLastCompartmentEndMessage, getLastCompartmentEndMessageId, clearRecompStaging, recordEmbeddingMeasurement, getMaxM0MutationId, queueMemoryMutation, getMemoryMutationsForRenderByProjects, getMaxMemoryMutationIdForProjects, MAX_EXECUTE_THRESHOLD, escalationBands, isEmergencyRecoveryArmed, isProviderOverflowReconfirmed, getEmergencyRecoveryArmedAt, loadPersistedUsage, loadProtectedTailMeta, resetProtectedTailNoEligibleHead, getWrapupInProgressState, acquireWrapupInProgress, updateWrapupInProgress, releaseWrapupInProgress, resolveCompactionModeRecord, getCompactionModeRecord, setCompactionModeRecord, getPersistedReasoningWatermark, setPersistedReasoningWatermark, clearPersistedReasoningWatermark, getEmergencyInputSample, setEmergencyDropSample, clearEmergencyDropSample, getLastNudgeUndropped, setLastNudgeUndropped, getLastNudgeLevel, setLastNudgeLevel, resetLastNudgeCycle, resetLastNudgeCycleIfTailShrank, getChannel2NudgeState, getChannel2NudgeClaim, setChannel2NudgeState, casChannel2NudgeState, claimChannel2NudgeState, casChannel2NudgeClaim, getPersistedNoteNudge, getNoteNudgeAnchors, getAutoSearchHintDecisions, appendAutoSearchHintDecision, pruneNoteNudgeAnchors, pruneAutoSearchHintDecisions, removeNoteNudgeAnchorByMessageId, removeAutoSearchHintDecisionByMessageId, getPersistedTodoPermissionDenied, setPersistedTodoPermissionDenied, getPersistedTodoSyntheticAnchor, setPersistedTodoSyntheticAnchor, clearPersistedTodoSyntheticAnchor, setNoteLastReadAt, getHistorianFailureState, clearHistorianFailureState, getOverflowState, recordOverflowDetected, recordDetectedContextLimit, clearEmergencyRecovery, clearDetectedContextLimit, getPersistedCompactionMarkerState, setPersistedCompactionMarkerState, getStrippedPlaceholderIds, applyStrippedPlaceholderDelta, removeStrippedPlaceholderId, getMergedReasoningStrippedIds, addMergedReasoningStrippedIds, getTrailingBlankDecisions, addTrailingBlankDecisions, getStaleReduceStrippedIds, addStaleReduceStrippedIds, getProcessedImageStrippedIds, addProcessedImageStrippedIds, getPendingCompactionMarkerState, clearPendingCompactionMarkerStateIf, peekDeferredExecutePending, setDeferredExecutePendingIfAbsent, clearDeferredExecutePendingIfMatches, getSessionsWithPendingMarker, setSessionWorkMetrics, getNotes, addNote, getSessionNotes, getPendingSmartNotes, getReadySmartNotes, updateNote, dismissNote, markNoteReady, markNoteChecked, queuePendingOp, getPendingOps, clearPendingOps, removePendingOp, PRIMER_CANDIDATE_TTL_MS, PRIMER_CANDIDATE_MAX_AGE_MS, primerOccurrenceKey, primerOccurrenceUtcDay, updatePrimerCandidateEmbedding, getPrimerCandidatesByIds, getPrimerCandidatesForPromotion, countPrimerCandidatesForProject, getActivePrimers, createPrimer, updatePrimerSupport, updatePrimerAnswer, GLOBAL_USER_PROFILE_PROJECT_PATH, getProjectState, bumpProjectMemoryEpoch, bumpProjectUserProfileVersion, saveSourceContent, replaceSourceContent, getSourceContents, getActiveTagTokenAggregate, AGE_RECLAIM_MIN_TOKENS, getOldestActiveUnprotectedToolTags, getActiveToolTagsForAgeReclaim, getTriggerTagTokenUpperBound, getActiveTagTokenTotalsByMessage, tagTokenCountIsNull, backfillTagTokenCounts, insertTag, updateTagStatus, updateTagDropMode, updateCavemanDepth, updateTagMessageId, deleteTagsByMessageId, getMaxTagNumberBySession, getTagNumberByMessageId, deriveTagLoadFloor, getTagsBySession, getActiveTagsBySession, getDroppedTagsBySession, getTagsByNumbers, getMaxDroppedTagNumber, getToolTagNumberByOwner, getNullOwnerToolTag, adoptNullOwnerToolTag, getCandidateToolOwners, pickNearestPriorOwner, createChildSessionWithFence, detectOverflow, promptSyncWithValidatedOutputRetry, normalizeSDKResponse, promptSurfaceHashMaterial, createPromptSurfaceRuntime, createPromptSurfaceGuidanceEpochCache, extractLatestAssistantText, hasLengthCappedOutput, setKeepSubagents, shouldKeepSubagents, recordChildInvocation, COMPARTMENT_AGENT_SYSTEM_PROMPT, HISTORIAN_EDITOR_SYSTEM_PROMPT, COMPARTMENT_STRUCTURAL_SYSTEM_PROMPT, Priority, AdmissionClass, StaleRouteHandleError, SocketClosedError, SocketTimeoutError, SubcClient, isConsumerReconnectTransient, connectionFileExists, getCompartmentEvents, loadCompartmentChunkEmbeddingsForSearch, cosineSimilarity, SYNAPSE_DEFAULT_MODEL, SynapseEmbeddingProvider, computeNormalizedHash, saveCommitEmbedding, loadProjectCommitEmbeddings, loadUnembeddedCommits, countEmbeddedCommits, upsertCommits, getLatestIndexedCommitTimeMs, enforceProjectCap, GIT_SWEEP_LEASE_RENEWAL_MS, acquireGitSweepLease, renewGitSweepLease, markGitSweepSuccessAndRelease, parkGitSweepNonIndexable, releaseGitSweepLease, saveEmbeddingIfHashMatches, getProjectEmbeddings, peekProjectEmbeddings, invalidateProject, invalidateMemory, markProjectLoadUntrusted, contentSha256, sweepStaleEmbeddingIdentitiesForProject, registerProjectEmbedding, registerProjectShadowEmbedding, getShadowEmbeddingMeasurementCohort, getPrimaryEmbeddingMeasurementCohort, embedShadowTextForProject, enqueueShadowEmbeddingItems, registerProjectInObservationMode, getProjectEmbeddingSnapshot, embedTextForProject, embedBatchForProject, embedItemsForProject, embedUnembeddedMemoriesForProject, drainCommitBacklogForProject, embedSessionCompartmentChunks, getEmbeddingCoverageStatus, isEmbeddingEnabled, embedText, ensureMemoryEmbeddings, computeCueContentHash, hasMuralCueColumns, getMuralCueState, memoryNeedsCue, setMuralCue, recordMuralCueRejection, hasMemoryShareableColumn, hasMemoryClassifiedAtColumn, getUnclassifiedMemoryIds, ModuleMemoryAuthorityError, insertMemory, insertMemoryIdempotent, getMemoryByHash, getMemoriesByProject, buildWorkspaceMemorySqlFilter, getMemoriesByProjects, getMaxMemoryIdForProjects, readNewMemoriesForM1Union, getMemoryById, getMemoriesByIds, updateMemorySeenCount, updateMemoryRetrievalCount, setMemoryClassification, supersededMemory, mergeMemoryStats, archiveMemory, getMemoryCountsByStatus, sanitizeFtsQuery, searchMemoriesFTS, searchMemoriesFTSUnion, recordMemoryMapping, recordMemoryVerifications, getUnmappedMemoryIds, clearMemoryVerifications, getMemoryVerifications, resolveGitTopLevel, readGitHead, readGitChangedFilesSince, readGitFileChangeTimesSince, verificationFileExists, normalizeVerificationFiles, USER_MEMORY_CANDIDATE_TTL_MS, insertUserMemoryCandidates, getUserMemoryCandidates, deleteUserMemoryCandidates, pruneExpiredUserMemoryCandidates, insertUserMemory, getActiveUserMemories, updateUserMemoryContent, dismissUserMemory, MARKER_SUMMARY_TEXT, applyDeferredCompactionMarker, removeCompactionMarkerForSession, checkCompactionMarkerConsistency, getMural, resolveMuralWire, BoundedSessionMap, extractM0Block, formatDate, injectTemporalMarkers, clearInjectionCache, getVisibleMemoryIds, prepareCompartmentInjection, renderCompartmentInjection, mustMaterialize, trimMemoriesToBudgetV2, renderMemoryBlockV2, injectM0M1, onNoteTrigger, peekNoteNudgeText, markNoteNudgeDelivered, clearNoteNudgeTriggerAndCooldown, resetNoteNudgeCooldownOnly, clearNoteNudgeTriggerOnly, RECOVERY_NO_HEAD_LIMIT, resolveOpenCodeProtectedTailBoundary, resolveWrapupProtectedTailBoundary, getRawHistoryEligibility, hasRunnableCompartmentWindow, recordHighPressureNoEligibleHead, runCompartmentAgent, snapRangeToCompartments, LKG_SNAPSHOT_ARRAY, LKG_SNAPSHOT_OBJECT, LKG_SNAPSHOT_KEY, LKG_SNAPSHOT_STRING, LKG_SNAPSHOT_NUMBER, LKG_SNAPSHOT_BOOLEAN, LKG_SNAPSHOT_NULL, LKG_SNAPSHOT_UNDEFINED, incrementalLkgContentDigests, lkgContentDigest, captureSlot, getSlot, dropSlot, noteEntry, getActiveCompartmentRun, markActiveCompartmentRunPublished, registerActiveCompartmentRun, startCompartmentAgent, isRecompFailure, isRecompSkip, isRecompComplete, extractRecompReason, contextualizeUpgradeReason, setRecompStarting, setRecompNote, setRecompTerminal, runManagedRecomp, runManagedUpgrade };