@cortexkit/opencode-magic-context 0.49.32 → 0.49.34

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 (65) hide show
  1. package/dist/auto-search-worker.js +1 -1
  2. package/dist/chunk-embedding-write-worker.js +1 -1
  3. package/dist/{context-n27jdyyh.js → context-p3xrarzt.js} +15 -10
  4. package/dist/features/magic-context/compaction-marker.d.ts +22 -6
  5. package/dist/features/magic-context/compaction-marker.d.ts.map +1 -1
  6. package/dist/features/magic-context/request-tool-definitions.d.ts +25 -0
  7. package/dist/features/magic-context/request-tool-definitions.d.ts.map +1 -0
  8. package/dist/features/magic-context/storage-meta-persisted.d.ts +7 -0
  9. package/dist/features/magic-context/storage-meta-persisted.d.ts.map +1 -1
  10. package/dist/hooks/magic-context/apply-operations.d.ts +1 -1
  11. package/dist/hooks/magic-context/apply-operations.d.ts.map +1 -1
  12. package/dist/hooks/magic-context/compaction-marker-manager.d.ts +5 -5
  13. package/dist/hooks/magic-context/compaction-marker-manager.d.ts.map +1 -1
  14. package/dist/hooks/magic-context/compaction-marker-publication.d.ts +9 -0
  15. package/dist/hooks/magic-context/compaction-marker-publication.d.ts.map +1 -0
  16. package/dist/hooks/magic-context/compartment-render-epoch.d.ts +7 -0
  17. package/dist/hooks/magic-context/compartment-render-epoch.d.ts.map +1 -1
  18. package/dist/hooks/magic-context/inject-compartments.d.ts +7 -2
  19. package/dist/hooks/magic-context/inject-compartments.d.ts.map +1 -1
  20. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
  21. package/dist/hooks/magic-context/transform.d.ts +1 -0
  22. package/dist/hooks/magic-context/transform.d.ts.map +1 -1
  23. package/dist/{index-94ef0qe2.js → index-04z754rd.js} +1 -1
  24. package/dist/{index-qr2mb02j.js → index-0677w9sd.js} +2 -2
  25. package/dist/{index-t6b3px80.js → index-07vskjn8.js} +3 -3
  26. package/dist/{index-0fe4q77z.js → index-7g9dr8gy.js} +34 -2
  27. package/dist/{index-3drcgsnf.js → index-97spytxq.js} +12 -11
  28. package/dist/{index-4s4zq97n.js → index-9gpw8hrm.js} +1 -1
  29. package/dist/{index-bzwh06cp.js → index-atekmqef.js} +327 -61
  30. package/dist/{index-hbt0sbv2.js → index-fm36bjv4.js} +1 -1
  31. package/dist/{index-2agkcr3y.js → index-ftr84kkv.js} +2 -2
  32. package/dist/{index-g0kqnc6y.js → index-hbx7m8he.js} +9 -4
  33. package/dist/{index-3jmx3fae.js → index-m1x9ghk5.js} +1 -1
  34. package/dist/index.js +14 -14
  35. package/dist/{message-index-bounded-zq7a5nm6.js → message-index-bounded-qh91fdr3.js} +2 -2
  36. package/dist/migration-worker.js +1 -1
  37. package/dist/raw-ordinal-warmup-worker.js +2 -2
  38. package/dist/{read-session-chunk-1ndphmb8.js → read-session-chunk-kaghtr75.js} +1 -1
  39. package/dist/{recomp-orchestrator-6ncc6wrw.js → recomp-orchestrator-0y983w7h.js} +5 -5
  40. package/dist/{search-archive-sr07c6aj.js → search-archive-1kw2rp19.js} +2 -2
  41. package/dist/{search-040pac3a.js → search-p684j8ww.js} +4 -4
  42. package/dist/{transform-postprocess-phase-wvt1k03d.js → transform-postprocess-phase-ph38mhrs.js} +6 -6
  43. package/dist/v2/auto-search-worker.js +1 -1
  44. package/dist/v2/chunk-embedding-write-worker.js +1 -1
  45. package/dist/v2/{context-ehews84p.js → context-s60hcatx.js} +19 -8
  46. package/dist/v2/hooks/context.d.ts +3 -3
  47. package/dist/v2/hooks/context.d.ts.map +1 -1
  48. package/dist/v2/{message-index-bounded-jvgz7vk9.js → message-index-bounded-4htdr1j6.js} +2 -2
  49. package/dist/v2/migration-worker.js +1 -1
  50. package/dist/v2/raw-ordinal-warmup-worker.js +2 -2
  51. package/dist/v2/{read-session-chunk-djzgm4jg.js → read-session-chunk-1fa9qzwb.js} +1 -1
  52. package/dist/v2/{recomp-orchestrator-3r9kcs61.js → recomp-orchestrator-7q9nvxte.js} +4 -4
  53. package/dist/v2/{search-archive-n3dhns4r.js → search-archive-xfp51s0g.js} +2 -2
  54. package/dist/v2/{search-q3wkpe8t.js → search-wf8rqxhm.js} +3 -3
  55. package/dist/v2/{server-n14edf07.js → server-ajxhrgjv.js} +1 -1
  56. package/dist/v2/{server-rr4cbkr0.js → server-grakwy1v.js} +1 -1
  57. package/dist/v2/{server-d01pe8q5.js → server-jw5qe9y8.js} +1 -1
  58. package/dist/v2/{server-hwag0khr.js → server-m1pfg2d4.js} +1 -1
  59. package/dist/v2/{server-rb8m4vry.js → server-qvy4qavp.js} +34 -2
  60. package/dist/v2/{server-4n176b5m.js → server-z2wft9zv.js} +352 -87
  61. package/dist/v2/server.js +2 -2
  62. package/dist/v2/{wrapup-orchestrator-ddmvbkra.js → wrapup-orchestrator-wxf7n5k6.js} +4 -4
  63. package/dist/{wrapup-orchestrator-fyvyzcbm.js → wrapup-orchestrator-ys2nrkkb.js} +6 -6
  64. package/package.json +1 -1
  65. package/src/shared/sqlite-transaction-mode-guard.test.ts +2 -0
@@ -65,7 +65,10 @@ import {
65
65
  getOverflowState,
66
66
  clearEmergencyRecovery,
67
67
  getPersistedCompactionMarkerState,
68
+ getCompactionMarkerPublicationState,
69
+ compareAndSetCompactionMarkerPublicationState,
68
70
  setPersistedCompactionMarkerState,
71
+ getDeferredClearedCompactionMarkerState,
69
72
  parseStrippedPlaceholderState,
70
73
  serializeStrippedPlaceholderState,
71
74
  THINKING_BINDING_RECOVERY_FROZEN_PREFIX,
@@ -98,7 +101,7 @@ import {
98
101
  getRawSessionTagKeysThrough2,
99
102
  getLegacyProtectedTailStartOrdinal2,
100
103
  readSessionChunk2
101
- } from "./index-0fe4q77z.js";
104
+ } from "./index-7g9dr8gy.js";
102
105
  import {
103
106
  getHarness2,
104
107
  harnessOwnsOpenCodeStore2
@@ -174,7 +177,7 @@ import {
174
177
  LATEST_SUPPORTED_VERSION,
175
178
  getPersistedSchemaVersion,
176
179
  openDatabase
177
- } from "./index-hbt0sbv2.js";
180
+ } from "./index-fm36bjv4.js";
178
181
  import {
179
182
  inRootAsyncContext2,
180
183
  Database2,
@@ -254,7 +257,7 @@ import {
254
257
  toMessageIndexSource,
255
258
  clearIndexedMessagesInTransaction,
256
259
  indexSourcesAfterOrdinal
257
- } from "./index-4s4zq97n.js";
260
+ } from "./index-9gpw8hrm.js";
258
261
  import {
259
262
  stripWellFormedLeadingTagPrefix,
260
263
  stripTagPrefix,
@@ -13006,6 +13009,44 @@ function resolveMuralWire(db, projectIdentity, modelKey, enabled, budgetTokens =
13006
13009
  };
13007
13010
  }
13008
13011
 
