@cortexkit/pi-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.
package/dist/index.js CHANGED
@@ -87,6 +87,7 @@ import {
87
87
  deleteUserMemoryCandidates,
88
88
  deliverNoteNudgeAtomic,
89
89
  deriveTagLoadFloor,
90
+ deriveWindowGeometry,
90
91
  describeError,
91
92
  dismissUserMemory,
92
93
  drainCommitBacklogForProject,
@@ -113,6 +114,7 @@ import {
113
114
  findAdoptableFallbackTags,
114
115
  findLastModelKeyFromBranch,
115
116
  findPiFallbackToolOwnerTags,
117
+ formatWindowDerivationLine,
116
118
  getActivePrimers,
117
119
  getActiveTagTokenAggregate,
118
120
  getActiveTagsBySession,
@@ -128,6 +130,7 @@ import {
128
130
  getCompartmentsByEndMessageId,
129
131
  getContextStoreUuid,
130
132
  getDatabasePath,
133
+ getDroppedTagsByNumbers,
131
134
  getEmbeddingCoverageStatus,
132
135
  getEmergencyInputSample,
133
136
  getErrorMessage,
@@ -204,6 +207,7 @@ import {
204
207
  getUnmappedMemoryIds,
205
208
  getUserMemoryCandidates,
206
209
  getVisibleMemoryIds,
210
+ getWindowOverlay,
207
211
  getWrapupInProgressState,
208
212
  hasMeaningfulUserText,
209
213
  hasMemoryClassifiedAtColumn,
@@ -241,6 +245,7 @@ import {
241
245
  markProtectedTailPolicyV3Seeded,
242
246
  memoryNeedsCue,
243
247
  migrateMagicContextConfigLocations,
248
+ modelRefLookupOrder,
244
249
  nextDueAtMs,
245
250
  nextOccurrence,
246
251
  normalizeText,
@@ -257,6 +262,7 @@ import {
257
262
  peelLeadingMcTagNotation,
258
263
  persistCachedM0,
259
264
  piModelRefToCanonical,
265
+ preloadTokenizer,
260
266
  prependTag,
261
267
  primeInMemoryTailRawMessageCache,
262
268
  primeTailRawMessageCache,
@@ -273,7 +279,6 @@ import {
273
279
  readGitChangedFilesSince,
274
280
  readGitFileChangeTimesSince,
275
281
  readGitHead,
276
- readNewMemoriesForM1Union,
277
282
  readPiSessionMessages,
278
283
  readProjectDocsCanonical,
279
284
  readRawSessionMessages,
@@ -308,7 +313,6 @@ import {
308
313
  resetLastNudgeCycleIfTailShrank,
309
314
  resolveCompactionModeRecord,
310
315
  resolveGitTopLevel,
311
- resolveLimit,
312
316
  resolveModelConfigOrDefault,
313
317
  resolveModelRefForOmp,
314
318
  resolveModelRefForPi,
@@ -317,6 +321,7 @@ import {
317
321
  resolveProjectIdentity,
318
322
  resolveProjectIdentityForSession,
319
323
  resolveProjectIdentityStrict,
324
+ resolveWindowOverlayFacts,
320
325
  resolveWorkspaceIdentitySet,
321
326
  resolveWorkspaceShareCategories,
322
327
  retryPendingSessionCleanups,
@@ -371,11 +376,12 @@ import {
371
376
  updateUserMemoryContent,
372
377
  updateWrapupInProgress,
373
378
  verificationFileExists,
379
+ wakePlaneStatus,
374
380
  withContentLanguageDirective,
375
381
  withMigrationLanguageDirective,
376
382
  withRawMessageProvider,
377
383
  withRawSessionMessageCache
378
- } from "./index-9t7jhq83.js";
384
+ } from "./index-kvttksef.js";
379
385
  import {
380
386
  pushNotification
381
387
  } from "./index-hw34xmzk.js";
@@ -387,7 +393,7 @@ import {
387
393
  log,
388
394
  sessionLog,
389
395
  setHarness
390
- } from "./index-npnqc564.js";
396
+ } from "./index-hk6sj7dn.js";
391
397
  import {
392
398
  __require,
393
399
  __toESM
@@ -885,7 +891,7 @@ var LIMIT_EXTRACTION_PATTERNS = [
885
891
  pattern: /too large for model with (\d+) maximum context length/i,
886
892
  provenance: "combined"
887
893
  },
888
- { pattern: /context size.*(\d+) tokens?/i, provenance: "combined" },
894
+ { pattern: /context size[^0-9]{0,40}(\d{4,})\s*tokens?/i, provenance: "combined" },
889
895
  { pattern: /exceeds? the context length of (\d+)/i, provenance: "combined" },
890
896
  {
891
897
  pattern: />\s*(\d+)\s*(?:tokens?\s*)?(?:maximum|max|limit)\b/i,
@@ -1508,11 +1514,13 @@ function isFinitePositive(v) {
1508
1514
  }
1509
1515
  function* modelKeyLookupOrder(modelKey) {
1510
1516
  const slash = modelKey.indexOf("/");
1511
- const provider = slash >= 0 ? modelKey.slice(0, slash) : "";
1517
+ const providerRefs = slash >= 0 ? modelRefLookupOrder(modelKey) : [];
1512
1518
  let modelId = slash >= 0 ? modelKey.slice(slash + 1) : modelKey;
1513
1519
  while (modelId.length > 0) {
1514
- if (provider)
1515
- yield `${provider}/${modelId}`;
1520
+ for (const providerRef of providerRefs) {
1521
+ const providerSlash = providerRef.indexOf("/");
1522
+ yield `${providerRef.slice(0, providerSlash)}/${modelId}`;
1523
+ }
1516
1524
  yield modelId;
1517
1525
  const lastDash = modelId.lastIndexOf("-");
1518
1526
  if (lastDash <= 0)
@@ -1950,6 +1958,7 @@ function createCloneFilter(entries) {
1950
1958
  const rawMessages = convertEntriesToRawMessages([...entries]);
1951
1959
  const rawOrdinalById = new Map(rawMessages.map((message) => [message.id, message.ordinal]));
1952
1960
  const validStateIds = new Set(rawOrdinalById.keys());
1961
+ const validOrdinals = new Set(rawOrdinalById.values());
1953
1962
  for (const entry of entries) {
1954
1963
  const id = entryId(entry);
1955
1964
  if (id)
@@ -1959,6 +1968,8 @@ function createCloneFilter(entries) {
1959
1968
  return {
1960
1969
  resolveBoundaryOrdinal: (id) => rawOrdinalById.get(id),
1961
1970
  includeMessageId,
1971
+ copySessionNotesAndFacts: true,
1972
+ mapOrdinal: (ordinal) => validOrdinals.has(ordinal) ? ordinal : undefined,
1962
1973
  includeTag: (tag) => {
1963
1974
  if (tag.type === "tool") {
1964
1975
  return typeof tag.toolOwnerMessageId === "string" && includeMessageId(tag.toolOwnerMessageId);
@@ -2036,7 +2047,7 @@ async function handlePiCloneSessionStart(event, ctx, deps) {
2036
2047
  if (result.pendingMarkerMigrated) {
2037
2048
  deps.signalPendingMarker(destinationSessionId);
2038
2049
  }
2039
- writeLog(`[magic-context][pi] clone-inheritance: migrated compartments=${result.compartmentsCopied} tags=${result.tagsCopied} source=${sourceSessionId} dest=${destinationSessionId} reason=fork`);
2050
+ writeLog(`[magic-context][pi] clone-inheritance: migrated compartments=${result.compartmentsCopied} tags=${result.tagsCopied} notes=${result.notesCopied} facts=${result.factsCopied} source=${sourceSessionId} dest=${destinationSessionId} reason=fork`);
2040
2051
  return result;
2041
2052
  } catch (error) {
2042
2053
  writeLog(`[magic-context][pi] clone-inheritance: failed source=${sourceSessionId} dest=${destinationSessionId} stage=${stage} error=${error instanceof Error ? error.message : String(error)}; run /ctx-wrapup to rebuild, or re-clone`);
@@ -2095,13 +2106,14 @@ var state = {
2095
2106
  noticeEmitted: false,
2096
2107
  failure: null
2097
2108
  };
2098
- function recordStaleFence(persistedVersion, supportedVersion) {
2109
+ function recordStaleFence(persistedVersion, supportedVersion, reason = "newer_schema") {
2099
2110
  state.consecutiveFailures += 1;
2100
2111
  state.totalFailures += 1;
2101
2112
  const latched = state.consecutiveFailures >= STALE_CHILD_SPAWN_LATCH_THRESHOLD;
2102
2113
  state.latched ||= latched;
2103
2114
  const failure = {
2104
2115
  failureClass: STALE_CHILD_SPAWN_FAILURE,
2116
+ reason,
2105
2117
  persistedVersion,
2106
2118
  supportedVersion,
2107
2119
  consecutiveFailures: state.consecutiveFailures,
@@ -2128,7 +2140,7 @@ function probeChildSpawnFence(db) {
2128
2140
  return recordStaleFence(persistedVersion, LATEST_SUPPORTED_VERSION);
2129
2141
  }
2130
2142
  } catch {
2131
- return { allowSpawn: true };
2143
+ return recordStaleFence(LATEST_SUPPORTED_VERSION, LATEST_SUPPORTED_VERSION, "read_error");
2132
2144
  }
2133
2145
  state.consecutiveFailures = 0;
2134
2146
  state.latched = false;
@@ -3755,7 +3767,7 @@ async function sendIgnoredMessageNow(client, sessionId, text, params, forcePersi
3755
3767
  queueIgnoredNotification({ client, sessionId, text, params, forcePersist });
3756
3768
  return "queued";
3757
3769
  }
3758
- const { waitForSafeNotificationTarget } = await import("./safe-notification-target-0s6j4m9f.js");
3770
+ const { waitForSafeNotificationTarget } = await import("./safe-notification-target-7n7s6xv7.js");
3759
3771
  if (await waitForSafeNotificationTarget(client, sessionId) === "skip") {
3760
3772
  sessionLog(sessionId, "notification skipped (session not titled yet)");
3761
3773
  return "skipped";
@@ -3832,25 +3844,31 @@ async function sendIgnoredMessage(client, sessionId, text, params, forcePersist
3832
3844
 
3833
3845
  // ../plugin/src/hooks/magic-context/child-session-spawn.ts
3834
3846
  var STALE_PLUGIN_RESTART_NOTICE = "Magic Context: plugin build is older than its database — restart OpenCode";
3835
- async function surfaceStalePluginBuild(args) {
3847
+ var SCHEMA_PROBE_FAILURE_NOTICE = `Magic Context: unable to verify the database schema before spawning a child — run ${FAIL_CLOSED_DOCTOR_COMMAND}`;
3848
+ async function surfaceSchemaFenceFailure(args, failure) {
3836
3849
  if (!args.parentSessionId)
3837
3850
  return;
3838
- try {
3839
- if (args.db) {
3851
+ const notice = failure.reason === "read_error" ? SCHEMA_PROBE_FAILURE_NOTICE : STALE_PLUGIN_RESTART_NOTICE;
3852
+ if (args.db) {
3853
+ try {
3840
3854
  updateSessionMeta(args.db, args.parentSessionId, {
3841
- lastTransformError: STALE_PLUGIN_RESTART_NOTICE
3855
+ lastTransformError: notice
3842
3856
  });
3857
+ } catch (error) {
3858
+ sessionLog(args.parentSessionId, `schema-fence warning persistence failed: ${error instanceof Error ? error.message : String(error)}`);
3843
3859
  }
3860
+ }
3861
+ try {
3844
3862
  pushNotification("toast", {
3845
3863
  title: "Magic Context",
3846
- message: STALE_PLUGIN_RESTART_NOTICE,
3864
+ message: notice,
3847
3865
  variant: "error",
3848
3866
  duration: 1e4
3849
3867
  }, args.parentSessionId);
3850
3868
  pushNotification("action", { action: "refresh-sidebar" }, args.parentSessionId);
3851
- await sendIgnoredMessage(args.client, args.parentSessionId, STALE_PLUGIN_RESTART_NOTICE, args.notificationParams ?? {}, true);
3869
+ await sendIgnoredMessage(args.client, args.parentSessionId, notice, args.notificationParams ?? {}, true);
3852
3870
  } catch (error) {
3853
- sessionLog(args.parentSessionId, `stale plugin-build warning delivery failed: ${error instanceof Error ? error.message : String(error)}`);
3871
+ sessionLog(args.parentSessionId, `schema-fence warning delivery failed: ${error instanceof Error ? error.message : String(error)}`);
3854
3872
  }
3855
3873
  }
3856
3874
  async function createChildSessionWithFence(args) {
@@ -3863,7 +3881,7 @@ async function createChildSessionWithFence(args) {
3863
3881
  if (args.onFenceLatched)
3864
3882
  await args.onFenceLatched(verdict.failure);
3865
3883
  else
3866
- await surfaceStalePluginBuild(args);
3884
+ await surfaceSchemaFenceFailure(args, verdict.failure);
3867
3885
  }
3868
3886
  return null;
3869
3887
  }
@@ -4255,7 +4273,7 @@ function parseFields(json) {
4255
4273
  }
4256
4274
 
4257
4275
  // ../plugin/src/features/magic-context/mural/compress-cues.ts
4258
- import { createHash as createHash2 } from "node:crypto";
4276
+ import { createHash as createHash3 } from "node:crypto";
4259
4277
 
4260
4278
  // ../plugin/src/features/magic-context/dreamer/storage-dream-state.ts
4261
4279
  var getDreamStateStatements = new WeakMap;
@@ -4304,13 +4322,15 @@ function rowKeys(leaseKey) {
4304
4322
  return {
4305
4323
  holder: "dreaming_lease_holder",
4306
4324
  heartbeat: "dreaming_lease_heartbeat",
4307
- expiry: "dreaming_lease_expiry"
4325
+ expiry: "dreaming_lease_expiry",
4326
+ generation: "dreaming_lease_generation"
4308
4327
  };
4309
4328
  }
4310
4329
  return {
4311
4330
  holder: `lease:${leaseKey}:holder`,
4312
4331
  heartbeat: `lease:${leaseKey}:heartbeat`,
4313
- expiry: `lease:${leaseKey}:expiry`
4332
+ expiry: `lease:${leaseKey}:expiry`,
4333
+ generation: `lease:${leaseKey}:generation`
4314
4334
  };
4315
4335
  }
4316
4336
  function getLeaseExpiry(db, keys) {
@@ -4328,6 +4348,13 @@ function isLeaseActive(db, leaseKey = DREAMING_LEASE_KEY) {
4328
4348
  function getLeaseHolder(db, leaseKey = DREAMING_LEASE_KEY) {
4329
4349
  return getDreamState(db, rowKeys(leaseKey).holder);
4330
4350
  }
4351
+ function getLeaseGeneration(db, leaseKey = DREAMING_LEASE_KEY) {
4352
+ const value = getDreamState(db, rowKeys(leaseKey).generation);
4353
+ if (!value)
4354
+ return null;
4355
+ const generation = Number(value);
4356
+ return Number.isSafeInteger(generation) && generation > 0 ? generation : null;
4357
+ }
4331
4358
  function peekLeaseHolderAndExpiry(db, expectedHolder, leaseKey = DREAMING_LEASE_KEY) {
4332
4359
  const keys = rowKeys(leaseKey);
4333
4360
  const holder = getDreamState(db, keys.holder);
@@ -4339,6 +4366,9 @@ function peekLeaseHolderAndExpiry(db, expectedHolder, leaseKey = DREAMING_LEASE_
4339
4366
  const expiry = Number(expiryStr);
4340
4367
  return Number.isFinite(expiry) && expiry >= Date.now();
4341
4368
  }
4369
+ function leaseOwnershipMatches(db, expectedHolder, expectedGeneration, leaseKey = DREAMING_LEASE_KEY) {
4370
+ return getLeaseGeneration(db, leaseKey) === expectedGeneration && peekLeaseHolderAndExpiry(db, expectedHolder, leaseKey);
4371
+ }
4342
4372
  function runImmediate(db, body) {
4343
4373
  db.exec("BEGIN IMMEDIATE");
4344
4374
  let committed = false;
@@ -4355,26 +4385,30 @@ function runImmediate(db, body) {
4355
4385
  }
4356
4386
  }
4357
4387
  }
4358
- function acquireLease(db, holderId, leaseKey = DREAMING_LEASE_KEY) {
4388
+ function acquireLeaseWithAcquisition(db, holderId, leaseKey = DREAMING_LEASE_KEY) {
4359
4389
  const keys = rowKeys(leaseKey);
4360
4390
  return runImmediate(db, () => {
4361
- if (isLeaseActive(db, leaseKey)) {
4362
- const existingHolder = getLeaseHolder(db, leaseKey);
4363
- if (existingHolder && existingHolder !== holderId) {
4364
- return false;
4365
- }
4391
+ const existingHolder = getLeaseHolder(db, leaseKey);
4392
+ if (isLeaseActive(db, leaseKey) && existingHolder && existingHolder !== holderId) {
4393
+ return null;
4366
4394
  }
4367
4395
  const now = Date.now();
4396
+ const priorGeneration = getLeaseGeneration(db, leaseKey) ?? 0;
4397
+ const generation = existingHolder === holderId ? Math.max(1, priorGeneration) : priorGeneration + 1;
4368
4398
  setDreamState(db, keys.holder, holderId);
4369
4399
  setDreamState(db, keys.heartbeat, String(now));
4370
4400
  setDreamState(db, keys.expiry, String(now + LEASE_DURATION_MS));
4371
- return true;
4401
+ setDreamState(db, keys.generation, String(generation));
4402
+ return { acquiredAt: now, generation };
4372
4403
  });
4373
4404
  }
4374
- function renewLease(db, holderId, leaseKey = DREAMING_LEASE_KEY) {
4405
+ function acquireLease(db, holderId, leaseKey = DREAMING_LEASE_KEY) {
4406
+ return acquireLeaseWithAcquisition(db, holderId, leaseKey) !== null;
4407
+ }
4408
+ function renewLease(db, holderId, leaseKey = DREAMING_LEASE_KEY, expectedGeneration) {
4375
4409
  const keys = rowKeys(leaseKey);
4376
4410
  return runImmediate(db, () => {
4377
- if (getLeaseHolder(db, leaseKey) !== holderId || !isLeaseActive(db, leaseKey)) {
4411
+ if (getLeaseHolder(db, leaseKey) !== holderId || !isLeaseActive(db, leaseKey) || expectedGeneration !== undefined && getLeaseGeneration(db, leaseKey) !== expectedGeneration) {
4378
4412
  return false;
4379
4413
  }
4380
4414
  const now = Date.now();
@@ -4392,9 +4426,12 @@ function runLeaseGuardedWrite(db, holderId, leaseKey, fn) {
4392
4426
  });
4393
4427
  }
4394
4428
  var LEASE_HEARTBEAT_INTERVAL_MS = 60 * 1000;
4395
- function startLeaseHeartbeat(db, holderId, leaseKey, onLost, intervalMs = LEASE_HEARTBEAT_INTERVAL_MS) {
4429
+ function startLeaseHeartbeat(db, holderId, leaseKey, onLost, intervalOrAcquisition = LEASE_HEARTBEAT_INTERVAL_MS) {
4430
+ const intervalMs = typeof intervalOrAcquisition === "number" ? intervalOrAcquisition : LEASE_HEARTBEAT_INTERVAL_MS;
4431
+ const acquisition = typeof intervalOrAcquisition === "number" ? undefined : intervalOrAcquisition;
4396
4432
  let lost = false;
4397
- let lastConfirmedAt = Date.now();
4433
+ let expectedGeneration = acquisition?.generation ?? getLeaseGeneration(db, leaseKey);
4434
+ let lastConfirmedAt = acquisition?.acquiredAt ?? Date.now();
4398
4435
  const declareLost = (reason) => {
4399
4436
  if (lost)
4400
4437
  return;
@@ -4405,15 +4442,25 @@ function startLeaseHeartbeat(db, holderId, leaseKey, onLost, intervalMs = LEASE_
4405
4442
  if (lost)
4406
4443
  return;
4407
4444
  try {
4408
- if (renewLease(db, holderId, leaseKey)) {
4445
+ if (renewLease(db, holderId, leaseKey, expectedGeneration === null ? undefined : expectedGeneration)) {
4409
4446
  lastConfirmedAt = Date.now();
4410
4447
  return;
4411
4448
  }
4449
+ if (expectedGeneration !== null && getLeaseGeneration(db, leaseKey) !== expectedGeneration) {
4450
+ declareLost("lease generation changed — another holder acquired it");
4451
+ return;
4452
+ }
4412
4453
  if (Date.now() - lastConfirmedAt > LEASE_DURATION_MS) {
4413
4454
  declareLost("lease lapsed past TTL — another holder may have run");
4414
4455
  return;
4415
4456
  }
4416
- if (acquireLease(db, holderId, leaseKey)) {
4457
+ const reacquired = acquireLeaseWithAcquisition(db, holderId, leaseKey);
4458
+ if (reacquired) {
4459
+ if (expectedGeneration !== null && reacquired.generation !== expectedGeneration) {
4460
+ declareLost("lease generation changed during reacquisition");
4461
+ return;
4462
+ }
4463
+ expectedGeneration = reacquired.generation;
4417
4464
  lastConfirmedAt = Date.now();
4418
4465
  return;
4419
4466
  }
@@ -4482,6 +4529,16 @@ function assertManifestCoversExactly(ids, expectedIds, rootName) {
4482
4529
  }
4483
4530
 
4484
4531
  // ../plugin/src/features/magic-context/dreamer/module-apply.ts
4532
+ class DreamerModuleBusyError extends Error {
4533
+ state;
4534
+ transient = true;
4535
+ constructor(state2) {
4536
+ super(`Rust memory authority is ${state2}; dreamer mutation deferred until authority settles.`);
4537
+ this.state = state2;
4538
+ this.name = "DreamerModuleBusyError";
4539
+ }
4540
+ }
4541
+
4485
4542
  class DreamerModuleFailureError extends Error {
4486
4543
  transient = true;
4487
4544
  constructor(operation, cause) {
@@ -4503,9 +4560,12 @@ async function resolveDreamerModuleRoute(args) {
4503
4560
  projectRoot: args.projectRoot,
4504
4561
  domain: "memories"
4505
4562
  });
4506
- if (result.authority?.state !== "MODULE")
4563
+ const authority = result.authority;
4564
+ if (authority?.state === "DRAINING")
4565
+ throw new DreamerModuleBusyError(authority.state);
4566
+ if (authority?.state !== "MODULE")
4507
4567
  return;
4508
- const generation = result.authority.generation;
4568
+ const generation = authority.generation;
4509
4569
  if (typeof generation !== "number")
4510
4570
  throw new Error("Rust authority status omitted generation");
4511
4571
  return {
@@ -4539,6 +4599,68 @@ function getModuleMemoryIdentities(db, projectIdentity, contextIds) {
4539
4599
  ] : []));
4540
4600
  }
4541
4601
 
4602
+ // ../plugin/src/features/magic-context/dreamer/provider-output-failure.ts
4603
+ import { createHash as createHash2 } from "node:crypto";
4604
+ var MAX_NEAR_ZERO_OUTPUT_TOKENS = 32;
4605
+
4606
+ class DreamerProviderOutputFailureError extends Error {
4607
+ fingerprint;
4608
+ outputTokens;
4609
+ reasoningTokens;
4610
+ transient = true;
4611
+ constructor(fingerprint, outputTokens, reasoningTokens, responseText) {
4612
+ const preview = responseText.trim().replace(/\s+/g, " ").slice(0, 160);
4613
+ super(`dreamer provider-outage completion (output_tokens=${outputTokens}, reasoning_tokens=${reasoningTokens}): ${JSON.stringify(preview)}`);
4614
+ this.fingerprint = fingerprint;
4615
+ this.outputTokens = outputTokens;
4616
+ this.reasoningTokens = reasoningTokens;
4617
+ this.name = "DreamerProviderOutputFailureError";
4618
+ }
4619
+ }
4620
+ function finiteTokenCount(value) {
4621
+ return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : null;
4622
+ }
4623
+ function completionShape(value) {
4624
+ if (!isRecord(value))
4625
+ return null;
4626
+ const info = isRecord(value.info) ? value.info : value;
4627
+ if (info.role !== "assistant")
4628
+ return null;
4629
+ const time = isRecord(info.time) ? info.time : null;
4630
+ const tokens = isRecord(info.tokens) ? info.tokens : null;
4631
+ return {
4632
+ createdAt: typeof time?.created === "number" ? time.created : 0,
4633
+ finish: typeof info.finish === "string" ? info.finish : typeof info.finish_reason === "string" ? info.finish_reason : typeof info.finishReason === "string" ? info.finishReason : null,
4634
+ error: info.error,
4635
+ outputTokens: finiteTokenCount(tokens?.output),
4636
+ reasoningTokens: finiteTokenCount(tokens?.reasoning)
4637
+ };
4638
+ }
4639
+ function latestAssistantCompletion(messages) {
4640
+ if (!Array.isArray(messages))
4641
+ return null;
4642
+ let latest = null;
4643
+ for (const message of messages) {
4644
+ const completion = completionShape(message);
4645
+ if (completion && (!latest || completion.createdAt >= latest.createdAt))
4646
+ latest = completion;
4647
+ }
4648
+ return latest;
4649
+ }
4650
+ function providerOutputFailureFromInvalidManifest(messages, responseText) {
4651
+ const completion = latestAssistantCompletion(messages);
4652
+ if (completion?.finish?.toLowerCase() !== "stop")
4653
+ return null;
4654
+ if (completion.error != null || completion.outputTokens === null || completion.outputTokens > MAX_NEAR_ZERO_OUTPUT_TOKENS || completion.reasoningTokens !== 0) {
4655
+ return null;
4656
+ }
4657
+ const normalized = responseText.trim().replace(/\s+/g, " ").toLowerCase();
4658
+ if (!normalized)
4659
+ return null;
4660
+ const fingerprint = createHash2("sha256").update(normalized).digest("hex").slice(0, 16);
4661
+ return new DreamerProviderOutputFailureError(fingerprint, completion.outputTokens, completion.reasoningTokens, responseText);
4662
+ }
4663
+
4542
4664
  // ../plugin/src/features/magic-context/mural/compress-cues-prompt.ts
4543
4665
  var CUE_BUDGET_HIGH = 90;
4544
4666
  var CUE_BUDGET_LOW = 50;
@@ -4711,7 +4833,7 @@ async function runCompressCues(args) {
4711
4833
  chunks.push(candidates.slice(i, i + COMPRESS_CUES_CHUNK_SIZE));
4712
4834
  }
4713
4835
  const abortController = new AbortController;
4714
- const heartbeat = startLeaseHeartbeat(args.db, args.holderId, args.leaseKey, () => abortController.abort());
4836
+ const heartbeat = startLeaseHeartbeat(args.db, args.holderId, args.leaseKey, () => abortController.abort(), args.leaseAcquisition);
4715
4837
  try {
4716
4838
  let consecutiveTimeouts = 0;
4717
4839
  let timeoutStreakElapsedMs = [];
@@ -4806,7 +4928,14 @@ async function compressOneChunk(args, chunk, sliceMs, signal) {
4806
4928
  const text = extractLatestAssistantText(messages);
4807
4929
  if (!text)
4808
4930
  throw new Error("compress-cues returned no output");
4809
- parseCuesManifest(text);
4931
+ try {
4932
+ parseCuesManifest(text);
4933
+ } catch (error) {
4934
+ const providerFailure = providerOutputFailureFromInvalidManifest(messages, text);
4935
+ if (providerFailure)
4936
+ throw providerFailure;
4937
+ throw error;
4938
+ }
4810
4939
  return text;
4811
4940
  }
4812
4941
  });
@@ -4814,7 +4943,7 @@ async function compressOneChunk(args, chunk, sliceMs, signal) {
4814
4943
  } catch (error) {
4815
4944
  const desc = describeError(error);
4816
4945
  log(`[dreamer] compress-cues chunk failed: ${desc.brief}`, desc.stackHead ? { stackHead: desc.stackHead } : undefined);
4817
- if (signal.aborted)
4946
+ if (signal.aborted || error instanceof DreamerProviderOutputFailureError)
4818
4947
  throw error;
4819
4948
  return {
4820
4949
  compressed: 0,
@@ -4922,7 +5051,7 @@ async function applyCuesThroughModule(args, chunk, manifestText, signal) {
4922
5051
  log(`[dreamer] compress-cues: skipped cue for memory ${entry.id} (${failure.reason}; rejection ${rejectionCount}/${CUE_REJECTION_LATCH_THRESHOLD})`);
4923
5052
  }
4924
5053
  }
4925
- const commandId = `mural-cues:${route.moduleCommandId}:${createHash2("sha256").update(chunk.map((candidate) => candidate.memory.id).join(",")).digest("hex").slice(0, 24)}`;
5054
+ const commandId = `mural-cues:${route.moduleCommandId}:${createHash3("sha256").update(chunk.map((candidate) => candidate.memory.id).join(",")).digest("hex").slice(0, 24)}`;
4926
5055
  let response;
4927
5056
  try {
4928
5057
  response = await route.moduleClient.call({
@@ -5364,7 +5493,7 @@ If no promotions are warranted, return empty arrays. Always consume reviewed can
5364
5493
  const heartbeat = startLeaseHeartbeat(args.db, args.holderId, leaseKey, (reason) => {
5365
5494
  log(`[dreamer] user-memories: lease lost (${reason}) — aborting`);
5366
5495
  abortController.abort();
5367
- });
5496
+ }, args.leaseAcquisition);
5368
5497
  try {
5369
5498
  const createResponse = await createChildSessionWithFence({
5370
5499
  client: args.client,
@@ -5487,7 +5616,7 @@ If no promotions are warranted, return empty arrays. Always consume reviewed can
5487
5616
  }
5488
5617
 
5489
5618
  // ../plugin/src/features/magic-context/dreamer/classify.ts
5490
- import { createHash as createHash3 } from "node:crypto";
5619
+ import { createHash as createHash4 } from "node:crypto";
5491
5620
 
5492
5621
  // ../plugin/src/plugin/rust-tool-backends.ts
5493
5622
  function isRustAuthorityDrainingError(error) {
@@ -5871,7 +6000,7 @@ async function runClassify(args) {
5871
6000
  chunks.push(toClassify.slice(i, i + CLASSIFY_CHUNK_SIZE));
5872
6001
  }
5873
6002
  const abortController = new AbortController;
5874
- const heartbeat = startLeaseHeartbeat(args.db, args.holderId, args.leaseKey, () => abortController.abort());
6003
+ const heartbeat = startLeaseHeartbeat(args.db, args.holderId, args.leaseKey, () => abortController.abort(), args.leaseAcquisition);
5875
6004
  try {
5876
6005
  for (let i = 0;i < chunks.length; i += 1) {
5877
6006
  const remainingMs = Math.max(0, args.deadline - Date.now());
@@ -5951,7 +6080,14 @@ async function classifyOneChunk(args, chunk, anchors, sliceMs, signal) {
5951
6080
  const text = extractLatestAssistantText(messages);
5952
6081
  if (!text)
5953
6082
  throw new Error("classify returned no output");
5954
- parseClassifyManifest(text);
6083
+ try {
6084
+ parseClassifyManifest(text);
6085
+ } catch (error) {
6086
+ const providerFailure = providerOutputFailureFromInvalidManifest(messages, text);
6087
+ if (providerFailure)
6088
+ throw providerFailure;
6089
+ throw error;
6090
+ }
5955
6091
  return text;
5956
6092
  }
5957
6093
  });
@@ -5962,7 +6098,7 @@ async function classifyOneChunk(args, chunk, anchors, sliceMs, signal) {
5962
6098
  const desc = describeError(failure);
5963
6099
  log(`[dreamer] classify chunk failed: ${desc.brief}`, desc.stackHead ? { stackHead: desc.stackHead } : undefined);
5964
6100
  recordInvocation(args, startedAt, { status: "failed", error: failure });
5965
- if (moduleRoute || signal.aborted)
6101
+ if (moduleRoute || signal.aborted || failure instanceof DreamerProviderOutputFailureError)
5966
6102
  throw failure;
5967
6103
  return { classified: 0, changed: 0 };
5968
6104
  } finally {
@@ -5991,7 +6127,7 @@ async function runClassifyThroughModule(args, chunk, anchors, signal) {
5991
6127
  v: 1,
5992
6128
  session_id: args.moduleSessionId,
5993
6129
  task: "classify",
5994
- command_id: `classify:${args.moduleCommandId ?? Date.now()}:${createHash3("sha256").update(chunk.map((candidate) => candidate.id).join(",")).digest("hex").slice(0, 24)}`,
6130
+ command_id: `classify:${args.moduleCommandId ?? Date.now()}:${createHash4("sha256").update(chunk.map((candidate) => candidate.id).join(",")).digest("hex").slice(0, 24)}`,
5995
6131
  authority_generation: args.moduleAuthorityGeneration,
5996
6132
  payload: {
5997
6133
  prompt_body: prompt,
@@ -6629,7 +6765,7 @@ function throwIfAborted2(signal) {
6629
6765
  }
6630
6766
 
6631
6767
  // ../plugin/src/features/magic-context/smart-notes/compiler.ts
6632
- import { createHash as createHash4 } from "node:crypto";
6768
+ import { createHash as createHash5 } from "node:crypto";
6633
6769
 
6634
6770
  // ../plugin/src/features/magic-context/smart-notes/compiler-prompt.ts
6635
6771
  var SMART_NOTE_COMPILER_SYSTEM_PROMPT = `You are the Magic Context smart-note compiler for the magic-context system.
@@ -7053,7 +7189,7 @@ function manifestAdvisoryWarnings(code, manifest) {
7053
7189
  return warnings;
7054
7190
  }
7055
7191
  function hashCheck(surfaceCondition, compiledCheck, manifest, checkCron) {
7056
- return createHash4("sha256").update(surfaceCondition ?? "").update("\x00").update(compiledCheck).update("\x00").update(JSON.stringify(manifest)).update("\x00").update(checkCron).digest("hex");
7192
+ return createHash5("sha256").update(surfaceCondition ?? "").update("\x00").update(compiledCheck).update("\x00").update(JSON.stringify(manifest)).update("\x00").update(checkCron).digest("hex");
7057
7193
  }
7058
7194
  function extractJsonObject(output) {
7059
7195
  const fenced = output.match(/```(?:json)?\s*([\s\S]*?)```/i);
@@ -7142,6 +7278,9 @@ var DEFAULT_MAX_CHECKS = 10;
7142
7278
  var DEFAULT_SWEEP_BUDGET_MS = 15000;
7143
7279
  var MAX_FAILURES_BEFORE_REAUTHOR = 3;
7144
7280
  async function runDueCompiledSmartNoteChecks(args) {
7281
+ if (await wakePlaneStatus() === "present") {
7282
+ return { ran: 0, surfaced: 0, failed: 0, networkFailed: 0 };
7283
+ }
7145
7284
  const startedAt = Date.now();
7146
7285
  const now = args.now ?? startedAt;
7147
7286
  const due = getDueCompiledSmartNoteChecks(args.db, args.projectIdentity, now, args.maxChecks ?? DEFAULT_MAX_CHECKS, args.retinaHandoff);
@@ -7271,6 +7410,11 @@ function createPromptAbortSignal(parent, timeoutMs, timeoutMessage) {
7271
7410
  };
7272
7411
  }
7273
7412
  async function evaluateSmartNotes(args) {
7413
+ if (await wakePlaneStatus() === "present") {
7414
+ const pending = getPendingSmartNotes(args.db, args.projectIdentity).length;
7415
+ log("[dreamer] evaluate-smart-notes: skipped (wake plane active)");
7416
+ return { surfaced: 0, pending, ran: false };
7417
+ }
7274
7418
  const projectRoot = args.sessionDirectory ?? args.projectIdentity;
7275
7419
  const moduleBridge = getModuleNoteEvaluationBridge(args.projectIdentity);
7276
7420
  await moduleBridge?.sync();
@@ -7294,7 +7438,7 @@ async function evaluateSmartNotes(args) {
7294
7438
  leaseAbortController.abort(new Error("Dream lease lost during smart notes"));
7295
7439
  log("[dreamer] smart notes: lease lost — aborting");
7296
7440
  args.onLeaseLost?.("smart notes");
7297
- });
7441
+ }, args.leaseAcquisition);
7298
7442
  let surfaced = 0;
7299
7443
  let didWork = false;
7300
7444
  try {
@@ -7735,7 +7879,7 @@ function enforceMaintainDocsProtectedRegions(args) {
7735
7879
  }
7736
7880
 
7737
7881
  // ../plugin/src/features/magic-context/dreamer/map-memories.ts
7738
- import { createHash as createHash5 } from "node:crypto";
7882
+ import { createHash as createHash6 } from "node:crypto";
7739
7883
 
7740
7884
  // ../plugin/src/features/magic-context/dreamer/map-memories-prompt.ts
7741
7885
  import { existsSync as existsSync6, statSync } from "node:fs";
@@ -7852,7 +7996,7 @@ async function mapMemories(args) {
7852
7996
  }
7853
7997
  result.remaining = inputs.length;
7854
7998
  const abortController = new AbortController;
7855
- const heartbeat = startLeaseHeartbeat(args.db, args.holderId, args.leaseKey, () => abortController.abort());
7999
+ const heartbeat = startLeaseHeartbeat(args.db, args.holderId, args.leaseKey, () => abortController.abort(), args.leaseAcquisition);
7856
8000
  try {
7857
8001
  for (let i = 0;i < batches.length; i += 1) {
7858
8002
  const remainingMs = Math.max(0, args.deadline - Date.now());
@@ -7996,7 +8140,7 @@ async function applyBatchMappings(args, batch, manifestText) {
7996
8140
  memory_project: args.projectIdentity,
7997
8141
  context_store_uuid: args.moduleRoute.moduleContextStoreUuid,
7998
8142
  authority_generation: args.moduleRoute.moduleAuthorityGeneration,
7999
- command_id: `${args.moduleRoute.moduleCommandId}:${createHash5("sha256").update(rows.map((row) => row.memory_id).join(",")).digest("hex").slice(0, 16)}`,
8143
+ command_id: `${args.moduleRoute.moduleCommandId}:${createHash6("sha256").update(rows.map((row) => row.memory_id).join(",")).digest("hex").slice(0, 16)}`,
8000
8144
  rows
8001
8145
  }
8002
8146
  }
@@ -8221,7 +8365,7 @@ async function promotePrimers(args) {
8221
8365
  const heartbeat = startLeaseHeartbeat(args.db, args.holderId, args.leaseKey, () => {
8222
8366
  leaseLost = true;
8223
8367
  log("[dreamer] primers: lease lost during promote-primers — aborting");
8224
- });
8368
+ }, args.leaseAcquisition);
8225
8369
  try {
8226
8370
  assertLeaseHeld("prune start");
8227
8371
  result.pruned = pruneExpiredPrimerCandidatesForProject(args.db, args.projectIdentity, Date.now(), PRIMER_CANDIDATE_TTL_MS);
@@ -8453,7 +8597,7 @@ async function refreshPrimers(args) {
8453
8597
  if (primers.length === 0)
8454
8598
  return result;
8455
8599
  const abortController = new AbortController;
8456
- const heartbeat = startLeaseHeartbeat(args.db, args.holderId, args.leaseKey, () => abortController.abort());
8600
+ const heartbeat = startLeaseHeartbeat(args.db, args.holderId, args.leaseKey, () => abortController.abort(), args.leaseAcquisition);
8457
8601
  try {
8458
8602
  for (let i = 0;i < primers.length; i += 1) {
8459
8603
  const primer = primers[i];
@@ -9056,68 +9200,6 @@ function insertDreamRun(db, run) {
9056
9200
  // ../plugin/src/features/magic-context/dreamer/verify.ts
9057
9201
  import { createHash as createHash7 } from "node:crypto";
9058
9202
 
9059
- // ../plugin/src/features/magic-context/dreamer/provider-output-failure.ts
9060
- import { createHash as createHash6 } from "node:crypto";
9061
- var MAX_NEAR_ZERO_OUTPUT_TOKENS = 32;
9062
-
9063
- class DreamerProviderOutputFailureError extends Error {
9064
- fingerprint;
9065
- outputTokens;
9066
- reasoningTokens;
9067
- transient = true;
9068
- constructor(fingerprint, outputTokens, reasoningTokens, responseText) {
9069
- const preview = responseText.trim().replace(/\s+/g, " ").slice(0, 160);
9070
- super(`verify provider-outage completion (output_tokens=${outputTokens}, reasoning_tokens=${reasoningTokens}): ${JSON.stringify(preview)}`);
9071
- this.fingerprint = fingerprint;
9072
- this.outputTokens = outputTokens;
9073
- this.reasoningTokens = reasoningTokens;
9074
- this.name = "DreamerProviderOutputFailureError";
9075
- }
9076
- }
9077
- function finiteTokenCount(value) {
9078
- return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : null;
9079
- }
9080
- function completionShape(value) {
9081
- if (!isRecord(value))
9082
- return null;
9083
- const info = isRecord(value.info) ? value.info : value;
9084
- if (info.role !== "assistant")
9085
- return null;
9086
- const time = isRecord(info.time) ? info.time : null;
9087
- const tokens = isRecord(info.tokens) ? info.tokens : null;
9088
- return {
9089
- createdAt: typeof time?.created === "number" ? time.created : 0,
9090
- finish: typeof info.finish === "string" ? info.finish : typeof info.finish_reason === "string" ? info.finish_reason : typeof info.finishReason === "string" ? info.finishReason : null,
9091
- error: info.error,
9092
- outputTokens: finiteTokenCount(tokens?.output),
9093
- reasoningTokens: finiteTokenCount(tokens?.reasoning)
9094
- };
9095
- }
9096
- function latestAssistantCompletion(messages) {
9097
- if (!Array.isArray(messages))
9098
- return null;
9099
- let latest = null;
9100
- for (const message of messages) {
9101
- const completion = completionShape(message);
9102
- if (completion && (!latest || completion.createdAt >= latest.createdAt))
9103
- latest = completion;
9104
- }
9105
- return latest;
9106
- }
9107
- function providerOutputFailureFromInvalidManifest(messages, responseText) {
9108
- const completion = latestAssistantCompletion(messages);
9109
- if (completion?.finish?.toLowerCase() !== "stop")
9110
- return null;
9111
- if (completion.error != null || completion.outputTokens === null || completion.outputTokens > MAX_NEAR_ZERO_OUTPUT_TOKENS || completion.reasoningTokens !== 0) {
9112
- return null;
9113
- }
9114
- const normalized = responseText.trim().replace(/\s+/g, " ").toLowerCase();
9115
- if (!normalized)
9116
- return null;
9117
- const fingerprint = createHash6("sha256").update(normalized).digest("hex").slice(0, 16);
9118
- return new DreamerProviderOutputFailureError(fingerprint, completion.outputTokens, completion.reasoningTokens, responseText);
9119
- }
9120
-
9121
9203
  // ../plugin/src/features/magic-context/dreamer/verify-gate.ts
9122
9204
  import path5 from "node:path";
9123
9205
  function minOf(values) {
@@ -9362,7 +9444,7 @@ async function runVerify(args) {
9362
9444
  batches.push(gate.inScope.slice(i, i + VERIFY_BATCH_SIZE));
9363
9445
  }
9364
9446
  const abortController = new AbortController;
9365
- const heartbeat = startLeaseHeartbeat(args.db, args.holderId, args.leaseKey, () => abortController.abort());
9447
+ const heartbeat = startLeaseHeartbeat(args.db, args.holderId, args.leaseKey, () => abortController.abort(), args.leaseAcquisition);
9366
9448
  let consecutiveProviderFailures = 0;
9367
9449
  let priorProviderFailureFingerprint = null;
9368
9450
  let lastProviderFailure = null;
@@ -9698,6 +9780,9 @@ function createDreamTaskExecutor(deps) {
9698
9780
  return async (config, ctx) => {
9699
9781
  const { db, projectIdentity, holderId, leaseKey } = ctx;
9700
9782
  const startedAt = Date.now();
9783
+ const leaseAcquisition = ctx.leaseAcquisition ?? acquireLeaseWithAcquisition(db, holderId, leaseKey) ?? (() => {
9784
+ throw new Error("Dream lease unavailable during executor setup");
9785
+ })();
9701
9786
  const deadline = startedAt + config.timeoutMinutes * 60 * 1000;
9702
9787
  const backlogAtStart = getDreamTaskBacklog(db, projectIdentity, config.task);
9703
9788
  const reportProgress = (processed) => {
@@ -9715,7 +9800,7 @@ function createDreamTaskExecutor(deps) {
9715
9800
  };
9716
9801
  const parent = await resolveParentSessionId();
9717
9802
  let moduleRoute;
9718
- if (config.task === "map-memories" || config.task === "compress-cues" || config.task === "verify" || config.task === "verify-broad" || config.task === "retrospective") {
9803
+ if (config.task === "map-memories" || config.task === "compress-cues" || config.task === "classify-memories" || config.task === "verify" || config.task === "verify-broad" || config.task === "retrospective") {
9719
9804
  try {
9720
9805
  moduleRoute = await resolveDreamerModuleRoute({
9721
9806
  db,
@@ -9729,6 +9814,9 @@ function createDreamTaskExecutor(deps) {
9729
9814
  throw new DreamerModuleFailureError("authority.status", error);
9730
9815
  }
9731
9816
  }
9817
+ if (!leaseOwnershipMatches(db, holderId, leaseAcquisition.generation, leaseKey)) {
9818
+ throw new Error("Dream lease lost during executor setup");
9819
+ }
9732
9820
  const recordRun = (status, error, extra) => {
9733
9821
  try {
9734
9822
  insertDreamRun(db, {
@@ -9801,6 +9889,7 @@ function createDreamTaskExecutor(deps) {
9801
9889
  holderId,
9802
9890
  leaseKey,
9803
9891
  deadline,
9892
+ leaseAcquisition,
9804
9893
  model: config.model ?? deps.mural.model ?? deps.dreamerModel,
9805
9894
  fallbackModels: config.fallbackModels,
9806
9895
  moduleRoute,
@@ -9824,6 +9913,7 @@ function createDreamTaskExecutor(deps) {
9824
9913
  holderId,
9825
9914
  leaseKey,
9826
9915
  deadline,
9916
+ leaseAcquisition,
9827
9917
  promotionThreshold: config.promotionThreshold ?? 3,
9828
9918
  model: config.model,
9829
9919
  fallbackModels: config.fallbackModels,
@@ -9843,6 +9933,7 @@ function createDreamTaskExecutor(deps) {
9843
9933
  holderId,
9844
9934
  leaseKey,
9845
9935
  deadline,
9936
+ leaseAcquisition,
9846
9937
  model: config.model,
9847
9938
  fallbackModels: config.fallbackModels,
9848
9939
  moduleRoute,
@@ -9868,6 +9959,7 @@ function createDreamTaskExecutor(deps) {
9868
9959
  holderId,
9869
9960
  leaseKey,
9870
9961
  deadline,
9962
+ leaseAcquisition,
9871
9963
  forceBroad: config.task === "verify-broad",
9872
9964
  model: config.model,
9873
9965
  fallbackModels: config.fallbackModels,
@@ -9901,40 +9993,15 @@ function createDreamTaskExecutor(deps) {
9901
9993
  }
9902
9994
  if (config.task === "classify-memories") {
9903
9995
  let moduleArgs;
9904
- const moduleTransport = deps.transformMode === "ts" ? undefined : deps.moduleClient;
9905
- if (moduleTransport?.authorityStatus) {
9906
- const contextStoreUuid = getContextStoreUuid(db);
9907
- if (!contextStoreUuid) {
9908
- throw new Error("Rust classify requires a context store identity");
9909
- }
9910
- let authority;
9911
- try {
9912
- authority = await moduleTransport.authorityStatus({
9913
- context_store_uuid: contextStoreUuid,
9914
- project: projectIdentity,
9915
- projectRoot: deps.sessionDirectory,
9916
- domain: "memories"
9917
- });
9918
- } catch (error) {
9919
- throw new ClassifyModuleFailureError("authority.status", error);
9920
- }
9921
- if (authority.authority?.state === "MODULE") {
9922
- const generation = authority.authority.generation;
9923
- if (typeof generation !== "number") {
9924
- throw new ClassifyModuleFailureError("authority.status", new Error("response omitted generation"));
9925
- }
9926
- const moduleClient = {
9927
- call: (callArgs) => moduleTransport.call(callArgs)
9928
- };
9929
- moduleArgs = {
9930
- moduleClient,
9931
- moduleSessionId: projectIdentity,
9932
- moduleProjectRoot: deps.sessionDirectory,
9933
- moduleContextStoreUuid: contextStoreUuid,
9934
- moduleAuthorityGeneration: generation,
9935
- moduleCommandId: `${startedAt}:${holderId}`
9936
- };
9937
- }
9996
+ if (moduleRoute) {
9997
+ moduleArgs = {
9998
+ moduleClient: moduleRoute.moduleClient,
9999
+ moduleSessionId: moduleRoute.moduleSessionId,
10000
+ moduleProjectRoot: moduleRoute.moduleProjectRoot,
10001
+ moduleContextStoreUuid: moduleRoute.moduleContextStoreUuid,
10002
+ moduleAuthorityGeneration: moduleRoute.moduleAuthorityGeneration,
10003
+ moduleCommandId: moduleRoute.moduleCommandId
10004
+ };
9938
10005
  }
9939
10006
  const result = await runClassify({
9940
10007
  db,
@@ -9945,6 +10012,7 @@ function createDreamTaskExecutor(deps) {
9945
10012
  holderId,
9946
10013
  leaseKey,
9947
10014
  deadline,
10015
+ leaseAcquisition,
9948
10016
  model: config.model,
9949
10017
  fallbackModels: config.fallbackModels,
9950
10018
  ...moduleArgs,
@@ -9968,6 +10036,7 @@ function createDreamTaskExecutor(deps) {
9968
10036
  holderId,
9969
10037
  leaseKey,
9970
10038
  deadline,
10039
+ leaseAcquisition,
9971
10040
  promotionThreshold: config.promotionThreshold ?? 2,
9972
10041
  ensureProjectRegistered: deps.ensureProjectRegistered
9973
10042
  });
@@ -9985,6 +10054,7 @@ function createDreamTaskExecutor(deps) {
9985
10054
  holderId,
9986
10055
  leaseKey,
9987
10056
  deadline,
10057
+ leaseAcquisition,
9988
10058
  model: config.model,
9989
10059
  fallbackModels: config.fallbackModels,
9990
10060
  language: config.language ?? deps.language,
@@ -10005,6 +10075,7 @@ function createDreamTaskExecutor(deps) {
10005
10075
  holderId,
10006
10076
  leaseKey,
10007
10077
  deadline,
10078
+ leaseAcquisition,
10008
10079
  model: config.model,
10009
10080
  fallbackModels: config.fallbackModels,
10010
10081
  retinaHandoff: deps.retinaHandoff
@@ -10150,7 +10221,7 @@ async function runRetrospectiveTask(config, ctx, helpers) {
10150
10221
  const heartbeat = startLeaseHeartbeat(db, holderId, leaseKey, () => {
10151
10222
  leaseLost = true;
10152
10223
  abortController.abort();
10153
- });
10224
+ }, ctx.leaseAcquisition);
10154
10225
  let childSessionId = null;
10155
10226
  try {
10156
10227
  const createResponse = await createChildSessionWithFence({
@@ -10340,7 +10411,7 @@ async function runAgenticTask(config, ctx, helpers) {
10340
10411
  const heartbeat = startLeaseHeartbeat(db, holderId, leaseKey, () => {
10341
10412
  leaseLost = true;
10342
10413
  abortController.abort();
10343
- });
10414
+ }, ctx.leaseAcquisition);
10344
10415
  let childSessionId = null;
10345
10416
  try {
10346
10417
  const createResponse = await createChildSessionWithFence({
@@ -10523,15 +10594,15 @@ async function runDomainGroup(deps, group, cb) {
10523
10594
  const { db, projectIdentity, executor } = deps;
10524
10595
  const leaseKey = leaseKeyFor(group[0].config.task, projectIdentity);
10525
10596
  const holderId = crypto.randomUUID();
10526
- let acquired = acquireLease(db, holderId, leaseKey);
10527
- if (!acquired && cb?.leaseWaitMs) {
10597
+ let acquisition = acquireLeaseWithAcquisition(db, holderId, leaseKey);
10598
+ if (!acquisition && cb?.leaseWaitMs) {
10528
10599
  const deadline = Date.now() + cb.leaseWaitMs;
10529
- while (!acquired && Date.now() < deadline) {
10600
+ while (!acquisition && Date.now() < deadline) {
10530
10601
  await new Promise((resolve) => setTimeout(resolve, LEASE_WAIT_POLL_MS));
10531
- acquired = acquireLease(db, holderId, leaseKey);
10602
+ acquisition = acquireLeaseWithAcquisition(db, holderId, leaseKey);
10532
10603
  }
10533
10604
  }
10534
- if (!acquired) {
10605
+ if (!acquisition) {
10535
10606
  log(`[dreamer] domain lease busy (${leaseKey}) — deferring ${group.length} task(s)`);
10536
10607
  for (const due of group)
10537
10608
  cb?.onBusy?.(due.config.task);
@@ -10539,7 +10610,7 @@ async function runDomainGroup(deps, group, cb) {
10539
10610
  }
10540
10611
  try {
10541
10612
  for (const due of [...group].sort((a, b) => compareTaskOrder(a.config.task, b.config.task))) {
10542
- if (!peekLeaseHolderAndExpiry(db, holderId, leaseKey)) {
10613
+ if (!leaseOwnershipMatches(db, holderId, acquisition.generation, leaseKey)) {
10543
10614
  log(`[dreamer] domain lease lost (${leaseKey}) — stopping remaining task(s)`);
10544
10615
  break;
10545
10616
  }
@@ -10558,7 +10629,13 @@ async function runDomainGroup(deps, group, cb) {
10558
10629
  }
10559
10630
  let outcome;
10560
10631
  try {
10561
- outcome = await executor(due.config, { db, projectIdentity, holderId, leaseKey });
10632
+ outcome = await executor(due.config, {
10633
+ db,
10634
+ projectIdentity,
10635
+ holderId,
10636
+ leaseKey,
10637
+ leaseAcquisition: acquisition
10638
+ });
10562
10639
  } catch (error) {
10563
10640
  outcome = { status: "failed", transient: true, error: String(error) };
10564
10641
  }
@@ -11962,6 +12039,7 @@ function maybeAutoEmbedPiSession(deps, sessionId, projectDir, projectIdentity, n
11962
12039
  return;
11963
12040
  autoEmbedAttemptedBySession.add(sessionId);
11964
12041
  (async () => {
12042
+ let completedDrainWithWork = false;
11965
12043
  try {
11966
12044
  await new Promise((resolve2) => setTimeout(resolve2, 0));
11967
12045
  await ensureProjectRegisteredFromPiDirectory(projectDir, deps.db);
@@ -11972,9 +12050,13 @@ function maybeAutoEmbedPiSession(deps, sessionId, projectDir, projectIdentity, n
11972
12050
  if (remaining <= 0)
11973
12051
  return;
11974
12052
  notify(`Embedding ${remaining} compartment${remaining === 1 ? "" : "s"} of history in the background…`);
11975
- const { text } = await runEmbedDrain(deps.db, projectIdentity, sessionId);
12053
+ const { text, level } = await runEmbedDrain(deps.db, projectIdentity, sessionId);
12054
+ completedDrainWithWork = level === "success";
11976
12055
  notify(text.replace(/^## \/ctx-embed\n\n/, ""));
11977
- } catch {}
12056
+ } catch {} finally {
12057
+ if (!completedDrainWithWork)
12058
+ autoEmbedAttemptedBySession.delete(sessionId);
12059
+ }
11978
12060
  })();
11979
12061
  }
11980
12062
 
@@ -16302,6 +16384,7 @@ function getPiToolResultCallId(message) {
16302
16384
  return typeof callId === "string" && callId.length > 0 ? callId : null;
16303
16385
  }
16304
16386
  var PI_M1_PLACEHOLDER = "<session-history-since>(no new content since last materialization)</session-history-since>";
16387
+ var MAX_FORCED_MEMORIES_PER_DELTA = 10;
16305
16388
  var PI_M0_UPGRADE_STATE = "pi-m0m1-v2";
16306
16389
  var EMPTY_MAX_COMPARTMENT_SEQ = -1;
16307
16390
  function historySliceTokensPi(m0Text) {
@@ -16379,6 +16462,9 @@ var EMPTY_PI_HARD_SIGNALS = {
16379
16462
  cacheExpired: false,
16380
16463
  lastResponseTime: 0
16381
16464
  };
16465
+ function renderBudgetIdentityPi(state2) {
16466
+ return `m${state2.injectionBudgetTokens ?? DEFAULT_MEMORY_BUDGET_TOKENS}-h${state2.historyBudgetTokens ?? DEFAULT_HISTORY_BUDGET_TOKENS}`;
16467
+ }
16382
16468
  var injectionTokenCountsBySession = new Map;
16383
16469
  var cachedMuralBySession = new Map;
16384
16470
  function rememberPiMuralPayload(sessionId, dataUrl, contentHash) {
@@ -16496,7 +16582,9 @@ function getCachedMarkers(db, state2, compartmentsForNormalization) {
16496
16582
  lastBaselineEndMessageId: cachedBoundary,
16497
16583
  systemHash: meta.cachedM0SystemHash ?? "",
16498
16584
  modelKey: meta.cachedM0ModelKey ?? "",
16499
- projectIdentity: meta.cachedM0ProjectIdentity ?? null
16585
+ projectIdentity: meta.cachedM0ProjectIdentity ?? null,
16586
+ muralEnabled: cachedUpgradeIdentity.muralEnabled ?? false,
16587
+ renderBudgetIdentity: cachedUpgradeIdentity.renderBudgetIdentity ?? ""
16500
16588
  };
16501
16589
  }
16502
16590
  function lastBaselineEndMessageId(compartments) {
@@ -16527,8 +16615,10 @@ function readCurrentMarkersFromCompartments(db, state2, compartments, projectDoc
16527
16615
  compartmentRenderEpoch: COMPARTMENT_RENDER_EPOCH,
16528
16616
  lastBaselineEndMessageId: lastBaselineEndMessageId(compartments),
16529
16617
  systemHash: (state2.hardSignals ?? EMPTY_PI_HARD_SIGNALS).systemHash,
16530
- modelKey: (state2.hardSignals ?? EMPTY_PI_HARD_SIGNALS).modelKey,
16531
- projectIdentity: state2.projectIdentity
16618
+ modelKey: piModelRefToCanonical((state2.hardSignals ?? EMPTY_PI_HARD_SIGNALS).modelKey),
16619
+ projectIdentity: state2.projectIdentity,
16620
+ muralEnabled: state2.muralEnabled === true,
16621
+ renderBudgetIdentity: renderBudgetIdentityPi(state2)
16532
16622
  };
16533
16623
  }
16534
16624
  function mustMaterializePi(state2, db, currentCompartmentsOverride) {
@@ -16549,8 +16639,13 @@ function mustMaterializePi(state2, db, currentCompartmentsOverride) {
16549
16639
  if (cached.compartmentRenderEpoch !== current.compartmentRenderEpoch) {
16550
16640
  return { value: true, reason: "compartment_render_epoch" };
16551
16641
  }
16642
+ if (cached.muralEnabled !== current.muralEnabled || cached.renderBudgetIdentity !== current.renderBudgetIdentity) {
16643
+ return { value: true, reason: "render_config" };
16644
+ }
16552
16645
  const hard = state2.hardSignals ?? EMPTY_PI_HARD_SIGNALS;
16553
- if (hard.modelKey !== "" && hard.modelKey !== (meta.cachedM0ModelKey ?? "")) {
16646
+ const canonicalHardModelKey = piModelRefToCanonical(hard.modelKey);
16647
+ const canonicalCachedModelKey = piModelRefToCanonical(meta.cachedM0ModelKey ?? "");
16648
+ if (canonicalHardModelKey !== "" && canonicalHardModelKey !== canonicalCachedModelKey) {
16554
16649
  return { value: true, reason: "model_change" };
16555
16650
  }
16556
16651
  if (hard.systemHash !== "" && hard.systemHash !== (meta.cachedM0SystemHash ?? "")) {
@@ -16685,8 +16780,10 @@ function readFrozenM0InputsPi(state2, db, docs = readProjectDocsForPiM0(state2),
16685
16780
  compartmentRenderEpoch: COMPARTMENT_RENDER_EPOCH,
16686
16781
  lastBaselineEndMessageId: lastBaselineEndMessageId(compartments),
16687
16782
  systemHash: (state2.hardSignals ?? EMPTY_PI_HARD_SIGNALS).systemHash,
16688
- modelKey: (state2.hardSignals ?? EMPTY_PI_HARD_SIGNALS).modelKey,
16689
- projectIdentity: state2.projectIdentity
16783
+ modelKey: piModelRefToCanonical((state2.hardSignals ?? EMPTY_PI_HARD_SIGNALS).modelKey),
16784
+ projectIdentity: state2.projectIdentity,
16785
+ muralEnabled: state2.muralEnabled === true,
16786
+ renderBudgetIdentity: renderBudgetIdentityPi(state2)
16690
16787
  };
16691
16788
  return { docs, markers, compartments, memories, userProfile, workspace };
16692
16789
  });
@@ -16773,7 +16870,7 @@ function materializeM0Pi(state2, db) {
16773
16870
  projectDocsHash: snapshotMarkers.projectDocsHash,
16774
16871
  materializedAt: snapshotMarkers.materializedAt,
16775
16872
  sessionFactsVersion: snapshotMarkers.sessionFactsVersion,
16776
- upgradeState: encodeCachedM0UpgradeIdentity(snapshotMarkers.upgradeState, snapshotMarkers.compartmentRenderEpoch),
16873
+ upgradeState: encodeCachedM0UpgradeIdentity(snapshotMarkers.upgradeState, snapshotMarkers.compartmentRenderEpoch, snapshotMarkers.muralEnabled, snapshotMarkers.renderBudgetIdentity),
16777
16874
  systemHash: snapshotMarkers.systemHash,
16778
16875
  modelKey: snapshotMarkers.modelKey,
16779
16876
  projectIdentity: snapshotMarkers.projectIdentity
@@ -16809,49 +16906,74 @@ function materializeM0PiWithRetry(state2, db, maxRetries = 3) {
16809
16906
  throw lastError ?? new PiMaterializeContentionError("materialization contention exhausted");
16810
16907
  }
16811
16908
  function renderMemoryUpdatesBlockPi(args) {
16812
- if (args.renderedMemoryIds.length === 0)
16813
- return { block: "", count: 0 };
16814
16909
  const renderedIds = new Set(args.renderedMemoryIds);
16815
16910
  const mutations = args.workspace.isWorkspaced ? getMemoryMutationsForRenderByProjects(args.db, args.workspace.expandedIdentities, args.afterId, args.renderedMemoryIds) : getMemoryMutationsForRender(args.db, args.projectPath, args.afterId, args.renderedMemoryIds);
16816
- if (mutations.length === 0)
16817
- return { block: "", count: 0 };
16911
+ if (mutations.length === 0) {
16912
+ return { block: "", count: 0, forcedMemoryIds: [] };
16913
+ }
16914
+ const forcedIds = new Set;
16818
16915
  const lines = [
16819
16916
  "These memories changed since the snapshot below — trust these:"
16820
16917
  ];
16821
16918
  for (const mutation of mutations) {
16822
- if (mutation.mutationType === "update") {
16823
- lines.push(` <updated id="${mutation.targetMemoryId}">${escapeXmlContent(mutation.newContent ?? "")}</updated>`);
16824
- continue;
16825
- }
16826
16919
  if (mutation.mutationType === "superseded") {
16827
- if (mutation.supersededById !== null && renderedIds.has(mutation.supersededById)) {
16828
- lines.push(` <superseded id="${mutation.targetMemoryId}" by="${mutation.supersededById}"/>`);
16920
+ const replacementId = mutation.supersededById;
16921
+ if (replacementId !== null && !renderedIds.has(replacementId) && args.eligibleMemoryIds.has(replacementId)) {
16922
+ forcedIds.add(replacementId);
16923
+ }
16924
+ if (!renderedIds.has(mutation.targetMemoryId))
16925
+ continue;
16926
+ if (replacementId !== null && args.eligibleMemoryIds.has(replacementId)) {
16927
+ lines.push(` <superseded id="${mutation.targetMemoryId}" by="${replacementId}"/>`);
16829
16928
  } else {
16830
16929
  lines.push(` <removed id="${mutation.targetMemoryId}"/>`);
16831
16930
  }
16832
16931
  continue;
16833
16932
  }
16933
+ if (!renderedIds.has(mutation.targetMemoryId)) {
16934
+ if (mutation.visibilityChanged && args.eligibleMemoryIds.has(mutation.targetMemoryId)) {
16935
+ forcedIds.add(mutation.targetMemoryId);
16936
+ }
16937
+ continue;
16938
+ }
16939
+ if (!args.eligibleMemoryIds.has(mutation.targetMemoryId)) {
16940
+ lines.push(` <removed id="${mutation.targetMemoryId}"/>`);
16941
+ continue;
16942
+ }
16943
+ if (mutation.visibilityChanged && mutation.newContent === null)
16944
+ continue;
16945
+ if (mutation.mutationType === "update") {
16946
+ lines.push(` <updated id="${mutation.targetMemoryId}">${escapeXmlContent(mutation.newContent ?? "")}</updated>`);
16947
+ continue;
16948
+ }
16834
16949
  lines.push(` <removed id="${mutation.targetMemoryId}"/>`);
16835
16950
  }
16951
+ const forcedMemoryIds = [...forcedIds].sort((left, right) => left - right).slice(0, MAX_FORCED_MEMORIES_PER_DELTA);
16952
+ if (lines.length === 1)
16953
+ return { block: "", count: 0, forcedMemoryIds };
16836
16954
  return {
16837
16955
  block: `<memory-updates>
16838
16956
  ${lines.join(`
16839
16957
  `)}
16840
16958
  </memory-updates>`,
16841
- count: mutations.length
16959
+ count: lines.length - 1,
16960
+ forcedMemoryIds
16842
16961
  };
16843
16962
  }
16844
16963
  function renderM1PiWithMetadata(state2, db, markers, renderedMemoryIds, compartmentsOverride) {
16845
16964
  const sections = [];
16846
16965
  const workspace = resolveWorkspaceRenderContextPi(state2, db);
16847
16966
  const memPath = memoryProjectPath(state2);
16967
+ const eligibleMemories = memPath ? workspace.isWorkspaced ? getMemoriesByProjects(db, workspace.expandedIdentities, ["active", "permanent"], markers.materializedAt, workspace.ownIdentities, workspace.shareCategories) : getMemoriesByProject(db, memPath, ["active", "permanent"], markers.materializedAt) : [];
16968
+ const eligibleMemoryIds = new Set(eligibleMemories.map((memory) => memory.id));
16848
16969
  const memoryUpdates = memPath ? renderMemoryUpdatesBlockPi({
16849
16970
  db,
16850
16971
  projectPath: memPath,
16851
16972
  workspace,
16852
16973
  afterId: markers.maxMemoryMutationId,
16853
- renderedMemoryIds
16854
- }) : { block: undefined, count: 0 };
16974
+ renderedMemoryIds,
16975
+ eligibleMemoryIds
16976
+ }) : { block: undefined, count: 0, forcedMemoryIds: [] };
16855
16977
  if (memoryUpdates.block)
16856
16978
  sections.push(memoryUpdates.block);
16857
16979
  const newCompartments = (compartmentsOverride ?? getRenderableCompartmentsPi(db, state2)).filter((compartment) => compartment.sequence > markers.maxCompartmentSeq);
@@ -16863,21 +16985,24 @@ function renderM1PiWithMetadata(state2, db, markers, renderedMemoryIds, compartm
16863
16985
  ${body}
16864
16986
  </new-compartments>`);
16865
16987
  }
16866
- const newMemories = memPath ? workspace.isWorkspaced ? readNewMemoriesForM1Union(db, workspace.expandedIdentities, markers.maxMemoryId, markers.materializedAt, workspace.ownIdentities, workspace.shareCategories) : getMemoriesByProject(db, memPath, ["active", "permanent"], markers.materializedAt).filter((memory) => memory.id > markers.maxMemoryId) : [];
16867
- if (newMemories.length > 0) {
16868
- const memoryBudget = state2.injectionBudgetTokens ?? DEFAULT_MEMORY_BUDGET_TOKENS;
16869
- const memoryRenderOptions = {
16870
- sourceNameByMemoryId: sourceNamesForPiMemories({
16871
- memories: newMemories,
16872
- projectPath: memPath,
16873
- workspace
16874
- })
16875
- };
16876
- const trimmedNewMemories = trimMemoriesToBudgetV2(state2.sessionId, newMemories, Math.max(1, Math.floor(memoryBudget * 0.25)), memoryRenderOptions).renderOrder;
16877
- const newMemoriesBlock = renderMemoryBlockV2(trimmedNewMemories, "new-memories", memoryRenderOptions);
16878
- if (newMemoriesBlock)
16879
- sections.push(newMemoriesBlock);
16880
- }
16988
+ const forcedMemoryIds = new Set(memoryUpdates.forcedMemoryIds);
16989
+ const newMemories = eligibleMemories.filter((memory) => memory.id > markers.maxMemoryId && !forcedMemoryIds.has(memory.id));
16990
+ const memoryBudget = state2.injectionBudgetTokens ?? DEFAULT_MEMORY_BUDGET_TOKENS;
16991
+ const memoryRenderOptions = {
16992
+ sourceNameByMemoryId: sourceNamesForPiMemories({
16993
+ memories: eligibleMemories,
16994
+ projectPath: memPath,
16995
+ workspace
16996
+ })
16997
+ };
16998
+ const trimmedNewMemories = trimMemoriesToBudgetV2(state2.sessionId, newMemories, Math.max(1, Math.floor(memoryBudget * 0.25)), memoryRenderOptions).renderOrder;
16999
+ const deltaMemories = [
17000
+ ...trimmedNewMemories,
17001
+ ...eligibleMemories.filter((memory) => forcedMemoryIds.has(memory.id))
17002
+ ];
17003
+ const newMemoriesBlock = renderMemoryBlockV2(deltaMemories, "new-memories", memoryRenderOptions);
17004
+ if (newMemoriesBlock)
17005
+ sections.push(newMemoriesBlock);
16881
17006
  const currentUserProfileVersion = getProjectState(db, GLOBAL_USER_PROFILE_PROJECT_PATH)?.projectUserProfileVersion ?? 0;
16882
17007
  if (currentUserProfileVersion !== markers.projectUserProfileVersion) {
16883
17008
  const profileBudget = state2.userProfileBudgetTokens ?? DEFAULT_USER_PROFILE_BUDGET_TOKENS;
@@ -16983,14 +17108,16 @@ function markersFromCachedPiRow(row, compartmentsForNormalization) {
16983
17108
  lastBaselineEndMessageId: typeof row.cached_m0_last_baseline_end_message_id === "string" && row.cached_m0_last_baseline_end_message_id.length > 0 ? row.cached_m0_last_baseline_end_message_id : null,
16984
17109
  systemHash: row.cached_m0_system_hash ?? "",
16985
17110
  modelKey: row.cached_m0_model_key ?? "",
16986
- projectIdentity: row.cached_m0_project_identity ?? null
17111
+ projectIdentity: row.cached_m0_project_identity ?? null,
17112
+ muralEnabled: cachedUpgradeIdentity.muralEnabled ?? false,
17113
+ renderBudgetIdentity: cachedUpgradeIdentity.renderBudgetIdentity ?? ""
16987
17114
  };
16988
17115
  }
16989
17116
  function cachedPiRowMatchesSnapshot(args) {
16990
17117
  const rowMarkers = markersFromCachedPiRow(args.row, args.compartmentsForNormalization);
16991
17118
  if (!rowMarkers)
16992
17119
  return false;
16993
- return bufferEqualsNullable(args.row.cached_m0_bytes, args.m0Bytes) && rowMarkers.projectMemoryEpoch === args.markers.projectMemoryEpoch && rowMarkers.projectUserProfileVersion === args.markers.projectUserProfileVersion && rowMarkers.maxCompartmentSeq === args.markers.maxCompartmentSeq && rowMarkers.maxMemoryId === args.markers.maxMemoryId && rowMarkers.maxMutationId === args.markers.maxMutationId && rowMarkers.maxMemoryMutationId === args.markers.maxMemoryMutationId && rowMarkers.materializedAt === args.markers.materializedAt && rowMarkers.sessionFactsVersion === args.markers.sessionFactsVersion && (rowMarkers.upgradeState ?? null) === (args.markers.upgradeState ?? null) && rowMarkers.compartmentRenderEpoch === args.markers.compartmentRenderEpoch && (rowMarkers.systemHash ?? "") === (args.markers.systemHash ?? "") && (rowMarkers.modelKey ?? "") === (args.markers.modelKey ?? "") && (rowMarkers.projectIdentity ?? null) === (args.markers.projectIdentity ?? null) && (rowMarkers.workspaceFingerprint ?? null) === (args.markers.workspaceFingerprint ?? null);
17120
+ return bufferEqualsNullable(args.row.cached_m0_bytes, args.m0Bytes) && rowMarkers.projectMemoryEpoch === args.markers.projectMemoryEpoch && rowMarkers.projectUserProfileVersion === args.markers.projectUserProfileVersion && rowMarkers.maxCompartmentSeq === args.markers.maxCompartmentSeq && rowMarkers.maxMemoryId === args.markers.maxMemoryId && rowMarkers.maxMutationId === args.markers.maxMutationId && rowMarkers.maxMemoryMutationId === args.markers.maxMemoryMutationId && rowMarkers.materializedAt === args.markers.materializedAt && rowMarkers.sessionFactsVersion === args.markers.sessionFactsVersion && (rowMarkers.upgradeState ?? null) === (args.markers.upgradeState ?? null) && rowMarkers.compartmentRenderEpoch === args.markers.compartmentRenderEpoch && (rowMarkers.systemHash ?? "") === (args.markers.systemHash ?? "") && piModelRefToCanonical(rowMarkers.modelKey ?? "") === piModelRefToCanonical(args.markers.modelKey ?? "") && (rowMarkers.projectIdentity ?? null) === (args.markers.projectIdentity ?? null) && (rowMarkers.workspaceFingerprint ?? null) === (args.markers.workspaceFingerprint ?? null);
16994
17121
  }
16995
17122
  function adoptCachedPiProjectIdentity(db, state2) {
16996
17123
  db.prepare("UPDATE session_meta SET cached_m0_project_identity = ? WHERE session_id = ? AND cached_m0_project_identity IS NULL").run(state2.projectIdentity, state2.sessionId);
@@ -17304,13 +17431,44 @@ function isSentinelPart(part) {
17304
17431
  }
17305
17432
 
17306
17433
  // src/pi-context-limit.ts
17307
- function resolvePiUsableContextLimit(args) {
17308
- const rawContext = isSaneLimit(args.rawContextWindow) ? args.rawContextWindow : undefined;
17309
- const detected = typeof args.detectedContextLimit === "number" && Number.isFinite(args.detectedContextLimit) && args.detectedContextLimit >= 1024 ? args.detectedContextLimit : undefined;
17310
- const context = rawContext !== undefined && detected !== undefined ? Math.min(rawContext, detected) : rawContext ?? detected;
17311
- if (context === undefined)
17434
+ var MIN_SANE_LIMIT = 16000;
17435
+ var MAX_SANE_LIMIT = 1e7;
17436
+ function isSaneLimit2(value) {
17437
+ return typeof value === "number" && Number.isFinite(value) && value >= MIN_SANE_LIMIT && value <= MAX_SANE_LIMIT;
17438
+ }
17439
+ function resolvePiWindowGeometry(args) {
17440
+ const runtimeWindow = isSaneLimit2(args.rawContextWindow) ? args.rawContextWindow : isSaneLimit2(args.model?.contextWindow) ? args.model.contextWindow : undefined;
17441
+ const persistedUsable = isSaneLimit2(args.persistedInputTokens) && typeof args.persistedPercentage === "number" && Number.isFinite(args.persistedPercentage) && args.persistedPercentage > 0 ? args.persistedInputTokens / (args.persistedPercentage / 100) : undefined;
17442
+ const persistedWindow = isSaneLimit2(args.persistedInputTokens) && typeof args.persistedPercentage === "number" && Number.isFinite(args.persistedPercentage) && args.persistedPercentage > 0 ? args.persistedInputTokens / (args.persistedPercentage / 100) : undefined;
17443
+ const context = runtimeWindow ?? persistedWindow;
17444
+ if (!isSaneLimit2(context))
17312
17445
  return;
17313
- return resolveLimit({ context, output: args.model?.maxTokens }, args.model?.provider ?? "unknown", args.model?.id ?? "unknown");
17446
+ const providerID = args.model?.provider ?? "unknown";
17447
+ const modelID = args.model?.id ?? "unknown";
17448
+ const result = deriveWindowGeometry(providerID, modelID, {
17449
+ context,
17450
+ output: args.model?.maxTokens
17451
+ }, {
17452
+ overlay: resolveWindowOverlayFacts(providerID, modelID, getWindowOverlay()),
17453
+ contextCap: isSaneLimit2(args.detectedContextLimit) ? args.detectedContextLimit : undefined,
17454
+ reserveConfig: args.reserveConfig,
17455
+ harness: "pi"
17456
+ });
17457
+ if (!result || !isSaneLimit2(persistedUsable))
17458
+ return result;
17459
+ const usableSoft = Math.round(persistedUsable);
17460
+ return {
17461
+ ...result,
17462
+ usableSoft,
17463
+ usableHard: Math.max(usableSoft, result.usableHard),
17464
+ derivation: {
17465
+ ...result.derivation,
17466
+ reserve: Math.max(0, result.derivation.window - usableSoft)
17467
+ }
17468
+ };
17469
+ }
17470
+ function resolvePiUsableContextLimit(args) {
17471
+ return resolvePiWindowGeometry(args)?.usableSoft;
17314
17472
  }
17315
17473
 
17316
17474
  // src/pi-historian-runner.ts
@@ -21868,10 +22026,14 @@ function processSystemPromptForCache(args) {
21868
22026
  const dateMatch = systemPrompt.match(DATE_PATTERN);
21869
22027
  const liveDate = dateMatch ? dateMatch[0] : null;
21870
22028
  const stickyDate = stickyDateBySession.get(sessionId);
22029
+ const stableCandidate = liveDate && stickyDate && liveDate !== stickyDate ? systemPrompt.replace(DATE_PATTERN, stickyDate) : systemPrompt;
22030
+ const stableCandidateHash = createHash10("md5").update(promptSurfaceHashMaterial(stableCandidate, args.promptSurfacePreset)).digest("hex");
22031
+ const contentOrPresetChanged = !isFirstHash && stableCandidateHash !== previousHash;
22032
+ const dateMayAdvance = isCacheBusting || contentOrPresetChanged;
21871
22033
  if (liveDate && !stickyDate) {
21872
22034
  stickyDateBySession.set(sessionId, liveDate);
21873
22035
  } else if (liveDate && stickyDate && liveDate !== stickyDate) {
21874
- if (isCacheBusting) {
22036
+ if (dateMayAdvance) {
21875
22037
  stickyDateBySession.set(sessionId, liveDate);
21876
22038
  sessionLog(sessionId, `system prompt date updated: ${stickyDate} → ${liveDate} (cache-busting pass)`);
21877
22039
  } else {
@@ -21908,6 +22070,37 @@ function clearPiSystemPromptSession(sessionId) {
21908
22070
  }
21909
22071
 
21910
22072
  // src/temporal-awareness-pi.ts
22073
+ function withoutPiLeadingTemporalMarker(text) {
22074
+ const { tagPrefix, body } = peelLeadingMcTagNotation(text);
22075
+ return tagPrefix + body.replace(TEMPORAL_MARKER_PATTERN, "");
22076
+ }
22077
+ function stripPiLeadingTemporalMarker(message) {
22078
+ if (!message || typeof message !== "object")
22079
+ return false;
22080
+ const userMessage = message;
22081
+ if (userMessage.role !== "user")
22082
+ return false;
22083
+ if (typeof userMessage.content === "string") {
22084
+ const stripped2 = withoutPiLeadingTemporalMarker(userMessage.content);
22085
+ if (stripped2 === userMessage.content)
22086
+ return false;
22087
+ userMessage.content = stripped2;
22088
+ return true;
22089
+ }
22090
+ if (!Array.isArray(userMessage.content))
22091
+ return false;
22092
+ const firstTextIndex = userMessage.content.findIndex((part) => part?.type === "text");
22093
+ if (firstTextIndex < 0)
22094
+ return false;
22095
+ const firstText = userMessage.content[firstTextIndex];
22096
+ const stripped = withoutPiLeadingTemporalMarker(firstText.text);
22097
+ if (stripped === firstText.text)
22098
+ return false;
22099
+ const content = userMessage.content.slice();
22100
+ content[firstTextIndex] = { ...firstText, text: stripped };
22101
+ userMessage.content = content;
22102
+ return true;
22103
+ }
21911
22104
  function injectPiTemporalMarkers(messages) {
21912
22105
  let injected = 0;
21913
22106
  let prevTimestampMs;
@@ -22679,6 +22872,9 @@ function extractStableId(msg, index, entryIds) {
22679
22872
  // src/context-handler.ts
22680
22873
  var EMERGENCY_BLOCK_PERCENTAGE = 95;
22681
22874
  var FORWARD_PRESSURE_LIMIT_FACTOR = 0.85;
22875
+ function isPiHardCacheExpired(lastResponseTime, ttlMs, now) {
22876
+ return lastResponseTime > 0 && now - lastResponseTime > ttlMs;
22877
+ }
22682
22878
  function applyForwardPressureFloor(trailingPercentage, trailingInputTokens, piUsageTokens, correctedLimit) {
22683
22879
  const forwardTokens = typeof piUsageTokens === "number" && piUsageTokens > 0 ? piUsageTokens : 0;
22684
22880
  if (forwardTokens === 0 || !isSaneLimit(correctedLimit)) {
@@ -22732,7 +22928,7 @@ function buildPiTextIdentityPlan(db, sessionId, tagger, transcript, reuseCandida
22732
22928
  const messageId = message.info.id;
22733
22929
  if (messageId === undefined)
22734
22930
  continue;
22735
- currentSourcesByMessageId.set(messageId, message.parts.filter((part) => part.kind === "text").map((part) => stripTagPrefix(part.getText() ?? "")));
22931
+ currentSourcesByMessageId.set(messageId, message.parts.filter((part) => part.kind === "text").map((part) => withoutPiLeadingTemporalMarker(stripTagPrefix(part.getText() ?? ""))));
22736
22932
  }
22737
22933
  const legacyRowsByMessageId = new Map;
22738
22934
  const versionedMessageIds = new Set;
@@ -22778,7 +22974,7 @@ function buildPiTextIdentityPlan(db, sessionId, tagger, transcript, reuseCandida
22778
22974
  if (legacyRows.length === 0)
22779
22975
  continue;
22780
22976
  legacyRows.sort((left, right) => left.ordinal - right.ordinal);
22781
- const vectorMatches = legacyRows.length === currentSources.length && legacyRows.every((row, index) => row.ordinal === index && sourceCache.get(row.tagId) === currentSources[index]);
22977
+ const vectorMatches = legacyRows.length === currentSources.length && legacyRows.every((row, index) => row.ordinal === index && withoutPiLeadingTemporalMarker(sourceCache.get(row.tagId) ?? "") === currentSources[index]);
22782
22978
  if (!vectorMatches)
22783
22979
  driftedMessageIds.add(messageId);
22784
22980
  }
@@ -23086,6 +23282,30 @@ function buildPiAlignedEntryIds(entries) {
23086
23282
  }
23087
23283
  return ids;
23088
23284
  }
23285
+ function stripMcOwnedPiCompactionSummary(messages, entryIds, branchEntries) {
23286
+ const summaryMessage = messages[0];
23287
+ if (summaryMessage?.role !== "compactionSummary")
23288
+ return false;
23289
+ let compaction;
23290
+ for (let index = branchEntries.length - 1;index >= 0; index -= 1) {
23291
+ const entry = branchEntries[index];
23292
+ if (entry?.type === "compaction") {
23293
+ compaction = entry;
23294
+ break;
23295
+ }
23296
+ }
23297
+ if (compaction?.fromHook !== true)
23298
+ return false;
23299
+ const details = compaction.details;
23300
+ if (details?.source !== "magic-context")
23301
+ return false;
23302
+ if (summaryMessage.summary !== compaction.summary || summaryMessage.tokensBefore !== compaction.tokensBefore || entryIds[0] !== undefined) {
23303
+ return false;
23304
+ }
23305
+ messages.splice(0, 1);
23306
+ entryIds.splice(0, 1);
23307
+ return true;
23308
+ }
23089
23309
  function getPiBranchEntryLookup(entries) {
23090
23310
  const cached = piBranchLookupByProjection.get(entries);
23091
23311
  if (cached)
@@ -23447,6 +23667,9 @@ function registerPiContextHandler(pi, baseOptions) {
23447
23667
  const alignedEntryIds = branchLookup?.alignedEntryIds ?? null;
23448
23668
  const resolvedEntryIds = alignedEntryIds?.length === event.messages.length ? alignedEntryIds : branchEntries === null ? null : collectMessageEntryIdsByRef(ctx, event.messages, sessionId, branchEntries);
23449
23669
  const strictEntryIds = resolvedEntryIds ? [...resolvedEntryIds] : null;
23670
+ if (strictEntryIds && branchEntries && options.injection && !options.compactionOff && stripMcOwnedPiCompactionSummary(event.messages, strictEntryIds, branchEntries)) {
23671
+ logTransformTiming(sessionId, "mcCompactionSummarySuppression", tEntryBranch);
23672
+ }
23450
23673
  if (strictEntryIds && options.injection && !options.compactionOff) {
23451
23674
  const removed = trimPiMessagesToCachedBoundary(options.db, sessionId, event.messages, strictEntryIds);
23452
23675
  if (removed > 0) {
@@ -23488,7 +23711,7 @@ function registerPiContextHandler(pi, baseOptions) {
23488
23711
  }
23489
23712
  const previousModelKey = liveModelBySession.get(sessionId);
23490
23713
  const currentModelKey = resolvePiContextModelKey(ctx);
23491
- const modelChanged = previousModelKey !== undefined && currentModelKey !== undefined && previousModelKey !== currentModelKey;
23714
+ const modelChanged = previousModelKey !== undefined && currentModelKey !== undefined && piModelRefToCanonical(previousModelKey) !== piModelRefToCanonical(currentModelKey);
23492
23715
  if (currentModelKey !== undefined) {
23493
23716
  liveModelBySession.set(sessionId, currentModelKey);
23494
23717
  }
@@ -23587,11 +23810,12 @@ function registerPiContextHandler(pi, baseOptions) {
23587
23810
  usageContextLimit = modelWindow;
23588
23811
  }
23589
23812
  }
23590
- usageContextLimit = resolvePiUsableContextLimit({
23813
+ const windowGeometry = resolvePiWindowGeometry({
23591
23814
  rawContextWindow: usageContextLimit,
23592
23815
  model: ctx.model,
23593
23816
  detectedContextLimit
23594
23817
  });
23818
+ usageContextLimit = windowGeometry?.usableSoft;
23595
23819
  const effectiveExecuteThresholdPercentage = resolveExecuteThreshold(schedulerConfig.executeThresholdPercentage, modelKey, 65, {
23596
23820
  tokensConfig: schedulerConfig.executeThresholdTokens,
23597
23821
  contextLimit: usageContextLimit,
@@ -23663,7 +23887,9 @@ function registerPiContextHandler(pi, baseOptions) {
23663
23887
  schedulerDecision = midTurnAdjustedSchedulerDecision;
23664
23888
  sessionLog(sessionId, `[boundary-exec] base=${schedulerDecisionEarly} bypass=${bypassReason} midTurn=${midTurn} effective=${midTurnAdjustedSchedulerDecision} sideEffect=${sideEffect}`);
23665
23889
  const forceMaterialization = !options.compactionOff && usagePercentage >= forceMaterializationPercentage;
23666
- const isEmergency = !options.compactionOff && usagePercentage >= EMERGENCY_BLOCK_PERCENTAGE;
23890
+ const hardUsagePercentage = needsEmergencyBump ? Math.max(EMERGENCY_BLOCK_PERCENTAGE, usagePercentage) : windowGeometry?.usableHard && usageInputTokens > 0 ? usageInputTokens / windowGeometry.usableHard * 100 : usagePercentage;
23891
+ const emergencyPercentage = ctx.model ? hardUsagePercentage : usagePercentage;
23892
+ const isEmergency = !options.compactionOff && emergencyPercentage >= EMERGENCY_BLOCK_PERCENTAGE;
23667
23893
  if (isEmergency) {
23668
23894
  const lastNotifiedAt = lastEmergencyNotificationAtMs.get(sessionId) ?? 0;
23669
23895
  const now = Date.now();
@@ -24474,7 +24700,7 @@ async function runPipeline(args) {
24474
24700
  return {
24475
24701
  systemHash: typeof hardMeta.systemPromptHash === "string" ? hardMeta.systemPromptHash : "",
24476
24702
  modelKey: liveModelBySession.get(args.sessionId) ?? "",
24477
- cacheExpired: hardMeta.lastResponseTime > 0 && Date.now() - hardMeta.lastResponseTime >= piTtlMs,
24703
+ cacheExpired: isPiHardCacheExpired(hardMeta.lastResponseTime, piTtlMs, Date.now()),
24478
24704
  lastResponseTime: hardMeta.lastResponseTime
24479
24705
  };
24480
24706
  })() : undefined;
@@ -24545,8 +24771,9 @@ async function runPipeline(args) {
24545
24771
  }
24546
24772
  const deferredMaterializationWasPending = deferredMaterializationSessions.has(args.sessionId);
24547
24773
  const deferredHistoryRefreshWasPending = deferredHistoryWasPendingAtPassStart;
24548
- const pendingOps = getPendingOps(args.db, args.sessionId);
24549
- const pendingOperationTags = getTagsForPendingOperations(args.db, args.sessionId, pendingOps.map((operation) => operation.tagId), args.protectedTags, RECENT_TOOL_SKELETON_WINDOW);
24774
+ const shouldReadPendingOps = !args.compactionOff && (args.schedulerDecision === "execute" || args.forceMaterialization || hasPendingMaterializeSignal || m0HardFoldThisPass || historianRunning);
24775
+ const pendingOps = shouldReadPendingOps ? getPendingOps(args.db, args.sessionId) : [];
24776
+ const pendingOperationTags = pendingOps.length > 0 ? getTagsForPendingOperations(args.db, args.sessionId, pendingOps.map((operation) => operation.tagId), args.protectedTags, RECENT_TOOL_SKELETON_WINDOW) : [];
24550
24777
  const baseShouldApplyPendingOps = args.schedulerDecision === "execute" || args.forceMaterialization || hasPendingMaterializeSignal || m0HardFoldThisPass;
24551
24778
  const deferredMaterialize = canConsumeDeferredLate && deferredMaterializationWasPending;
24552
24779
  const deferredHistoryRefresh = canConsumeDeferredLate && deferredHistoryRefreshWasPending;
@@ -24578,10 +24805,10 @@ async function runPipeline(args) {
24578
24805
  }
24579
24806
  const targetTagNumbers = [...targets.keys()];
24580
24807
  const tGetTags = performance.now();
24581
- const flushedSliceTags = getTagsByNumbers(args.db, args.sessionId, targetTagNumbers);
24582
- logTransformTiming(args.sessionId, "getTagsByNumbers", tGetTags, `targets=${targetTagNumbers.length} fetched=${flushedSliceTags.length}`);
24808
+ const flushedDroppedTags = getDroppedTagsByNumbers(args.db, args.sessionId, targetTagNumbers);
24809
+ logTransformTiming(args.sessionId, "getDroppedTagsByNumbers", tGetTags, `targets=${targetTagNumbers.length} fetched=${flushedDroppedTags.length}`);
24583
24810
  const tFlushed = performance.now();
24584
- didMutateFromFlushedStatuses = applyFlushedStatuses(args.sessionId, args.db, targets, flushedSliceTags);
24811
+ didMutateFromFlushedStatuses = applyFlushedStatuses(args.sessionId, args.db, targets, flushedDroppedTags);
24585
24812
  logTransformTiming(args.sessionId, "applyFlushedStatuses", tFlushed);
24586
24813
  logTransformTiming(args.sessionId, "batchFinalize:flushed", tFlushed);
24587
24814
  const messageIdToMaxTag = buildMessageIdToMaxTag(targets);
@@ -24825,6 +25052,10 @@ async function runPipeline(args) {
24825
25052
  hardSignals: piHardSignals,
24826
25053
  muralEnabled: args.injection.muralEnabled === true
24827
25054
  }, args.db, args.messages, args.entryIds, args.isCacheBusting || deferredHistoryRefresh || executedWorkThisPass);
25055
+ if (args.temporalAwareness && injectionResult.skippedVisibleMessages > 0) {
25056
+ const firstRetainedMessage = args.messages[injectionResult.syntheticLeadingCount];
25057
+ stripPiLeadingTemporalMarker(firstRetainedMessage);
25058
+ }
24828
25059
  if (args.isCacheBusting) {
24829
25060
  historyRefreshSessions.delete(args.sessionId);
24830
25061
  historyWasConsumedThisPass = true;
@@ -27394,7 +27625,7 @@ function formatExecuteThreshold(detail, contextLimit) {
27394
27625
  }
27395
27626
  return `${percentage}%${clampNote}`;
27396
27627
  }
27397
- function executeStatus(db, sessionId, protectedTags, executeThresholdPercentageConfig = DEFAULT_EXECUTE_THRESHOLD_PERCENTAGE, liveModelKey, historyBudgetPercentage, commitClusterTrigger, executeThresholdTokens, contextLimit, dreamer) {
27628
+ function executeStatus(db, sessionId, protectedTags, executeThresholdPercentageConfig = DEFAULT_EXECUTE_THRESHOLD_PERCENTAGE, liveModelKey, historyBudgetPercentage, commitClusterTrigger, executeThresholdTokens, contextLimit, dreamer, windowGeometry) {
27398
27629
  const thresholdDetail = resolveExecuteThresholdDetail(executeThresholdPercentageConfig, liveModelKey, DEFAULT_EXECUTE_THRESHOLD_PERCENTAGE, {
27399
27630
  tokensConfig: executeThresholdTokens,
27400
27631
  contextLimit,
@@ -27455,7 +27686,7 @@ function executeStatus(db, sessionId, protectedTags, executeThresholdPercentageC
27455
27686
  ] : [], ...formatDreamTaskBacklogs(dreamer.backlog).split("\\n"));
27456
27687
  }
27457
27688
  if (meta.lastContextPercentage > 0 || meta.lastInputTokens > 0) {
27458
- lines.push("", "### Context Usage", `- Last percentage: ${meta.lastContextPercentage.toFixed(1)}%`, `- Last input tokens: ${meta.lastInputTokens.toLocaleString()}`, `- Resolved context limit: ${displayContextLimit > 0 ? displayContextLimit.toLocaleString() : "unknown"}`, `- Proactive compartment evaluation: ${proactiveCompartmentTrigger}%`, `- Post-drop target for historian: ${(executeThresholdPercentage * POST_DROP_TARGET_RATIO).toFixed(0)}% (${executeThresholdPercentage}% * ${POST_DROP_TARGET_RATIO})`, `- Commit cluster trigger: ${commitClusterTrigger?.enabled !== false ? `enabled (min ${commitClusterTrigger?.min_clusters ?? 3} clusters)` : "disabled"}, tail-size trigger: > 3x compartment budget`);
27689
+ lines.push("", "### Context Usage", `- Last percentage: ${meta.lastContextPercentage.toFixed(1)}%`, `- Last input tokens: ${meta.lastInputTokens.toLocaleString()}`, `- Resolved context limit: ${displayContextLimit > 0 ? displayContextLimit.toLocaleString() : "unknown"}`, ...windowGeometry ? [`- ${formatWindowDerivationLine(meta.lastInputTokens, windowGeometry)}`] : [], `- Proactive compartment evaluation: ${proactiveCompartmentTrigger}%`, `- Post-drop target for historian: ${(executeThresholdPercentage * POST_DROP_TARGET_RATIO).toFixed(0)}% (${executeThresholdPercentage}% * ${POST_DROP_TARGET_RATIO})`, `- Commit cluster trigger: ${commitClusterTrigger?.enabled !== false ? `enabled (min ${commitClusterTrigger?.min_clusters ?? 3} clusters)` : "disabled"}, tail-size trigger: > 3x compartment budget`);
27459
27690
  }
27460
27691
  const compartments = getCompartments(db, sessionId);
27461
27692
  let historyBlockTokens = 0;
@@ -27556,7 +27787,7 @@ ${c.content}
27556
27787
  // package.json
27557
27788
  var package_default = {
27558
27789
  name: "@cortexkit/pi-magic-context",
27559
- version: "0.36.0",
27790
+ version: "0.37.0",
27560
27791
  type: "module",
27561
27792
  description: "Pi and OMP coding agent extension for Magic Context — cross-session memory and context management",
27562
27793
  main: "dist/index.js",
@@ -27596,6 +27827,7 @@ var package_default = {
27596
27827
  prepublishOnly: "bun run build"
27597
27828
  },
27598
27829
  dependencies: {
27830
+ "@cortexkit/subc-client": "0.4.1",
27599
27831
  "@huggingface/transformers": "^4.1.0",
27600
27832
  "@jitl/quickjs-singlefile-cjs-release-asyncify": "0.32.0",
27601
27833
  "ai-tokenizer": "^1.0.6",
@@ -27723,6 +27955,9 @@ function renderInner(s, theme, innerWidth) {
27723
27955
  lines.push(`${theme.fg("accent", theme.bold("⚡ Magic Context Status"))} ${theme.fg("muted", `v${package_default.version}`)}`);
27724
27956
  lines.push("");
27725
27957
  lines.push(`Context ${theme.fg(pctColor, theme.bold(`${s.usagePercentage.toFixed(1)}%`))} · ${fmt2(s.inputTokens)} / ${s.contextLimit > 0 ? fmt2(s.contextLimit) : "?"} tokens`);
27958
+ if (s.windowGeometry) {
27959
+ lines.push(formatWindowDerivationLine(s.inputTokens, s.windowGeometry));
27960
+ }
27726
27961
  lines.push(`Work tokens ${fmt2(s.newWorkTokens)} new · ${fmt2(s.totalInputTokens)} total input`);
27727
27962
  lines.push(renderBar(s, innerWidth));
27728
27963
  for (const seg of breakdownSegments(s)) {
@@ -27783,18 +28018,22 @@ function drawBorder(inner, width, theme) {
27783
28018
  function buildPiStatusDetail(pi, ctx, deps, sessionId) {
27784
28019
  const usage = ctx.getContextUsage?.();
27785
28020
  const meta = getOrCreateSessionMeta(deps.db, sessionId);
27786
- const inputTokens = typeof usage?.tokens === "number" ? usage.tokens : meta.lastInputTokens;
28021
+ const hasPersistedPressure = meta.lastInputTokens > 0 && meta.lastContextPercentage > 0;
28022
+ const inputTokens = hasPersistedPressure ? meta.lastInputTokens : typeof usage?.tokens === "number" ? usage.tokens : 0;
27787
28023
  let detectedContextLimit;
27788
28024
  try {
27789
28025
  const detected = getOverflowState(deps.db, sessionId).detectedContextLimit;
27790
28026
  if (detected > 0)
27791
28027
  detectedContextLimit = detected;
27792
28028
  } catch {}
27793
- const contextLimit = resolvePiUsableContextLimit({
28029
+ const windowGeometry = resolvePiWindowGeometry({
27794
28030
  rawContextWindow: usage?.contextWindow ?? ctx.model?.contextWindow,
27795
28031
  model: ctx.model,
27796
- detectedContextLimit
27797
- }) ?? (meta.lastContextPercentage > 0 ? Math.round(inputTokens / (meta.lastContextPercentage / 100)) : 0);
28032
+ detectedContextLimit,
28033
+ persistedInputTokens: meta.lastInputTokens,
28034
+ persistedPercentage: meta.lastContextPercentage
28035
+ });
28036
+ const contextLimit = windowGeometry?.usableSoft ?? 0;
27798
28037
  const usagePercentage = contextLimit > 0 && inputTokens > 0 ? inputTokens / contextLimit * 100 : meta.lastContextPercentage;
27799
28038
  const compartments = getCompartments(deps.db, sessionId);
27800
28039
  const metaRow = readSessionMetaRow(deps.db, sessionId);
@@ -27888,6 +28127,7 @@ ${safeStringify(tool.parameters)}`);
27888
28127
  lastTransformError: meta.lastTransformError,
27889
28128
  isSubagent: meta.isSubagent,
27890
28129
  contextLimit,
28130
+ windowGeometry,
27891
28131
  executeThreshold: threshold.percentage,
27892
28132
  executeThresholdMode: threshold.mode,
27893
28133
  executeThresholdClamped: threshold.clamped,
@@ -28075,14 +28315,18 @@ No active Pi session is available.`,
28075
28315
  if (detected > 0)
28076
28316
  detectedContextLimit = detected;
28077
28317
  } catch {}
28078
- const usableContextLimit = resolvePiUsableContextLimit({
28318
+ const meta = getOrCreateSessionMeta(currentDeps.db, sessionId);
28319
+ const windowGeometry = resolvePiWindowGeometry({
28079
28320
  rawContextWindow: usage?.contextWindow ?? ctx.model?.contextWindow,
28080
28321
  model: ctx.model,
28081
- detectedContextLimit
28322
+ detectedContextLimit,
28323
+ persistedInputTokens: meta.lastInputTokens,
28324
+ persistedPercentage: meta.lastContextPercentage
28082
28325
  });
28326
+ const usableContextLimit = windowGeometry?.usableSoft;
28083
28327
  const statusText = executeStatus(currentDeps.db, sessionId, currentDeps.protectedTags ?? 20, currentDeps.executeThresholdPercentage, modelKey, currentDeps.historyBudgetPercentage, currentDeps.commitClusterTrigger, currentDeps.executeThresholdTokens, usableContextLimit, {
28084
28328
  backlog: getDreamTaskBacklogs(currentDeps.db, currentDeps.projectIdentity, CANONICAL_DREAM_TASKS)
28085
- });
28329
+ }, windowGeometry);
28086
28330
  const details = buildStatusDetails(currentDeps, sessionId);
28087
28331
  sendCtxStatusMessage(pi, { title: "/ctx-status", text: statusText, level: "info" }, details);
28088
28332
  } catch (error) {
@@ -28675,6 +28919,9 @@ async function handlePiSessionBeforeCompact(args) {
28675
28919
  info("session_before_compact: cancelling — magic-context owns compaction");
28676
28920
  return { cancel: true };
28677
28921
  }
28922
+ function canonicalPiModelKey(provider, model) {
28923
+ return piModelRefToCanonical(`${provider}/${model}`);
28924
+ }
28678
28925
  function persistPiMessageEndModelMeta(args) {
28679
28926
  if (!args.message || typeof args.message !== "object")
28680
28927
  return;
@@ -28682,7 +28929,7 @@ function persistPiMessageEndModelMeta(args) {
28682
28929
  if (msg.role !== "assistant" || typeof msg.provider !== "string" || msg.provider.length === 0 || typeof msg.model !== "string" || msg.model.length === 0) {
28683
28930
  return;
28684
28931
  }
28685
- const modelKey = `${msg.provider}/${msg.model}`;
28932
+ const modelKey = canonicalPiModelKey(msg.provider, msg.model);
28686
28933
  recordPiLiveModel(args.sessionId, modelKey);
28687
28934
  const cacheTtl = resolveCacheTtl(args.cacheTtlConfig, modelKey);
28688
28935
  const currentMeta = getOrCreateSessionMeta(args.db, args.sessionId);
@@ -29398,6 +29645,7 @@ async function startPiMagicContextRuntime(pi, database, dbPath) {
29398
29645
  info(bootProjectDeps.dreamerEnabled ? "registered dreamer: DISABLED (no dreamer config)" : "registered dreamer: DISABLED (dreamer.disable=true or no dreamer config)");
29399
29646
  }
29400
29647
  pi.on("before_agent_start", async (event, ctx) => {
29648
+ await preloadTokenizer();
29401
29649
  try {
29402
29650
  if (ctx.hasUI && shouldShowAnnouncement()) {
29403
29651
  const featureText = ANNOUNCEMENT_FEATURES.map((line) => ` • ${line}`).join(`
@@ -29493,7 +29741,7 @@ async function startPiMagicContextRuntime(pi, database, dbPath) {
29493
29741
  }
29494
29742
  const isCacheBusting = sessionId ? hasSystemPromptRefresh(sessionId) : true;
29495
29743
  const promptSurfaceModel = ctx.model;
29496
- const promptSurfaceModelKey = typeof promptSurfaceModel?.provider === "string" && promptSurfaceModel.provider.length > 0 && typeof promptSurfaceModel.id === "string" && promptSurfaceModel.id.length > 0 ? `${promptSurfaceModel.provider}/${promptSurfaceModel.id}` : undefined;
29744
+ const promptSurfaceModelKey = typeof promptSurfaceModel?.provider === "string" && promptSurfaceModel.provider.length > 0 && typeof promptSurfaceModel.id === "string" && promptSurfaceModel.id.length > 0 ? canonicalPiModelKey(promptSurfaceModel.provider, promptSurfaceModel.id) : undefined;
29497
29745
  const promptSurface = sessionId ? promptSurfaceGuidanceEpochs.resolve(sessionId, effectiveConfig.prompt_surface, promptSurfaceModelKey) : promptSurfaceRuntime.resolveGuidance(effectiveConfig.prompt_surface, promptSurfaceModelKey);
29498
29746
  const block = buildMagicContextBlock({
29499
29747
  db,
@@ -29778,5 +30026,6 @@ export {
29778
30026
  src_default as default,
29779
30027
  capturePiTodowriteMessageIfCompatible,
29780
30028
  capturePiTodowriteArgsIfCompatible,
30029
+ canonicalPiModelKey,
29781
30030
  __test
29782
30031
  };