13012
+ // src/features/magic-context/request-tool-definitions.ts
13013
+ import { createHash as createHash13 } from "node:crypto";
13014
+ var IDENTITY_SCOPE = "names-descriptions-v1";
13015
+ var sha = (value) => createHash13("sha256").update(JSON.stringify(value)).digest("hex");
13016
+ function v2ToolDefinitionsHash(tools) {
13017
+ const pairs = Object.entries(tools).map(([name, tool]) => [name, tool.description]).sort(([left], [right]) => left < right ? -1 : left > right ? 1 : 0);
13018
+ return JSON.stringify({
13019
+ scope: IDENTITY_SCOPE,
13020
+ hash: sha(pairs),
13021
+ tools: pairs.map(([name, description]) => [name, sha([name, description])])
13022
+ });
13023
+ }
13024
+ function needsRequestToolIdentityAdoption(previous, current) {
13025
+ return readIdentity(current).scope === IDENTITY_SCOPE && readIdentity(previous).scope !== IDENTITY_SCOPE;
13026
+ }
13027
+ function readIdentity(value) {
13028
+ try {
13029
+ const parsed = JSON.parse(value);
13030
+ if (typeof parsed.hash === "string" && Array.isArray(parsed.tools) && parsed.tools.every((item) => Array.isArray(item) && item.length === 2 && item.every((part) => typeof part === "string")))
13031
+ return parsed;
13032
+ } catch {}
13033
+ return { hash: value, tools: [] };
13034
+ }
13035
+ function describeRequestToolDefinitionChange(previous, current) {
13036
+ const before = readIdentity(previous);
13037
+ const after = readIdentity(current);
13038
+ let firstDifferingTool = "unknown";
13039
+ for (let index = 0;index < Math.max(before.tools.length, after.tools.length); index++) {
13040
+ const left = before.tools[index];
13041
+ const right = after.tools[index];
13042
+ if (left?.[0] === right?.[0] && left?.[1] === right?.[1])
13043
+ continue;
13044
+ firstDifferingTool = left?.[0] === right?.[0] ? left?.[0] ?? "unknown" : `${left?.[0] ?? "(absent)"}→${right?.[0] ?? "(absent)"}`;
13045
+ break;
13046
+ }
13047
+ return { previousHash: before.hash, currentHash: after.hash, firstDifferingTool };
13048
+ }
13049
+
13009
13050
  // src/features/magic-context/user-memory/storage-user-memory.ts
13010
13051
  var USER_MEMORY_CANDIDATE_TTL_MS = 30 * 24 * 60 * 60 * 1000;
13011
13052
  function insertUserMemoryCandidates(db, candidates) {
@@ -13139,14 +13180,14 @@ function parseUserMemoryRow(row) {
13139
13180
  }
13140
13181
 
13141
13182
  // src/features/magic-context/compaction-marker.ts
13142
- import { createHash as createHash13 } from "node:crypto";
13183
+ import { createHash as createHash14 } from "node:crypto";
13143
13184
  import { existsSync as existsSync6, statSync as statSync7 } from "node:fs";
13144
13185
  var BASE62_CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
13145
13186
  var ID_PREFIX_HEX_LENGTH = 12;
13146
13187
  var ID_SUFFIX_LENGTH = 14;
13147
13188
  var ID_PREFIX_MASK = (1n << BigInt(ID_PREFIX_HEX_LENGTH * 4)) - 1n;
13148
13189
  function deterministicBase62(seed, length) {
13149
- let value = BigInt(`0x${createHash13("sha256").update(seed).digest("hex")}`);
13190
+ let value = BigInt(`0x${createHash14("sha256").update(seed).digest("hex")}`);
13150
13191
  const chars = Array(length);
13151
13192
  for (let index = length - 1;index >= 0; index -= 1) {
13152
13193
  chars[index] = BASE62_CHARS[Number(value % 62n)];
@@ -13367,6 +13408,80 @@ function getOpenCodeMessageById(sessionId, messageId) {
13367
13408
  const row = db.prepare(`SELECT id FROM message WHERE session_id = ? AND id = ? LIMIT 1`).get(sessionId, messageId);
13368
13409
  return row ?? null;
13369
13410
  }
13411
+ function planCompactionMarker(args, boundary) {
13412
+ const identity = `${args.sessionId}\x00${args.endMessageId}`;
13413
+ return {
13414
+ boundaryMessageId: boundary.id,
13415
+ summaryMessageId: generateMessageId(boundary.timeCreated + 1, 1n, `${identity}\x00summary-message`),
13416
+ compactionPartId: generatePartId(boundary.timeCreated, 1n, `${identity}\x00compaction-part`),
13417
+ summaryPartId: generatePartId(boundary.timeCreated + 1, 2n, `${identity}\x00summary-part`)
13418
+ };
13419
+ }
13420
+ function isCompactionMarkerIntentAbsent(marker, targetEndMessageId) {
13421
+ if (!targetEndMessageId)
13422
+ return false;
13423
+ const db = getWritableOpenCodeDb();
13424
+ return !db.prepare(`SELECT 1 FROM message WHERE id IN (?, ?)
13425
+ UNION ALL SELECT 1 FROM part WHERE id IN (?, ?) LIMIT 1`).get(targetEndMessageId, marker.summaryMessageId, marker.compactionPartId, marker.summaryPartId);
13426
+ }
13427
+ function withCompactionMarkerPublicationLock(operation) {
13428
+ return runMarkerWriteTransaction(getWritableOpenCodeDb(), "compaction-marker-replace", operation);
13429
+ }
13430
+ function inspectCompactionMarkerPublication(sessionId, recognized, summaryText) {
13431
+ const db = getWritableOpenCodeDb();
13432
+ const basis = readMarkerCandidateBasis2(db, sessionId);
13433
+ if (!basis)
13434
+ return { kind: "deferred" };
13435
+ const pairs = [];
13436
+ for (const id of basis.ids) {
13437
+ const rows = db.prepare(`SELECT m.id AS summaryId, p.message_id AS boundaryId, p.id AS partId
13438
+ FROM message m JOIN part p ON p.message_id = json_extract(m.data, '$.parentID')
13439
+ AND +p.session_id = m.session_id
13440
+ WHERE m.id = ? AND m.session_id = ? AND json_extract(m.data, '$.summary') = 1
13441
+ AND COALESCE(json_extract(m.data, '$.finish'), '') <> ''
13442
+ AND json_extract(p.data, '$.type') = 'compaction'`).all(id, sessionId);
13443
+ pairs.push(...rows);
13444
+ }
13445
+ if (pairs.length > 1)
13446
+ return { kind: "ambiguous" };
13447
+ if (pairs.length === 0) {
13448
+ for (const marker of recognized) {
13449
+ if (db.prepare(`SELECT 1 FROM message WHERE id = ?
13450
+ UNION ALL SELECT 1 FROM part WHERE id IN (?, ?) LIMIT 1`).get(marker.summaryMessageId, marker.compactionPartId, marker.summaryPartId))
13451
+ return { kind: "ambiguous" };
13452
+ }
13453
+ return { kind: "verified", marker: null };
13454
+ }
13455
+ const pair = pairs[0];
13456
+ const marker = recognized.find((item) => item.summaryMessageId === pair.summaryId && item.boundaryMessageId === pair.boundaryId && item.compactionPartId === pair.partId);
13457
+ if (!marker)
13458
+ return { kind: "ambiguous" };
13459
+ for (const other of recognized) {
13460
+ if (other.summaryMessageId === marker.summaryMessageId && other.compactionPartId === marker.compactionPartId && other.summaryPartId === marker.summaryPartId)
13461
+ continue;
13462
+ if (db.prepare(`SELECT 1 FROM message WHERE id = ?
13463
+ UNION ALL SELECT 1 FROM part WHERE id IN (?, ?) LIMIT 1`).get(other.summaryMessageId, other.compactionPartId, other.summaryPartId))
13464
+ return { kind: "ambiguous" };
13465
+ }
13466
+ const row = db.prepare(`SELECT c.data AS compactionData FROM message m
13467
+ JOIN message b ON b.id = ? AND b.session_id = m.session_id
13468
+ JOIN part c ON c.id = ? AND c.message_id = b.id AND c.session_id = m.session_id
13469
+ JOIN part t ON t.id = ? AND t.message_id = m.id AND t.session_id = m.session_id
13470
+ WHERE m.id = ? AND m.session_id = ?
13471
+ AND json_extract(b.data, '$.role') = 'user'
13472
+ AND json_extract(m.data, '$.role') = 'assistant'
13473
+ AND json_extract(m.data, '$.parentID') = b.id
13474
+ AND json_extract(m.data, '$.summary') = 1
13475
+ AND json_extract(m.data, '$.finish') = 'stop'
13476
+ AND json_extract(m.data, '$.error') IS NULL
13477
+ AND json_extract(m.data, '$.providerID') = 'magic-context'
13478
+ AND json_extract(m.data, '$.modelID') = 'magic-context'
13479
+ AND json_extract(t.data, '$.type') = 'text' AND json_extract(t.data, '$.text') = ?
13480
+ AND (SELECT COUNT(*) FROM part p WHERE p.message_id = m.id AND +p.session_id = m.session_id) = 1`).get(marker.boundaryMessageId, marker.compactionPartId, marker.summaryPartId, marker.summaryMessageId, sessionId, summaryText);
13481
+ if (!row || !isMcCanonicalCompactionPartData(JSON.parse(row.compactionData)) || findBoundaryUserMessage(sessionId, marker.boundaryMessageId)?.id !== marker.boundaryMessageId)
13482
+ return { kind: "ambiguous" };
13483
+ return { kind: "verified", marker };
13484
+ }
13370
13485
  var LEGACY_MARKER_LINEAGE_SQL = `SELECT m.id
13371
13486
  FROM message m
13372
13487
  WHERE +m.session_id = ? AND m.id IN (SELECT value FROM json_each(?)) AND m.id <> ?
@@ -13416,10 +13531,11 @@ function injectCompactionMarkerFromBasis(args, validatedBasis) {
13416
13531
  return null;
13417
13532
  }
13418
13533
  const boundaryTime = boundary.timeCreated;
13419
- const markerIdentity = `${args.sessionId}\x00${args.endMessageId}`;
13420
- const summaryMsgId = generateMessageId(boundaryTime + 1, 1n, `${markerIdentity}\x00summary-message`);
13421
- const compactionPartId = generatePartId(boundaryTime, 1n, `${markerIdentity}\x00compaction-part`);
13422
- const summaryPartId = generatePartId(boundaryTime + 1, 2n, `${markerIdentity}\x00summary-part`);
13534
+ const {
13535
+ summaryMessageId: summaryMsgId,
13536
+ compactionPartId,
13537
+ summaryPartId
13538
+ } = planCompactionMarker(args, boundary);
13423
13539
  const summaryMsgData = JSON.stringify({
13424
13540
  role: "assistant",
13425
13541
  parentID: boundary.id,
@@ -13579,10 +13695,12 @@ function listSessionCompactionMarkers(sessionId) {
13579
13695
  markers.sort((left, right) => left.timeCreated - right.timeCreated || left.compactionPartId.localeCompare(right.compactionPartId));
13580
13696
  return markers.map(({ timeCreated: _, ...marker }) => marker);
13581
13697
  }
13582
- function removeForeignCompactionMarker(sessionId, marker, protectedSummaryMessageId) {
13698
+ function removeForeignCompactionMarker(sessionId, marker, protectedSummaryMessageId, shouldRemove) {
13583
13699
  try {
13584
13700
  const db = getWritableOpenCodeDb("removal");
13585
13701
  runMarkerRemovalTransaction(db, () => {
13702
+ if (shouldRemove && !shouldRemove())
13703
+ return;
13586
13704
  const deletePartsOfMessage = db.prepare("DELETE FROM part WHERE +session_id = ? AND message_id = ?");
13587
13705
  const deleteMessage = db.prepare("DELETE FROM message WHERE session_id = ? AND id = ?");
13588
13706
  for (const summaryMessageId of marker.summaryMessageIds) {
@@ -13777,24 +13895,118 @@ function removeCompactionMarker(state) {
13777
13895
  }
13778
13896
  }
13779
13897
 
13780
- // src/hooks/magic-context/compaction-marker-manager.ts
13781
- var MARKER_SUMMARY_TEXT = "[Compacted by magic-context — session history is managed by the plugin]";
13782
- function dropMarkerSummaryTag(db, sessionId, summaryMessageId) {
13783
- const tagNumber = getTagNumberByMessageId2(db, sessionId, `${summaryMessageId}:p0`);
13784
- if (tagNumber !== null)
13785
- updateTagStatus2(db, sessionId, tagNumber, "dropped");
13898
+ // src/hooks/magic-context/compaction-marker-publication.ts
13899
+ function samePair(left, right) {
13900
+ return left.boundaryMessageId === right.boundaryMessageId && left.summaryMessageId === right.summaryMessageId && left.compactionPartId === right.compactionPartId && left.summaryPartId === right.summaryPartId;
13786
13901
  }
13787
- function persistMarkerStateAndDropReplacedTag(db, sessionId, state, replacedSummaryMessageId) {
13788
- let transactionStartedAt = 0;
13789
- db.transaction(() => {
13790
- transactionStartedAt = performance.now();
13791
- setPersistedCompactionMarkerState(db, sessionId, state);
13792
- if (replacedSummaryMessageId !== null) {
13793
- dropMarkerSummaryTag(db, sessionId, replacedSummaryMessageId);
13902
+ function publishRecoverableCompactionMarker(db, args, targetIsCurrent) {
13903
+ const { sessionId } = args;
13904
+ let raw = "";
13905
+ let previous = null;
13906
+ let oldSummary = null;
13907
+ let intended;
13908
+ let reason = "publication-failed";
13909
+ let recovered;
13910
+ let cut = "uncertain";
13911
+ let writingState = false;
13912
+ const persist = (state) => {
13913
+ writingState = true;
13914
+ db.transaction(() => {
13915
+ raw = compareAndSetCompactionMarkerPublicationState(db, sessionId, raw, state, null);
13916
+ if (previous && previous.summaryMessageId !== state.summaryMessageId) {
13917
+ const tag = getTagNumberByMessageId2(db, sessionId, `${previous.summaryMessageId}:p0`);
13918
+ if (tag !== null)
13919
+ updateTagStatus2(db, sessionId, tag, "dropped");
13920
+ }
13921
+ }).immediate();
13922
+ writingState = false;
13923
+ previous = state;
13924
+ };
13925
+ try {
13926
+ cut = getCompactionMarkerPublicationState(db, sessionId).pending ? "uncertain" : "definitely-no-cut";
13927
+ const result = withCompactionMarkerPublicationLock(() => {
13928
+ const snapshot = getCompactionMarkerPublicationState(db, sessionId);
13929
+ if (snapshot.pending)
13930
+ cut = "uncertain";
13931
+ raw = snapshot.raw;
13932
+ previous = getPersistedCompactionMarkerState(db, sessionId) ?? getDeferredClearedCompactionMarkerState(db, sessionId);
13933
+ oldSummary = previous?.summaryMessageId ?? null;
13934
+ if (snapshot.pending && (snapshot.pending.boundaryOrdinal > args.endOrdinal || snapshot.pending.boundaryOrdinal === args.endOrdinal && snapshot.pending.targetEndMessageId !== args.endMessageId) && !isCompactionMarkerIntentAbsent(snapshot.pending, snapshot.pending.targetEndMessageId))
13935
+ throw new Error("a newer marker publication intent is pending");
13936
+ const boundary = findBoundaryUserMessage(sessionId, args.endMessageId);
13937
+ if (!targetIsCurrent() || !boundary || boundary.id !== args.resolvedBoundary?.id || boundary.timeCreated !== args.resolvedBoundary.timeCreated)
13938
+ throw new Error("marker publication frontier changed before publication");
13939
+ intended = {
13940
+ ...planCompactionMarker(args, boundary),
13941
+ boundaryOrdinal: args.endOrdinal,
13942
+ targetEndMessageId: args.endMessageId
13943
+ };
13944
+ let pending = snapshot.pending;
13945
+ if (pending) {
13946
+ const pendingTarget = pending.targetEndMessageId;
13947
+ const pendingBoundary = pendingTarget ? findBoundaryUserMessage(sessionId, pendingTarget) : null;
13948
+ const compartments = pendingTarget ? getCompartmentsByEndMessageId(db, sessionId, pendingTarget) : [];
13949
+ const validTarget = pending.targetEndMessageId === args.endMessageId && pending.boundaryOrdinal === args.endOrdinal || compartments.length === 1 && compartments[0].endMessage === pending.boundaryOrdinal;
13950
+ if (!validTarget || !pendingBoundary || !pendingTarget || !samePair(pending, planCompactionMarker({ ...args, endMessageId: pendingTarget }, pendingBoundary)))
13951
+ pending = null;
13952
+ }
13953
+ const inspection = inspectCompactionMarkerPublication(sessionId, [intended, ...previous ? [previous] : [], ...pending ? [pending] : []], args.summaryText);
13954
+ if (inspection.kind === "deferred") {
13955
+ reason = "candidate-preparation";
13956
+ return {
13957
+ kind: cut === "uncertain" ? "uncertain" : "deferred",
13958
+ error: new Error("marker candidate preparation pending")
13959
+ };
13960
+ }
13961
+ if (inspection.kind === "ambiguous") {
13962
+ reason = "ambiguous-left-alone";
13963
+ return {
13964
+ kind: cut,
13965
+ error: new Error("unverified or ambiguous host marker pairs; left alone")
13966
+ };
13967
+ }
13968
+ cut = "definitely-no-cut";
13969
+ const host = inspection.marker;
13970
+ if (host && (pending && samePair(host, pending) || samePair(host, intended))) {
13971
+ const adopted = pending && samePair(host, pending) ? pending : intended;
13972
+ recovered = adopted === pending ? "pending-intent-recovered" : "adopted-existing-pair";
13973
+ cut = "uncertain";
13974
+ if (samePair(host, intended))
13975
+ return { kind: "committed", marker: host };
13976
+ persist(adopted);
13977
+ }
13978
+ writingState = true;
13979
+ raw = compareAndSetCompactionMarkerPublicationState(db, sessionId, raw, previous, intended);
13980
+ writingState = false;
13981
+ cut = "uncertain";
13982
+ const replacement = replaceCompactionMarker(host, {
13983
+ ...args,
13984
+ resolvedBoundary: boundary
13985
+ });
13986
+ if (recovered && replacement.kind !== "committed")
13987
+ return { kind: "uncertain", error: replacement.error };
13988
+ if (replacement.kind !== "committed")
13989
+ cut = replacement.kind === "uncertain" ? "uncertain" : "definitely-no-cut";
13990
+ return replacement;
13991
+ });
13992
+ if (result.kind === "committed") {
13993
+ if (!intended)
13994
+ throw new Error("committed marker has no publication intent");
13995
+ persist(intended);
13996
+ reason = recovered ?? "published";
13794
13997
  }
13795
- }).immediate();
13796
- logSlowWriteTransaction("marker-drain", transactionStartedAt);
13998
+ return result;
13999
+ } catch (error) {
14000
+ if (writingState)
14001
+ reason = "state-write-failed";
14002
+ return { kind: cut, error: error instanceof Error ? error : new Error(String(error)) };
14003
+ } finally {
14004
+ sessionLog2(sessionId, `compaction-marker publication reason=${reason} oldSummary=${oldSummary ?? "none"} newSummary=${intended?.summaryMessageId ?? "none"} target=${args.endMessageId} at=${Date.now()}`);
14005
+ }
13797
14006
  }
14007
+
14008
+ // src/hooks/magic-context/compaction-marker-manager.ts
14009
+ var MARKER_SUMMARY_TEXT = "[Compacted by magic-context — session history is managed by the plugin]";
13798
14010
  function markerUpdateDefinitelyDidNotCut(outcome) {
13799
14011
  return outcome.kind === "already-current" || outcome.kind === "deferred" || outcome.kind === "stale-skip" || outcome.kind === "retryable-failure" && outcome.cut === "definitely-no-cut";
13800
14012
  }
@@ -13863,7 +14075,7 @@ function boundaryWouldDiscardUncoveredMessage(db, sessionId, ordinal, boundaryMe
13863
14075
  return false;
13864
14076
  }
13865
14077
  function applyDeferredCompactionMarker(db, sessionId, pending, directory, trustedBoundary) {
13866
- let cut = "definitely-no-cut";
14078
+ let cut = "uncertain";
13867
14079
  let stepStartedAt = performance.now();
13868
14080
  const stepMs = [];
13869
14081
  const endStep = (name) => {
@@ -13872,41 +14084,61 @@ function applyDeferredCompactionMarker(db, sessionId, pending, directory, truste
13872
14084
  stepStartedAt = now;
13873
14085
  };
13874
14086
  try {
14087
+ cut = getCompactionMarkerPublicationState(db, sessionId).pending ? "uncertain" : "definitely-no-cut";
14088
+ const unresolvedIntentFailure = () => {
14089
+ const alreadyUncertain = cut === "uncertain";
14090
+ cut = "uncertain";
14091
+ if (getCompactionMarkerPublicationState(db, sessionId).pending || alreadyUncertain) {
14092
+ return {
14093
+ kind: "retryable-failure",
14094
+ cut,
14095
+ error: new Error("unresolved marker publication intent; retaining retry state")
14096
+ };
14097
+ }
14098
+ cut = "definitely-no-cut";
14099
+ return null;
14100
+ };
13875
14101
  const responseFencesTarget = trustedBoundary !== undefined && Number.isSafeInteger(trustedBoundary.rowVersion) && trustedBoundary.rowVersion > 0 && trustedBoundary.ordinal === pending.ordinal && trustedBoundary.endMessageId === pending.endMessageId;
13876
14102
  const validation = responseFencesTarget ? "ok" : validatePendingTarget(db, sessionId, pending);
13877
14103
  endStep("validate");
13878
14104
  if (validation !== "ok") {
14105
+ const unresolved = unresolvedIntentFailure();
14106
+ if (unresolved)
14107
+ return unresolved;
13879
14108
  sessionLog2(sessionId, `compaction-marker drain: stale-skip (${validation}) for ordinal ${pending.ordinal} endMessageId=${pending.endMessageId}`);
13880
14109
  return { kind: "stale-skip", reason: validation };
13881
14110
  }
13882
14111
  const existing = getPersistedCompactionMarkerState(db, sessionId);
13883
14112
  if (existing && existingMarkerAlreadyCoversTarget(sessionId, existing, pending.ordinal, pending.endMessageId)) {
13884
- return { kind: "already-current" };
14113
+ if (!unresolvedIntentFailure())
14114
+ return { kind: "already-current" };
13885
14115
  }
13886
14116
  const boundary = findBoundaryUserMessage(sessionId, pending.endMessageId);
13887
14117
  endStep("boundary");
13888
14118
  if (!boundary) {
13889
- return {
14119
+ return unresolvedIntentFailure() ?? {
13890
14120
  kind: "retryable-failure",
13891
14121
  cut: "definitely-no-cut",
13892
14122
  error: new Error(`no user boundary found at or before endMessageId ${pending.endMessageId} (ordinal ${pending.ordinal}); preserving existing marker`)
13893
14123
  };
13894
14124
  }
13895
14125
  if (boundaryWouldDiscardUncoveredMessage(db, sessionId, pending.ordinal, boundary.id)) {
14126
+ const unresolved = unresolvedIntentFailure();
14127
+ if (unresolved)
14128
+ return unresolved;
13896
14129
  sessionLog2(sessionId, `compaction-marker drain: stale-skip (partial-message-boundary) for ordinal ${pending.ordinal} endMessageId=${pending.endMessageId}`);
13897
14130
  return { kind: "stale-skip", reason: "partial-message-boundary" };
13898
14131
  }
13899
14132
  endStep("discardCheck");
13900
- const removedSummaryMessageId = existing?.summaryMessageId ?? null;
13901
14133
  cut = "uncertain";
13902
- const replacement = replaceCompactionMarker(existing, {
14134
+ const replacement = publishRecoverableCompactionMarker(db, {
13903
14135
  sessionId,
13904
14136
  endOrdinal: pending.ordinal,
13905
14137
  endMessageId: pending.endMessageId,
13906
14138
  summaryText: MARKER_SUMMARY_TEXT,
13907
14139
  directory: directory ?? process.cwd(),
13908
14140
  resolvedBoundary: boundary
13909
- });
14141
+ }, () => JSON.stringify(getPersistedCompactionMarkerState(db, sessionId)) === JSON.stringify(existing) && (responseFencesTarget || validatePendingTarget(db, sessionId, pending) === "ok"));
13910
14142
  endStep("replace");
13911
14143
  if (replacement.kind === "deferred")
13912
14144
  return { kind: "deferred", reason: "candidate-preparation" };
@@ -13917,14 +14149,8 @@ function applyDeferredCompactionMarker(db, sessionId, pending, directory, truste
13917
14149
  error: replacement.error
13918
14150
  };
13919
14151
  }
13920
- const result = replacement.marker;
13921
- persistMarkerStateAndDropReplacedTag(db, sessionId, {
13922
- ...result,
13923
- boundaryOrdinal: pending.ordinal,
13924
- targetEndMessageId: pending.endMessageId
13925
- }, removedSummaryMessageId);
13926
14152
  endStep("persist");
13927
- sessionLog2(sessionId, `compaction-marker drain: applied at ordinal ${pending.ordinal}, boundary user msg ${result.boundaryMessageId} ${stepMs.join(" ")}`);
14153
+ sessionLog2(sessionId, `compaction-marker drain: applied at ordinal ${pending.ordinal}, boundary user msg ${replacement.marker.boundaryMessageId} ${stepMs.join(" ")}`);
13928
14154
  return {
13929
14155
  kind: "applied",
13930
14156
  markerOrdinal: pending.ordinal
@@ -13945,8 +14171,7 @@ function updateCompactionMarkerAfterPublication(db, sessionId, lastCompartmentEn
13945
14171
  return false;
13946
14172
  }
13947
14173
  const existing = getPersistedCompactionMarkerState(db, sessionId);
13948
- const removedSummaryMessageId = existing?.summaryMessageId ?? null;
13949
- if (existing) {
14174
+ if (existing && !getCompactionMarkerPublicationState(db, sessionId).pending) {
13950
14175
  if (existingMarkerAlreadyCoversTarget(sessionId, existing, lastCompartmentEnd, targetEndMessageId)) {
13951
14176
  return true;
13952
14177
  }
@@ -13959,22 +14184,15 @@ function updateCompactionMarkerAfterPublication(db, sessionId, lastCompartmentEn
13959
14184
  if (boundaryWouldDiscardUncoveredMessage(db, sessionId, lastCompartmentEnd, boundary.id)) {
13960
14185
  return false;
13961
14186
  }
13962
- const replacement = replaceCompactionMarker(existing, {
14187
+ const replacement = publishRecoverableCompactionMarker(db, {
13963
14188
  sessionId,
13964
14189
  endOrdinal: lastCompartmentEnd,
13965
14190
  endMessageId: targetEndMessageId,
13966
14191
  summaryText: MARKER_SUMMARY_TEXT,
13967
14192
  directory: directory ?? process.cwd(),
13968
14193
  resolvedBoundary: boundary
13969
- });
14194
+ }, () => JSON.stringify(getPersistedCompactionMarkerState(db, sessionId)) === JSON.stringify(existing) && getCompartmentEndMessageIdForOrdinal(db, sessionId, lastCompartmentEnd) === targetEndMessageId);
13970
14195
  if (replacement.kind === "committed") {
13971
- const result = replacement.marker;
13972
- persistMarkerStateAndDropReplacedTag(db, sessionId, {
13973
- ...result,
13974
- boundaryOrdinal: lastCompartmentEnd,
13975
- targetEndMessageId
13976
- }, removedSummaryMessageId);
13977
- sessionLog2(sessionId, `compaction-marker: injected at ordinal ${lastCompartmentEnd}, boundary user msg ${result.boundaryMessageId}`);
13978
14196
  return true;
13979
14197
  }
13980
14198
  return false;
@@ -13992,13 +14210,13 @@ function removeCompactionMarkerForSession(db, sessionId) {
13992
14210
  }
13993
14211
  }
13994
14212
  }
13995
- function reconcileForkOrphanedCompactionMarkers(db, sessionId) {
13996
- if (getHarness2() !== "opencode") {
14213
+ function reconcileForkOrphanedCompactionMarkers(db, sessionId, isCacheBusting) {
14214
+ if (!isCacheBusting || getHarness2() !== "opencode") {
13997
14215
  return { removed: 0, failed: false };
13998
14216
  }
13999
14217
  try {
14000
14218
  const owned = getPersistedCompactionMarkerState(db, sessionId);
14001
- if (!owned) {
14219
+ if (!owned || getCompactionMarkerPublicationState(db, sessionId).pending) {
14002
14220
  return { removed: 0, failed: false };
14003
14221
  }
14004
14222
  const markers = listSessionCompactionMarkers(sessionId);
@@ -14019,7 +14237,15 @@ function reconcileForkOrphanedCompactionMarkers(db, sessionId) {
14019
14237
  if (!currentOwned || marker.compactionPartId === currentOwned.compactionPartId) {
14020
14238
  continue;
14021
14239
  }
14022
- const ok = removeForeignCompactionMarker(sessionId, marker, currentOwned.summaryMessageId);
14240
+ let protectedByState = false;
14241
+ const ok = removeForeignCompactionMarker(sessionId, marker, currentOwned.summaryMessageId, () => db.transaction(() => {
14242
+ const publication = getCompactionMarkerPublicationState(db, sessionId);
14243
+ const latestOwned = getPersistedCompactionMarkerState(db, sessionId);
14244
+ protectedByState = Boolean(publication.pending || !latestOwned || marker.compactionPartId === latestOwned.compactionPartId || marker.summaryMessageIds.includes(latestOwned.summaryMessageId) || compareOpenCodeMessagesByCanonicalOrder(sessionId, marker.boundaryMessageId, latestOwned.boundaryMessageId) !== 1);
14245
+ return !protectedByState;
14246
+ }).deferred());
14247
+ if (protectedByState)
14248
+ continue;
14023
14249
  if (ok) {
14024
14250
  removed += 1;
14025
14251
  sessionLog2(sessionId, `compaction-marker hygiene: removed fork-orphaned marker part=${marker.compactionPartId} boundary=${marker.boundaryMessageId} (outranked owned boundary ${currentOwned.boundaryMessageId})`);
@@ -14090,6 +14316,7 @@ var MURAL_COMPONENT_PREFIX = "|mural-enabled:";
14090
14316
  var BUDGET_COMPONENT_PREFIX = "|render-budgets:";
14091
14317
  var RENDERED_BUDGETS_COMPONENT_PREFIX = "|rendered-budgets:";
14092
14318
  var M0_MEMORY_IDS_COMPONENT_PREFIX = "|m0-memory-ids:";
14319
+ var TOOL_DEFINITIONS_COMPONENT_PREFIX = "|request-tool-definitions:";
14093
14320
  function encodeCachedM0UpgradeIdentity(upgradeState, compartmentRenderEpoch = COMPARTMENT_RENDER_EPOCH, muralEnabled = null, renderBudgetIdentity = null, memoryRenderEpoch = MEMORY_RENDER_FORMAT_EPOCH, renderedBudgets = null) {
14094
14321
  let encoded = upgradeState ?? "";
14095
14322
  if (compartmentRenderEpoch !== null) {
@@ -14135,7 +14362,8 @@ function decodeCachedM0UpgradeIdentity(value) {
14135
14362
  value.indexOf(MURAL_COMPONENT_PREFIX),
14136
14363
  value.indexOf(BUDGET_COMPONENT_PREFIX),
14137
14364
  value.indexOf(RENDERED_BUDGETS_COMPONENT_PREFIX),
14138
- value.indexOf(M0_MEMORY_IDS_COMPONENT_PREFIX)
14365
+ value.indexOf(M0_MEMORY_IDS_COMPONENT_PREFIX),
14366
+ value.indexOf(TOOL_DEFINITIONS_COMPONENT_PREFIX)
14139
14367
  ].filter((index) => index >= 0);
14140
14368
  const identityEnd = componentIndexes.length > 0 ? Math.min(...componentIndexes) : value.length;
14141
14369
  const upgradeState = value.slice(0, identityEnd);
@@ -14153,6 +14381,22 @@ function withCachedM0MemoryIds(identity, ids) {
14153
14381
  const withoutIds = (identity ?? "").replace(/\|m0-memory-ids:[^|]*/g, "");
14154
14382
  return `${withoutIds}${M0_MEMORY_IDS_COMPONENT_PREFIX}${JSON.stringify(ids)}`;
14155
14383
  }
14384
+ function withCachedM0ToolDefinitionsHash(identity, hash) {
14385
+ const withoutHash = (identity ?? "").replace(/\|request-tool-definitions:[^|]*/g, "");
14386
+ if (hash === null)
14387
+ return withoutHash || null;
14388
+ return `${withoutHash}${TOOL_DEFINITIONS_COMPONENT_PREFIX}${encodeURIComponent(hash)}`;
14389
+ }
14390
+ function readCachedM0ToolDefinitionsHash(identity) {
14391
+ const encoded = component(identity ?? "", TOOL_DEFINITIONS_COMPONENT_PREFIX);
14392
+ if (!encoded)
14393
+ return null;
14394
+ try {
14395
+ return decodeURIComponent(encoded) || null;
14396
+ } catch {
14397
+ return null;
14398
+ }
14399
+ }
14156
14400
  function readCachedM0MemoryIds(identity, legacyVisibleIds, maxMemoryId) {
14157
14401
  const encoded = component(identity ?? "", M0_MEMORY_IDS_COMPONENT_PREFIX);
14158
14402
  if (encoded !== null) {
@@ -14846,8 +15090,8 @@ function prepareCompartmentInjection(db, sessionId, messages, isCacheBusting, co
14846
15090
  resultEndMessageId = trimEndMessageId;
14847
15091
  } else {
14848
15092
  const degradedCount = noteDegradedRebuild(sessionId);
14849
- if (degradedCount === 1) {
14850
- reconcileForkOrphanedCompactionMarkers(db, sessionId);
15093
+ if (isCacheBusting) {
15094
+ reconcileForkOrphanedCompactionMarkers(db, sessionId, isCacheBusting);
14851
15095
  }
14852
15096
  let reAnchored = false;
14853
15097
  if (degradedCount >= REANCHOR_MIN_DEGRADED_PASSES && isCacheBusting) {
@@ -15249,6 +15493,7 @@ function readCurrentM0SnapshotMarkersUncached(args) {
15249
15493
  memoryRenderEpoch: MEMORY_RENDER_FORMAT_EPOCH,
15250
15494
  systemHash: hard.systemHash,
15251
15495
  toolSetHash: hard.toolSetHash ?? "",
15496
+ toolDefinitionsHash: hard.toolDefinitionsHash ?? null,
15252
15497
  modelKey: piModelRefToCanonical(hard.modelKey),
15253
15498
  projectIdentity: args.projectPath ?? null,
15254
15499
  muralEnabled: args.memoryEnabled !== false && args.muralEnabled === true,
@@ -15264,6 +15509,7 @@ function refreshVolatileMarkerInputs(markers, args) {
15264
15509
  materializedAt: Date.now(),
15265
15510
  systemHash: hard.systemHash,
15266
15511
  toolSetHash: hard.toolSetHash ?? "",
15512
+ toolDefinitionsHash: hard.toolDefinitionsHash ?? null,
15267
15513
  modelKey: hard.modelKey,
15268
15514
  projectIdentity: args.projectPath ?? null,
15269
15515
  muralEnabled: args.memoryEnabled !== false && args.muralEnabled === true,
@@ -15334,6 +15580,7 @@ function snapshotMarkersFromCachedM0(state) {
15334
15580
  memoryRenderEpoch: cachedUpgradeIdentity.memoryRenderEpoch,
15335
15581
  systemHash: state.cachedM0SystemHash ?? "",
15336
15582
  toolSetHash: state.cachedM0ToolSetHash ?? "",
15583
+ toolDefinitionsHash: readCachedM0ToolDefinitionsHash(state.cachedM0UpgradeState),
15337
15584
  modelKey: state.cachedM0ModelKey ?? "",
15338
15585
  projectIdentity: state.cachedM0ProjectIdentity ?? null,
15339
15586
  muralHash: state.cachedM0MuralHash ?? null,
@@ -15394,6 +15641,23 @@ function mustMaterialize(args) {
15394
15641
  systemHashNew: hard.systemHash
15395
15642
  };
15396
15643
  }
15644
+ const liveDefinitionsHash = hard.toolDefinitionsHash;
15645
+ if (liveDefinitionsHash) {
15646
+ const cachedDefinitionsHash = readCachedM0ToolDefinitionsHash(args.state.cachedM0UpgradeState);
15647
+ if (!cachedDefinitionsHash || needsRequestToolIdentityAdoption(cachedDefinitionsHash, liveDefinitionsHash)) {
15648
+ const previousIdentity = args.state.cachedM0UpgradeState;
15649
+ const adoptedIdentity = withCachedM0ToolDefinitionsHash(previousIdentity, liveDefinitionsHash);
15650
+ const adopted = args.db.prepare("UPDATE session_meta SET cached_m0_upgrade_state = ? WHERE session_id = ? AND cached_m0_upgrade_state IS ?").run(adoptedIdentity, args.sessionId, previousIdentity);
15651
+ if (adopted.changes > 0)
15652
+ args.state.cachedM0UpgradeState = adoptedIdentity;
15653
+ } else if (cachedDefinitionsHash !== liveDefinitionsHash) {
15654
+ return {
15655
+ value: true,
15656
+ reason: "tool_definitions",
15657
+ toolDefinitionsChange: describeRequestToolDefinitionChange(cachedDefinitionsHash, liveDefinitionsHash)
15658
+ };
15659
+ }
15660
+ }
15397
15661
  const liveToolSetHash = hard.toolSetHash ?? "";
15398
15662
  const toolSetHashComparison = liveToolSetHash !== "" ? {
15399
15663
  m0ToolSetHashPrev: args.state.cachedM0ToolSetHash,
@@ -15727,7 +15991,7 @@ function applyMarkersToState(state, m0Bytes, markers, m1Bytes, renderedM0Ids) {
15727
15991
  state.cachedM0ProjectDocsHash = markers.projectDocsHash;
15728
15992
  state.cachedM0MaterializedAt = markers.materializedAt;
15729
15993
  state.cachedM0SessionFactsVersion = markers.sessionFactsVersion;
15730
- state.cachedM0UpgradeState = withCachedM0MemoryIds(encodeCachedM0UpgradeIdentity(markers.upgradeState, markers.compartmentRenderEpoch, markers.muralEnabled, markers.renderBudgetIdentity, markers.memoryRenderEpoch, markers.renderedBudgets ?? null), renderedM0Ids);
15994
+ state.cachedM0UpgradeState = withCachedM0ToolDefinitionsHash(withCachedM0MemoryIds(encodeCachedM0UpgradeIdentity(markers.upgradeState, markers.compartmentRenderEpoch, markers.muralEnabled, markers.renderBudgetIdentity, markers.memoryRenderEpoch, markers.renderedBudgets ?? null), renderedM0Ids), markers.toolDefinitionsHash ?? null);
15731
15995
  state.cachedM0SystemHash = markers.systemHash;
15732
15996
  state.cachedM0ToolSetHash = markers.toolSetHash;
15733
15997
  state.cachedM0ModelKey = markers.modelKey;
@@ -15852,7 +16116,7 @@ function materializeM0(options) {
15852
16116
  const renderedMemoryIds = trimmed.renderOrder.map((m) => m.id);
15853
16117
  options.beforePhase3ForTest?.();
15854
16118
  const steps = new WriteTransactionSteps;
15855
- const upgradeIdentity = withCachedM0MemoryIds(encodeCachedM0UpgradeIdentity(snapshotMarkers.upgradeState, snapshotMarkers.compartmentRenderEpoch, snapshotMarkers.muralEnabled, snapshotMarkers.renderBudgetIdentity, snapshotMarkers.memoryRenderEpoch, snapshotMarkers.renderedBudgets ?? null), renderedMemoryIds);
16119
+ const upgradeIdentity = withCachedM0ToolDefinitionsHash(withCachedM0MemoryIds(encodeCachedM0UpgradeIdentity(snapshotMarkers.upgradeState, snapshotMarkers.compartmentRenderEpoch, snapshotMarkers.muralEnabled, snapshotMarkers.renderBudgetIdentity, snapshotMarkers.memoryRenderEpoch, snapshotMarkers.renderedBudgets ?? null), renderedMemoryIds), snapshotMarkers.toolDefinitionsHash ?? null);
15856
16120
  const baselineEndMessageId = lastCompartmentBoundaryId(compartments);
15857
16121
  steps.mark("pre_metadata");
15858
16122
  const commitFold = options.onFoldPrepare?.();
@@ -15885,6 +16149,7 @@ function materializeM0(options) {
15885
16149
  memoryRenderEpoch: MEMORY_RENDER_FORMAT_EPOCH,
15886
16150
  systemHash: snapshotMarkers.systemHash,
15887
16151
  toolSetHash: snapshotMarkers.toolSetHash,
16152
+ toolDefinitionsHash: snapshotMarkers.toolDefinitionsHash,
15888
16153
  modelKey: snapshotMarkers.modelKey,
15889
16154
  projectIdentity: projectPath ?? null,
15890
16155
  muralEnabled: snapshotMarkers.muralEnabled,
@@ -16142,7 +16407,7 @@ function readCachedM0M1Row(db, sessionId) {
16142
16407
  cached_m0_session_facts_version,
16143
16408
  cached_m0_upgrade_state,
16144
16409
  cached_m0_system_hash,
16145
- cached_m0_tool_set_hash,
16410
+ cached_m0_tool_set_hash,
16146
16411
  cached_m0_model_key,
16147
16412
  cached_m0_project_identity,
16148
16413
  cached_m0_last_baseline_end_message_id,
@@ -16184,6 +16449,7 @@ function markersFromCachedRow(row) {
16184
16449
  memoryRenderEpoch: cachedUpgradeIdentity.memoryRenderEpoch,
16185
16450
  systemHash: row.cached_m0_system_hash ?? "",
16186
16451
  toolSetHash: row.cached_m0_tool_set_hash ?? "",
16452
+ toolDefinitionsHash: readCachedM0ToolDefinitionsHash(row.cached_m0_upgrade_state),
16187
16453
  modelKey: row.cached_m0_model_key ?? "",
16188
16454
  projectIdentity: row.cached_m0_project_identity ?? null,
16189
16455
  muralHash: row.cached_m0_mural_hash ?? null,
@@ -16214,7 +16480,7 @@ function applyCachedRowToState(state, row) {
16214
16480
  state.cachedM0ProjectDocsHash = markers.projectDocsHash;
16215
16481
  state.cachedM0MaterializedAt = markers.materializedAt;
16216
16482
  state.cachedM0SessionFactsVersion = markers.sessionFactsVersion;
16217
- state.cachedM0UpgradeState = encodeCachedM0UpgradeIdentity(markers.upgradeState, markers.compartmentRenderEpoch, markers.muralEnabled, markers.renderBudgetIdentity, markers.memoryRenderEpoch, markers.renderedBudgets ?? null);
16483
+ state.cachedM0UpgradeState = withCachedM0ToolDefinitionsHash(encodeCachedM0UpgradeIdentity(markers.upgradeState, markers.compartmentRenderEpoch, markers.muralEnabled, markers.renderBudgetIdentity, markers.memoryRenderEpoch, markers.renderedBudgets ?? null), markers.toolDefinitionsHash ?? null);
16218
16484
  state.cachedM0SystemHash = markers.systemHash;
16219
16485
  state.cachedM0ToolSetHash = markers.toolSetHash;
16220
16486
  state.cachedM0ModelKey = markers.modelKey;
@@ -23374,4 +23640,4 @@ async function executeContextRecomp(deps, options = {}) {
23374
23640
  return (await executeContextRecompWithResult(deps, options)).message;
23375
23641
  }
23376
23642
 
23377
- export { denyTaskRoutingToCallerAgents, buildHiddenAgentRegistrations, buildZenReadAgentRegistrations, buildHiddenAgentConfig, getMagicContextBuiltinCommands, formatConfigParseStatusLine, claimConfigParseFailuresOnce, isCommitRetentionPaused, cortexKitUserConfigBasePath, cortexKitProjectConfigBasePath, resolveLegacyConfigSources, migrateMagicContextConfigLocations, getProtectedTokensTierOverrides, loadPluginConfigDetailed, historianRunConfig, dreamerRunConfig, pluginConfigReader, currentPluginConfigReader, withLiveDreamerOutputCap, createDreamerOutputCapSampler, advanceSessionActivity, observeSessionActivity, backfillSessionActivity, COMPARTMENT_AGENT_SYSTEM_PROMPT, HISTORIAN_EDITOR_SYSTEM_PROMPT, COMPARTMENT_STRUCTURAL_SYSTEM_PROMPT, clampProducerAtomChars, producerInputTokenLimit, historianProducerReserve, producerPromptFailureReason, DREAMER_AGENT, DREAMER_RETROSPECTIVE_AGENT, DREAMER_PRIMER_INVESTIGATOR_AGENT, DREAMER_MEMORY_MAPPER_AGENT, DREAMER_CLASSIFIER_AGENT, DREAMER_DOCS_AGENT, DREAMER_REVIEWER_AGENT, COMPARTMENT_LEASE_RENEWAL_MS, acquireCompartmentLease, renewCompartmentLease, releaseCompartmentLeaseBestEffort, isCompartmentLeaseHeld, queueM0Mutation, getMaxM0MutationId, getCompartments, getLastCompartmentEndMessage, getLastCompartmentEndMessageId, getUncoveredCompartmentEndsThrough, providerResponseFailed, isSuccessfulProviderCompletion, LkgRecoveryFenceError, lkgServedArrayDigest, hasCleanLkgRecoveryFence, dirtyLkgRecoveryRevision, ownsLkgDirtyFence, invalidateCleanLkgRecoveryFence, prepareLkgCaptureFence, certifyCommittedLkgCapture, markLkgRecoveryDirty, rememberUnpublishedAutoSearchNoHint, getUnpublishedAutoSearchNoHint, forgetUnpublishedAutoSearchNoHint, registerAutoSearchWork, cancelAutoSearchWork, gaDatabasePath, RAW_MESSAGE_TYPES, V2StoreReaderPool, V2StoreReader, getOrCreateSessionMeta, updateSessionMeta, advanceToolReclaimWatermark, markSessionCleanupPending, retryPendingSessionCleanups, retryPendingRustSessionCleanupsForProject, clearSession, requestPendingMaterialization, pendingMaterializationOrigin, hasPendingMaterializationOrigin, clearPendingMaterialization, recordSystemPromptForRequest, recordHeldHeadForRequest, bindSystemPromptResponse, isHeldHeadForRequest, deferDeliveredSystemRefresh, retirePendingSystemPromptDelivery, lkgProviderInputTotal, beginV2LkgRequest, claimLkgRequestIdentity, currentLkgRequestIdentity, noteCapturedLkgRequest, noteLkgProviderResponse, measuredLkgPrefix, clearLkgMeasuredRequest, saveLkgSlotToDb, clearPersistedLkgSlotStrict, loadPersistedLkgSlot, drainStaleLkgSlots, createDbLkgPersistence, resolveLkgModelKeys, createLkgEntryProjector, captureLkgSlot, validateAnthropicReasoningRuns, validateLkgSeam, replayLkg, coldStartRawServedIndex, coldStartUncapturedReplay, noteUncertifiedNormalLkg, hasProcessLocalLkgProof, lkgDirtyRevision, rememberLkgDirtyRevision, readPersistedLkgUntaggedInputIds, persistLkgUntaggedInputIds, noteLkgRecoveryPrefix, readLkgRecoveryPrefix, noteLkgHealthyPrefix, lkgRecoveryReplayUnproven, lkgRecoveryEntryUnproven, lkgInputIdentity, registerLkgPersistence, beginLkgPass, visitMessageContentFields, contentSnapshotValue, messageContentFields, signatureForFields, exactReusablePrefix, incrementalLkgContentDigests, lkgSlotRejection, captureSlot, getInMemorySlot, getSlot, forgetInMemorySlot, dropSlot, noteEntry, getLkgSlotHeapStats, TOOL_SWEEP_SCOPED_MARKER, useScopedToolSweep, createPreAdoptionToolSweepResolver, copySessionStateForClone, queueMemoryMutation, getMaxMemoryMutationIdForProjects, GLOBAL_USER_PROFILE_PROJECT_PATH, getProjectState, bumpProjectUserProfileVersion, saveSourceContent, replaceSourceContent, getSourceContents, createChildSessionWithFence, HiddenCompletionRefusal, DreamerProviderOutputFailureError, withDreamerModelCooldown, providerOutputFailureFromInvalidManifest, HIDDEN_HISTORIAN_AGENT, HIDDEN_DREAMER_AGENT, HIDDEN_CURATE_AGENT, hiddenAgentFor, hiddenToolLoop, HIDDEN_RUN_DISPOSED_REASON, noteChildOfDisposedInstance, hiddenChildPermissions, registerHiddenChildAgents, hiddenToolCallRefusal, HiddenAgentStepLimit, HiddenChildHook, extractLatestAssistantText, hasLengthCappedOutput, parseProviderModel, modelBodyField, toModelEntry, ModelProducedNoOutputError, noteModelActivityMonitored, noteModelOutputReceived, isPromptTimeoutError, getPromptFailureDetail, raceWithSignal, promptSyncWithValidatedOutputRetry, normalizeSDKResponse, annotateSubagentInvocationError, failedInvocationStatus, emptyTokenTotals, sumTokensFromChildMessages, recordChildInvocation, recordPromptSessionError, createPromptAsyncTransport, CTX_NOTE_LIGHT_DESCRIPTION, ACTIVE_TOOL_IDS, systemPromptFingerprint, createPromptSurfaceRuntime, createPromptSurfaceGuidanceEpochCache, setKeepSubagents, teardownChildSession, getCompartmentEvents, runTokenLog, formatRunTokenLog, buildMagicContextSection, getMuralIdentity, getMural, modelKeyAcceptsImages, resolveMuralWire, USER_MEMORY_CANDIDATE_TTL_MS, insertUserMemoryCandidates, getUserMemoryCandidates, deleteUserMemoryCandidates, pruneExpiredUserMemoryCandidates, insertUserMemory, getActiveUserMemories, updateUserMemoryContent, dismissUserMemory, getOpenCodeDbPath, compareOpenCodeMessagesByCanonicalOrder, prepareCompactionMarkerCandidates, removeMcOwnedCompactionMarkers, MARKER_SUMMARY_TEXT, markerUpdateDefinitelyDidNotCut, applyDeferredCompactionMarker, removeCompactionMarkerForSession, checkCompactionMarkerConsistency, extractM0Block, formatDate, TEMPORAL_MARKER_REPLAY_PATTERN, collectTemporalCandidates, injectTemporalMarkers, clearInjectionCache, getVisibleMemoryIds, selectHiddenMessagesAtCompactionSeam, prepareCompartmentInjection, renderCompartmentInjection, MaterializeContentionError, mustMaterialize, trimMemoriesToBudgetV2, renderMemoryBlockV2, materializeM0, hydrateCachedM0Mural, resetPrefixTrimFallbackState, findHostCompactionWindow, capturePrefixTrimSourceOrder, prepareCachedM0M1Replay, hasCompleteCachedM0M1, injectM0M1, resolveHiddenCompletionExecutor, createV1HiddenCompletionExecutor, readCoordinateGeneration, readCoordinateRebaseNotice, formatCoordinateRebaseNotice, rebaseSessionCoordinatesAsync, shouldWaitForNewHistorianHistory, EMPTY_READ_REPLY, noteTouchedAt, renderGlance, renderNotesById, formatWriteReply, observeNoteNudgeServe, onNoteTrigger, peekNoteNudgeText, markNoteNudgeDelivered, clearNoteNudgeTriggerAndCooldown, resetNoteNudgeCooldownOnly, clearNoteNudgeTriggerOnly, omitIncompleteFileTokenTotals, describeBoundaryDiagnostics, RECOVERY_NO_HEAD_LIMIT, deriveProtectedTailTokenTarget, selectPerRunCap, resolveOpenCodeProtectedTailBoundary, resolveWrapupProtectedTailBoundary, getRawHistoryEligibility, hasRunnableCompartmentWindow, recordHighPressureNoEligibleHead, noteTransformPassForExactOrdinalReads, runCompartmentAgent, snapRangeToCompartments, getActiveCompartmentRun, markActiveCompartmentRunPublished, registerActiveCompartmentRun, startCompartmentAgent, executeContextRecomp };
23643
+ export { denyTaskRoutingToCallerAgents, buildHiddenAgentRegistrations, buildZenReadAgentRegistrations, buildHiddenAgentConfig, getMagicContextBuiltinCommands, formatConfigParseStatusLine, claimConfigParseFailuresOnce, isCommitRetentionPaused, cortexKitUserConfigBasePath, cortexKitProjectConfigBasePath, resolveLegacyConfigSources, migrateMagicContextConfigLocations, getProtectedTokensTierOverrides, loadPluginConfigDetailed, historianRunConfig, dreamerRunConfig, pluginConfigReader, currentPluginConfigReader, withLiveDreamerOutputCap, createDreamerOutputCapSampler, advanceSessionActivity, observeSessionActivity, backfillSessionActivity, COMPARTMENT_AGENT_SYSTEM_PROMPT, HISTORIAN_EDITOR_SYSTEM_PROMPT, COMPARTMENT_STRUCTURAL_SYSTEM_PROMPT, clampProducerAtomChars, producerInputTokenLimit, historianProducerReserve, producerPromptFailureReason, DREAMER_AGENT, DREAMER_RETROSPECTIVE_AGENT, DREAMER_PRIMER_INVESTIGATOR_AGENT, DREAMER_MEMORY_MAPPER_AGENT, DREAMER_CLASSIFIER_AGENT, DREAMER_DOCS_AGENT, DREAMER_REVIEWER_AGENT, COMPARTMENT_LEASE_RENEWAL_MS, acquireCompartmentLease, renewCompartmentLease, releaseCompartmentLeaseBestEffort, isCompartmentLeaseHeld, queueM0Mutation, getMaxM0MutationId, getCompartments, getLastCompartmentEndMessage, getLastCompartmentEndMessageId, getUncoveredCompartmentEndsThrough, providerResponseFailed, isSuccessfulProviderCompletion, LkgRecoveryFenceError, lkgServedArrayDigest, hasCleanLkgRecoveryFence, dirtyLkgRecoveryRevision, ownsLkgDirtyFence, invalidateCleanLkgRecoveryFence, prepareLkgCaptureFence, certifyCommittedLkgCapture, markLkgRecoveryDirty, rememberUnpublishedAutoSearchNoHint, getUnpublishedAutoSearchNoHint, forgetUnpublishedAutoSearchNoHint, registerAutoSearchWork, cancelAutoSearchWork, gaDatabasePath, RAW_MESSAGE_TYPES, V2StoreReaderPool, V2StoreReader, getOrCreateSessionMeta, updateSessionMeta, advanceToolReclaimWatermark, markSessionCleanupPending, retryPendingSessionCleanups, retryPendingRustSessionCleanupsForProject, clearSession, requestPendingMaterialization, pendingMaterializationOrigin, hasPendingMaterializationOrigin, clearPendingMaterialization, recordSystemPromptForRequest, recordHeldHeadForRequest, bindSystemPromptResponse, isHeldHeadForRequest, deferDeliveredSystemRefresh, retirePendingSystemPromptDelivery, lkgProviderInputTotal, beginV2LkgRequest, claimLkgRequestIdentity, currentLkgRequestIdentity, noteCapturedLkgRequest, noteLkgProviderResponse, measuredLkgPrefix, clearLkgMeasuredRequest, saveLkgSlotToDb, clearPersistedLkgSlotStrict, loadPersistedLkgSlot, drainStaleLkgSlots, createDbLkgPersistence, resolveLkgModelKeys, createLkgEntryProjector, captureLkgSlot, validateAnthropicReasoningRuns, validateLkgSeam, replayLkg, coldStartRawServedIndex, coldStartUncapturedReplay, noteUncertifiedNormalLkg, hasProcessLocalLkgProof, lkgDirtyRevision, rememberLkgDirtyRevision, readPersistedLkgUntaggedInputIds, persistLkgUntaggedInputIds, noteLkgRecoveryPrefix, readLkgRecoveryPrefix, noteLkgHealthyPrefix, lkgRecoveryReplayUnproven, lkgRecoveryEntryUnproven, lkgInputIdentity, registerLkgPersistence, beginLkgPass, visitMessageContentFields, contentSnapshotValue, messageContentFields, signatureForFields, exactReusablePrefix, incrementalLkgContentDigests, lkgSlotRejection, captureSlot, getInMemorySlot, getSlot, forgetInMemorySlot, dropSlot, noteEntry, getLkgSlotHeapStats, TOOL_SWEEP_SCOPED_MARKER, useScopedToolSweep, createPreAdoptionToolSweepResolver, copySessionStateForClone, queueMemoryMutation, getMaxMemoryMutationIdForProjects, GLOBAL_USER_PROFILE_PROJECT_PATH, getProjectState, bumpProjectUserProfileVersion, saveSourceContent, replaceSourceContent, getSourceContents, createChildSessionWithFence, HiddenCompletionRefusal, DreamerProviderOutputFailureError, withDreamerModelCooldown, providerOutputFailureFromInvalidManifest, HIDDEN_HISTORIAN_AGENT, HIDDEN_DREAMER_AGENT, HIDDEN_CURATE_AGENT, hiddenAgentFor, hiddenToolLoop, HIDDEN_RUN_DISPOSED_REASON, noteChildOfDisposedInstance, hiddenChildPermissions, registerHiddenChildAgents, hiddenToolCallRefusal, HiddenAgentStepLimit, HiddenChildHook, extractLatestAssistantText, hasLengthCappedOutput, parseProviderModel, modelBodyField, toModelEntry, ModelProducedNoOutputError, noteModelActivityMonitored, noteModelOutputReceived, isPromptTimeoutError, getPromptFailureDetail, raceWithSignal, promptSyncWithValidatedOutputRetry, normalizeSDKResponse, annotateSubagentInvocationError, failedInvocationStatus, emptyTokenTotals, sumTokensFromChildMessages, recordChildInvocation, recordPromptSessionError, createPromptAsyncTransport, CTX_NOTE_LIGHT_DESCRIPTION, ACTIVE_TOOL_IDS, systemPromptFingerprint, createPromptSurfaceRuntime, createPromptSurfaceGuidanceEpochCache, setKeepSubagents, teardownChildSession, getCompartmentEvents, runTokenLog, formatRunTokenLog, buildMagicContextSection, getMuralIdentity, getMural, modelKeyAcceptsImages, resolveMuralWire, v2ToolDefinitionsHash, USER_MEMORY_CANDIDATE_TTL_MS, insertUserMemoryCandidates, getUserMemoryCandidates, deleteUserMemoryCandidates, pruneExpiredUserMemoryCandidates, insertUserMemory, getActiveUserMemories, updateUserMemoryContent, dismissUserMemory, getOpenCodeDbPath, compareOpenCodeMessagesByCanonicalOrder, prepareCompactionMarkerCandidates, removeMcOwnedCompactionMarkers, MARKER_SUMMARY_TEXT, markerUpdateDefinitelyDidNotCut, applyDeferredCompactionMarker, removeCompactionMarkerForSession, checkCompactionMarkerConsistency, extractM0Block, formatDate, TEMPORAL_MARKER_REPLAY_PATTERN, collectTemporalCandidates, injectTemporalMarkers, clearInjectionCache, getVisibleMemoryIds, selectHiddenMessagesAtCompactionSeam, prepareCompartmentInjection, renderCompartmentInjection, MaterializeContentionError, mustMaterialize, trimMemoriesToBudgetV2, renderMemoryBlockV2, materializeM0, hydrateCachedM0Mural, resetPrefixTrimFallbackState, findHostCompactionWindow, capturePrefixTrimSourceOrder, prepareCachedM0M1Replay, hasCompleteCachedM0M1, injectM0M1, resolveHiddenCompletionExecutor, createV1HiddenCompletionExecutor, readCoordinateGeneration, readCoordinateRebaseNotice, formatCoordinateRebaseNotice, rebaseSessionCoordinatesAsync, shouldWaitForNewHistorianHistory, EMPTY_READ_REPLY, noteTouchedAt, renderGlance, renderNotesById, formatWriteReply, observeNoteNudgeServe, onNoteTrigger, peekNoteNudgeText, markNoteNudgeDelivered, clearNoteNudgeTriggerAndCooldown, resetNoteNudgeCooldownOnly, clearNoteNudgeTriggerOnly, omitIncompleteFileTokenTotals, describeBoundaryDiagnostics, RECOVERY_NO_HEAD_LIMIT, deriveProtectedTailTokenTarget, selectPerRunCap, resolveOpenCodeProtectedTailBoundary, resolveWrapupProtectedTailBoundary, getRawHistoryEligibility, hasRunnableCompartmentWindow, recordHighPressureNoEligibleHead, noteTransformPassForExactOrdinalReads, runCompartmentAgent, snapRangeToCompartments, getActiveCompartmentRun, markActiveCompartmentRunPublished, registerActiveCompartmentRun, startCompartmentAgent, executeContextRecomp };