@cortexkit/pi-magic-context 0.36.1 → 0.38.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,9 +1,12 @@
1
1
  import {
2
2
  AGE_RECLAIM_MIN_TOKENS,
3
3
  BoundedSessionMap,
4
+ CHANNEL1_FLOOR_TOKENS,
5
+ CHANNEL1_SENTINEL,
4
6
  COMPACTION_ENABLED_PATH,
5
7
  COMPARTMENT_LEASE_RENEWAL_MS,
6
8
  COMPARTMENT_RENDER_EPOCH,
9
+ CTX_REDUCE_KEEP,
7
10
  DEFAULT_EXECUTE_THRESHOLD_PERCENTAGE,
8
11
  DEFAULT_HISTORIAN_TIMEOUT_MS,
9
12
  DEFAULT_HISTORY_BUDGET_TOKENS,
@@ -37,6 +40,8 @@ import {
37
40
  backfillTagTokenCounts,
38
41
  beginBootQuietPeriod,
39
42
  buildCanonicalChunkTextFromFts,
43
+ buildChannel1Reminder,
44
+ buildChannel2Reminder,
40
45
  buildCompartmentSummaryFallbackText,
41
46
  buildPrimaryLanguageDirective,
42
47
  buildSyntheticTodoPart,
@@ -46,9 +51,11 @@ import {
46
51
  bumpProjectUserProfileVersion,
47
52
  byteSize,
48
53
  canonicalizeInMemoryChunkTextForEmbedding,
54
+ casChannel2NudgeClaim,
49
55
  casChannel2NudgeState,
50
56
  chunkCanonicalText,
51
57
  chunkEmbeddingWindowsAreCurrent,
58
+ claimChannel2NudgeState,
52
59
  cleanUserText,
53
60
  clearCachedM0M1,
54
61
  clearCompressionDepth,
@@ -82,14 +89,17 @@ import {
82
89
  createPrimer,
83
90
  createPromptSurfaceGuidanceEpochCache,
84
91
  createPromptSurfaceRuntime,
92
+ decideChannel1,
85
93
  decodeCachedM0UpgradeIdentity,
86
94
  deleteMemory,
87
95
  deleteUserMemoryCandidates,
88
96
  deliverNoteNudgeAtomic,
89
97
  deriveTagLoadFloor,
98
+ deriveWindowGeometry,
90
99
  describeError,
91
100
  dismissUserMemory,
92
101
  drainCommitBacklogForProject,
102
+ effectiveTailHygiene,
93
103
  embedBatchForProject,
94
104
  embedItemsForProject,
95
105
  embedPromotedFacts,
@@ -103,8 +113,10 @@ import {
103
113
  escalationBands,
104
114
  escapeXmlAttr,
105
115
  escapeXmlContent,
116
+ estimateImageTokensFromDataUrl,
106
117
  estimateTokens,
107
118
  estimateTrueRawMessageTokens,
119
+ evaluateChannel2,
108
120
  expandWorkspaceIdentitySetWithAliases,
109
121
  extractM0Block,
110
122
  extractTexts,
@@ -113,8 +125,8 @@ import {
113
125
  findAdoptableFallbackTags,
114
126
  findLastModelKeyFromBranch,
115
127
  findPiFallbackToolOwnerTags,
128
+ formatWindowDerivationLine,
116
129
  getActivePrimers,
117
- getActiveTagTokenAggregate,
118
130
  getActiveTagsBySession,
119
131
  getActiveToolTagsForAgeReclaim,
120
132
  getActiveUserMemories,
@@ -122,6 +134,7 @@ import {
122
134
  getAllStatusTagTokenTotalsFlat,
123
135
  getAutoSearchHintDecisions,
124
136
  getCachedAbsoluteMessageCount,
137
+ getChannel2NudgeClaim,
125
138
  getChannel2NudgeState,
126
139
  getCompactionModeRecord,
127
140
  getCompartments,
@@ -205,6 +218,7 @@ import {
205
218
  getUnmappedMemoryIds,
206
219
  getUserMemoryCandidates,
207
220
  getVisibleMemoryIds,
221
+ getWindowOverlay,
208
222
  getWrapupInProgressState,
209
223
  hasMeaningfulUserText,
210
224
  hasMemoryClassifiedAtColumn,
@@ -242,6 +256,7 @@ import {
242
256
  markProtectedTailPolicyV3Seeded,
243
257
  memoryNeedsCue,
244
258
  migrateMagicContextConfigLocations,
259
+ modelRefLookupOrder,
245
260
  nextDueAtMs,
246
261
  nextOccurrence,
247
262
  normalizeText,
@@ -258,6 +273,7 @@ import {
258
273
  peelLeadingMcTagNotation,
259
274
  persistCachedM0,
260
275
  piModelRefToCanonical,
276
+ planEmergencyDrop,
261
277
  preloadTokenizer,
262
278
  prependTag,
263
279
  primeInMemoryTailRawMessageCache,
@@ -275,7 +291,6 @@ import {
275
291
  readGitChangedFilesSince,
276
292
  readGitFileChangeTimesSince,
277
293
  readGitHead,
278
- readNewMemoriesForM1Union,
279
294
  readPiSessionMessages,
280
295
  readProjectDocsCanonical,
281
296
  readRawSessionMessages,
@@ -310,15 +325,16 @@ import {
310
325
  resetLastNudgeCycleIfTailShrank,
311
326
  resolveCompactionModeRecord,
312
327
  resolveGitTopLevel,
313
- resolveLimit,
314
328
  resolveModelConfigOrDefault,
315
329
  resolveModelRefForOmp,
316
330
  resolveModelRefForPi,
317
331
  resolveMuralWire,
332
+ resolveOutputReserve,
318
333
  resolvePiStableId,
319
334
  resolveProjectIdentity,
320
335
  resolveProjectIdentityForSession,
321
336
  resolveProjectIdentityStrict,
337
+ resolveWindowOverlayFacts,
322
338
  resolveWorkspaceIdentitySet,
323
339
  resolveWorkspaceShareCategories,
324
340
  retryPendingSessionCleanups,
@@ -346,6 +362,7 @@ import {
346
362
  setStoragePrivatePermissionEnforcement,
347
363
  setTodoSnapshot,
348
364
  sourceNameForMemory,
365
+ stripChannel1ReminderSpans,
349
366
  stripMemoryMuralBlock,
350
367
  stripPersistedAssistantText,
351
368
  stripTagPrefix,
@@ -373,11 +390,12 @@ import {
373
390
  updateUserMemoryContent,
374
391
  updateWrapupInProgress,
375
392
  verificationFileExists,
393
+ wakePlaneStatus,
376
394
  withContentLanguageDirective,
377
395
  withMigrationLanguageDirective,
378
396
  withRawMessageProvider,
379
397
  withRawSessionMessageCache
380
- } from "./index-zxgbtsnj.js";
398
+ } from "./index-6hs6yh6r.js";
381
399
  import {
382
400
  pushNotification
383
401
  } from "./index-hw34xmzk.js";
@@ -389,7 +407,7 @@ import {
389
407
  log,
390
408
  sessionLog,
391
409
  setHarness
392
- } from "./index-npnqc564.js";
410
+ } from "./index-hk6sj7dn.js";
393
411
  import {
394
412
  __require,
395
413
  __toESM
@@ -573,24 +591,44 @@ function isMagicContextHiddenAgentName(agent) {
573
591
  return false;
574
592
  }
575
593
  var MAX_FORMATTED_BLOCKING_PROCESSES = 8;
594
+ function normalizeFailClosedProcessKind(process2) {
595
+ switch (process2.kind) {
596
+ case "OpenCode server":
597
+ case "OpenCode instance (TUI/CLI)":
598
+ case "Pi":
599
+ case "process":
600
+ return process2.kind;
601
+ }
602
+ switch (process2.harness?.trim().toLowerCase()) {
603
+ case "opencode server":
604
+ return "OpenCode server";
605
+ case "opencode instance (tui/cli)":
606
+ case "opencode instance":
607
+ return "OpenCode instance (TUI/CLI)";
608
+ case "pi":
609
+ case "pi harness":
610
+ case "omp":
611
+ return "Pi";
612
+ default:
613
+ return "process";
614
+ }
615
+ }
576
616
  function formatFailClosedBlockingProcesses(processes) {
577
617
  const uniqueProcesses = new Map;
578
618
  for (const process2 of processes) {
579
- if (!process2.harness.trim() || !Number.isInteger(process2.pid) || process2.pid <= 0)
619
+ if (!Number.isInteger(process2.pid) || process2.pid <= 0)
580
620
  continue;
581
- uniqueProcesses.set(`${process2.harness}\x00${process2.pid}`, {
582
- harness: process2.harness.trim(),
583
- pid: process2.pid
584
- });
621
+ const kind = normalizeFailClosedProcessKind(process2);
622
+ uniqueProcesses.set(`${kind}\x00${process2.pid}`, { kind, pid: process2.pid });
585
623
  }
586
624
  const entries = [...uniqueProcesses.values()];
587
625
  const visible = entries.slice(0, MAX_FORMATTED_BLOCKING_PROCESSES);
588
- const rendered = visible.map(({ harness, pid }) => `${harness} (PID ${pid})`);
626
+ const rendered = visible.map(({ kind, pid }) => `${kind} (PID ${pid})`);
589
627
  const omitted = entries.length - visible.length;
590
628
  if (omitted > 0)
591
629
  rendered.push(`${omitted} more blocking process(es)`);
592
630
  if (rendered.length === 0)
593
- return "a live harness process";
631
+ return "a live process";
594
632
  if (rendered.length === 1)
595
633
  return rendered[0];
596
634
  const last = rendered.pop();
@@ -600,9 +638,9 @@ function formatFailClosedBlockingMessage(reason) {
600
638
  if (reason.kind === "migration_guard") {
601
639
  if (reason.unreadableFile) {
602
640
  const arm = reason.unreadableArm ?? "io";
603
- const recovery = arm === "io" ? `If no OpenCode server is running, it is safe to delete ${reason.unreadableFile} and retry.` : `The file may be a recent incomplete write; retry after the file is older than the ten-minute grace window, or stop OpenCode before deleting it.`;
641
+ const recovery = arm === "io" ? `If none of these processes are running, it is safe to delete ${reason.unreadableFile} and retry.` : `The file may be a recent incomplete write; retry after the file is older than the ten-minute grace window, or stop the relevant process before deleting it.`;
604
642
  return [
605
- `Magic Context cannot migrate the shared database because RPC discovery file ${reason.unreadableFile} is uncertain (${arm} arm), so the absence of a live OpenCode server cannot be proven.`,
643
+ `Magic Context cannot migrate the shared database because RPC discovery file ${reason.unreadableFile} is uncertain (${arm} arm), so the absence of a live process cannot be proven.`,
606
644
  recovery,
607
645
  `Recovery: ${FAIL_CLOSED_DOCTOR_COMMAND}`
608
646
  ].join(" ");
@@ -887,7 +925,7 @@ var LIMIT_EXTRACTION_PATTERNS = [
887
925
  pattern: /too large for model with (\d+) maximum context length/i,
888
926
  provenance: "combined"
889
927
  },
890
- { pattern: /context size.*(\d+) tokens?/i, provenance: "combined" },
928
+ { pattern: /context size[^0-9]{0,40}(\d{4,})\s*tokens?/i, provenance: "combined" },
891
929
  { pattern: /exceeds? the context length of (\d+)/i, provenance: "combined" },
892
930
  {
893
931
  pattern: />\s*(\d+)\s*(?:tokens?\s*)?(?:maximum|max|limit)\b/i,
@@ -1510,11 +1548,13 @@ function isFinitePositive(v) {
1510
1548
  }
1511
1549
  function* modelKeyLookupOrder(modelKey) {
1512
1550
  const slash = modelKey.indexOf("/");
1513
- const provider = slash >= 0 ? modelKey.slice(0, slash) : "";
1551
+ const providerRefs = slash >= 0 ? modelRefLookupOrder(modelKey) : [];
1514
1552
  let modelId = slash >= 0 ? modelKey.slice(slash + 1) : modelKey;
1515
1553
  while (modelId.length > 0) {
1516
- if (provider)
1517
- yield `${provider}/${modelId}`;
1554
+ for (const providerRef of providerRefs) {
1555
+ const providerSlash = providerRef.indexOf("/");
1556
+ yield `${providerRef.slice(0, providerSlash)}/${modelId}`;
1557
+ }
1518
1558
  yield modelId;
1519
1559
  const lastDash = modelId.lastIndexOf("-");
1520
1560
  if (lastDash <= 0)
@@ -3761,7 +3801,7 @@ async function sendIgnoredMessageNow(client, sessionId, text, params, forcePersi
3761
3801
  queueIgnoredNotification({ client, sessionId, text, params, forcePersist });
3762
3802
  return "queued";
3763
3803
  }
3764
- const { waitForSafeNotificationTarget } = await import("./safe-notification-target-0s6j4m9f.js");
3804
+ const { waitForSafeNotificationTarget } = await import("./safe-notification-target-7n7s6xv7.js");
3765
3805
  if (await waitForSafeNotificationTarget(client, sessionId) === "skip") {
3766
3806
  sessionLog(sessionId, "notification skipped (session not titled yet)");
3767
3807
  return "skipped";
@@ -4521,6 +4561,34 @@ function assertManifestCoversExactly(ids, expectedIds, rootName) {
4521
4561
  throw new Error(`${rootName} manifest missing id ${id}`);
4522
4562
  }
4523
4563
  }
4564
+ var OPEN_TAG_RE = /<([A-Za-z][\w:-]*)\b/;
4565
+ function describeUnrecognizedManifestShape(text, expectedRoot, expectedEntry) {
4566
+ const expected = `expected <${expectedRoot}> with <${expectedEntry}> entries`;
4567
+ const trimmed = text.trim();
4568
+ if (trimmed.startsWith("[") || trimmed.startsWith("{")) {
4569
+ return `JSON ${trimmed.startsWith("[") ? "array" : "object"} unrecognized; ${expected}`;
4570
+ }
4571
+ const firstTag = OPEN_TAG_RE.exec(trimmed)?.[1];
4572
+ if (firstTag && firstTag.toLowerCase() !== expectedRoot.toLowerCase()) {
4573
+ return `root <${firstTag}> unrecognized; ${expected}`;
4574
+ }
4575
+ const escapedRoot = expectedRoot.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
4576
+ const bodyMatch = new RegExp(`<${escapedRoot}\\b[^>]*>([\\s\\S]*?)<\\/${escapedRoot}>`, "i").exec(text);
4577
+ const body = (bodyMatch?.[1] ?? "").trim();
4578
+ if (body.startsWith("[") || body.startsWith("{")) {
4579
+ return `JSON ${body.startsWith("[") ? "array" : "object"} unrecognized; ${expected}`;
4580
+ }
4581
+ const innerTag = OPEN_TAG_RE.exec(body)?.[1];
4582
+ if (innerTag && innerTag.toLowerCase() !== expectedEntry.toLowerCase()) {
4583
+ return `root <${innerTag}> unrecognized; ${expected}`;
4584
+ }
4585
+ return `parsed zero entries; ${expected}`;
4586
+ }
4587
+ function assertParsedManifestNonEmpty(parsedCount, expectedCount, text, expectedRoot, expectedEntry) {
4588
+ if (expectedCount > 0 && parsedCount === 0) {
4589
+ throw new Error(describeUnrecognizedManifestShape(text, expectedRoot, expectedEntry));
4590
+ }
4591
+ }
4524
4592
 
4525
4593
  // ../plugin/src/features/magic-context/dreamer/module-apply.ts
4526
4594
  class DreamerModuleBusyError extends Error {
@@ -5839,9 +5907,19 @@ ${renderAnchors(args.anchors ?? [])}### Memory pool to classify
5839
5907
  ${renderPool2(args.memories)}`;
5840
5908
  }
5841
5909
  var SCOPES = new Set(["project", "ecosystem", "universe"]);
5910
+ function classifyBody(text) {
5911
+ try {
5912
+ return extractCompleteManifestBody(text, "classify");
5913
+ } catch (error) {
5914
+ const described = describeUnrecognizedManifestShape(text, "classify", "memory");
5915
+ if (!described.startsWith("parsed zero entries"))
5916
+ throw new Error(described);
5917
+ throw error;
5918
+ }
5919
+ }
5842
5920
  function parseClassifyManifest(text) {
5843
5921
  const out = [];
5844
- const body = extractCompleteManifestBody(text, "classify");
5922
+ const body = classifyBody(text);
5845
5923
  for (const m of body.matchAll(/<memory\b([^>]*)\/?>/g)) {
5846
5924
  const attrs = m[1];
5847
5925
  const idMatch = attrs.match(/\bid\s*=\s*"(\d+)"/);
@@ -5874,9 +5952,18 @@ function parseClassifyManifest(text) {
5874
5952
  }
5875
5953
  out.push(entry);
5876
5954
  }
5955
+ if (out.length === 0 && body.trim().length > 0) {
5956
+ throw new Error(describeUnrecognizedManifestShape(text, "classify", "memory"));
5957
+ }
5877
5958
  assertNoDuplicateManifestIds(out.map((entry) => entry.id), "classify");
5878
5959
  return out;
5879
5960
  }
5961
+ function validateClassifyManifest(text, expectedIds) {
5962
+ const parsed = parseClassifyManifest(text);
5963
+ assertParsedManifestNonEmpty(parsed.length, expectedIds.size, text, "classify", "memory");
5964
+ assertManifestCoversExactly(parsed.map((entry) => entry.id), expectedIds, "classify");
5965
+ return parsed;
5966
+ }
5880
5967
 
5881
5968
  // ../plugin/src/features/magic-context/dreamer/classify.ts
5882
5969
  var MIN_POOL_TO_CLASSIFY = 10;
@@ -6075,7 +6162,7 @@ async function classifyOneChunk(args, chunk, anchors, sliceMs, signal) {
6075
6162
  if (!text)
6076
6163
  throw new Error("classify returned no output");
6077
6164
  try {
6078
- parseClassifyManifest(text);
6165
+ validateClassifyManifest(text, new Set(chunk.map((candidate) => candidate.id)));
6079
6166
  } catch (error) {
6080
6167
  const providerFailure = providerOutputFailureFromInvalidManifest(messages, text);
6081
6168
  if (providerFailure)
@@ -6143,8 +6230,7 @@ async function runClassifyThroughModule(args, chunk, anchors, signal) {
6143
6230
  if (result.truncated === true) {
6144
6231
  throw new Error("classify returned length-capped output");
6145
6232
  }
6146
- const parsed = parseClassifyManifest(manifestText);
6147
- assertManifestCoversExactly(parsed.map((entry) => entry.id), new Set(chunk.map((candidate) => candidate.id)), "classify");
6233
+ const parsed = validateClassifyManifest(manifestText, new Set(chunk.map((candidate) => candidate.id)));
6148
6234
  const rows = parsed.map((entry) => {
6149
6235
  const candidate = chunk.find((item) => item.id === entry.id);
6150
6236
  if (!candidate)
@@ -7272,6 +7358,9 @@ var DEFAULT_MAX_CHECKS = 10;
7272
7358
  var DEFAULT_SWEEP_BUDGET_MS = 15000;
7273
7359
  var MAX_FAILURES_BEFORE_REAUTHOR = 3;
7274
7360
  async function runDueCompiledSmartNoteChecks(args) {
7361
+ if (await wakePlaneStatus() === "present") {
7362
+ return { ran: 0, surfaced: 0, failed: 0, networkFailed: 0 };
7363
+ }
7275
7364
  const startedAt = Date.now();
7276
7365
  const now = args.now ?? startedAt;
7277
7366
  const due = getDueCompiledSmartNoteChecks(args.db, args.projectIdentity, now, args.maxChecks ?? DEFAULT_MAX_CHECKS, args.retinaHandoff);
@@ -7401,6 +7490,11 @@ function createPromptAbortSignal(parent, timeoutMs, timeoutMessage) {
7401
7490
  };
7402
7491
  }
7403
7492
  async function evaluateSmartNotes(args) {
7493
+ if (await wakePlaneStatus() === "present") {
7494
+ const pending = getPendingSmartNotes(args.db, args.projectIdentity).length;
7495
+ log("[dreamer] evaluate-smart-notes: skipped (wake plane active)");
7496
+ return { surfaced: 0, pending, ran: false };
7497
+ }
7404
7498
  const projectRoot = args.sessionDirectory ?? args.projectIdentity;
7405
7499
  const moduleBridge = getModuleNoteEvaluationBridge(args.projectIdentity);
7406
7500
  await moduleBridge?.sync();
@@ -7933,11 +8027,33 @@ For each memory below, find the repo file(s) it makes a claim about, or mark it
7933
8027
  ${list}
7934
8028
  </memories>`;
7935
8029
  }
8030
+ var MEMORY_ELEMENT_PATTERN = "<memory\\b([^>]*)(?:\\/>|>([\\s\\S]*?)<\\/memory>)";
8031
+ var NESTED_FILE_PATTERN = "<file\\b([^>]*)\\/?>";
8032
+ function extractNestedFilePaths(inner) {
8033
+ const files = [];
8034
+ for (const match of inner.matchAll(new RegExp(NESTED_FILE_PATTERN, "gi"))) {
8035
+ const pathMatch = match[1].match(/\bpath\s*=\s*"([^"]+)"/);
8036
+ if (pathMatch)
8037
+ files.push(pathMatch[1].trim());
8038
+ }
8039
+ return files.filter(Boolean);
8040
+ }
8041
+ function mappingsBody(text) {
8042
+ try {
8043
+ return extractCompleteManifestBody(text, "mappings");
8044
+ } catch (error) {
8045
+ const described = describeUnrecognizedManifestShape(text, "mappings", "memory");
8046
+ if (!described.startsWith("parsed zero entries"))
8047
+ throw new Error(described);
8048
+ throw error;
8049
+ }
8050
+ }
7936
8051
  function parseMapMemoriesManifest(text) {
7937
8052
  const out = [];
7938
- const body = extractCompleteManifestBody(text, "mappings");
7939
- for (const m of body.matchAll(/<memory\b([^>]*)\/?>/g)) {
8053
+ const body = mappingsBody(text);
8054
+ for (const m of body.matchAll(new RegExp(MEMORY_ELEMENT_PATTERN, "gi"))) {
7940
8055
  const attrs = m[1];
8056
+ const inner = m[2];
7941
8057
  const idMatch = attrs.match(/\bid\s*=\s*"(\d+)"/);
7942
8058
  if (!idMatch)
7943
8059
  throw new Error("mappings manifest entry missing numeric id");
@@ -7946,24 +8062,67 @@ function parseMapMemoriesManifest(text) {
7946
8062
  throw new Error("mappings manifest entry missing numeric id");
7947
8063
  const independent = /\bindependent\s*=\s*"(?:true|1)"/i.test(attrs);
7948
8064
  const filesMatch = attrs.match(/\bfiles\s*=\s*"([^"]*)"/);
7949
- const files = filesMatch ? filesMatch[1].split(",").map((f) => f.trim()).filter(Boolean) : [];
7950
- out.push({ id, files, independent: independent || files.length === 0 });
8065
+ const attrFiles = filesMatch ? filesMatch[1].split(",").map((f) => f.trim()).filter(Boolean) : [];
8066
+ const nestedFiles = inner ? extractNestedFilePaths(inner) : [];
8067
+ const files = attrFiles.length > 0 ? attrFiles : nestedFiles;
8068
+ if (!independent && files.length === 0) {
8069
+ throw new Error(`mappings manifest entry ${id} has neither files nor independent="true"`);
8070
+ }
8071
+ out.push({
8072
+ id,
8073
+ files: independent && files.length === 0 ? [] : files,
8074
+ independent: independent && files.length === 0
8075
+ });
8076
+ }
8077
+ if (out.length === 0 && body.trim().length > 0) {
8078
+ throw new Error(describeUnrecognizedManifestShape(text, "mappings", "memory"));
7951
8079
  }
7952
8080
  assertNoDuplicateManifestIds(out.map((entry) => entry.id), "mappings");
7953
8081
  return out;
7954
8082
  }
8083
+ function validateMapMemoriesManifest(text, expectedIds) {
8084
+ const parsed = parseMapMemoriesManifest(text);
8085
+ assertParsedManifestNonEmpty(parsed.length, expectedIds.size, text, "mappings", "memory");
8086
+ assertManifestCoversExactly(parsed.map((entry) => entry.id), expectedIds, "mappings");
8087
+ return parsed;
8088
+ }
7955
8089
 
7956
8090
  // ../plugin/src/features/magic-context/dreamer/map-memories.ts
7957
8091
  var MAP_BATCH_SIZE = 80;
7958
- function loadUnmappedInputs(db, projectIdentity, repoDir) {
8092
+ var MAX_INDEPENDENT_REQUEUE_PER_RUN = MAP_BATCH_SIZE;
8093
+ function shouldRequeueIndependentMapping(state2, content, repoDir) {
8094
+ if (!state2.hasSentinel || state2.files.length > 0)
8095
+ return false;
8096
+ return extractMemoryCandidatePaths(content, repoDir).length > 0;
8097
+ }
8098
+ function toMapInput(memory, repoDir) {
8099
+ return {
8100
+ id: memory.id,
8101
+ category: memory.category,
8102
+ content: memory.content,
8103
+ candidates: extractMemoryCandidatePaths(memory.content, repoDir)
8104
+ };
8105
+ }
8106
+ function selectMapMemoryInputs(db, projectIdentity, repoDir) {
7959
8107
  const active = getMemoriesByProject(db, projectIdentity);
7960
- const unmapped = new Set(getUnmappedMemoryIds(db, active.map((m) => m.id)));
7961
- return active.filter((m) => unmapped.has(m.id)).map((m) => ({
7962
- id: m.id,
7963
- category: m.category,
7964
- content: m.content,
7965
- candidates: extractMemoryCandidatePaths(m.content, repoDir)
7966
- }));
8108
+ const activeIds = active.map((m) => m.id);
8109
+ const unmapped = new Set(getUnmappedMemoryIds(db, activeIds));
8110
+ const verifications = getMemoryVerifications(db, activeIds);
8111
+ const unmappedInputs = active.filter((m) => unmapped.has(m.id)).map((m) => toMapInput(m, repoDir));
8112
+ const requeue = [];
8113
+ for (const memory of active) {
8114
+ if (unmapped.has(memory.id))
8115
+ continue;
8116
+ const state2 = verifications.get(memory.id);
8117
+ if (!state2)
8118
+ continue;
8119
+ if (!shouldRequeueIndependentMapping(state2, memory.content, repoDir))
8120
+ continue;
8121
+ requeue.push(toMapInput(memory, repoDir));
8122
+ if (requeue.length >= MAX_INDEPENDENT_REQUEUE_PER_RUN)
8123
+ break;
8124
+ }
8125
+ return [...unmappedInputs, ...requeue];
7967
8126
  }
7968
8127
  async function mapMemories(args) {
7969
8128
  const result = {
@@ -7973,7 +8132,7 @@ async function mapMemories(args) {
7973
8132
  remaining: 0,
7974
8133
  complete: true
7975
8134
  };
7976
- const inputs = loadUnmappedInputs(args.db, args.projectIdentity, args.sessionDirectory);
8135
+ const inputs = selectMapMemoryInputs(args.db, args.projectIdentity, args.sessionDirectory);
7977
8136
  if (inputs.length === 0)
7978
8137
  return result;
7979
8138
  const batches = [];
@@ -8052,7 +8211,7 @@ async function mapOneBatch(args, batch, sliceMs, signal) {
8052
8211
  const text = extractLatestAssistantText(messages);
8053
8212
  if (!text)
8054
8213
  throw new Error("map-memories returned no output");
8055
- parseMapMemoriesManifest(text);
8214
+ validateMapMemoriesManifest(text, new Set(batch.map((memory) => memory.id)));
8056
8215
  return text;
8057
8216
  }
8058
8217
  });
@@ -8086,10 +8245,13 @@ async function applyBatchMappings(args, batch, manifestText) {
8086
8245
  return { mapped: 0, independent: 0 };
8087
8246
  const planned = [];
8088
8247
  for (const p of parsed) {
8089
- if (p.independent || p.files.length === 0) {
8248
+ if (p.independent) {
8090
8249
  planned.push({ id: p.id, files: [], independent: true });
8091
8250
  continue;
8092
8251
  }
8252
+ if (p.files.length === 0) {
8253
+ throw new Error(`mapping entry ${p.id} has no files and no independent sentinel`);
8254
+ }
8093
8255
  const normalized = await normalizeVerificationFiles({
8094
8256
  cwd: args.sessionDirectory,
8095
8257
  files: p.files
@@ -9350,9 +9512,22 @@ function attrOf(s, name) {
9350
9512
  function filesOf(s) {
9351
9513
  return (attrOf(s, "files") ?? "").split(",").map((f) => f.trim()).filter(Boolean);
9352
9514
  }
9515
+ function verifyIds(parsed) {
9516
+ return [...parsed.verified, ...parsed.updated, ...parsed.archived].map((entry) => entry.id);
9517
+ }
9518
+ function verifyBody(text) {
9519
+ try {
9520
+ return extractCompleteManifestBody(text, "verify");
9521
+ } catch (error) {
9522
+ const described = describeUnrecognizedManifestShape(text, "verify", "verified");
9523
+ if (!described.startsWith("parsed zero entries"))
9524
+ throw new Error(described);
9525
+ throw error;
9526
+ }
9527
+ }
9353
9528
  function parseVerifyManifest(text) {
9354
9529
  const out = { verified: [], updated: [], archived: [] };
9355
- const body = extractCompleteManifestBody(text, "verify");
9530
+ const body = verifyBody(text);
9356
9531
  for (const m of body.matchAll(/<verified\b([^>]*)\/?>/g)) {
9357
9532
  const id = Number.parseInt(attrOf(m[1], "id") ?? "", 10);
9358
9533
  if (!Number.isInteger(id))
@@ -9371,9 +9546,19 @@ function parseVerifyManifest(text) {
9371
9546
  throw new Error("verify manifest entry missing numeric id");
9372
9547
  out.archived.push({ id, reason: attrOf(m[1], "reason") ?? "" });
9373
9548
  }
9374
- assertNoDuplicateManifestIds([...out.verified, ...out.updated, ...out.archived].map((entry) => entry.id), "verify");
9549
+ if (verifyIds(out).length === 0 && body.trim().length > 0) {
9550
+ throw new Error(describeUnrecognizedManifestShape(text, "verify", "verified"));
9551
+ }
9552
+ assertNoDuplicateManifestIds(verifyIds(out), "verify");
9375
9553
  return out;
9376
9554
  }
9555
+ function validateVerifyManifest(text, expectedIds) {
9556
+ const parsed = parseVerifyManifest(text);
9557
+ const ids = verifyIds(parsed);
9558
+ assertParsedManifestNonEmpty(ids.length, expectedIds.size, text, "verify", "verified");
9559
+ assertManifestCoversExactly(ids, expectedIds, "verify");
9560
+ return parsed;
9561
+ }
9377
9562
 
9378
9563
  // ../plugin/src/features/magic-context/dreamer/verify.ts
9379
9564
  var VERIFY_BATCH_SIZE = 50;
@@ -9525,7 +9710,7 @@ async function verifyOneBatch(args, batch, sliceMs, signal) {
9525
9710
  if (!text)
9526
9711
  throw new Error("verify returned no output");
9527
9712
  try {
9528
- parseVerifyManifest(text);
9713
+ validateVerifyManifest(text, new Set(batch.map((memory) => memory.id)));
9529
9714
  } catch (error) {
9530
9715
  const providerFailure = providerOutputFailureFromInvalidManifest(messages, text);
9531
9716
  if (providerFailure)
@@ -9745,6 +9930,18 @@ function loadActiveMemoryPromptMemories(db, projectIdentity) {
9745
9930
  const verificationById = getMemoryVerifications(db, memories.map((memory) => memory.id));
9746
9931
  return memories.map((memory) => toCuratePromptMemory(memory, verificationById));
9747
9932
  }
9933
+ var TEXTUAL_CURATE_TOOL_CALL_PATTERNS = [
9934
+ /\[\s*historical tool call\s*\][\s\S]*?(?:^|\n)\s*name\s*:\s*ctx_memory\b[\s\S]*?(?:^|\n)\s*arguments\s*:/im,
9935
+ /(?:^|\n)\s*name\s*:\s*ctx_memory\b[\s\S]*?(?:^|\n)\s*arguments\s*:/im,
9936
+ /(?:^|\n)\s*(?:```[^\n]*\n\s*)?ctx_memory\s*\(\s*action\s*=/im,
9937
+ /["']name["']\s*:\s*["']ctx_memory["'][\s\S]*?["']arguments["']\s*:/i
9938
+ ];
9939
+ function validateCurateAssistantText(text) {
9940
+ if (TEXTUAL_CURATE_TOOL_CALL_PATTERNS.some((pattern) => pattern.test(text))) {
9941
+ throw new Error("Curate returned an unresolved textual ctx_memory tool call.");
9942
+ }
9943
+ return text;
9944
+ }
9748
9945
  function createDreamTaskExecutor(deps) {
9749
9946
  let parentSessionIdPromise;
9750
9947
  const resolveParentSessionId = () => {
@@ -9815,7 +10012,8 @@ function createDreamTaskExecutor(deps) {
9815
10012
  name: config.task,
9816
10013
  durationMs: Date.now() - startedAt,
9817
10014
  resultChars: 0,
9818
- ...error ? { error } : {},
10015
+ ...status === "failed" && error ? { error } : {},
10016
+ ...extra?.progress ? { progress: extra.progress } : {},
9819
10017
  backlog: (() => {
9820
10018
  const end = extra?.backlogAfter ?? getDreamTaskBacklog(db, projectIdentity, config.task);
9821
10019
  const processed = processedDreamTaskItems(backlogAtStart.pending, end.pending);
@@ -9958,11 +10156,12 @@ function createDreamTaskExecutor(deps) {
9958
10156
  const backlogAfter = config.task === "verify-broad" ? { pending: result.remaining, total: backlogAtStart.total } : undefined;
9959
10157
  if (!result.complete) {
9960
10158
  if (broadProgress && processed > 0) {
9961
- recordRun("completed", broadProgress, {
10159
+ recordRun("completed", null, {
10160
+ progress: broadProgress,
9962
10161
  memoryChanges: computeMemoryDelta(memoryBefore),
9963
10162
  backlogAfter
9964
10163
  });
9965
- return { status: "completed", error: broadProgress };
10164
+ return { status: "completed" };
9966
10165
  }
9967
10166
  const error = incompleteMessage(result.remaining);
9968
10167
  recordRun("failed", error, {
@@ -9971,11 +10170,12 @@ function createDreamTaskExecutor(deps) {
9971
10170
  });
9972
10171
  return { status: "failed", transient: true, error };
9973
10172
  }
9974
- recordRun("completed", broadProgress, {
10173
+ recordRun("completed", null, {
10174
+ progress: broadProgress,
9975
10175
  memoryChanges: computeMemoryDelta(memoryBefore),
9976
10176
  backlogAfter
9977
10177
  });
9978
- return broadProgress ? { status: "completed", error: broadProgress } : { status: "completed" };
10178
+ return { status: "completed" };
9979
10179
  }
9980
10180
  if (config.task === "classify-memories") {
9981
10181
  let moduleArgs;
@@ -10442,7 +10642,7 @@ async function runAgenticTask(config, ctx, helpers) {
10442
10642
  const text = extractLatestAssistantText(messages);
10443
10643
  if (!text)
10444
10644
  throw new Error("Dreamer returned no assistant output.");
10445
- return text;
10645
+ return task === "curate" ? validateCurateAssistantText(text) : text;
10446
10646
  }
10447
10647
  });
10448
10648
  if (leaseLost)
@@ -13261,6 +13461,21 @@ function replayCavemanCompression(sessionId, db, targets, tags) {
13261
13461
  return replayed;
13262
13462
  }
13263
13463
 
13464
+ // ../plugin/src/hooks/magic-context/channel2-cycle.ts
13465
+ function rearmChannel2AfterCoverageAdvancingHardFold(input) {
13466
+ if (input.compactionOff || !input.foldExecuted || input.previousCoverage === null || input.currentCoverage === null || input.currentCoverage <= input.previousCoverage) {
13467
+ return false;
13468
+ }
13469
+ return casChannel2NudgeState(input.db, input.sessionId, "delivered", "");
13470
+ }
13471
+ function rearmChannel2AfterMeasuredCollapse(input) {
13472
+ if (!input.baseline.evaluable || input.baseline.generationInvalidated)
13473
+ return false;
13474
+ if (effectiveTailHygiene(input.baseline).u >= CHANNEL1_FLOOR_TOKENS)
13475
+ return false;
13476
+ return casChannel2NudgeState(input.db, input.sessionId, "delivered", "");
13477
+ }
13478
+
13264
13479
  // ../plugin/src/hooks/magic-context/protected-tail-boundary.ts
13265
13480
  var ALPHA = 0.3;
13266
13481
  var FLOOR_RATIO = 0.08;
@@ -14146,132 +14361,13 @@ function checkCompartmentTrigger(db, sessionId, sessionMeta, usage, _previousPer
14146
14361
  };
14147
14362
  }
14148
14363
 
14149
- // ../plugin/src/hooks/magic-context/ctx-reduce-nudge.ts
14150
- var CHANNEL1_SENTINEL = "<system-reminder>";
14151
- var TOKENS_PER_BYTE = 0.25;
14152
- var CHANNEL1_FLOOR_TOKENS = 1e4;
14153
- var CHANNEL1_REFIRE_FLOOR_TOKENS = 1e4;
14154
- function channel1RefireTokens(workingWindowTokens) {
14155
- const scaled = Math.round(0.05 * Math.max(0, workingWindowTokens));
14156
- return Math.max(CHANNEL1_REFIRE_FLOOR_TOKENS, scaled);
14157
- }
14158
- var S_GENTLE = 0.2;
14159
- var S_FIRM = 0.4;
14160
- var S_URGENT = 0.65;
14161
- var CHANNEL1_PRESSURE_FLOOR = 0.8;
14162
- var LEVEL_RANK = { gentle: 1, firm: 2, urgent: 3 };
14163
- var DROP_SENTINELS = ["[dropped", "[truncated"];
14164
- function isDroppedToolOutput(output) {
14165
- const head = output.slice(0, 16);
14166
- return DROP_SENTINELS.some((s) => head.startsWith(s));
14167
- }
14168
- function toolOutputTokens(output) {
14169
- return Math.round(byteSize(output) * TOKENS_PER_BYTE);
14170
- }
14171
- function decideChannel1(input) {
14172
- const { undroppedTokens, workingWindowTokens, hasRecentReduce } = input;
14173
- const pressure = Math.min(1, Math.max(0, input.pressure));
14174
- const resetCycle = hasRecentReduce || undroppedTokens < input.lastNudgeUndropped;
14175
- const lastNudge = resetCycle ? 0 : input.lastNudgeUndropped;
14176
- const lastLevel = resetCycle ? "" : input.lastNudgeLevel;
14177
- const quiet = () => ({
14178
- fire: false,
14179
- level: "gentle",
14180
- undroppedTokens,
14181
- nextLastNudge: lastNudge,
14182
- nextLastNudgeLevel: lastLevel
14183
- });
14184
- if (hasRecentReduce)
14185
- return quiet();
14186
- if (undroppedTokens < CHANNEL1_FLOOR_TOKENS)
14187
- return quiet();
14188
- if (pressure < CHANNEL1_PRESSURE_FLOOR)
14189
- return quiet();
14190
- const denom = Math.max(input.estimatedInputTokens, 1);
14191
- const severity = Math.min(1, undroppedTokens / denom);
14192
- if (severity < S_GENTLE)
14193
- return quiet();
14194
- let level;
14195
- if (severity >= S_URGENT)
14196
- level = "urgent";
14197
- else if (severity >= S_FIRM)
14198
- level = "firm";
14199
- else
14200
- level = "gentle";
14201
- if (lastLevel === "") {
14202
- if (undroppedTokens < lastNudge + channel1RefireTokens(workingWindowTokens)) {
14203
- return quiet();
14204
- }
14205
- } else if (LEVEL_RANK[level] <= LEVEL_RANK[lastLevel]) {
14206
- return quiet();
14207
- }
14208
- return {
14209
- fire: true,
14210
- level,
14211
- undroppedTokens,
14212
- nextLastNudge: undroppedTokens,
14213
- nextLastNudgeLevel: level
14214
- };
14215
- }
14216
- function computePressure(input) {
14217
- const { lastInputTokens, turnToolTokens, contextLimit, executeThresholdPercentage } = input;
14218
- if (contextLimit <= 0 || executeThresholdPercentage <= 0)
14219
- return 0;
14220
- const estimatedInput = lastInputTokens + turnToolTokens;
14221
- const usagePercentage = estimatedInput / contextLimit * 100;
14222
- return usagePercentage / executeThresholdPercentage;
14223
- }
14224
- function approxThousands(tokens) {
14225
- return `${Math.round(tokens / 1000)}k`;
14226
- }
14227
- function formatOldestReclaimableHint(hint) {
14228
- if (!hint || hint.length === 0)
14229
- return "";
14230
- const rendered = hint.slice(0, 4).map((tag) => `§${tag.tagNumber}§ ${tag.toolName ?? "tool"}`).join(" · ");
14231
- return rendered.length > 0 ? `
14232
- oldest reclaimable: ${rendered}.` : "";
14233
- }
14234
- var CHANNEL2_USABLE_FRACTION = 1 / 3;
14235
- var CHANNEL2_MIN_RECLAIMABLE = 1e4;
14236
- function shouldTriggerChannel2(input) {
14237
- if (input.reclaimableTokens < CHANNEL2_MIN_RECLAIMABLE)
14238
- return false;
14239
- if (input.usableTokens <= 0)
14240
- return true;
14241
- return input.reclaimableTokens >= input.usableTokens * CHANNEL2_USABLE_FRACTION;
14242
- }
14243
- function buildChannel2Reminder(undroppedTokens, hint) {
14244
- const amount = approxThousands(undroppedTokens);
14245
- const hintText = formatOldestReclaimableHint(hint);
14246
- return `<system-reminder>
14247
- ` + `Routine context housekeeping is near: a large span of this session will be comparted soon, ` + `and ~${amount} tokens of tool output remain unreduced. Drop spent outputs with ctx_reduce ` + `first so the archived span is the part that matters.${hintText}
14248
- ` + `</system-reminder>`;
14249
- }
14250
- function buildChannel1Reminder(level, undroppedTokens, hint) {
14251
- const amount = approxThousands(undroppedTokens);
14252
- const hintText = formatOldestReclaimableHint(hint);
14253
- let body;
14254
- switch (level) {
14255
- case "gentle":
14256
- body = `You have ~${amount} tokens of tool output you have not reduced. ` + `When you are done with earlier outputs, dropping them with ctx_reduce keeps context lean.`;
14257
- break;
14258
- case "firm":
14259
- body = `~${amount} tokens of unreduced tool output has built up. ` + `At your next natural stopping point, consider dropping what you have already processed with ctx_reduce.`;
14260
- break;
14261
- case "urgent":
14262
- body = `~${amount} tokens of unreduced tool output remain, and a large span of this session will be comparted before long. ` + `Consider dropping spent outputs with ctx_reduce so the archived span is the part that matters.`;
14263
- break;
14264
- }
14265
- return `
14266
-
14267
- <system-reminder>
14268
- ${body}${hintText}
14269
- </system-reminder>`;
14364
+ // ../plugin/src/hooks/magic-context/fold-execution-gate.ts
14365
+ function foldExecutesThisPass(foldDue, materialized) {
14366
+ return foldDue && materialized;
14270
14367
  }
14271
14368
 
14272
14369
  // ../plugin/src/hooks/magic-context/supersession-reclaim.ts
14273
14370
  var TODOWRITE_KEEP = 1;
14274
- var CTX_REDUCE_KEEP = 5;
14275
14371
  var ZERO_VALUE_META_TOOLS = new Set(["bash_status", "bash_kill"]);
14276
14372
  var CTX_NOTE_ZERO_VALUE_ACTIONS = new Set(["read", "dismiss"]);
14277
14373
  function buildSupersessionReclaimOps(input) {
@@ -14399,158 +14495,6 @@ function advanceToolReclaimWatermarkToCurrentMax(db, sessionId) {
14399
14495
 
14400
14496
  // ../plugin/src/shared/tag-transcript.ts
14401
14497
  import { createHash as createHash9 } from "node:crypto";
14402
-
14403
- // ../plugin/src/hooks/magic-context/image-token-estimate.ts
14404
- var IMAGE_TOKEN_DIVISOR = 750;
14405
- var IMAGE_FALLBACK_TOKENS = 1200;
14406
- var IMAGE_TOKEN_CAP = 4500;
14407
- function estimateImageTokensFromDataUrl(url) {
14408
- const comma = url.indexOf(",");
14409
- if (comma < 0)
14410
- return IMAGE_FALLBACK_TOKENS;
14411
- const header = url.slice(0, comma);
14412
- const payload = url.slice(comma + 1);
14413
- const sliceLen = Math.min(512, payload.length);
14414
- const preview = payload.slice(0, sliceLen);
14415
- let bytes;
14416
- try {
14417
- bytes = base64Decode(preview);
14418
- } catch {
14419
- return IMAGE_FALLBACK_TOKENS;
14420
- }
14421
- if (header.includes("image/png")) {
14422
- const dims = parsePngDimensions(bytes);
14423
- if (dims)
14424
- return clampImageTokens(Math.ceil(dims.w * dims.h / IMAGE_TOKEN_DIVISOR));
14425
- } else if (header.includes("image/jpeg") || header.includes("image/jpg")) {
14426
- const dims = parseJpegDimensions(bytes);
14427
- if (dims)
14428
- return clampImageTokens(Math.ceil(dims.w * dims.h / IMAGE_TOKEN_DIVISOR));
14429
- } else if (header.includes("image/webp")) {
14430
- const dims = parseWebpDimensions(bytes);
14431
- if (dims)
14432
- return clampImageTokens(Math.ceil(dims.w * dims.h / IMAGE_TOKEN_DIVISOR));
14433
- } else if (header.includes("image/gif")) {
14434
- const dims = parseGifDimensions(bytes);
14435
- if (dims)
14436
- return clampImageTokens(Math.ceil(dims.w * dims.h / IMAGE_TOKEN_DIVISOR));
14437
- }
14438
- return IMAGE_FALLBACK_TOKENS;
14439
- }
14440
- function clampImageTokens(n) {
14441
- if (n < 1)
14442
- return 1;
14443
- if (n > IMAGE_TOKEN_CAP)
14444
- return IMAGE_TOKEN_CAP;
14445
- return n;
14446
- }
14447
- function base64Decode(b64) {
14448
- const pad = b64.length % 4;
14449
- const padded = pad === 0 ? b64 : b64 + "=".repeat(4 - pad);
14450
- const binary = atob(padded);
14451
- const out = new Uint8Array(binary.length);
14452
- for (let i = 0;i < binary.length; i++)
14453
- out[i] = binary.charCodeAt(i);
14454
- return out;
14455
- }
14456
- function parsePngDimensions(b) {
14457
- if (b.length < 24)
14458
- return null;
14459
- if (b[0] !== 137 || b[1] !== 80 || b[2] !== 78 || b[3] !== 71 || b[4] !== 13 || b[5] !== 10 || b[6] !== 26 || b[7] !== 10)
14460
- return null;
14461
- const w = readUint32BE(b, 16);
14462
- const h = readUint32BE(b, 20);
14463
- if (!w || !h)
14464
- return null;
14465
- return { w, h };
14466
- }
14467
- function parseJpegDimensions(b) {
14468
- if (b.length < 4 || b[0] !== 255 || b[1] !== 216)
14469
- return null;
14470
- let i = 2;
14471
- while (i < b.length - 8) {
14472
- if (b[i] !== 255) {
14473
- i++;
14474
- continue;
14475
- }
14476
- const marker = b[i + 1];
14477
- if (marker === undefined)
14478
- break;
14479
- if (isSofMarker(marker)) {
14480
- const h = b[i + 5] << 8 | b[i + 6];
14481
- const w = b[i + 7] << 8 | b[i + 8];
14482
- if (w && h)
14483
- return { w, h };
14484
- return null;
14485
- }
14486
- if (marker === 216 || marker === 217 || marker === 1) {
14487
- i += 2;
14488
- continue;
14489
- }
14490
- const segLen = b[i + 2] << 8 | b[i + 3];
14491
- if (segLen < 2)
14492
- return null;
14493
- i += 2 + segLen;
14494
- }
14495
- return null;
14496
- }
14497
- function isSofMarker(m) {
14498
- if (m >= 192 && m <= 195)
14499
- return true;
14500
- if (m >= 197 && m <= 199)
14501
- return true;
14502
- if (m >= 201 && m <= 203)
14503
- return true;
14504
- if (m >= 205 && m <= 207)
14505
- return true;
14506
- return false;
14507
- }
14508
- function parseWebpDimensions(b) {
14509
- if (b.length < 30)
14510
- return null;
14511
- if (b[0] !== 82 || b[1] !== 73 || b[2] !== 70 || b[3] !== 70)
14512
- return null;
14513
- if (b[8] !== 87 || b[9] !== 69 || b[10] !== 66 || b[11] !== 80)
14514
- return null;
14515
- const variant = String.fromCharCode(b[12], b[13], b[14], b[15]);
14516
- if (variant === "VP8 ") {
14517
- const w = (b[26] | b[27] << 8) & 16383;
14518
- const h = (b[28] | b[29] << 8) & 16383;
14519
- if (w && h)
14520
- return { w, h };
14521
- } else if (variant === "VP8L") {
14522
- const b0 = b[21];
14523
- const b1 = b[22];
14524
- const b2 = b[23];
14525
- const b3 = b[24];
14526
- const w = 1 + ((b0 | b1 << 8) & 16383);
14527
- const h = 1 + ((b1 >> 6 | b2 << 2 | b3 << 10) & 16383);
14528
- if (w && h)
14529
- return { w, h };
14530
- } else if (variant === "VP8X") {
14531
- const w = 1 + (b[24] | b[25] << 8 | b[26] << 16);
14532
- const h = 1 + (b[27] | b[28] << 8 | b[29] << 16);
14533
- if (w && h)
14534
- return { w, h };
14535
- }
14536
- return null;
14537
- }
14538
- function parseGifDimensions(b) {
14539
- if (b.length < 10)
14540
- return null;
14541
- if (b[0] !== 71 || b[1] !== 73 || b[2] !== 70)
14542
- return null;
14543
- const w = b[6] | b[7] << 8;
14544
- const h = b[8] | b[9] << 8;
14545
- if (!w || !h)
14546
- return null;
14547
- return { w, h };
14548
- }
14549
- function readUint32BE(b, offset) {
14550
- return (b[offset] << 24 | b[offset + 1] << 16 | b[offset + 2] << 8 | b[offset + 3]) >>> 0;
14551
- }
14552
-
14553
- // ../plugin/src/shared/tag-transcript.ts
14554
14498
  var TEXT_TAG_IDENTITY_MARKER = ":mc-text-v1:";
14555
14499
  function textIdentityDigest(value) {
14556
14500
  return createHash9("sha256").update(value).digest("hex");
@@ -15569,435 +15513,76 @@ function recordPiTransformTiming(sample) {
15569
15513
  }
15570
15514
 
15571
15515
  // src/ctx-reduce-nudge-pi.ts
15572
- function sealDeliveredAfterUnconfirmedSend(db, sessionId) {
15573
- try {
15574
- if (getChannel2NudgeState(db, sessionId) === "delivered") {
15575
- return "already-delivered";
15516
+ import { randomUUID as randomUUID2 } from "node:crypto";
15517
+
15518
+ // ../plugin/src/hooks/magic-context/system-injection-stripper.ts
15519
+ var SYSTEM_INJECTION_MARKERS = [
15520
+ "<!-- OMO_INTERNAL_INITIATOR -->",
15521
+ "[SYSTEM DIRECTIVE: MAGIC-CONTEXT",
15522
+ "[SYSTEM DIRECTIVE: OH-MY-OPENCODE",
15523
+ "[Category+Skill Reminder]",
15524
+ "[EDIT ERROR - IMMEDIATE ACTION REQUIRED]",
15525
+ "[task CALL FAILED - IMMEDIATE RETRY REQUIRED]",
15526
+ "[EMERGENCY CONTEXT WINDOW WARNING]",
15527
+ "Unstable background agent appears idle",
15528
+ "**THE SUBAGENT JUST CLAIMED THIS TASK IS DONE."
15529
+ ];
15530
+ var SYSTEM_REMINDER_REGEX = /<system-reminder>[\s\S]*?<\/system-reminder>/gi;
15531
+ var OMO_MARKER_REGEX = /<!-- OMO_INTERNAL_INITIATOR -->/g;
15532
+ function stripSystemInjection(text) {
15533
+ let hasInjection = false;
15534
+ for (const marker of SYSTEM_INJECTION_MARKERS) {
15535
+ if (text.includes(marker)) {
15536
+ hasInjection = true;
15537
+ break;
15576
15538
  }
15577
- } catch {}
15578
- try {
15579
- setChannel2NudgeState(db, sessionId, "delivered");
15580
- return "sealed";
15581
- } catch {
15582
- return "stuck-claimed";
15583
- }
15584
- }
15585
- var channel1StateBySession = new Map;
15586
- function setPiChannel1Baseline(sessionId, state2) {
15587
- channel1StateBySession.set(sessionId, state2);
15588
- }
15589
- function clearPiChannel1State(sessionId) {
15590
- channel1StateBySession.delete(sessionId);
15591
- }
15592
- function markPiChannel1Reduced(sessionId, db) {
15593
- const state2 = channel1StateBySession.get(sessionId);
15594
- if (state2)
15595
- state2.reducedSinceRefresh = true;
15596
- if (db)
15597
- resetLastNudgeCycle(db, sessionId);
15598
- }
15599
- function isPiTextContent(c) {
15600
- return c !== null && typeof c === "object" && c.type === "text" && typeof c.text === "string";
15601
- }
15602
- function toolResultText(content) {
15603
- let text = "";
15604
- for (const c of content) {
15605
- if (isPiTextContent(c))
15606
- text += c.text;
15607
15539
  }
15608
- return text;
15609
- }
15610
- function jsonTokens(value) {
15611
- if (value === undefined || value === null)
15612
- return 0;
15613
- try {
15614
- return toolOutputTokens(JSON.stringify(value));
15615
- } catch {
15616
- return 0;
15540
+ if (SYSTEM_REMINDER_REGEX.test(text))
15541
+ hasInjection = true;
15542
+ SYSTEM_REMINDER_REGEX.lastIndex = 0;
15543
+ if (!hasInjection)
15544
+ return null;
15545
+ let cleaned = text;
15546
+ cleaned = cleaned.replace(SYSTEM_REMINDER_REGEX, "");
15547
+ cleaned = cleaned.replace(OMO_MARKER_REGEX, "");
15548
+ cleaned = cleaned.replace(/\[SYSTEM DIRECTIVE: OH-MY-(?:OPENCODE|CLAUDE)[^\]]*\][\s\S]*?(?=\n\n(?!\s*[-*])|$)/g, "");
15549
+ for (const marker of SYSTEM_INJECTION_MARKERS) {
15550
+ if (marker.startsWith("<!-- ") || marker.startsWith("[SYSTEM DIRECTIVE"))
15551
+ continue;
15552
+ const idx = cleaned.indexOf(marker);
15553
+ if (idx === -1)
15554
+ continue;
15555
+ const blockEnd = cleaned.indexOf(`
15556
+
15557
+ `, idx + marker.length);
15558
+ cleaned = blockEnd !== -1 ? cleaned.slice(0, idx) + cleaned.slice(blockEnd) : cleaned.slice(0, idx);
15617
15559
  }
15560
+ return cleaned.trim();
15618
15561
  }
15619
- function textTokens(content) {
15620
- if (typeof content === "string")
15621
- return toolOutputTokens(content);
15622
- if (!Array.isArray(content))
15623
- return 0;
15624
- let tokens = 0;
15625
- for (const part of content) {
15626
- if (!part || typeof part !== "object")
15562
+
15563
+ // src/heuristic-cleanup-pi.ts
15564
+ var PI_CTX_REDUCE_KEEP = 3;
15565
+ var DEDUP_SAFE_TOOLS = new Set([
15566
+ "mcp_grep",
15567
+ "mcp_read",
15568
+ "mcp_glob",
15569
+ "mcp_ast_grep_search",
15570
+ "mcp_lsp_diagnostics",
15571
+ "mcp_lsp_symbols",
15572
+ "mcp_lsp_find_references",
15573
+ "mcp_lsp_goto_definition",
15574
+ "mcp_lsp_prepare_rename"
15575
+ ]);
15576
+ function buildPiToolFingerprints(messages, resolveStableId) {
15577
+ const fingerprints = new Map;
15578
+ for (let i = 0;i < messages.length; i++) {
15579
+ const message = messages[i];
15580
+ if (!message || typeof message !== "object")
15627
15581
  continue;
15628
- const p = part;
15629
- if (typeof p.text === "string")
15630
- tokens += toolOutputTokens(p.text);
15631
- else if (typeof p.thinking === "string")
15632
- tokens += toolOutputTokens(p.thinking);
15633
- else if (p.type === "image")
15634
- tokens += 1200;
15635
- }
15636
- return tokens;
15637
- }
15638
- function computeTailTokenEstimatePi(messages) {
15639
- let tailToolTokens = 0;
15640
- let liveTailTokens = 0;
15641
- for (const raw of messages) {
15642
- if (!raw || typeof raw !== "object")
15582
+ const msg = message;
15583
+ if (msg.role !== "assistant")
15643
15584
  continue;
15644
- const msg = raw;
15645
- if (msg.role === "toolResult") {
15646
- const outputText = Array.isArray(msg.content) ? toolResultText(msg.content) : typeof msg.content === "string" ? msg.content : "";
15647
- const outputTokens = outputText && !isDroppedToolOutput(outputText) ? toolOutputTokens(outputText) : 0;
15648
- tailToolTokens += outputTokens;
15649
- liveTailTokens += outputTokens;
15650
- continue;
15651
- }
15652
- if (msg.role === "assistant" && Array.isArray(msg.content)) {
15653
- for (const part of msg.content) {
15654
- if (!part || typeof part !== "object")
15655
- continue;
15656
- const p = part;
15657
- if (p.type === "toolCall") {
15658
- if (typeof p.name === "string")
15659
- liveTailTokens += toolOutputTokens(p.name);
15660
- liveTailTokens += jsonTokens(p.arguments);
15661
- }
15662
- }
15663
- }
15664
- liveTailTokens += textTokens(msg.content);
15665
- }
15666
- return { tailToolTokens, liveTailTokens };
15667
- }
15668
- function maybeChannel1ReminderForToolResult(args) {
15669
- const { db, sessionId, toolName } = args;
15670
- const state2 = channel1StateBySession.get(sessionId);
15671
- if (!state2)
15672
- return null;
15673
- if (toolName === "ctx_reduce") {
15674
- state2.reducedSinceRefresh = true;
15675
- resetLastNudgeCycle(db, sessionId);
15676
- return null;
15677
- }
15678
- const text = toolResultText(args.content);
15679
- if (text.length === 0)
15680
- return null;
15681
- if (text.includes(CHANNEL1_SENTINEL))
15682
- return null;
15683
- state2.turnToolTokens += toolOutputTokens(text);
15684
- if (state2.reducedSinceRefresh)
15685
- return null;
15686
- const undroppedTokens = state2.tailToolTokens + state2.turnToolTokens;
15687
- const pressure = computePressure({
15688
- lastInputTokens: state2.lastInputTokens,
15689
- turnToolTokens: state2.turnToolTokens,
15690
- contextLimit: state2.contextLimit,
15691
- executeThresholdPercentage: state2.executeThresholdPercentage
15692
- });
15693
- const workingWindowTokens = Math.round(state2.contextLimit * state2.executeThresholdPercentage / 100);
15694
- const decision = decideChannel1({
15695
- undroppedTokens,
15696
- pressure,
15697
- estimatedInputTokens: state2.lastInputTokens + state2.turnToolTokens,
15698
- workingWindowTokens,
15699
- lastNudgeUndropped: getLastNudgeUndropped(db, sessionId),
15700
- lastNudgeLevel: getLastNudgeLevel(db, sessionId),
15701
- hasRecentReduce: false
15702
- });
15703
- setLastNudgeUndropped(db, sessionId, decision.nextLastNudge);
15704
- setLastNudgeLevel(db, sessionId, decision.nextLastNudgeLevel);
15705
- if (!decision.fire)
15706
- return null;
15707
- return {
15708
- type: "text",
15709
- text: buildChannel1Reminder(decision.level, decision.undroppedTokens, state2.oldestReclaimableToolTags)
15710
- };
15711
- }
15712
- var CHANNEL2_NUDGE_CUSTOM_TYPE = "magic-context:ceiling-nudge";
15713
- function maybeDeliverChannel2Pi(pi, db, sessionId, deliverAs = "followUp") {
15714
- let state2;
15715
- try {
15716
- state2 = getChannel2NudgeState(db, sessionId);
15717
- } catch {
15718
- return false;
15719
- }
15720
- if (state2 !== "pending")
15721
- return false;
15722
- const baseline = channel1StateBySession.get(sessionId);
15723
- if (!baseline)
15724
- return false;
15725
- if (baseline.reducedSinceRefresh)
15726
- return false;
15727
- const undropped = baseline.tailToolTokens + baseline.turnToolTokens;
15728
- if (!shouldTriggerChannel2({
15729
- reclaimableTokens: undropped,
15730
- usableTokens: baseline.usableTokens
15731
- })) {
15732
- try {
15733
- casChannel2NudgeState(db, sessionId, "pending", "");
15734
- } catch {}
15735
- return false;
15736
- }
15737
- if (!casChannel2NudgeState(db, sessionId, "pending", "claimed"))
15738
- return false;
15739
- try {
15740
- pi.sendMessage({
15741
- customType: CHANNEL2_NUDGE_CUSTOM_TYPE,
15742
- content: buildChannel2Reminder(undropped, baseline.oldestReclaimableToolTags),
15743
- display: false,
15744
- details: { kind: "channel-2-ceiling-nudge" }
15745
- }, { deliverAs });
15746
- } catch (error) {
15747
- try {
15748
- casChannel2NudgeState(db, sessionId, "claimed", "pending");
15749
- } catch (revertError) {
15750
- sessionLog(sessionId, "channel2 ceiling nudge delivery failed; pending restore was busy so the stale claim will heal later:", { deliveryError: error, revertError });
15751
- return false;
15752
- }
15753
- sessionLog(sessionId, "channel2 ceiling nudge delivery failed (will retry):", error);
15754
- return false;
15755
- }
15756
- try {
15757
- const confirmed = casChannel2NudgeState(db, sessionId, "claimed", "delivered");
15758
- if (confirmed) {
15759
- sessionLog(sessionId, "channel2 ceiling nudge delivered");
15760
- return true;
15761
- }
15762
- const outcome = sealDeliveredAfterUnconfirmedSend(db, sessionId);
15763
- if (outcome === "already-delivered") {
15764
- sessionLog(sessionId, "channel2 ceiling nudge duplicate window: our send returned after a sibling reclaimed the stale lease and already delivered");
15765
- } else if (outcome === "sealed") {
15766
- sessionLog(sessionId, "channel2 ceiling nudge sent but claim confirmation was lost; sealed delivered without an authoritative confirm");
15767
- } else {
15768
- sessionLog(sessionId, "channel2 ceiling nudge sent but claim confirmation was lost; lease stayed claimed and will heal later");
15769
- }
15770
- return false;
15771
- } catch (error) {
15772
- const outcome = sealDeliveredAfterUnconfirmedSend(db, sessionId);
15773
- if (outcome === "already-delivered") {
15774
- sessionLog(sessionId, "channel2 ceiling nudge duplicate window: our send returned after a sibling reclaimed the stale lease and already delivered");
15775
- } else if (outcome === "sealed") {
15776
- sessionLog(sessionId, "channel2 ceiling nudge sent but confirm failed:", error);
15777
- } else {
15778
- sessionLog(sessionId, "channel2 ceiling nudge sent but confirm failed; lease stayed claimed and will heal later:", error);
15779
- }
15780
- return false;
15781
- }
15782
- }
15783
-
15784
- // src/detect-recent-commit.ts
15785
- var COMMIT_LOOKBACK = 5;
15786
- function detectRecentCommit(messages) {
15787
- let assistantsScanned = 0;
15788
- for (let i = messages.length - 1;i >= 0; i--) {
15789
- const message = messages[i];
15790
- if (!message || typeof message !== "object" || !("role" in message) || message.role !== "assistant") {
15791
- continue;
15792
- }
15793
- assistantsScanned++;
15794
- if (assistantsScanned > COMMIT_LOOKBACK)
15795
- break;
15796
- if (!("content" in message))
15797
- continue;
15798
- const content = message.content;
15799
- if (!Array.isArray(content))
15800
- continue;
15801
- for (const part of content) {
15802
- if (part && typeof part === "object" && "type" in part && part.type === "text" && "text" in part && typeof part.text === "string") {
15803
- if (textMentionsRecentCommit(part.text)) {
15804
- return true;
15805
- }
15806
- }
15807
- }
15808
- }
15809
- return false;
15810
- }
15811
-
15812
- // ../plugin/src/hooks/magic-context/emergency-drop.ts
15813
- var TARGET_FRACTION = 0.3;
15814
- var TIER_RECENCY_RESERVE = 0.2;
15815
- var EMERGENCY_REARM_MIN_TOKENS = 2000;
15816
- var T1_TOOLS = new Set(["read", "todowrite", "task", "aft_outline", "aft_zoom"]);
15817
- var T2_TOOLS = new Set(["edit", "write", "apply_patch", "grep", "glob", "aft_search"]);
15818
- function normalizeToolName(toolName) {
15819
- if (!toolName)
15820
- return "";
15821
- let name = toolName.toLowerCase();
15822
- if (name.startsWith("mcp_"))
15823
- name = name.slice(4);
15824
- return name;
15825
- }
15826
- function resolveToolTier(toolName) {
15827
- const name = normalizeToolName(toolName);
15828
- if (T1_TOOLS.has(name))
15829
- return 1;
15830
- if (T2_TOOLS.has(name))
15831
- return 2;
15832
- return 3;
15833
- }
15834
- function tagReclaimBytes(tag) {
15835
- return tag.byteSize + tag.inputByteSize + tag.reasoningByteSize;
15836
- }
15837
- function estimateEmergencyDropReclaimTokens(tag) {
15838
- return Math.round(tagReclaimBytes(tag) * TOKENS_PER_BYTE);
15839
- }
15840
- function planEmergencyDrop(input) {
15841
- const {
15842
- tags,
15843
- floorTags,
15844
- maxTag,
15845
- protectedTags,
15846
- currentTotalInputTokens,
15847
- ceilingTokens,
15848
- priorInputSample,
15849
- hasPriorDrop
15850
- } = input;
15851
- const noop = (reason) => ({
15852
- shouldDrop: false,
15853
- tagNumbers: [],
15854
- reclaimTokens: 0,
15855
- reason
15856
- });
15857
- if (!Number.isFinite(ceilingTokens) || ceilingTokens <= 0) {
15858
- return noop("unknown-ceiling");
15859
- }
15860
- if (!Number.isFinite(currentTotalInputTokens) || currentTotalInputTokens <= 0) {
15861
- return noop("unknown-usage");
15862
- }
15863
- if (hasPriorDrop && currentTotalInputTokens === priorInputSample) {
15864
- return noop("same-input-sample (awaiting fresh usage after prior drop)");
15865
- }
15866
- let tailTokens = 0;
15867
- for (const tag of floorTags) {
15868
- if (tag.status !== "active")
15869
- continue;
15870
- tailTokens += estimateEmergencyDropReclaimTokens(tag);
15871
- }
15872
- const fixedFloor = Math.max(currentTotalInputTokens - tailTokens, 0);
15873
- const workingSpan = Math.max(ceilingTokens - fixedFloor, 0);
15874
- const target = fixedFloor + TARGET_FRACTION * workingSpan;
15875
- const reclaimTokens = Math.round(currentTotalInputTokens - target);
15876
- if (reclaimTokens <= EMERGENCY_REARM_MIN_TOKENS) {
15877
- return noop(`reclaim<=min (${reclaimTokens} <= ${EMERGENCY_REARM_MIN_TOKENS})`);
15878
- }
15879
- const protectedCutoff = maxTag - protectedTags;
15880
- const tierActive = { 1: [], 2: [] };
15881
- for (const tag of tags) {
15882
- if (tag.status !== "active" || tag.type !== "tool")
15883
- continue;
15884
- const tier = resolveToolTier(tag.toolName);
15885
- if (tier === 1 || tier === 2)
15886
- tierActive[tier].push(tag.tagNumber);
15887
- }
15888
- const reserved = new Set;
15889
- for (const tier of [1, 2]) {
15890
- const nums = tierActive[tier];
15891
- if (nums.length === 0)
15892
- continue;
15893
- nums.sort((a, b) => b - a);
15894
- const reserveCount = Math.ceil(TIER_RECENCY_RESERVE * nums.length);
15895
- for (let i = 0;i < reserveCount && i < nums.length; i++) {
15896
- reserved.add(nums[i]);
15897
- }
15898
- }
15899
- const byTier = { 1: [], 2: [], 3: [] };
15900
- for (const tag of tags) {
15901
- if (tag.status !== "active" || tag.type !== "tool")
15902
- continue;
15903
- if (tag.tagNumber > protectedCutoff)
15904
- continue;
15905
- const tier = resolveToolTier(tag.toolName);
15906
- if ((tier === 1 || tier === 2) && reserved.has(tag.tagNumber))
15907
- continue;
15908
- byTier[tier].push(tag);
15909
- }
15910
- const selected = [];
15911
- let reclaimed = 0;
15912
- outer:
15913
- for (const tier of [3, 2, 1]) {
15914
- const group = byTier[tier];
15915
- group.sort((a, b) => a.tagNumber - b.tagNumber);
15916
- for (const tag of group) {
15917
- selected.push(tag.tagNumber);
15918
- reclaimed += estimateEmergencyDropReclaimTokens(tag);
15919
- if (reclaimed >= reclaimTokens)
15920
- break outer;
15921
- }
15922
- }
15923
- if (selected.length === 0) {
15924
- return noop("no-candidates");
15925
- }
15926
- return {
15927
- shouldDrop: true,
15928
- tagNumbers: selected,
15929
- reclaimTokens,
15930
- reason: `tiered drop: ${selected.length} tags, reclaim≈${reclaimed}/${reclaimTokens} tokens (floor≈${fixedFloor}, ceiling=${Math.round(ceilingTokens)})`
15931
- };
15932
- }
15933
-
15934
- // ../plugin/src/hooks/magic-context/system-injection-stripper.ts
15935
- var SYSTEM_INJECTION_MARKERS = [
15936
- "<!-- OMO_INTERNAL_INITIATOR -->",
15937
- "[SYSTEM DIRECTIVE: MAGIC-CONTEXT",
15938
- "[SYSTEM DIRECTIVE: OH-MY-OPENCODE",
15939
- "[Category+Skill Reminder]",
15940
- "[EDIT ERROR - IMMEDIATE ACTION REQUIRED]",
15941
- "[task CALL FAILED - IMMEDIATE RETRY REQUIRED]",
15942
- "[EMERGENCY CONTEXT WINDOW WARNING]",
15943
- "Unstable background agent appears idle",
15944
- "**THE SUBAGENT JUST CLAIMED THIS TASK IS DONE."
15945
- ];
15946
- var SYSTEM_REMINDER_REGEX = /<system-reminder>[\s\S]*?<\/system-reminder>/gi;
15947
- var OMO_MARKER_REGEX = /<!-- OMO_INTERNAL_INITIATOR -->/g;
15948
- function stripSystemInjection(text) {
15949
- let hasInjection = false;
15950
- for (const marker of SYSTEM_INJECTION_MARKERS) {
15951
- if (text.includes(marker)) {
15952
- hasInjection = true;
15953
- break;
15954
- }
15955
- }
15956
- if (SYSTEM_REMINDER_REGEX.test(text))
15957
- hasInjection = true;
15958
- SYSTEM_REMINDER_REGEX.lastIndex = 0;
15959
- if (!hasInjection)
15960
- return null;
15961
- let cleaned = text;
15962
- cleaned = cleaned.replace(SYSTEM_REMINDER_REGEX, "");
15963
- cleaned = cleaned.replace(OMO_MARKER_REGEX, "");
15964
- cleaned = cleaned.replace(/\[SYSTEM DIRECTIVE: OH-MY-(?:OPENCODE|CLAUDE)[^\]]*\][\s\S]*?(?=\n\n(?!\s*[-*])|$)/g, "");
15965
- for (const marker of SYSTEM_INJECTION_MARKERS) {
15966
- if (marker.startsWith("<!-- ") || marker.startsWith("[SYSTEM DIRECTIVE"))
15967
- continue;
15968
- const idx = cleaned.indexOf(marker);
15969
- if (idx === -1)
15970
- continue;
15971
- const blockEnd = cleaned.indexOf(`
15972
-
15973
- `, idx + marker.length);
15974
- cleaned = blockEnd !== -1 ? cleaned.slice(0, idx) + cleaned.slice(blockEnd) : cleaned.slice(0, idx);
15975
- }
15976
- return cleaned.trim();
15977
- }
15978
-
15979
- // src/heuristic-cleanup-pi.ts
15980
- var DEDUP_SAFE_TOOLS = new Set([
15981
- "mcp_grep",
15982
- "mcp_read",
15983
- "mcp_glob",
15984
- "mcp_ast_grep_search",
15985
- "mcp_lsp_diagnostics",
15986
- "mcp_lsp_symbols",
15987
- "mcp_lsp_find_references",
15988
- "mcp_lsp_goto_definition",
15989
- "mcp_lsp_prepare_rename"
15990
- ]);
15991
- function buildPiToolFingerprints(messages, resolveStableId) {
15992
- const fingerprints = new Map;
15993
- for (let i = 0;i < messages.length; i++) {
15994
- const message = messages[i];
15995
- if (!message || typeof message !== "object")
15996
- continue;
15997
- const msg = message;
15998
- if (msg.role !== "assistant")
15999
- continue;
16000
- if (!Array.isArray(msg.content))
15585
+ if (!Array.isArray(msg.content))
16001
15586
  continue;
16002
15587
  const ownerMsgId = resolveStableId(message, i);
16003
15588
  if (!ownerMsgId)
@@ -16031,9 +15616,8 @@ function buildPiToolFingerprints(messages, resolveStableId) {
16031
15616
  }
16032
15617
  return fingerprints;
16033
15618
  }
16034
- function collectStaleReduceCallIds(messages, messageIdToMaxTag, toolAgeCutoff, resolveStableId) {
16035
- const composite = new Set;
16036
- const bareCallIds = new Set;
15619
+ function collectStaleReduceCallIds(messages, messageIdToMaxTag, ctxReduceTagNumbers, toolAgeCutoff, resolveStableId) {
15620
+ const reduceCalls = new Map;
16037
15621
  for (let i = 0;i < messages.length; i++) {
16038
15622
  const raw = messages[i];
16039
15623
  if (!raw || typeof raw !== "object")
@@ -16044,9 +15628,7 @@ function collectStaleReduceCallIds(messages, messageIdToMaxTag, toolAgeCutoff, r
16044
15628
  const stableId = resolveStableId(raw, i);
16045
15629
  if (!stableId)
16046
15630
  continue;
16047
- const maxTag = messageIdToMaxTag.get(stableId) ?? 0;
16048
- if (maxTag === 0 || maxTag > toolAgeCutoff)
16049
- continue;
15631
+ const ownerMaxTag = messageIdToMaxTag.get(stableId) ?? 0;
16050
15632
  for (const part of msg.content) {
16051
15633
  if (!part || typeof part !== "object")
16052
15634
  continue;
@@ -16057,10 +15639,35 @@ function collectStaleReduceCallIds(messages, messageIdToMaxTag, toolAgeCutoff, r
16057
15639
  continue;
16058
15640
  if (typeof p.id !== "string" || p.id.length === 0)
16059
15641
  continue;
16060
- composite.add(`${stableId}\x00${p.id}`);
16061
- bareCallIds.add(p.id);
15642
+ const composite2 = `${stableId}\x00${p.id}`;
15643
+ const maxTag = ctxReduceTagNumbers.get(composite2) ?? ownerMaxTag;
15644
+ if (maxTag === 0)
15645
+ continue;
15646
+ reduceCalls.set(composite2, {
15647
+ composite: composite2,
15648
+ callId: p.id,
15649
+ maxTag,
15650
+ messageIndex: i
15651
+ });
16062
15652
  }
16063
15653
  }
15654
+ const newestFirst = [...reduceCalls.values()].sort((left, right) => {
15655
+ const byPosition = right.maxTag - left.maxTag || right.messageIndex - left.messageIndex;
15656
+ if (byPosition !== 0)
15657
+ return byPosition;
15658
+ if (left.composite === right.composite)
15659
+ return 0;
15660
+ return left.composite < right.composite ? 1 : -1;
15661
+ });
15662
+ const protectedComposite = new Set(newestFirst.slice(0, PI_CTX_REDUCE_KEEP).map((call) => call.composite));
15663
+ const composite = new Set;
15664
+ const bareCallIds = new Set;
15665
+ for (const call of newestFirst) {
15666
+ if (call.maxTag > toolAgeCutoff || protectedComposite.has(call.composite))
15667
+ continue;
15668
+ composite.add(call.composite);
15669
+ bareCallIds.add(call.callId);
15670
+ }
16064
15671
  return { composite, bareCallIds };
16065
15672
  }
16066
15673
  function applyPiHeuristicCleanup(sessionId, db, targets, piMessages, config, preloadedTags, resolveId) {
@@ -16123,7 +15730,7 @@ function applyPiHeuristicCleanup(sessionId, db, targets, piMessages, config, pre
16123
15730
  }
16124
15731
  setEmergencyDropSample(db, sessionId, emergency.currentTotalInputTokens);
16125
15732
  }
16126
- const staleReduce = config.staleReduceStripEnabled ? collectStaleReduceCallIds(piMessages, buildMessageIdToMaxTagFromTargets(targets), toolAgeCutoff, resolveStableId) : { composite: new Set, bareCallIds: new Set };
15733
+ const staleReduce = config.staleReduceStripEnabled ? collectStaleReduceCallIds(piMessages, buildMessageIdToMaxTagFromTargets(targets), buildCtxReduceTagNumbers(tags), toolAgeCutoff, resolveStableId) : { composite: new Set, bareCallIds: new Set };
16127
15734
  if (config.staleReduceStripEnabled && (staleReduce.composite.size > 0 || staleReduce.bareCallIds.size > 0)) {
16128
15735
  db.transaction(() => {
16129
15736
  for (const tag of tags) {
@@ -16148,115 +15755,843 @@ function applyPiHeuristicCleanup(sessionId, db, targets, piMessages, config, pre
16148
15755
  }
16149
15756
  })();
16150
15757
  }
16151
- db.transaction(() => {
16152
- for (const tag of tags) {
16153
- if (tag.status !== "active")
16154
- continue;
16155
- if (tag.tagNumber > protectedCutoff)
16156
- continue;
16157
- if (tag.type !== "message")
16158
- continue;
16159
- const target = targets.get(tag.tagNumber);
16160
- if (!target)
16161
- continue;
16162
- const content = target.getContent?.();
16163
- if (!content)
16164
- continue;
16165
- const stripped = stripSystemInjection(content);
16166
- if (stripped === null)
16167
- continue;
16168
- const strippedSource = stripTagPrefix(stripped);
16169
- if (strippedSource.trim().length === 0) {
16170
- const dropResult = target.drop?.() ?? "absent";
16171
- const didReplace = dropResult === "absent" ? target.setContent(`[dropped §${tag.tagNumber}§]`) : false;
16172
- if (dropResult === "removed" || dropResult === "absent") {
16173
- replaceSourceContent(db, sessionId, tag.tagNumber, "");
16174
- updateTagStatus(db, sessionId, tag.tagNumber, "dropped");
16175
- if (dropResult === "removed" || didReplace) {
16176
- droppedInjections++;
16177
- }
16178
- }
16179
- } else {
16180
- const didSet = target.setContent(stripped);
16181
- if (didSet) {
16182
- replaceSourceContent(db, sessionId, tag.tagNumber, strippedSource);
16183
- droppedInjections++;
16184
- }
16185
- }
15758
+ db.transaction(() => {
15759
+ for (const tag of tags) {
15760
+ if (tag.status !== "active")
15761
+ continue;
15762
+ if (tag.tagNumber > protectedCutoff)
15763
+ continue;
15764
+ if (tag.type !== "message")
15765
+ continue;
15766
+ const target = targets.get(tag.tagNumber);
15767
+ if (!target)
15768
+ continue;
15769
+ const content = target.getContent?.();
15770
+ if (!content)
15771
+ continue;
15772
+ const stripped = stripSystemInjection(content);
15773
+ if (stripped === null)
15774
+ continue;
15775
+ const strippedSource = stripTagPrefix(stripped);
15776
+ if (strippedSource.trim().length === 0) {
15777
+ const dropResult = target.drop?.() ?? "absent";
15778
+ const didReplace = dropResult === "absent" ? target.setContent(`[dropped §${tag.tagNumber}§]`) : false;
15779
+ if (dropResult === "removed" || dropResult === "absent") {
15780
+ replaceSourceContent(db, sessionId, tag.tagNumber, "");
15781
+ updateTagStatus(db, sessionId, tag.tagNumber, "dropped");
15782
+ if (dropResult === "removed" || didReplace) {
15783
+ droppedInjections++;
15784
+ }
15785
+ }
15786
+ } else {
15787
+ const didSet = target.setContent(stripped);
15788
+ if (didSet) {
15789
+ replaceSourceContent(db, sessionId, tag.tagNumber, strippedSource);
15790
+ droppedInjections++;
15791
+ }
15792
+ }
15793
+ }
15794
+ })();
15795
+ const toolFingerprints = buildPiToolFingerprints(piMessages, resolveStableId);
15796
+ if (toolFingerprints.size > 0) {
15797
+ const tagsByCompositeKey = new Map;
15798
+ for (const tag of tags) {
15799
+ if (tag.type === "tool" && tag.status === "active" && tag.messageId) {
15800
+ const key = tag.toolOwnerMessageId ? `${tag.toolOwnerMessageId}\x00${tag.messageId}` : tag.messageId;
15801
+ tagsByCompositeKey.set(key, tag);
15802
+ }
15803
+ }
15804
+ const fingerprintGroups = new Map;
15805
+ for (const [compositeKey, fingerprint] of toolFingerprints) {
15806
+ const tag = tagsByCompositeKey.get(compositeKey);
15807
+ if (!tag || tag.tagNumber > protectedCutoff)
15808
+ continue;
15809
+ const group = fingerprintGroups.get(fingerprint) ?? [];
15810
+ group.push(tag);
15811
+ fingerprintGroups.set(fingerprint, group);
15812
+ }
15813
+ db.transaction(() => {
15814
+ for (const [, group] of fingerprintGroups) {
15815
+ if (group.length <= 1)
15816
+ continue;
15817
+ group.sort((a, b) => a.tagNumber - b.tagNumber);
15818
+ for (let i = 0;i < group.length - 1; i++) {
15819
+ const tag = group[i];
15820
+ const target = targets.get(tag.tagNumber);
15821
+ const result = target?.drop?.() ?? "absent";
15822
+ if (result === "incomplete")
15823
+ continue;
15824
+ updateTagDropMode(db, sessionId, tag.tagNumber, "full");
15825
+ updateTagStatus(db, sessionId, tag.tagNumber, "dropped");
15826
+ if (result === "removed" || result === "truncated") {
15827
+ deduplicatedTools++;
15828
+ }
15829
+ }
15830
+ }
15831
+ })();
15832
+ }
15833
+ if (droppedTools > 0 || deduplicatedTools > 0 || droppedInjections > 0 || droppedStaleReduceCalls > 0) {
15834
+ sessionLog(sessionId, `heuristic cleanup: dropped ${droppedTools} tool tags, stale ctx_reduce=${droppedStaleReduceCalls}, deduplicated ${deduplicatedTools} tool calls, dropped ${droppedInjections} system injections`);
15835
+ }
15836
+ let compressedTextTags = 0;
15837
+ let mutatedTextTags = 0;
15838
+ if (config.caveman?.enabled) {
15839
+ const cavemanResult = applyCavemanCleanup(sessionId, db, targets, tags, {
15840
+ enabled: true,
15841
+ minChars: config.caveman.minChars,
15842
+ protectedTags: config.protectedTags
15843
+ });
15844
+ compressedTextTags = cavemanResult.compressedToLite + cavemanResult.compressedToFull + cavemanResult.compressedToUltra;
15845
+ mutatedTextTags = cavemanResult.mutatedTextTags;
15846
+ }
15847
+ return {
15848
+ droppedTools,
15849
+ deduplicatedTools,
15850
+ droppedInjections,
15851
+ droppedStaleReduceCalls,
15852
+ emergencyDroppedTools,
15853
+ compressedTextTags,
15854
+ mutatedTextTags
15855
+ };
15856
+ }
15857
+ function buildCtxReduceTagNumbers(tags) {
15858
+ const byComposite = new Map;
15859
+ for (const tag of tags) {
15860
+ if (tag.status !== "active" || tag.type !== "tool" || tag.toolName !== "ctx_reduce" || !tag.toolOwnerMessageId) {
15861
+ continue;
15862
+ }
15863
+ byComposite.set(`${tag.toolOwnerMessageId}\x00${tag.messageId}`, tag.tagNumber);
15864
+ }
15865
+ return byComposite;
15866
+ }
15867
+ function buildMessageIdToMaxTagFromTargets(targets) {
15868
+ const byMessage = new Map;
15869
+ for (const [tagNumber, target] of targets) {
15870
+ const id = target.message?.info?.id;
15871
+ if (typeof id !== "string" || id.length === 0)
15872
+ continue;
15873
+ if (tagNumber > (byMessage.get(id) ?? 0))
15874
+ byMessage.set(id, tagNumber);
15875
+ }
15876
+ return byMessage;
15877
+ }
15878
+
15879
+ // src/tail-hygiene-walk-pi.ts
15880
+ var TAG_PREFIX = /^§(\d+)§\s*/;
15881
+ var SYNTHETIC_TODO_PREFIX = "mc_synthetic_todo_";
15882
+ var MAX_CONTENT_MEMO_ENTRIES = 1e5;
15883
+ var MAX_CONTENT_MEMO_BYTES = 64 * 1024 * 1024;
15884
+ var contentMemo = new Map;
15885
+ var contentMemoBytes = 0;
15886
+ var FNV1A_32_OFFSET = 2166136261;
15887
+ var FNV1A_32_PRIME = 16777619;
15888
+ function isRecord3(value) {
15889
+ return value !== null && typeof value === "object";
15890
+ }
15891
+ function fnv1a32(value) {
15892
+ let hash = FNV1A_32_OFFSET;
15893
+ for (let index = 0;index < value.length; index += 1) {
15894
+ hash ^= value.charCodeAt(index);
15895
+ hash = Math.imul(hash, FNV1A_32_PRIME);
15896
+ }
15897
+ return (hash >>> 0).toString(16).padStart(8, "0");
15898
+ }
15899
+ function safeStableStringify(value) {
15900
+ const seen = new Set;
15901
+ try {
15902
+ return JSON.stringify(value, (_key, current) => {
15903
+ if (!isRecord3(current) || Array.isArray(current))
15904
+ return current;
15905
+ if (seen.has(current))
15906
+ return "[Circular]";
15907
+ seen.add(current);
15908
+ return Object.fromEntries(Object.entries(current).sort(([left], [right]) => left.localeCompare(right)));
15909
+ }) ?? "";
15910
+ } catch {
15911
+ return "";
15912
+ }
15913
+ }
15914
+ function memoizedContent(kind, content) {
15915
+ const key = `${kind}\x00${content}`;
15916
+ const cached = contentMemo.get(key);
15917
+ if (cached)
15918
+ return cached;
15919
+ const measured = {
15920
+ hash: fnv1a32(key),
15921
+ tokens: kind === "excluded" ? 0 : estimateTokens(content),
15922
+ keyBytes: key.length * 2 + 32
15923
+ };
15924
+ contentMemo.set(key, measured);
15925
+ contentMemoBytes += measured.keyBytes;
15926
+ while (contentMemo.size > MAX_CONTENT_MEMO_ENTRIES || contentMemoBytes > MAX_CONTENT_MEMO_BYTES) {
15927
+ const oldest = contentMemo.keys().next().value;
15928
+ if (typeof oldest !== "string")
15929
+ break;
15930
+ const removed = contentMemo.get(oldest);
15931
+ if (removed)
15932
+ contentMemoBytes -= removed.keyBytes;
15933
+ contentMemo.delete(oldest);
15934
+ }
15935
+ return measured;
15936
+ }
15937
+ function memoizedTokens(kind, content) {
15938
+ return memoizedContent(kind, content).tokens;
15939
+ }
15940
+ function partHash(kind, content) {
15941
+ return memoizedContent(kind, content).hash;
15942
+ }
15943
+ function parseVisibleTag(content, tagsByNumber) {
15944
+ const match = content.trimStart().match(TAG_PREFIX);
15945
+ if (!match)
15946
+ return;
15947
+ const tagNumber = Number(match[1]);
15948
+ return Number.isSafeInteger(tagNumber) ? tagsByNumber.get(tagNumber) : undefined;
15949
+ }
15950
+ function isDropSentinel(content) {
15951
+ const head = content.trimStart().replace(TAG_PREFIX, "").trimStart().toLowerCase();
15952
+ return head.startsWith("[dropped") || head.startsWith("[truncated");
15953
+ }
15954
+ function messageIdentity(message, index, stableId) {
15955
+ const resolved = stableId?.(message, index);
15956
+ if (resolved)
15957
+ return resolved;
15958
+ if (isRecord3(message)) {
15959
+ if (typeof message.responseId === "string" && message.responseId.length > 0) {
15960
+ return `response:${message.responseId}`;
15961
+ }
15962
+ if (typeof message.timestamp === "number") {
15963
+ return `timestamp:${message.timestamp}:${String(message.role ?? "unknown")}`;
15964
+ }
15965
+ }
15966
+ return `pi-message:${index}`;
15967
+ }
15968
+ function isSyntheticMessage(message, index, input) {
15969
+ if (index < Math.max(0, input.syntheticLeadingCount ?? 0))
15970
+ return true;
15971
+ if (input.syntheticMessages?.has(message))
15972
+ return true;
15973
+ if (message.syntheticTodoMarker === true)
15974
+ return true;
15975
+ const role = typeof message.role === "string" ? message.role : "";
15976
+ return role === "system" || role === "custom" || role === "compactionSummary";
15977
+ }
15978
+ function imageContentAndTokens(part) {
15979
+ const data = typeof part.data === "string" ? part.data : "";
15980
+ const mimeType = typeof part.mimeType === "string" ? part.mimeType : "image/png";
15981
+ const content = data.startsWith("data:") ? data : `data:${mimeType};base64,${data}`;
15982
+ return {
15983
+ content,
15984
+ tokens: content.length > 0 ? estimateImageTokensFromDataUrl(content) : 0
15985
+ };
15986
+ }
15987
+ function messageIdForTag(tag) {
15988
+ if (tag.type === "tool")
15989
+ return tag.toolOwnerMessageId;
15990
+ const positional = tag.messageId.match(/^(.*):(?:p|file)\d+$/);
15991
+ if (positional)
15992
+ return positional[1] ?? null;
15993
+ const contentDerived = tag.messageId.indexOf(":mc-text-v1:");
15994
+ return contentDerived >= 0 ? tag.messageId.slice(0, contentDerived) : null;
15995
+ }
15996
+ function neighborhoodConsistent(input) {
15997
+ let previousMax = null;
15998
+ for (let index = 0;index <= input.messageIndex; index += 1) {
15999
+ const bound = input.boundsByMessageIndex.get(index);
16000
+ if (bound)
16001
+ previousMax = previousMax === null ? bound.max : Math.max(previousMax, bound.max);
16002
+ }
16003
+ let nextMin = null;
16004
+ for (let index = input.messageIndex + 1;index < input.messageCount; index += 1) {
16005
+ const bound = input.boundsByMessageIndex.get(index);
16006
+ if (bound)
16007
+ nextMin = nextMin === null ? bound.min : Math.min(nextMin, bound.min);
16008
+ }
16009
+ return previousMax !== null && nextMin !== null && input.orphanTagNumber >= previousMax && input.orphanTagNumber <= nextMin;
16010
+ }
16011
+ function collectToolArcs(input) {
16012
+ const arcs = [];
16013
+ const arcByPart = new Map;
16014
+ const pendingByCall = new Map;
16015
+ const messageIds = input.messages.map((message, index) => messageIdentity(message, index, input.stableId));
16016
+ for (let messageIndex = 0;messageIndex < input.messages.length; messageIndex += 1) {
16017
+ const raw = input.messages[messageIndex];
16018
+ if (!isRecord3(raw))
16019
+ continue;
16020
+ const role = raw.role;
16021
+ if (role === "assistant" && Array.isArray(raw.content)) {
16022
+ for (let partIndex = 0;partIndex < raw.content.length; partIndex += 1) {
16023
+ const part = raw.content[partIndex];
16024
+ if (!isRecord3(part) || part.type !== "toolCall")
16025
+ continue;
16026
+ if (typeof part.id !== "string" || part.id.length === 0)
16027
+ continue;
16028
+ const ownerId2 = messageIds[messageIndex] ?? `pi-message:${messageIndex}`;
16029
+ const arc2 = {
16030
+ key: `${ownerId2}\x00${part.id}\x00${partIndex}`,
16031
+ callId: part.id,
16032
+ ownerId: ownerId2,
16033
+ ownerIndex: messageIndex,
16034
+ toolName: typeof part.name === "string" ? part.name : null,
16035
+ sentinel: isRecord3(part.arguments) && typeof part.arguments.__magic_context_dropped__ === "string",
16036
+ parts: [part]
16037
+ };
16038
+ arcs.push(arc2);
16039
+ arcByPart.set(part, arc2);
16040
+ const pending2 = pendingByCall.get(part.id) ?? [];
16041
+ pending2.push(arc2);
16042
+ pendingByCall.set(part.id, pending2);
16043
+ }
16044
+ continue;
16045
+ }
16046
+ if (role !== "toolResult")
16047
+ continue;
16048
+ if (typeof raw.toolCallId !== "string" || raw.toolCallId.length === 0)
16049
+ continue;
16050
+ const pending = pendingByCall.get(raw.toolCallId);
16051
+ const matched = pending?.pop();
16052
+ const ownerId = matched?.ownerId ?? messageIds[messageIndex] ?? `pi-message:${messageIndex}`;
16053
+ const arc = matched ?? {
16054
+ key: `${ownerId}\x00${raw.toolCallId}\x00result:${messageIndex}`,
16055
+ callId: raw.toolCallId,
16056
+ ownerId,
16057
+ ownerIndex: messageIndex,
16058
+ toolName: typeof raw.toolName === "string" ? raw.toolName : null,
16059
+ sentinel: false,
16060
+ parts: []
16061
+ };
16062
+ if (!matched)
16063
+ arcs.push(arc);
16064
+ if (!Array.isArray(raw.content))
16065
+ continue;
16066
+ for (const part of raw.content) {
16067
+ if (!isRecord3(part))
16068
+ continue;
16069
+ arc.parts.push(part);
16070
+ arcByPart.set(part, arc);
16071
+ if (part.type === "text" && typeof part.text === "string" && isDropSentinel(part.text)) {
16072
+ arc.sentinel = true;
16073
+ }
16074
+ }
16075
+ }
16076
+ return { arcs, arcByPart, messageIds };
16077
+ }
16078
+ function attributeTags(input, arcs, messageIds) {
16079
+ const messageTags = new Map;
16080
+ const tagsByNumber = new Map;
16081
+ const exactToolTags = new Map;
16082
+ const orphanTagsByCall = new Map;
16083
+ const messageIndexById = new Map;
16084
+ for (let index = 0;index < messageIds.length; index += 1) {
16085
+ const id = input.stableId?.(input.messages[index], index);
16086
+ if (id)
16087
+ messageIndexById.set(id, index);
16088
+ }
16089
+ const boundsByMessageIndex = new Map;
16090
+ for (const tag of input.tags) {
16091
+ tagsByNumber.set(tag.tagNumber, tag);
16092
+ if (tag.type === "tool") {
16093
+ if (tag.toolOwnerMessageId === null) {
16094
+ const rows = orphanTagsByCall.get(tag.messageId) ?? [];
16095
+ rows.push(tag);
16096
+ orphanTagsByCall.set(tag.messageId, rows);
16097
+ } else {
16098
+ exactToolTags.set(`${tag.toolOwnerMessageId}\x00${tag.messageId}`, tag);
16099
+ }
16100
+ } else {
16101
+ messageTags.set(tag.messageId, tag);
16102
+ }
16103
+ const ownerId = messageIdForTag(tag);
16104
+ const messageIndex = ownerId === null ? undefined : messageIndexById.get(ownerId);
16105
+ if (messageIndex === undefined)
16106
+ continue;
16107
+ const current = boundsByMessageIndex.get(messageIndex);
16108
+ boundsByMessageIndex.set(messageIndex, {
16109
+ min: current ? Math.min(current.min, tag.tagNumber) : tag.tagNumber,
16110
+ max: current ? Math.max(current.max, tag.tagNumber) : tag.tagNumber
16111
+ });
16112
+ }
16113
+ const orphanCandidates = new Map;
16114
+ for (const arc of arcs) {
16115
+ const exact = exactToolTags.get(`${arc.ownerId}\x00${arc.callId}`);
16116
+ if (exact) {
16117
+ arc.tag = exact;
16118
+ continue;
16119
+ }
16120
+ const orphans = orphanTagsByCall.get(arc.callId);
16121
+ if (orphans?.length !== 1)
16122
+ continue;
16123
+ if (!neighborhoodConsistent({
16124
+ orphanTagNumber: orphans[0].tagNumber,
16125
+ messageIndex: arc.ownerIndex,
16126
+ boundsByMessageIndex,
16127
+ messageCount: input.messages.length
16128
+ })) {
16129
+ continue;
16130
+ }
16131
+ const byOwner = orphanCandidates.get(arc.callId) ?? new Map;
16132
+ const ownerArcs = byOwner.get(arc.ownerId) ?? [];
16133
+ ownerArcs.push(arc);
16134
+ byOwner.set(arc.ownerId, ownerArcs);
16135
+ orphanCandidates.set(arc.callId, byOwner);
16136
+ }
16137
+ for (const [callId, byOwner] of orphanCandidates) {
16138
+ if (byOwner.size !== 1)
16139
+ continue;
16140
+ const orphan = orphanTagsByCall.get(callId)?.[0];
16141
+ if (!orphan)
16142
+ continue;
16143
+ for (const ownerArcs of byOwner.values()) {
16144
+ for (const arc of ownerArcs)
16145
+ arc.tag = orphan;
16146
+ }
16147
+ }
16148
+ for (const arc of arcs) {
16149
+ if (arc.tag)
16150
+ continue;
16151
+ for (const part of arc.parts) {
16152
+ if (part.type !== "text" || typeof part.text !== "string")
16153
+ continue;
16154
+ const visible = parseVisibleTag(part.text, tagsByNumber);
16155
+ if (visible?.type === "tool") {
16156
+ arc.tag = visible;
16157
+ break;
16158
+ }
16159
+ }
16160
+ }
16161
+ return { messageTags, tagsByNumber };
16162
+ }
16163
+ function excludedDraft(key, value) {
16164
+ return {
16165
+ key,
16166
+ kind: "excluded",
16167
+ content: typeof value === "string" ? value : safeStableStringify(value),
16168
+ tokens: 0
16169
+ };
16170
+ }
16171
+ function finalizeParts(drafts, protectedTags) {
16172
+ const visibleTags = new Map;
16173
+ for (const part of drafts) {
16174
+ if (part.kind !== "excluded" && part.tag)
16175
+ visibleTags.set(part.tag.tagNumber, part.tag);
16176
+ }
16177
+ const protectedNumbers = new Set([...visibleTags.keys()].sort((left, right) => right - left).slice(0, Math.max(0, protectedTags)));
16178
+ const exemplarNumbers = [...visibleTags.values()].filter((tag) => tag.type === "tool" && tag.toolName === "ctx_reduce").sort((left, right) => right.tagNumber - left.tagNumber).slice(0, PI_CTX_REDUCE_KEEP).map((tag) => tag.tagNumber);
16179
+ for (const tagNumber of exemplarNumbers)
16180
+ protectedNumbers.add(tagNumber);
16181
+ let u = 0;
16182
+ let t = 0;
16183
+ const parts = drafts.map((draft) => {
16184
+ const protectedPart = draft.tag ? protectedNumbers.has(draft.tag.tagNumber) : false;
16185
+ const tokens = Math.max(0, draft.tokens);
16186
+ const uTokens = draft.tag && !protectedPart && draft.kind !== "excluded" ? tokens : 0;
16187
+ t += tokens;
16188
+ u += uTokens;
16189
+ return {
16190
+ key: draft.key,
16191
+ contentHash: partHash(draft.kind, draft.content),
16192
+ kind: draft.kind,
16193
+ tokens,
16194
+ uTokens,
16195
+ tagNumber: draft.tag?.tagNumber ?? null,
16196
+ tagStatus: draft.tag ? "active" : null,
16197
+ protected: protectedPart
16198
+ };
16199
+ });
16200
+ const clampedT = Math.max(0, t);
16201
+ return {
16202
+ u: Math.min(clampedT, Math.max(0, u)),
16203
+ t: clampedT,
16204
+ contentSignature: fnv1a32(parts.map((part) => `${part.key}:${part.contentHash}`).join("\x00")),
16205
+ parts
16206
+ };
16207
+ }
16208
+ function measurePiTailHygiene(input) {
16209
+ const { arcs, arcByPart, messageIds } = collectToolArcs(input);
16210
+ const { messageTags, tagsByNumber } = attributeTags(input, arcs, messageIds);
16211
+ const drafts = [];
16212
+ for (let messageIndex = 0;messageIndex < input.messages.length; messageIndex += 1) {
16213
+ const raw = input.messages[messageIndex];
16214
+ const messageKey = messageIds[messageIndex] ?? `pi-message:${messageIndex}`;
16215
+ if (!isRecord3(raw)) {
16216
+ drafts.push(excludedDraft(`${messageKey}\x00excluded`, raw));
16217
+ continue;
16218
+ }
16219
+ if (isSyntheticMessage(raw, messageIndex, input)) {
16220
+ drafts.push(excludedDraft(`${messageKey}\x00synthetic`, raw));
16221
+ continue;
16222
+ }
16223
+ const role = raw.role;
16224
+ if (role !== "user" && role !== "assistant" && role !== "toolResult") {
16225
+ drafts.push(excludedDraft(`${messageKey}\x00excluded-role`, raw));
16226
+ continue;
16227
+ }
16228
+ if (typeof raw.content === "string") {
16229
+ const content = raw.content;
16230
+ const tag = parseVisibleTag(content, tagsByNumber) ?? messageTags.get(`${messageKey}:p0`);
16231
+ if (!content || isDropSentinel(content)) {
16232
+ drafts.push(excludedDraft(`${messageKey}\x00text:0`, content));
16233
+ } else {
16234
+ drafts.push({
16235
+ key: `${messageKey}\x00text:0`,
16236
+ kind: "text",
16237
+ content,
16238
+ tokens: memoizedTokens("text", content),
16239
+ tag
16240
+ });
16241
+ }
16242
+ continue;
16243
+ }
16244
+ if (!Array.isArray(raw.content)) {
16245
+ drafts.push(excludedDraft(`${messageKey}\x00excluded-content`, raw.content));
16246
+ continue;
16247
+ }
16248
+ let textOrdinal = 0;
16249
+ for (let partIndex = 0;partIndex < raw.content.length; partIndex += 1) {
16250
+ const part = raw.content[partIndex];
16251
+ const key = `${messageKey}\x00${partIndex}`;
16252
+ if (!isRecord3(part)) {
16253
+ drafts.push(excludedDraft(`${key}\x00excluded`, part));
16254
+ continue;
16255
+ }
16256
+ if (part.syntheticTodoMarker === true) {
16257
+ drafts.push(excludedDraft(`${key}\x00synthetic-todo`, part));
16258
+ continue;
16259
+ }
16260
+ if (part.type === "thinking" || part.type === "reasoning" || part.type === "redacted_thinking") {
16261
+ drafts.push(excludedDraft(`${key}\x00reasoning`, part));
16262
+ continue;
16263
+ }
16264
+ if (part.type === "text" && typeof part.text === "string") {
16265
+ if (role === "toolResult") {
16266
+ const arc = arcByPart.get(part);
16267
+ const content2 = stripChannel1ReminderSpans(part.text);
16268
+ const tag2 = parseVisibleTag(content2, tagsByNumber) ?? arc?.tag;
16269
+ if (arc?.sentinel || !content2 || isDropSentinel(content2)) {
16270
+ drafts.push(excludedDraft(`${key}\x00toolOutput`, content2));
16271
+ } else {
16272
+ drafts.push({
16273
+ key: `${key}\x00toolOutput`,
16274
+ kind: "toolOutput",
16275
+ content: content2,
16276
+ tokens: memoizedTokens("toolOutput", content2),
16277
+ tag: tag2
16278
+ });
16279
+ }
16280
+ continue;
16281
+ }
16282
+ const content = part.text;
16283
+ const tag = parseVisibleTag(content, tagsByNumber) ?? messageTags.get(`${messageKey}:p${textOrdinal}`);
16284
+ textOrdinal += 1;
16285
+ if (!content || isDropSentinel(content)) {
16286
+ drafts.push(excludedDraft(`${key}\x00text`, content));
16287
+ } else {
16288
+ drafts.push({
16289
+ key: `${key}\x00text`,
16290
+ kind: "text",
16291
+ content,
16292
+ tokens: memoizedTokens("text", content),
16293
+ tag
16294
+ });
16295
+ }
16296
+ continue;
16297
+ }
16298
+ if (part.type === "image") {
16299
+ const image = imageContentAndTokens(part);
16300
+ const arc = role === "toolResult" ? arcByPart.get(part) : undefined;
16301
+ const tag = arc?.tag ?? messageTags.get(`${messageKey}:file${partIndex}`);
16302
+ if (arc?.sentinel || !image.content) {
16303
+ drafts.push(excludedDraft(`${key}\x00image`, part));
16304
+ } else {
16305
+ drafts.push({
16306
+ key: `${key}\x00${role === "toolResult" ? "toolOutput" : "file"}`,
16307
+ kind: role === "toolResult" ? "toolOutput" : "file",
16308
+ content: image.content,
16309
+ tokens: image.tokens,
16310
+ tag
16311
+ });
16312
+ }
16313
+ continue;
16314
+ }
16315
+ if (part.type === "toolCall") {
16316
+ const arc = arcByPart.get(part);
16317
+ const callId = typeof part.id === "string" ? part.id : "";
16318
+ if (part.syntheticTodoMarker === true || callId.startsWith(SYNTHETIC_TODO_PREFIX) || arc?.sentinel) {
16319
+ drafts.push(excludedDraft(`${key}\x00toolInput`, part));
16320
+ continue;
16321
+ }
16322
+ const content = safeStableStringify(part.arguments);
16323
+ if (!content) {
16324
+ drafts.push(excludedDraft(`${key}\x00toolInput`, part));
16325
+ } else {
16326
+ drafts.push({
16327
+ key: `${key}\x00toolInput`,
16328
+ kind: "toolInput",
16329
+ content,
16330
+ tokens: memoizedTokens("toolInput", content),
16331
+ tag: arc?.tag
16332
+ });
16333
+ }
16334
+ continue;
16335
+ }
16336
+ drafts.push(excludedDraft(`${key}\x00excluded`, part));
16337
+ }
16338
+ }
16339
+ return finalizeParts(drafts, input.protectedTags);
16340
+ }
16341
+ function sameMeasuredPrefix(baseline, current) {
16342
+ if (current.length < baseline.length)
16343
+ return { valid: false, boundaryAdvanceU: 0 };
16344
+ let boundaryAdvanceU = 0;
16345
+ for (let index = 0;index < baseline.length; index += 1) {
16346
+ const before = baseline[index];
16347
+ const after = current[index];
16348
+ if (before.key !== after.key || before.contentHash !== after.contentHash || before.kind !== after.kind || before.tokens !== after.tokens || before.tagNumber !== after.tagNumber || before.tagStatus !== after.tagStatus) {
16349
+ return { valid: false, boundaryAdvanceU: 0 };
16350
+ }
16351
+ if (!before.protected && after.protected)
16352
+ return { valid: false, boundaryAdvanceU: 0 };
16353
+ if (before.protected && !after.protected) {
16354
+ if (after.tagStatus !== "active")
16355
+ return { valid: false, boundaryAdvanceU: 0 };
16356
+ boundaryAdvanceU += after.tokens;
16357
+ } else if (before.uTokens !== after.uTokens) {
16358
+ return { valid: false, boundaryAdvanceU: 0 };
16359
+ }
16360
+ }
16361
+ return { valid: true, boundaryAdvanceU };
16362
+ }
16363
+ function refreshPiTailHygieneBaseline(input) {
16364
+ const measured = measurePiTailHygiene(input);
16365
+ const now = input.now ?? Date.now();
16366
+ if (!input.cacheBusting && input.previous?.generationInvalidated) {
16367
+ return { ...input.previous, contentSignature: measured.contentSignature };
16368
+ }
16369
+ if (input.cacheBusting || !input.previous) {
16370
+ return {
16371
+ baselineU: measured.u,
16372
+ baselineT: measured.t,
16373
+ turnDeltaU: 0,
16374
+ turnDeltaT: 0,
16375
+ baselineGeneration: (input.previous?.baselineGeneration ?? 0) + 1,
16376
+ computedAt: now,
16377
+ evaluable: true,
16378
+ generationInvalidated: false,
16379
+ baselineParts: measured.parts,
16380
+ contentSignature: measured.contentSignature
16381
+ };
16382
+ }
16383
+ const prefix = sameMeasuredPrefix(input.previous.baselineParts, measured.parts);
16384
+ if (!prefix.valid) {
16385
+ return {
16386
+ ...input.previous,
16387
+ evaluable: false,
16388
+ generationInvalidated: true,
16389
+ contentSignature: measured.contentSignature
16390
+ };
16391
+ }
16392
+ let turnDeltaT = 0;
16393
+ let turnDeltaU = prefix.boundaryAdvanceU;
16394
+ for (let index = input.previous.baselineParts.length;index < measured.parts.length; index += 1) {
16395
+ const part = measured.parts[index];
16396
+ turnDeltaT += part.tokens;
16397
+ if (part.kind !== "toolOutput")
16398
+ turnDeltaU += part.uTokens;
16399
+ }
16400
+ return {
16401
+ ...input.previous,
16402
+ turnDeltaU,
16403
+ turnDeltaT,
16404
+ evaluable: true,
16405
+ generationInvalidated: false,
16406
+ contentSignature: measured.contentSignature
16407
+ };
16408
+ }
16409
+ function effectivePiTailHygiene(baseline) {
16410
+ const t = Math.max(0, baseline.baselineT + baseline.turnDeltaT);
16411
+ const u = Math.min(t, Math.max(0, baseline.baselineU + baseline.turnDeltaU));
16412
+ return { u, t };
16413
+ }
16414
+ function measurePiToolResultDelta(content) {
16415
+ let tokens = 0;
16416
+ for (const part of content) {
16417
+ if (!isRecord3(part))
16418
+ continue;
16419
+ if (part.type === "text" && typeof part.text === "string") {
16420
+ const text = stripChannel1ReminderSpans(part.text);
16421
+ if (text && !isDropSentinel(text))
16422
+ tokens += memoizedTokens("toolOutput", text);
16423
+ } else if (part.type === "image") {
16424
+ tokens += imageContentAndTokens(part).tokens;
16425
+ }
16426
+ }
16427
+ return Math.max(0, tokens);
16428
+ }
16429
+ function assertPiTailHygieneContentUnchanged(input) {
16430
+ const current = measurePiTailHygiene(input);
16431
+ if (current.contentSignature !== input.expectedSignature) {
16432
+ throw new Error("Pi tail hygiene walk was not the last byte-affecting operation");
16433
+ }
16434
+ }
16435
+
16436
+ // src/ctx-reduce-nudge-pi.ts
16437
+ var channel1StateBySession = new Map;
16438
+ function setPiChannel1Baseline(sessionId, state2) {
16439
+ channel1StateBySession.set(sessionId, state2);
16440
+ }
16441
+ function getPiChannel1Baseline(sessionId) {
16442
+ return channel1StateBySession.get(sessionId);
16443
+ }
16444
+ function clearPiChannel1State(sessionId) {
16445
+ channel1StateBySession.delete(sessionId);
16446
+ }
16447
+ function markPiChannel1Reduced(sessionId, db) {
16448
+ const state2 = channel1StateBySession.get(sessionId);
16449
+ if (state2) {
16450
+ state2.reducedSinceRefresh = true;
16451
+ state2.evaluable = false;
16452
+ state2.generationInvalidated = true;
16453
+ }
16454
+ if (db)
16455
+ resetLastNudgeCycle(db, sessionId);
16456
+ }
16457
+ function isPiTextContent(c) {
16458
+ return c !== null && typeof c === "object" && c.type === "text" && typeof c.text === "string";
16459
+ }
16460
+ function toolResultText(content) {
16461
+ let text = "";
16462
+ for (const c of content) {
16463
+ if (isPiTextContent(c))
16464
+ text += c.text;
16465
+ }
16466
+ return text;
16467
+ }
16468
+ function maybeChannel1ReminderForToolResult(args) {
16469
+ const { db, sessionId, toolName } = args;
16470
+ const state2 = channel1StateBySession.get(sessionId);
16471
+ if (!state2)
16472
+ return null;
16473
+ if (toolName === "ctx_reduce") {
16474
+ state2.reducedSinceRefresh = true;
16475
+ state2.evaluable = false;
16476
+ state2.generationInvalidated = true;
16477
+ resetLastNudgeCycle(db, sessionId);
16478
+ return null;
16479
+ }
16480
+ const text = toolResultText(args.content);
16481
+ if (text.includes(CHANNEL1_SENTINEL))
16482
+ return null;
16483
+ const deltaTokens = measurePiToolResultDelta(args.content);
16484
+ if (deltaTokens === 0)
16485
+ return null;
16486
+ state2.turnDeltaT += deltaTokens;
16487
+ const decision = decideChannel1({
16488
+ ...state2,
16489
+ lastNudgeUndropped: getLastNudgeUndropped(db, sessionId),
16490
+ lastNudgeLevel: getLastNudgeLevel(db, sessionId),
16491
+ hasRecentReduce: state2.reducedSinceRefresh
16492
+ });
16493
+ setLastNudgeUndropped(db, sessionId, decision.nextLastNudge);
16494
+ setLastNudgeLevel(db, sessionId, decision.nextLastNudgeLevel);
16495
+ if (!decision.fire)
16496
+ return null;
16497
+ return {
16498
+ type: "text",
16499
+ text: buildChannel1Reminder(decision.level, decision.undroppedTokens, state2.oldestReclaimableToolTags)
16500
+ };
16501
+ }
16502
+ var CHANNEL2_NUDGE_CUSTOM_TYPE = "magic-context:ceiling-nudge";
16503
+ function maybeDeliverChannel2Pi(pi, db, sessionId) {
16504
+ let state2;
16505
+ try {
16506
+ state2 = getChannel2NudgeState(db, sessionId);
16507
+ } catch {
16508
+ return false;
16509
+ }
16510
+ if (state2 !== "pending")
16511
+ return false;
16512
+ const baseline = channel1StateBySession.get(sessionId);
16513
+ if (!baseline)
16514
+ return false;
16515
+ const evaluation = evaluateChannel2(baseline);
16516
+ if (!evaluation.evaluable)
16517
+ return false;
16518
+ if (!evaluation.shouldTrigger) {
16519
+ try {
16520
+ casChannel2NudgeState(db, sessionId, "pending", "");
16521
+ } catch {}
16522
+ return false;
16523
+ }
16524
+ const undropped = evaluation.reclaimableTokens;
16525
+ const claimToken = randomUUID2();
16526
+ if (!claimChannel2NudgeState(db, sessionId, claimToken))
16527
+ return false;
16528
+ try {
16529
+ const message = {
16530
+ customType: CHANNEL2_NUDGE_CUSTOM_TYPE,
16531
+ content: buildChannel2Reminder(undropped, baseline.oldestReclaimableToolTags),
16532
+ display: false,
16533
+ details: { kind: "channel-2-ceiling-nudge" }
16534
+ };
16535
+ const claim = getChannel2NudgeClaim(db, sessionId);
16536
+ if (claim.state !== "claimed" || claim.claimToken !== claimToken) {
16537
+ sessionLog(sessionId, `channel2 ceiling nudge delivery skipped: claim no longer owned before send (state=${claim.state || "empty"})`);
16538
+ return false;
16186
16539
  }
16187
- })();
16188
- const toolFingerprints = buildPiToolFingerprints(piMessages, resolveStableId);
16189
- if (toolFingerprints.size > 0) {
16190
- const tagsByCompositeKey = new Map;
16191
- for (const tag of tags) {
16192
- if (tag.type === "tool" && tag.status === "active" && tag.messageId) {
16193
- const key = tag.toolOwnerMessageId ? `${tag.toolOwnerMessageId}\x00${tag.messageId}` : tag.messageId;
16194
- tagsByCompositeKey.set(key, tag);
16540
+ pi.sendMessage(message, { deliverAs: "nextTurn" });
16541
+ } catch (error) {
16542
+ try {
16543
+ const restored = casChannel2NudgeClaim(db, sessionId, "pending", claimToken);
16544
+ if (restored) {
16545
+ sessionLog(sessionId, "channel2 ceiling nudge delivery failed (will retry):", error);
16546
+ } else {
16547
+ sessionLog(sessionId, "channel2 ceiling nudge delivery failed after its claim was no longer owned; lease state left unchanged:", error);
16195
16548
  }
16549
+ } catch (revertError) {
16550
+ sessionLog(sessionId, "channel2 ceiling nudge delivery failed; token-bound pending restore was busy so the stale claim will heal later:", { deliveryError: error, revertError });
16196
16551
  }
16197
- const fingerprintGroups = new Map;
16198
- for (const [compositeKey, fingerprint] of toolFingerprints) {
16199
- const tag = tagsByCompositeKey.get(compositeKey);
16200
- if (!tag || tag.tagNumber > protectedCutoff)
16201
- continue;
16202
- const group = fingerprintGroups.get(fingerprint) ?? [];
16203
- group.push(tag);
16204
- fingerprintGroups.set(fingerprint, group);
16205
- }
16206
- db.transaction(() => {
16207
- for (const [, group] of fingerprintGroups) {
16208
- if (group.length <= 1)
16209
- continue;
16210
- group.sort((a, b) => a.tagNumber - b.tagNumber);
16211
- for (let i = 0;i < group.length - 1; i++) {
16212
- const tag = group[i];
16213
- const target = targets.get(tag.tagNumber);
16214
- const result = target?.drop?.() ?? "absent";
16215
- if (result === "incomplete")
16216
- continue;
16217
- updateTagDropMode(db, sessionId, tag.tagNumber, "full");
16218
- updateTagStatus(db, sessionId, tag.tagNumber, "dropped");
16219
- if (result === "removed" || result === "truncated") {
16220
- deduplicatedTools++;
16221
- }
16222
- }
16223
- }
16224
- })();
16225
- }
16226
- if (droppedTools > 0 || deduplicatedTools > 0 || droppedInjections > 0 || droppedStaleReduceCalls > 0) {
16227
- sessionLog(sessionId, `heuristic cleanup: dropped ${droppedTools} tool tags, stale ctx_reduce=${droppedStaleReduceCalls}, deduplicated ${deduplicatedTools} tool calls, dropped ${droppedInjections} system injections`);
16552
+ return false;
16228
16553
  }
16229
- let compressedTextTags = 0;
16230
- let mutatedTextTags = 0;
16231
- if (config.caveman?.enabled) {
16232
- const cavemanResult = applyCavemanCleanup(sessionId, db, targets, tags, {
16233
- enabled: true,
16234
- minChars: config.caveman.minChars,
16235
- protectedTags: config.protectedTags
16236
- });
16237
- compressedTextTags = cavemanResult.compressedToLite + cavemanResult.compressedToFull + cavemanResult.compressedToUltra;
16238
- mutatedTextTags = cavemanResult.mutatedTextTags;
16554
+ try {
16555
+ const confirmed = casChannel2NudgeClaim(db, sessionId, "delivered", claimToken);
16556
+ if (confirmed) {
16557
+ sessionLog(sessionId, "channel2 ceiling nudge delivered");
16558
+ return true;
16559
+ }
16560
+ const claim = getChannel2NudgeClaim(db, sessionId);
16561
+ sessionLog(sessionId, `channel2 ceiling nudge sent but claim confirmation was not ours (state=${claim.state || "empty"}); leaving existing lease state unchanged`);
16562
+ return false;
16563
+ } catch (error) {
16564
+ sessionLog(sessionId, "channel2 ceiling nudge sent but token-confirm failed; lease state left unchanged:", error);
16565
+ return false;
16239
16566
  }
16240
- return {
16241
- droppedTools,
16242
- deduplicatedTools,
16243
- droppedInjections,
16244
- droppedStaleReduceCalls,
16245
- emergencyDroppedTools,
16246
- compressedTextTags,
16247
- mutatedTextTags
16248
- };
16249
16567
  }
16250
- function buildMessageIdToMaxTagFromTargets(targets) {
16251
- const byMessage = new Map;
16252
- for (const [tagNumber, target] of targets) {
16253
- const id = target.message?.info?.id;
16254
- if (typeof id !== "string" || id.length === 0)
16568
+
16569
+ // src/detect-recent-commit.ts
16570
+ var COMMIT_LOOKBACK = 5;
16571
+ function detectRecentCommit(messages) {
16572
+ let assistantsScanned = 0;
16573
+ for (let i = messages.length - 1;i >= 0; i--) {
16574
+ const message = messages[i];
16575
+ if (!message || typeof message !== "object" || !("role" in message) || message.role !== "assistant") {
16255
16576
  continue;
16256
- if (tagNumber > (byMessage.get(id) ?? 0))
16257
- byMessage.set(id, tagNumber);
16577
+ }
16578
+ assistantsScanned++;
16579
+ if (assistantsScanned > COMMIT_LOOKBACK)
16580
+ break;
16581
+ if (!("content" in message))
16582
+ continue;
16583
+ const content = message.content;
16584
+ if (!Array.isArray(content))
16585
+ continue;
16586
+ for (const part of content) {
16587
+ if (part && typeof part === "object" && "type" in part && part.type === "text" && "text" in part && typeof part.text === "string") {
16588
+ if (textMentionsRecentCommit(part.text)) {
16589
+ return true;
16590
+ }
16591
+ }
16592
+ }
16258
16593
  }
16259
- return byMessage;
16594
+ return false;
16260
16595
  }
16261
16596
 
16262
16597
  // src/inject-compartments-pi.ts
@@ -16370,6 +16705,7 @@ function getPiToolResultCallId(message) {
16370
16705
  return typeof callId === "string" && callId.length > 0 ? callId : null;
16371
16706
  }
16372
16707
  var PI_M1_PLACEHOLDER = "<session-history-since>(no new content since last materialization)</session-history-since>";
16708
+ var MAX_FORCED_MEMORIES_PER_DELTA = 10;
16373
16709
  var PI_M0_UPGRADE_STATE = "pi-m0m1-v2";
16374
16710
  var EMPTY_MAX_COMPARTMENT_SEQ = -1;
16375
16711
  function historySliceTokensPi(m0Text) {
@@ -16450,6 +16786,9 @@ var EMPTY_PI_HARD_SIGNALS = {
16450
16786
  function renderBudgetIdentityPi(state2) {
16451
16787
  return `m${state2.injectionBudgetTokens ?? DEFAULT_MEMORY_BUDGET_TOKENS}-h${state2.historyBudgetTokens ?? DEFAULT_HISTORY_BUDGET_TOKENS}`;
16452
16788
  }
16789
+ function piMaterializeMismatch(reason, signal, cached, current) {
16790
+ return { value: true, reason, mismatch: { signal, cached, current } };
16791
+ }
16453
16792
  var injectionTokenCountsBySession = new Map;
16454
16793
  var cachedMuralBySession = new Map;
16455
16794
  function rememberPiMuralPayload(sessionId, dataUrl, contentHash) {
@@ -16600,7 +16939,7 @@ function readCurrentMarkersFromCompartments(db, state2, compartments, projectDoc
16600
16939
  compartmentRenderEpoch: COMPARTMENT_RENDER_EPOCH,
16601
16940
  lastBaselineEndMessageId: lastBaselineEndMessageId(compartments),
16602
16941
  systemHash: (state2.hardSignals ?? EMPTY_PI_HARD_SIGNALS).systemHash,
16603
- modelKey: (state2.hardSignals ?? EMPTY_PI_HARD_SIGNALS).modelKey,
16942
+ modelKey: piModelRefToCanonical((state2.hardSignals ?? EMPTY_PI_HARD_SIGNALS).modelKey),
16604
16943
  projectIdentity: state2.projectIdentity,
16605
16944
  muralEnabled: state2.muralEnabled === true,
16606
16945
  renderBudgetIdentity: renderBudgetIdentityPi(state2)
@@ -16622,36 +16961,41 @@ function mustMaterializePi(state2, db, currentCompartmentsOverride) {
16622
16961
  return { value: true, reason: "cache_invalid" };
16623
16962
  }
16624
16963
  if (cached.compartmentRenderEpoch !== current.compartmentRenderEpoch) {
16625
- return { value: true, reason: "compartment_render_epoch" };
16964
+ return piMaterializeMismatch("compartment_render_epoch", "compartmentRenderEpoch", cached.compartmentRenderEpoch, current.compartmentRenderEpoch);
16626
16965
  }
16627
- if (cached.muralEnabled !== current.muralEnabled || cached.renderBudgetIdentity !== current.renderBudgetIdentity) {
16628
- return { value: true, reason: "render_config" };
16966
+ if (cached.muralEnabled !== current.muralEnabled) {
16967
+ return piMaterializeMismatch("render_config", "muralEnabled", cached.muralEnabled, current.muralEnabled);
16968
+ }
16969
+ if (cached.renderBudgetIdentity !== current.renderBudgetIdentity) {
16970
+ return piMaterializeMismatch("render_config", "renderBudgetIdentity", cached.renderBudgetIdentity, current.renderBudgetIdentity);
16629
16971
  }
16630
16972
  const hard = state2.hardSignals ?? EMPTY_PI_HARD_SIGNALS;
16631
- if (hard.modelKey !== "" && hard.modelKey !== (meta.cachedM0ModelKey ?? "")) {
16632
- return { value: true, reason: "model_change" };
16973
+ const canonicalHardModelKey = piModelRefToCanonical(hard.modelKey);
16974
+ const canonicalCachedModelKey = piModelRefToCanonical(meta.cachedM0ModelKey ?? "");
16975
+ if (canonicalHardModelKey !== "" && canonicalHardModelKey !== canonicalCachedModelKey) {
16976
+ return piMaterializeMismatch("model_change", "modelKey", canonicalCachedModelKey, canonicalHardModelKey);
16633
16977
  }
16634
16978
  if (hard.systemHash !== "" && hard.systemHash !== (meta.cachedM0SystemHash ?? "")) {
16635
- return { value: true, reason: "system_hash" };
16979
+ return piMaterializeMismatch("system_hash", "systemHash", meta.cachedM0SystemHash ?? "", hard.systemHash);
16636
16980
  }
16637
16981
  if (meta.cachedM0ProjectIdentity !== null && meta.cachedM0ProjectIdentity !== state2.projectIdentity) {
16638
- return { value: true, reason: "project_change" };
16982
+ return piMaterializeMismatch("project_change", "projectIdentity", meta.cachedM0ProjectIdentity, state2.projectIdentity);
16639
16983
  }
16640
16984
  if (hard.cacheExpired && hard.lastResponseTime > 0 && hard.lastResponseTime > (meta.cachedM0MaterializedAt ?? 0)) {
16641
- return { value: true, reason: "ttl_idle" };
16985
+ return piMaterializeMismatch("ttl_idle", "lastResponseTimeAfterMaterialization", meta.cachedM0MaterializedAt ?? 0, hard.lastResponseTime);
16642
16986
  }
16643
16987
  if (cached.upgradeState !== current.upgradeState) {
16644
- return { value: true, reason: "renderer_upgrade" };
16988
+ return piMaterializeMismatch("renderer_upgrade", "upgradeState", cached.upgradeState, current.upgradeState);
16645
16989
  }
16646
16990
  if (current.workspaceFingerprint !== null || (meta.cachedM0WorkspaceFingerprint ?? null) !== null) {
16647
16991
  if (current.workspaceFingerprint !== (meta.cachedM0WorkspaceFingerprint ?? null)) {
16648
- return { value: true, reason: "project_memory_change" };
16992
+ return piMaterializeMismatch("project_memory_change", "workspaceFingerprint", meta.cachedM0WorkspaceFingerprint ?? null, current.workspaceFingerprint);
16649
16993
  }
16650
16994
  } else if (current.projectMemoryEpoch !== (meta.cachedM0ProjectMemoryEpoch ?? 0)) {
16651
- return { value: true, reason: "project_memory_change" };
16995
+ return piMaterializeMismatch("project_memory_change", "projectMemoryEpoch", meta.cachedM0ProjectMemoryEpoch ?? 0, current.projectMemoryEpoch);
16652
16996
  }
16653
16997
  if (current.maxMutationId !== (meta.cachedM0MaxMutationId ?? 0)) {
16654
- return { value: true, reason: "pending_mutations" };
16998
+ return piMaterializeMismatch("pending_mutations", "maxMutationId", meta.cachedM0MaxMutationId ?? 0, current.maxMutationId);
16655
16999
  }
16656
17000
  return { value: false, reason: null };
16657
17001
  }
@@ -16763,7 +17107,7 @@ function readFrozenM0InputsPi(state2, db, docs = readProjectDocsForPiM0(state2),
16763
17107
  compartmentRenderEpoch: COMPARTMENT_RENDER_EPOCH,
16764
17108
  lastBaselineEndMessageId: lastBaselineEndMessageId(compartments),
16765
17109
  systemHash: (state2.hardSignals ?? EMPTY_PI_HARD_SIGNALS).systemHash,
16766
- modelKey: (state2.hardSignals ?? EMPTY_PI_HARD_SIGNALS).modelKey,
17110
+ modelKey: piModelRefToCanonical((state2.hardSignals ?? EMPTY_PI_HARD_SIGNALS).modelKey),
16767
17111
  projectIdentity: state2.projectIdentity,
16768
17112
  muralEnabled: state2.muralEnabled === true,
16769
17113
  renderBudgetIdentity: renderBudgetIdentityPi(state2)
@@ -16889,49 +17233,74 @@ function materializeM0PiWithRetry(state2, db, maxRetries = 3) {
16889
17233
  throw lastError ?? new PiMaterializeContentionError("materialization contention exhausted");
16890
17234
  }
16891
17235
  function renderMemoryUpdatesBlockPi(args) {
16892
- if (args.renderedMemoryIds.length === 0)
16893
- return { block: "", count: 0 };
16894
17236
  const renderedIds = new Set(args.renderedMemoryIds);
16895
17237
  const mutations = args.workspace.isWorkspaced ? getMemoryMutationsForRenderByProjects(args.db, args.workspace.expandedIdentities, args.afterId, args.renderedMemoryIds) : getMemoryMutationsForRender(args.db, args.projectPath, args.afterId, args.renderedMemoryIds);
16896
- if (mutations.length === 0)
16897
- return { block: "", count: 0 };
17238
+ if (mutations.length === 0) {
17239
+ return { block: "", count: 0, forcedMemoryIds: [] };
17240
+ }
17241
+ const forcedIds = new Set;
16898
17242
  const lines = [
16899
17243
  "These memories changed since the snapshot below — trust these:"
16900
17244
  ];
16901
17245
  for (const mutation of mutations) {
16902
- if (mutation.mutationType === "update") {
16903
- lines.push(` <updated id="${mutation.targetMemoryId}">${escapeXmlContent(mutation.newContent ?? "")}</updated>`);
16904
- continue;
16905
- }
16906
17246
  if (mutation.mutationType === "superseded") {
16907
- if (mutation.supersededById !== null && renderedIds.has(mutation.supersededById)) {
16908
- lines.push(` <superseded id="${mutation.targetMemoryId}" by="${mutation.supersededById}"/>`);
17247
+ const replacementId = mutation.supersededById;
17248
+ if (replacementId !== null && !renderedIds.has(replacementId) && args.eligibleMemoryIds.has(replacementId)) {
17249
+ forcedIds.add(replacementId);
17250
+ }
17251
+ if (!renderedIds.has(mutation.targetMemoryId))
17252
+ continue;
17253
+ if (replacementId !== null && args.eligibleMemoryIds.has(replacementId)) {
17254
+ lines.push(` <superseded id="${mutation.targetMemoryId}" by="${replacementId}"/>`);
16909
17255
  } else {
16910
17256
  lines.push(` <removed id="${mutation.targetMemoryId}"/>`);
16911
17257
  }
16912
17258
  continue;
16913
17259
  }
17260
+ if (!renderedIds.has(mutation.targetMemoryId)) {
17261
+ if (mutation.visibilityChanged && args.eligibleMemoryIds.has(mutation.targetMemoryId)) {
17262
+ forcedIds.add(mutation.targetMemoryId);
17263
+ }
17264
+ continue;
17265
+ }
17266
+ if (!args.eligibleMemoryIds.has(mutation.targetMemoryId)) {
17267
+ lines.push(` <removed id="${mutation.targetMemoryId}"/>`);
17268
+ continue;
17269
+ }
17270
+ if (mutation.visibilityChanged && mutation.newContent === null)
17271
+ continue;
17272
+ if (mutation.mutationType === "update") {
17273
+ lines.push(` <updated id="${mutation.targetMemoryId}">${escapeXmlContent(mutation.newContent ?? "")}</updated>`);
17274
+ continue;
17275
+ }
16914
17276
  lines.push(` <removed id="${mutation.targetMemoryId}"/>`);
16915
17277
  }
17278
+ const forcedMemoryIds = [...forcedIds].sort((left, right) => left - right).slice(0, MAX_FORCED_MEMORIES_PER_DELTA);
17279
+ if (lines.length === 1)
17280
+ return { block: "", count: 0, forcedMemoryIds };
16916
17281
  return {
16917
17282
  block: `<memory-updates>
16918
17283
  ${lines.join(`
16919
17284
  `)}
16920
17285
  </memory-updates>`,
16921
- count: mutations.length
17286
+ count: lines.length - 1,
17287
+ forcedMemoryIds
16922
17288
  };
16923
17289
  }
16924
17290
  function renderM1PiWithMetadata(state2, db, markers, renderedMemoryIds, compartmentsOverride) {
16925
17291
  const sections = [];
16926
17292
  const workspace = resolveWorkspaceRenderContextPi(state2, db);
16927
17293
  const memPath = memoryProjectPath(state2);
17294
+ const eligibleMemories = memPath ? workspace.isWorkspaced ? getMemoriesByProjects(db, workspace.expandedIdentities, ["active", "permanent"], markers.materializedAt, workspace.ownIdentities, workspace.shareCategories) : getMemoriesByProject(db, memPath, ["active", "permanent"], markers.materializedAt) : [];
17295
+ const eligibleMemoryIds = new Set(eligibleMemories.map((memory) => memory.id));
16928
17296
  const memoryUpdates = memPath ? renderMemoryUpdatesBlockPi({
16929
17297
  db,
16930
17298
  projectPath: memPath,
16931
17299
  workspace,
16932
17300
  afterId: markers.maxMemoryMutationId,
16933
- renderedMemoryIds
16934
- }) : { block: undefined, count: 0 };
17301
+ renderedMemoryIds,
17302
+ eligibleMemoryIds
17303
+ }) : { block: undefined, count: 0, forcedMemoryIds: [] };
16935
17304
  if (memoryUpdates.block)
16936
17305
  sections.push(memoryUpdates.block);
16937
17306
  const newCompartments = (compartmentsOverride ?? getRenderableCompartmentsPi(db, state2)).filter((compartment) => compartment.sequence > markers.maxCompartmentSeq);
@@ -16943,21 +17312,24 @@ function renderM1PiWithMetadata(state2, db, markers, renderedMemoryIds, compartm
16943
17312
  ${body}
16944
17313
  </new-compartments>`);
16945
17314
  }
16946
- 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) : [];
16947
- if (newMemories.length > 0) {
16948
- const memoryBudget = state2.injectionBudgetTokens ?? DEFAULT_MEMORY_BUDGET_TOKENS;
16949
- const memoryRenderOptions = {
16950
- sourceNameByMemoryId: sourceNamesForPiMemories({
16951
- memories: newMemories,
16952
- projectPath: memPath,
16953
- workspace
16954
- })
16955
- };
16956
- const trimmedNewMemories = trimMemoriesToBudgetV2(state2.sessionId, newMemories, Math.max(1, Math.floor(memoryBudget * 0.25)), memoryRenderOptions).renderOrder;
16957
- const newMemoriesBlock = renderMemoryBlockV2(trimmedNewMemories, "new-memories", memoryRenderOptions);
16958
- if (newMemoriesBlock)
16959
- sections.push(newMemoriesBlock);
16960
- }
17315
+ const forcedMemoryIds = new Set(memoryUpdates.forcedMemoryIds);
17316
+ const newMemories = eligibleMemories.filter((memory) => memory.id > markers.maxMemoryId && !forcedMemoryIds.has(memory.id));
17317
+ const memoryBudget = state2.injectionBudgetTokens ?? DEFAULT_MEMORY_BUDGET_TOKENS;
17318
+ const memoryRenderOptions = {
17319
+ sourceNameByMemoryId: sourceNamesForPiMemories({
17320
+ memories: eligibleMemories,
17321
+ projectPath: memPath,
17322
+ workspace
17323
+ })
17324
+ };
17325
+ const trimmedNewMemories = trimMemoriesToBudgetV2(state2.sessionId, newMemories, Math.max(1, Math.floor(memoryBudget * 0.25)), memoryRenderOptions).renderOrder;
17326
+ const deltaMemories = [
17327
+ ...trimmedNewMemories,
17328
+ ...eligibleMemories.filter((memory) => forcedMemoryIds.has(memory.id))
17329
+ ];
17330
+ const newMemoriesBlock = renderMemoryBlockV2(deltaMemories, "new-memories", memoryRenderOptions);
17331
+ if (newMemoriesBlock)
17332
+ sections.push(newMemoriesBlock);
16961
17333
  const currentUserProfileVersion = getProjectState(db, GLOBAL_USER_PROFILE_PROJECT_PATH)?.projectUserProfileVersion ?? 0;
16962
17334
  if (currentUserProfileVersion !== markers.projectUserProfileVersion) {
16963
17335
  const profileBudget = state2.userProfileBudgetTokens ?? DEFAULT_USER_PROFILE_BUDGET_TOKENS;
@@ -17072,7 +17444,7 @@ function cachedPiRowMatchesSnapshot(args) {
17072
17444
  const rowMarkers = markersFromCachedPiRow(args.row, args.compartmentsForNormalization);
17073
17445
  if (!rowMarkers)
17074
17446
  return false;
17075
- 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);
17447
+ 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);
17076
17448
  }
17077
17449
  function adoptCachedPiProjectIdentity(db, state2) {
17078
17450
  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);
@@ -17188,6 +17560,10 @@ function prependM0M1Messages(piMessages, m0, m1, mural) {
17188
17560
  function injectM0M1Pi(state2, db, piMessages, entryIds, recomputeM1ThisPass = false) {
17189
17561
  const currentCompartments = getRenderableCompartmentsPi(db, state2);
17190
17562
  let decision = mustMaterializePi(state2, db, currentCompartments);
17563
+ if (decision.value) {
17564
+ const mismatch = decision.mismatch ? ` mismatch=${JSON.stringify(decision.mismatch)}` : "";
17565
+ sessionLog(state2.sessionId, `pi m[0] HARD fold firing: reason=${decision.reason ?? "unknown"}${mismatch}`);
17566
+ }
17191
17567
  let m0 = "";
17192
17568
  let m1 = PI_M1_PLACEHOLDER;
17193
17569
  let markers = null;
@@ -17386,13 +17762,45 @@ function isSentinelPart(part) {
17386
17762
  }
17387
17763
 
17388
17764
  // src/pi-context-limit.ts
17389
- function resolvePiUsableContextLimit(args) {
17390
- const rawContext = isSaneLimit(args.rawContextWindow) ? args.rawContextWindow : undefined;
17391
- const detected = typeof args.detectedContextLimit === "number" && Number.isFinite(args.detectedContextLimit) && args.detectedContextLimit >= 1024 ? args.detectedContextLimit : undefined;
17392
- const context = rawContext !== undefined && detected !== undefined ? Math.min(rawContext, detected) : rawContext ?? detected;
17393
- if (context === undefined)
17765
+ var MIN_SANE_LIMIT = 16000;
17766
+ var MAX_SANE_LIMIT = 1e7;
17767
+ function isSaneLimit2(value) {
17768
+ return typeof value === "number" && Number.isFinite(value) && value >= MIN_SANE_LIMIT && value <= MAX_SANE_LIMIT;
17769
+ }
17770
+ function resolvePiWindowGeometry(args) {
17771
+ const runtimeWindow = isSaneLimit2(args.rawContextWindow) ? args.rawContextWindow : isSaneLimit2(args.model?.contextWindow) ? args.model.contextWindow : undefined;
17772
+ const persistedUsable = isSaneLimit2(args.persistedInputTokens) && typeof args.persistedPercentage === "number" && Number.isFinite(args.persistedPercentage) && args.persistedPercentage > 0 ? args.persistedInputTokens / (args.persistedPercentage / 100) : undefined;
17773
+ const persistedWindow = isSaneLimit2(args.persistedInputTokens) && typeof args.persistedPercentage === "number" && Number.isFinite(args.persistedPercentage) && args.persistedPercentage > 0 ? args.persistedInputTokens / (args.persistedPercentage / 100) : undefined;
17774
+ const context = runtimeWindow ?? persistedWindow;
17775
+ if (!isSaneLimit2(context))
17394
17776
  return;
17395
- return resolveLimit({ context, output: args.model?.maxTokens }, args.model?.provider ?? "unknown", args.model?.id ?? "unknown");
17777
+ const providerID = args.model?.provider ?? "unknown";
17778
+ const modelID = args.model?.id ?? "unknown";
17779
+ const outputReserveOverride = resolveOutputReserve(providerID, modelID, args.reserveConfig);
17780
+ const result = deriveWindowGeometry(providerID, modelID, {
17781
+ context,
17782
+ output: args.model?.maxTokens
17783
+ }, {
17784
+ overlay: resolveWindowOverlayFacts(providerID, modelID, getWindowOverlay()),
17785
+ contextCap: isSaneLimit2(args.detectedContextLimit) ? args.detectedContextLimit : undefined,
17786
+ outputReserveOverride,
17787
+ harness: "pi"
17788
+ });
17789
+ if (!result || outputReserveOverride !== undefined || !isSaneLimit2(persistedUsable))
17790
+ return result;
17791
+ const usableSoft = Math.round(persistedUsable);
17792
+ return {
17793
+ ...result,
17794
+ usableSoft,
17795
+ usableHard: Math.max(usableSoft, result.usableHard),
17796
+ derivation: {
17797
+ ...result.derivation,
17798
+ reserve: Math.max(0, result.derivation.window - usableSoft)
17799
+ }
17800
+ };
17801
+ }
17802
+ function resolvePiUsableContextLimit(args) {
17803
+ return resolvePiWindowGeometry(args)?.usableSoft;
17396
17804
  }
17397
17805
 
17398
17806
  // src/pi-historian-runner.ts
@@ -21935,6 +22343,11 @@ function buildMagicContextBlock(opts) {
21935
22343
  return null;
21936
22344
  return buildMagicContextSection(null, opts.protectedTags ?? 20, opts.ctxReduceCallable ?? true, opts.dreamerEnabled ?? false, opts.temporalAwarenessEnabled ?? false, opts.cavemanTextCompressionEnabled ?? false, false, opts.language, opts.memoryEnabled !== false, opts.promptSurfacePreset, opts.primaryGuidanceOverride);
21937
22345
  }
22346
+ function composeMagicContextSystemPrompt(basePrompt, block) {
22347
+ return block ? `${basePrompt}
22348
+
22349
+ ${block}` : basePrompt;
22350
+ }
21938
22351
  var DATE_PATTERN = /Today's date: .+/;
21939
22352
  function processSystemPromptForCache(args) {
21940
22353
  const { db, sessionId, systemPrompt, isCacheBusting } = args;
@@ -22796,6 +23209,9 @@ function extractStableId(msg, index, entryIds) {
22796
23209
  // src/context-handler.ts
22797
23210
  var EMERGENCY_BLOCK_PERCENTAGE = 95;
22798
23211
  var FORWARD_PRESSURE_LIMIT_FACTOR = 0.85;
23212
+ function isPiHardCacheExpired(lastResponseTime, ttlMs, now) {
23213
+ return lastResponseTime > 0 && now - lastResponseTime > ttlMs;
23214
+ }
22799
23215
  function applyForwardPressureFloor(trailingPercentage, trailingInputTokens, piUsageTokens, correctedLimit) {
22800
23216
  const forwardTokens = typeof piUsageTokens === "number" && piUsageTokens > 0 ? piUsageTokens : 0;
22801
23217
  if (forwardTokens === 0 || !isSaneLimit(correctedLimit)) {
@@ -22812,6 +23228,7 @@ var injectM0M1PiForRun = injectM0M1Pi;
22812
23228
  var persistReasoningWatermarkForRun = updateSessionMeta;
22813
23229
  var persistStableIdSchemeForRun = updateSessionMeta;
22814
23230
  var afterFallbackAdoptionForTests;
23231
+ var mutationGateObserverForTests;
22815
23232
  var DEFAULT_CLEAR_REASONING_AGE = 50;
22816
23233
  var PI_STABLE_ID_SCHEME = 1;
22817
23234
  var lastEmergencyNotificationAtMs = new Map;
@@ -23632,7 +24049,7 @@ function registerPiContextHandler(pi, baseOptions) {
23632
24049
  }
23633
24050
  const previousModelKey = liveModelBySession.get(sessionId);
23634
24051
  const currentModelKey = resolvePiContextModelKey(ctx);
23635
- const modelChanged = previousModelKey !== undefined && currentModelKey !== undefined && previousModelKey !== currentModelKey;
24052
+ const modelChanged = previousModelKey !== undefined && currentModelKey !== undefined && piModelRefToCanonical(previousModelKey) !== piModelRefToCanonical(currentModelKey);
23636
24053
  if (currentModelKey !== undefined) {
23637
24054
  liveModelBySession.set(sessionId, currentModelKey);
23638
24055
  }
@@ -23731,11 +24148,12 @@ function registerPiContextHandler(pi, baseOptions) {
23731
24148
  usageContextLimit = modelWindow;
23732
24149
  }
23733
24150
  }
23734
- usageContextLimit = resolvePiUsableContextLimit({
24151
+ const windowGeometry = resolvePiWindowGeometry({
23735
24152
  rawContextWindow: usageContextLimit,
23736
24153
  model: ctx.model,
23737
24154
  detectedContextLimit
23738
24155
  });
24156
+ usageContextLimit = windowGeometry?.usableSoft;
23739
24157
  const effectiveExecuteThresholdPercentage = resolveExecuteThreshold(schedulerConfig.executeThresholdPercentage, modelKey, 65, {
23740
24158
  tokensConfig: schedulerConfig.executeThresholdTokens,
23741
24159
  contextLimit: usageContextLimit,
@@ -23807,7 +24225,9 @@ function registerPiContextHandler(pi, baseOptions) {
23807
24225
  schedulerDecision = midTurnAdjustedSchedulerDecision;
23808
24226
  sessionLog(sessionId, `[boundary-exec] base=${schedulerDecisionEarly} bypass=${bypassReason} midTurn=${midTurn} effective=${midTurnAdjustedSchedulerDecision} sideEffect=${sideEffect}`);
23809
24227
  const forceMaterialization = !options.compactionOff && usagePercentage >= forceMaterializationPercentage;
23810
- const isEmergency = !options.compactionOff && usagePercentage >= EMERGENCY_BLOCK_PERCENTAGE;
24228
+ const hardUsagePercentage = needsEmergencyBump ? Math.max(EMERGENCY_BLOCK_PERCENTAGE, usagePercentage) : windowGeometry?.usableHard && usageInputTokens > 0 ? usageInputTokens / windowGeometry.usableHard * 100 : usagePercentage;
24229
+ const emergencyPercentage = ctx.model ? hardUsagePercentage : usagePercentage;
24230
+ const isEmergency = !options.compactionOff && emergencyPercentage >= EMERGENCY_BLOCK_PERCENTAGE;
23811
24231
  if (isEmergency) {
23812
24232
  const lastNotifiedAt = lastEmergencyNotificationAtMs.get(sessionId) ?? 0;
23813
24233
  const now = Date.now();
@@ -23929,6 +24349,7 @@ function registerPiContextHandler(pi, baseOptions) {
23929
24349
  logTransformTiming(sessionId, "historianScheduling", tHistorianScheduling);
23930
24350
  const tPostTransform = performance.now();
23931
24351
  let outputMessages = result.messages;
24352
+ let assertTailHygieneLastWriter;
23932
24353
  const tNoteNudges = performance.now();
23933
24354
  try {
23934
24355
  if (!options.compactionOff) {
@@ -23992,60 +24413,61 @@ function registerPiContextHandler(pi, baseOptions) {
23992
24413
  try {
23993
24414
  const sessionMetaForCh1 = getOrCreateSessionMeta(options.db, sessionId);
23994
24415
  if (!options.compactionOff && !sessionMetaForCh1.isSubagent) {
23995
- const resolvedExecuteThresholdPct = resolveExecuteThreshold(schedulerConfig.executeThresholdPercentage ?? 65, liveModelBySession.get(sessionId), 65, {
23996
- tokensConfig: schedulerConfig.executeThresholdTokens,
23997
- contextLimit: usageContextLimit ?? 0
23998
- });
23999
- const historyBudgetTokens = resolveHistoryBudgetTokensForPi({
24000
- historyBudgetPercentage: options.historian?.historyBudgetPercentage,
24001
- usagePercentage,
24002
- usageInputTokens,
24003
- usageContextLimit,
24004
- executeThresholdPercentage: schedulerConfig.executeThresholdPercentage,
24005
- executeThresholdTokens: schedulerConfig.executeThresholdTokens,
24006
- modelKey: liveModelBySession.get(sessionId)
24416
+ const tags = getTagsBySession(options.db, sessionId);
24417
+ const protectedTags = options.protectedTags ?? 20;
24418
+ const stableId = (message) => message && typeof message === "object" ? result.postCommitEntryIdByRef.get(message) : undefined;
24419
+ const baseline = refreshPiTailHygieneBaseline({
24420
+ messages: outputMessages,
24421
+ tags,
24422
+ protectedTags,
24423
+ stableId,
24424
+ syntheticLeadingCount: result.syntheticLeadingCount,
24425
+ cacheBusting: result.bustedThisPass,
24426
+ previous: getPiChannel1Baseline(sessionId)
24007
24427
  });
24008
- let tailToolTokens;
24009
- let liveTailTokens;
24010
- try {
24011
- const agg = getActiveTagTokenAggregate(options.db, sessionId, options.protectedTags ?? 20);
24012
- tailToolTokens = agg.toolOutput;
24013
- liveTailTokens = agg.conversation + agg.toolCall;
24014
- } catch {
24015
- const estimate = computeTailTokenEstimatePi(outputMessages);
24016
- tailToolTokens = estimate.tailToolTokens;
24017
- liveTailTokens = estimate.liveTailTokens;
24018
- }
24019
- const executeThresholdTokensPi = Math.round((usageContextLimit ?? 0) * resolvedExecuteThresholdPct / 100);
24020
- const usableTokensPi = Math.max(0, executeThresholdTokensPi - usageInputTokens + liveTailTokens);
24021
- resetLastNudgeCycleIfTailShrank(options.db, sessionId, tailToolTokens);
24022
- const oldestReclaimableToolTags = getOldestActiveUnprotectedToolTags(options.db, sessionId, options.protectedTags ?? 20);
24023
- setPiChannel1Baseline(sessionId, {
24024
- tailToolTokens,
24025
- historyBudgetTokens: historyBudgetTokens ?? 0,
24026
- contextLimit: usageContextLimit ?? 0,
24027
- executeThresholdPercentage: resolvedExecuteThresholdPct,
24028
- lastInputTokens: usageInputTokens,
24029
- turnToolTokens: 0,
24030
- usableTokens: usableTokensPi,
24428
+ const effective = effectivePiTailHygiene(baseline);
24429
+ resetLastNudgeCycleIfTailShrank(options.db, sessionId, effective.u);
24430
+ const oldestReclaimableToolTags = getOldestActiveUnprotectedToolTags(options.db, sessionId, protectedTags);
24431
+ const channelState = {
24432
+ ...baseline,
24031
24433
  reducedSinceRefresh: false,
24032
24434
  oldestReclaimableToolTags
24033
- });
24034
- if (usageContextLimit && usageContextLimit > 0 && resolvedExecuteThresholdPct > 0) {
24035
- const channel2ShouldTrigger = shouldTriggerChannel2({
24036
- reclaimableTokens: tailToolTokens,
24037
- usableTokens: usableTokensPi
24038
- });
24039
- if (channel2ShouldTrigger) {
24435
+ };
24436
+ setPiChannel1Baseline(sessionId, channelState);
24437
+ const channel2Evaluation = evaluateChannel2(channelState);
24438
+ if (channel2Evaluation.evaluable) {
24439
+ try {
24440
+ rearmChannel2AfterMeasuredCollapse({
24441
+ db: options.db,
24442
+ sessionId,
24443
+ baseline: channelState
24444
+ });
24445
+ } catch (error) {
24446
+ sessionLog(sessionId, `pi channel2 U-collapse reset failed: ${error instanceof Error ? error.message : String(error)}`);
24447
+ }
24448
+ if (channel2Evaluation.shouldTrigger) {
24040
24449
  casChannel2NudgeState(options.db, sessionId, "", "pending");
24041
24450
  } else {
24042
24451
  casChannel2NudgeState(options.db, sessionId, "pending", "");
24043
24452
  }
24044
24453
  }
24454
+ assertTailHygieneLastWriter = () => assertPiTailHygieneContentUnchanged({
24455
+ messages: outputMessages,
24456
+ tags,
24457
+ protectedTags,
24458
+ stableId,
24459
+ syntheticLeadingCount: result.syntheticLeadingCount,
24460
+ expectedSignature: baseline.contentSignature
24461
+ });
24045
24462
  } else {
24046
24463
  clearPiChannel1State(sessionId);
24047
24464
  }
24048
24465
  } catch (err) {
24466
+ const stale = getPiChannel1Baseline(sessionId);
24467
+ if (stale) {
24468
+ stale.evaluable = false;
24469
+ stale.generationInvalidated = true;
24470
+ }
24049
24471
  sessionLog(sessionId, `channel1 baseline / channel2 trigger failed: ${err instanceof Error ? err.message : String(err)}`);
24050
24472
  }
24051
24473
  logTransformTiming(sessionId, "channelNudgeAccounting", tChannelAccounting);
@@ -24081,6 +24503,9 @@ function registerPiContextHandler(pi, baseOptions) {
24081
24503
  extra: `messages=${outputMessages.length} targets=${result.targetCount}`
24082
24504
  });
24083
24505
  sessionLog(sessionId, `transform completed in ${transformElapsedMs.toFixed(1)}ms (${outputMessages.length} messages, ${result.targetCount} targets, watermark: ${result.reasoningWatermark})`);
24506
+ if (assertTailHygieneLastWriter && true) {
24507
+ assertTailHygieneLastWriter();
24508
+ }
24084
24509
  return { messages: outputMessages };
24085
24510
  } catch (err) {
24086
24511
  if (isFailClosedBlockingError(err) && !baseOptions.compactionOff)
@@ -24618,23 +25043,53 @@ async function runPipeline(args) {
24618
25043
  return {
24619
25044
  systemHash: typeof hardMeta.systemPromptHash === "string" ? hardMeta.systemPromptHash : "",
24620
25045
  modelKey: liveModelBySession.get(args.sessionId) ?? "",
24621
- cacheExpired: hardMeta.lastResponseTime > 0 && Date.now() - hardMeta.lastResponseTime >= piTtlMs,
25046
+ cacheExpired: isPiHardCacheExpired(hardMeta.lastResponseTime, piTtlMs, Date.now()),
24622
25047
  lastResponseTime: hardMeta.lastResponseTime
24623
25048
  };
24624
25049
  })() : undefined;
24625
- const m0HardFoldThisPass = args.injection && piHardSignals ? mustMaterializePi({
25050
+ const piM0State = args.injection && piHardSignals ? {
24626
25051
  sessionId: args.sessionId,
24627
25052
  projectIdentity: args.projectIdentity,
24628
25053
  projectDirectory: args.projectDirectory,
24629
25054
  memoryEnabled: args.injection.memoryEnabled,
25055
+ injectDocs: args.injection.injectDocs,
24630
25056
  injectionBudgetTokens: args.injection.injectionBudgetTokens,
24631
25057
  historyBudgetTokens: args.injection.historyBudgetTokens,
24632
- hardSignals: piHardSignals
24633
- }, args.db, getCompartments(args.db, args.sessionId)).value : false;
25058
+ hardSignals: piHardSignals,
25059
+ muralEnabled: args.injection.muralEnabled === true
25060
+ } : undefined;
25061
+ const foldDueDecision = piM0State ? mustMaterializePi(piM0State, args.db, getCompartments(args.db, args.sessionId)) : { value: false, reason: null };
25062
+ let foldExecutedThisPass = false;
25063
+ let preFoldInjectionResult = null;
25064
+ const persistedM0BeforeFold = getOrCreateSessionMeta(args.db, args.sessionId);
25065
+ const m0CoverageBeforeFold = persistedM0BeforeFold.cachedM0Bytes === null ? -1 : persistedM0BeforeFold.cachedM0MaxCompartmentSeq;
25066
+ if (foldDueDecision.value && piM0State) {
25067
+ try {
25068
+ preFoldInjectionResult = injectM0M1PiForRun(piM0State, args.db, [], undefined, false);
25069
+ foldExecutedThisPass = foldExecutesThisPass(foldDueDecision.value, preFoldInjectionResult.m0Materialized === true);
25070
+ const m0CoverageAfterFold = getOrCreateSessionMeta(args.db, args.sessionId).cachedM0MaxCompartmentSeq;
25071
+ try {
25072
+ rearmChannel2AfterCoverageAdvancingHardFold({
25073
+ db: args.db,
25074
+ sessionId: args.sessionId,
25075
+ foldExecuted: foldExecutedThisPass,
25076
+ compactionOff: false,
25077
+ previousCoverage: m0CoverageBeforeFold,
25078
+ currentCoverage: m0CoverageAfterFold
25079
+ });
25080
+ } catch (error) {
25081
+ sessionLog(args.sessionId, `pi channel2 fold-cycle reset failed: ${error instanceof Error ? error.message : String(error)}`);
25082
+ }
25083
+ } catch (error) {
25084
+ sessionLog(args.sessionId, `pi m[0] HARD fold pre-execution failed: ${error instanceof Error ? error.message : String(error)}`);
25085
+ }
25086
+ const mismatch = foldDueDecision.mismatch ? ` mismatch=${JSON.stringify(foldDueDecision.mismatch)}` : "";
25087
+ sessionLog(args.sessionId, `pi m[0] HARD fold decision: reason=${foldDueDecision.reason ?? "unknown"}${mismatch} executed=${foldExecutedThisPass}`);
25088
+ }
24634
25089
  const historianRunning = inFlightHistorian.has(args.sessionId);
24635
- const bypassHistorianGate = args.forceMaterialization === true || m0HardFoldThisPass;
25090
+ const bypassHistorianGate = args.forceMaterialization === true || foldExecutedThisPass;
24636
25091
  const hasPendingMaterializeSignal = hasPendingMaterialization(args.sessionId);
24637
- const shouldRunHeuristics = args.heuristics !== undefined && (!historianRunning || bypassHistorianGate) && (args.forceMaterialization === true || hasPendingMaterializeSignal || deferredMaterializeEligible || m0HardFoldThisPass || args.schedulerDecision === "execute" && !alreadyRanHeuristicsThisTurn);
25092
+ const shouldRunHeuristics = args.heuristics !== undefined && (!historianRunning || bypassHistorianGate) && (args.forceMaterialization === true || hasPendingMaterializeSignal || deferredMaterializeEligible || foldExecutedThisPass || args.schedulerDecision === "execute" && !alreadyRanHeuristicsThisTurn);
24638
25093
  const tFallbackIdentity = performance.now();
24639
25094
  const hasFallbackMessageTags = hasPiFallbackMessageTags(args.db, args.sessionId);
24640
25095
  const entryFingerprintByMessageId = buildEntryFingerprintMap(args.messages, stableIdResolver, args.reusableMessageIds, hasFallbackMessageTags);
@@ -24689,14 +25144,22 @@ async function runPipeline(args) {
24689
25144
  }
24690
25145
  const deferredMaterializationWasPending = deferredMaterializationSessions.has(args.sessionId);
24691
25146
  const deferredHistoryRefreshWasPending = deferredHistoryWasPendingAtPassStart;
24692
- const pendingOps = getPendingOps(args.db, args.sessionId);
24693
- const pendingOperationTags = getTagsForPendingOperations(args.db, args.sessionId, pendingOps.map((operation) => operation.tagId), args.protectedTags, RECENT_TOOL_SKELETON_WINDOW);
24694
- const baseShouldApplyPendingOps = args.schedulerDecision === "execute" || args.forceMaterialization || hasPendingMaterializeSignal || m0HardFoldThisPass;
25147
+ const shouldReadPendingOps = !args.compactionOff && (args.schedulerDecision === "execute" || args.forceMaterialization || hasPendingMaterializeSignal || foldExecutedThisPass || historianRunning);
25148
+ const pendingOps = shouldReadPendingOps ? getPendingOps(args.db, args.sessionId) : [];
25149
+ const pendingOperationTags = pendingOps.length > 0 ? getTagsForPendingOperations(args.db, args.sessionId, pendingOps.map((operation) => operation.tagId), args.protectedTags, RECENT_TOOL_SKELETON_WINDOW) : [];
25150
+ const baseShouldApplyPendingOps = args.schedulerDecision === "execute" || args.forceMaterialization || hasPendingMaterializeSignal || foldExecutedThisPass;
24695
25151
  const deferredMaterialize = canConsumeDeferredLate && deferredMaterializationWasPending;
24696
25152
  const deferredHistoryRefresh = canConsumeDeferredLate && deferredHistoryRefreshWasPending;
24697
25153
  const shouldApplyPendingOps = (baseShouldApplyPendingOps || deferredMaterialize) && (!historianRunning || bypassHistorianGate);
25154
+ mutationGateObserverForTests?.({
25155
+ foldDue: foldDueDecision.value,
25156
+ foldExecuted: foldExecutedThisPass,
25157
+ shouldApplyPendingOps,
25158
+ shouldRunHeuristics,
25159
+ shouldRunReasoningCleanup: args.reasoningClearing !== undefined && shouldRunHeuristics
25160
+ });
24698
25161
  if (shouldApplyPendingOps) {
24699
- const applyReason = hasPendingMaterializeSignal ? "explicit_flush" : deferredMaterialize ? "deferred_publication" : args.forceMaterialization ? "force_materialization" : m0HardFoldThisPass && args.schedulerDecision !== "execute" ? `m0_hard_fold (drain folded into known m[0] bust, scheduler=${args.schedulerDecision})` : `scheduler_execute (scheduler=${args.schedulerDecision})`;
25162
+ const applyReason = hasPendingMaterializeSignal ? "explicit_flush" : deferredMaterialize ? "deferred_publication" : args.forceMaterialization ? "force_materialization" : foldExecutedThisPass && args.schedulerDecision !== "execute" ? `m0_hard_fold (drain folded into executed m[0] bust, scheduler=${args.schedulerDecision})` : `scheduler_execute (scheduler=${args.schedulerDecision})`;
24700
25163
  sessionLog(args.sessionId, `pending ops WILL APPLY — reason=${applyReason}, pendingOps=${pendingOps.length}, context=${args.contextUsage.percentage.toFixed(1)}%`);
24701
25164
  try {
24702
25165
  const tApplyPending = performance.now();
@@ -24774,7 +25237,7 @@ async function runPipeline(args) {
24774
25237
  const activeTags = getActiveTagsBySession(args.db, args.sessionId);
24775
25238
  logTransformTiming(args.sessionId, "getActiveTagsBySession", tActiveTags, `count=${activeTags.length}`);
24776
25239
  if (shouldRunHeuristics) {
24777
- const reason = args.forceMaterialization ? "force_materialization" : m0HardFoldThisPass && args.schedulerDecision !== "execute" ? `m0_hard_fold (drain folded into known m[0] bust, scheduler=${args.schedulerDecision})` : `scheduler_execute (pendingOps=${pendingOps.length}, scheduler=${args.schedulerDecision})`;
25240
+ const reason = args.forceMaterialization ? "force_materialization" : foldExecutedThisPass && args.schedulerDecision !== "execute" ? `m0_hard_fold (drain folded into executed m[0] bust, scheduler=${args.schedulerDecision})` : `scheduler_execute (pendingOps=${pendingOps.length}, scheduler=${args.schedulerDecision})`;
24778
25241
  sessionLog(args.sessionId, `heuristics WILL RUN — reason=${reason}, context=${args.contextUsage.percentage.toFixed(1)}%, turn=n/a`);
24779
25242
  } else {
24780
25243
  const reason = args.heuristics === undefined ? "disabled" : "scheduler_defer";
@@ -24958,17 +25421,12 @@ async function runPipeline(args) {
24958
25421
  if (args.injection) {
24959
25422
  try {
24960
25423
  const tInjection = performance.now();
24961
- injectionResult = injectM0M1PiForRun({
24962
- sessionId: args.sessionId,
24963
- projectIdentity: args.projectIdentity,
24964
- projectDirectory: args.projectDirectory,
24965
- memoryEnabled: args.injection.memoryEnabled,
24966
- injectDocs: args.injection.injectDocs,
24967
- injectionBudgetTokens: args.injection.injectionBudgetTokens,
24968
- historyBudgetTokens: args.injection.historyBudgetTokens,
24969
- hardSignals: piHardSignals,
24970
- muralEnabled: args.injection.muralEnabled === true
24971
- }, args.db, args.messages, args.entryIds, args.isCacheBusting || deferredHistoryRefresh || executedWorkThisPass);
25424
+ const wireInjectionResult = injectM0M1PiForRun(piM0State, args.db, args.messages, args.entryIds, args.isCacheBusting || deferredHistoryRefresh || executedWorkThisPass);
25425
+ injectionResult = preFoldInjectionResult?.m0Materialized ? {
25426
+ ...wireInjectionResult,
25427
+ m0Materialized: true,
25428
+ m0Reason: preFoldInjectionResult.m0Reason ?? wireInjectionResult.m0Reason
25429
+ } : wireInjectionResult;
24972
25430
  if (args.temporalAwareness && injectionResult.skippedVisibleMessages > 0) {
24973
25431
  const firstRetainedMessage = args.messages[injectionResult.syntheticLeadingCount];
24974
25432
  stripPiLeadingTemporalMarker(firstRetainedMessage);
@@ -26711,9 +27169,19 @@ function updateStatusLine(ctx, deps, force = false) {
26711
27169
  }
26712
27170
  function renderStatusText(ctx, db, sessionId) {
26713
27171
  const usage = ctx.getContextUsage?.();
26714
- const inputTokens = typeof usage?.tokens === "number" ? usage.tokens : undefined;
26715
- const pct = typeof usage?.percent === "number" ? usage.percent : undefined;
26716
27172
  const meta = readSessionMetaStatus(db, sessionId);
27173
+ const liveInputTokens = typeof usage?.tokens === "number" && Number.isFinite(usage.tokens) ? usage.tokens : undefined;
27174
+ const persistedInputTokens = typeof meta?.last_input_tokens === "number" && Number.isFinite(meta.last_input_tokens) && meta.last_input_tokens >= 0 ? meta.last_input_tokens : undefined;
27175
+ const inputTokens = liveInputTokens ?? persistedInputTokens;
27176
+ const windowGeometry = resolvePiWindowGeometry({
27177
+ rawContextWindow: usage?.contextWindow ?? ctx.model?.contextWindow,
27178
+ model: ctx.model,
27179
+ detectedContextLimit: typeof meta?.detected_context_limit === "number" && meta.detected_context_limit > 0 ? meta.detected_context_limit : undefined,
27180
+ persistedInputTokens,
27181
+ persistedPercentage: typeof meta?.last_context_percentage === "number" ? meta.last_context_percentage : undefined
27182
+ });
27183
+ const usableSoft = windowGeometry?.usableSoft;
27184
+ const pct = inputTokens !== undefined && usableSoft !== undefined && usableSoft > 0 ? inputTokens / usableSoft * 100 : typeof meta?.last_context_percentage === "number" ? meta.last_context_percentage : undefined;
26717
27185
  const state2 = renderHistorianState(meta, recompSessions.has(sessionId));
26718
27186
  return `mc: ${inputTokens === undefined ? "--" : fmt(inputTokens)} (${pct === undefined ? "--" : `${Math.round(pct)}%`}) · ${state2}`;
26719
27187
  }
@@ -26733,7 +27201,10 @@ function renderHistorianState(meta, recompActive) {
26733
27201
  }
26734
27202
  function readSessionMetaStatus(db, sessionId) {
26735
27203
  try {
26736
- return db.prepare("SELECT compartment_in_progress, historian_failure_count, historian_last_failure_at FROM session_meta WHERE session_id = ?").get(sessionId);
27204
+ return db.prepare(`SELECT compartment_in_progress, historian_failure_count,
27205
+ historian_last_failure_at, last_input_tokens,
27206
+ last_context_percentage, detected_context_limit
27207
+ FROM session_meta WHERE session_id = ?`).get(sessionId);
26737
27208
  } catch {
26738
27209
  return;
26739
27210
  }
@@ -27514,6 +27985,44 @@ function formatThresholdClampNote(opts) {
27514
27985
  return ` [clamped: ${opts.configuredValue}% > ${opts.maxPercentage}%]`;
27515
27986
  }
27516
27987
 
27988
+ // ../plugin/src/shared/tail-hygiene-status.ts
27989
+ function finiteNumber(value, fallback = 0) {
27990
+ return typeof value === "number" && Number.isFinite(value) ? value : fallback;
27991
+ }
27992
+ function resolveTailHygieneStatus(tsBaseline, rustBaseline) {
27993
+ if (rustBaseline !== undefined && rustBaseline !== null) {
27994
+ const t2 = Math.max(0, finiteNumber(rustBaseline.t));
27995
+ const u2 = Math.min(t2, Math.max(0, finiteNumber(rustBaseline.u)));
27996
+ return {
27997
+ u: u2,
27998
+ t: t2,
27999
+ severity: Math.min(1, Math.max(0, finiteNumber(rustBaseline.severity, u2 / Math.max(t2, 1)))),
28000
+ evaluable: rustBaseline.evaluable === true,
28001
+ generationInvalidated: rustBaseline.generation_invalidated === true,
28002
+ baselineGeneration: Math.max(0, finiteNumber(rustBaseline.baseline_generation)),
28003
+ computedAt: Math.max(0, finiteNumber(rustBaseline.computed_at_ms))
28004
+ };
28005
+ }
28006
+ if (tsBaseline === undefined)
28007
+ return;
28008
+ const t = Math.max(0, tsBaseline.baselineT + tsBaseline.turnDeltaT);
28009
+ const u = Math.min(t, Math.max(0, tsBaseline.baselineU + tsBaseline.turnDeltaU));
28010
+ return {
28011
+ u,
28012
+ t,
28013
+ severity: Math.min(1, Math.max(0, u / Math.max(t, 1))),
28014
+ evaluable: tsBaseline.evaluable && !tsBaseline.generationInvalidated,
28015
+ generationInvalidated: tsBaseline.generationInvalidated,
28016
+ baselineGeneration: Math.max(0, tsBaseline.baselineGeneration),
28017
+ computedAt: Math.max(0, tsBaseline.computedAt)
28018
+ };
28019
+ }
28020
+ function formatTailHygiene(status) {
28021
+ const percentage = (status.severity * 100).toFixed(1);
28022
+ const state2 = status.evaluable ? "" : " · held until baseline refresh";
28023
+ return `${percentage}% · ${status.u.toLocaleString()} / ${status.t.toLocaleString()} tok${state2}`;
28024
+ }
28025
+
27517
28026
  // ../plugin/src/shared/format-bytes.ts
27518
28027
  function formatBytes(bytes) {
27519
28028
  if (bytes < 1024)
@@ -27542,7 +28051,7 @@ function formatExecuteThreshold(detail, contextLimit) {
27542
28051
  }
27543
28052
  return `${percentage}%${clampNote}`;
27544
28053
  }
27545
- function executeStatus(db, sessionId, protectedTags, executeThresholdPercentageConfig = DEFAULT_EXECUTE_THRESHOLD_PERCENTAGE, liveModelKey, historyBudgetPercentage, commitClusterTrigger, executeThresholdTokens, contextLimit, dreamer) {
28054
+ function executeStatus(db, sessionId, protectedTags, executeThresholdPercentageConfig = DEFAULT_EXECUTE_THRESHOLD_PERCENTAGE, liveModelKey, historyBudgetPercentage, commitClusterTrigger, executeThresholdTokens, contextLimit, dreamer, windowGeometry, tailHygiene) {
27546
28055
  const thresholdDetail = resolveExecuteThresholdDetail(executeThresholdPercentageConfig, liveModelKey, DEFAULT_EXECUTE_THRESHOLD_PERCENTAGE, {
27547
28056
  tokensConfig: executeThresholdTokens,
27548
28057
  contextLimit,
@@ -27597,13 +28106,16 @@ function executeStatus(db, sessionId, protectedTags, executeThresholdPercentageC
27597
28106
  `**Protected tags:** ${protectedTags}`,
27598
28107
  `**Subagent session:** ${meta.isSubagent}`
27599
28108
  ];
28109
+ if (tailHygiene !== undefined) {
28110
+ lines.push("", "### Tail Hygiene", `- Reclaimable / eligible: ${formatTailHygiene(tailHygiene)}`, "- Reasoning is excluded from both terms.");
28111
+ }
27600
28112
  if (dreamer?.backlog && Object.keys(dreamer.backlog).length > 0) {
27601
28113
  lines.push("", "### Dreamer", ...dreamer.progress ? [
27602
28114
  `- Running: ${dreamer.progress.task} — ${dreamer.progress.processed}/${dreamer.progress.total} processed`
27603
28115
  ] : [], ...formatDreamTaskBacklogs(dreamer.backlog).split("\\n"));
27604
28116
  }
27605
28117
  if (meta.lastContextPercentage > 0 || meta.lastInputTokens > 0) {
27606
- 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`);
28118
+ 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`);
27607
28119
  }
27608
28120
  const compartments = getCompartments(db, sessionId);
27609
28121
  let historyBlockTokens = 0;
@@ -27704,7 +28216,7 @@ ${c.content}
27704
28216
  // package.json
27705
28217
  var package_default = {
27706
28218
  name: "@cortexkit/pi-magic-context",
27707
- version: "0.36.1",
28219
+ version: "0.38.0",
27708
28220
  type: "module",
27709
28221
  description: "Pi and OMP coding agent extension for Magic Context — cross-session memory and context management",
27710
28222
  main: "dist/index.js",
@@ -27744,6 +28256,7 @@ var package_default = {
27744
28256
  prepublishOnly: "bun run build"
27745
28257
  },
27746
28258
  dependencies: {
28259
+ "@cortexkit/subc-client": "0.4.1",
27747
28260
  "@huggingface/transformers": "^4.1.0",
27748
28261
  "@jitl/quickjs-singlefile-cjs-release-asyncify": "0.32.0",
27749
28262
  "ai-tokenizer": "^1.0.6",
@@ -27754,8 +28267,9 @@ var package_default = {
27754
28267
  },
27755
28268
  devDependencies: {
27756
28269
  "@biomejs/biome": "^2.5.1",
27757
- "@earendil-works/pi-coding-agent": "^0.80.2",
27758
- "@earendil-works/pi-tui": "^0.80.2",
28270
+ "@earendil-works/pi-ai": "0.83.0",
28271
+ "@earendil-works/pi-coding-agent": "0.83.0",
28272
+ "@earendil-works/pi-tui": "0.83.0",
27759
28273
  "@types/better-sqlite3": "^7.6.13",
27760
28274
  "@types/bun": "^1.3.10",
27761
28275
  "@types/node": "^22.20.0",
@@ -27871,7 +28385,13 @@ function renderInner(s, theme, innerWidth) {
27871
28385
  lines.push(`${theme.fg("accent", theme.bold("⚡ Magic Context Status"))} ${theme.fg("muted", `v${package_default.version}`)}`);
27872
28386
  lines.push("");
27873
28387
  lines.push(`Context ${theme.fg(pctColor, theme.bold(`${s.usagePercentage.toFixed(1)}%`))} · ${fmt2(s.inputTokens)} / ${s.contextLimit > 0 ? fmt2(s.contextLimit) : "?"} tokens`);
28388
+ if (s.windowGeometry) {
28389
+ lines.push(formatWindowDerivationLine(s.inputTokens, s.windowGeometry).replace(/^Context:.* — window /, "Window "));
28390
+ }
27874
28391
  lines.push(`Work tokens ${fmt2(s.newWorkTokens)} new · ${fmt2(s.totalInputTokens)} total input`);
28392
+ if (s.tailHygiene !== undefined) {
28393
+ lines.push(`Hygiene ${formatTailHygiene(s.tailHygiene)}`);
28394
+ }
27875
28395
  lines.push(renderBar(s, innerWidth));
27876
28396
  for (const seg of breakdownSegments(s)) {
27877
28397
  const pct = (seg.tokens / (s.inputTokens || 1) * 100).toFixed(1);
@@ -27879,6 +28399,7 @@ function renderInner(s, theme, innerWidth) {
27879
28399
  const right = theme.fg("muted", `${fmt2(seg.tokens)} (${pct}%)`);
27880
28400
  lines.push(`${left} ${right}`);
27881
28401
  }
28402
+ lines.push("* Conversation includes model Reasoning; hygiene excludes it.");
27882
28403
  lines.push("");
27883
28404
  lines.push(`Counts: ${s.compartmentCount} compartments · ${s.memoryCount} memories (${s.memoryBlockCount} injected) · ${s.sessionNoteCount + s.readySmartNoteCount} notes`);
27884
28405
  lines.push(`Historian: ${s.historianRunning ? theme.fg("warning", "running") : theme.fg("accent", "idle")}${s.historianFailureCount > 0 ? ` · ${theme.fg("error", `last failure ${s.historianLastFailureAt ? relTime(s.historianLastFailureAt) : "unknown"}`)}` : ""}`);
@@ -27931,18 +28452,22 @@ function drawBorder(inner, width, theme) {
27931
28452
  function buildPiStatusDetail(pi, ctx, deps, sessionId) {
27932
28453
  const usage = ctx.getContextUsage?.();
27933
28454
  const meta = getOrCreateSessionMeta(deps.db, sessionId);
27934
- const inputTokens = typeof usage?.tokens === "number" ? usage.tokens : meta.lastInputTokens;
28455
+ const hasPersistedPressure = meta.lastInputTokens > 0 && meta.lastContextPercentage > 0;
28456
+ const inputTokens = hasPersistedPressure ? meta.lastInputTokens : typeof usage?.tokens === "number" ? usage.tokens : 0;
27935
28457
  let detectedContextLimit;
27936
28458
  try {
27937
28459
  const detected = getOverflowState(deps.db, sessionId).detectedContextLimit;
27938
28460
  if (detected > 0)
27939
28461
  detectedContextLimit = detected;
27940
28462
  } catch {}
27941
- const contextLimit = resolvePiUsableContextLimit({
28463
+ const windowGeometry = resolvePiWindowGeometry({
27942
28464
  rawContextWindow: usage?.contextWindow ?? ctx.model?.contextWindow,
27943
28465
  model: ctx.model,
27944
- detectedContextLimit
27945
- }) ?? (meta.lastContextPercentage > 0 ? Math.round(inputTokens / (meta.lastContextPercentage / 100)) : 0);
28466
+ detectedContextLimit,
28467
+ persistedInputTokens: meta.lastInputTokens,
28468
+ persistedPercentage: meta.lastContextPercentage
28469
+ });
28470
+ const contextLimit = windowGeometry?.usableSoft ?? 0;
27946
28471
  const usagePercentage = contextLimit > 0 && inputTokens > 0 ? inputTokens / contextLimit * 100 : meta.lastContextPercentage;
27947
28472
  const compartments = getCompartments(deps.db, sessionId);
27948
28473
  const metaRow = readSessionMetaRow(deps.db, sessionId);
@@ -27984,6 +28509,7 @@ ${safeStringify(tool.parameters)}`);
27984
28509
  } catch {}
27985
28510
  const conversationTokens = Math.max(0, inputTokens - systemPromptTokens - compartmentTokens - factTokens - memoryTokens - docsTokens - profileTokens - toolCallTokens - toolDefinitionTokens);
27986
28511
  const workMetrics = getSessionWorkMetrics(deps.db, sessionId);
28512
+ const tailHygiene = resolveTailHygieneStatus(getPiChannel1Baseline(sessionId));
27987
28513
  const modelKey = ctx.model ? `${ctx.model.provider}/${ctx.model.id}` : undefined;
27988
28514
  const threshold = resolveExecuteThresholdDetail(deps.executeThresholdPercentage ?? 65, modelKey, 65, {
27989
28515
  tokensConfig: deps.executeThresholdTokens,
@@ -28036,6 +28562,7 @@ ${safeStringify(tool.parameters)}`);
28036
28562
  lastTransformError: meta.lastTransformError,
28037
28563
  isSubagent: meta.isSubagent,
28038
28564
  contextLimit,
28565
+ windowGeometry,
28039
28566
  executeThreshold: threshold.percentage,
28040
28567
  executeThresholdMode: threshold.mode,
28041
28568
  executeThresholdClamped: threshold.clamped,
@@ -28056,6 +28583,7 @@ ${safeStringify(tool.parameters)}`);
28056
28583
  conversationTokens,
28057
28584
  toolCallTokens,
28058
28585
  toolDefinitionTokens,
28586
+ ...tailHygiene === undefined ? {} : { tailHygiene },
28059
28587
  newWorkTokens: workMetrics.newWorkTokens,
28060
28588
  totalInputTokens: workMetrics.totalInputTokens,
28061
28589
  upgradeNeededCount: safeRead(() => countCompartmentsNeedingUpgrade(deps.db, sessionId), 0),
@@ -28103,7 +28631,7 @@ function breakdownSegments(s) {
28103
28631
  });
28104
28632
  if (s.conversationTokens > 0)
28105
28633
  segs.push({
28106
- label: "Conversation",
28634
+ label: "Conversation*",
28107
28635
  tokens: s.conversationTokens,
28108
28636
  color: COLORS.conversation
28109
28637
  });
@@ -28223,14 +28751,18 @@ No active Pi session is available.`,
28223
28751
  if (detected > 0)
28224
28752
  detectedContextLimit = detected;
28225
28753
  } catch {}
28226
- const usableContextLimit = resolvePiUsableContextLimit({
28754
+ const meta = getOrCreateSessionMeta(currentDeps.db, sessionId);
28755
+ const windowGeometry = resolvePiWindowGeometry({
28227
28756
  rawContextWindow: usage?.contextWindow ?? ctx.model?.contextWindow,
28228
28757
  model: ctx.model,
28229
- detectedContextLimit
28758
+ detectedContextLimit,
28759
+ persistedInputTokens: meta.lastInputTokens,
28760
+ persistedPercentage: meta.lastContextPercentage
28230
28761
  });
28762
+ const usableContextLimit = windowGeometry?.usableSoft;
28231
28763
  const statusText = executeStatus(currentDeps.db, sessionId, currentDeps.protectedTags ?? 20, currentDeps.executeThresholdPercentage, modelKey, currentDeps.historyBudgetPercentage, currentDeps.commitClusterTrigger, currentDeps.executeThresholdTokens, usableContextLimit, {
28232
28764
  backlog: getDreamTaskBacklogs(currentDeps.db, currentDeps.projectIdentity, CANONICAL_DREAM_TASKS)
28233
- });
28765
+ }, windowGeometry, resolveTailHygieneStatus(getPiChannel1Baseline(sessionId)));
28234
28766
  const details = buildStatusDetails(currentDeps, sessionId);
28235
28767
  sendCtxStatusMessage(pi, { title: "/ctx-status", text: statusText, level: "info" }, details);
28236
28768
  } catch (error) {
@@ -29111,10 +29643,7 @@ async function src_default(pi) {
29111
29643
  return;
29112
29644
  }
29113
29645
  const migration = getMigrationOnOpenRefusal();
29114
- const blockingProcesses = migration?.serverPids.map((pid) => ({
29115
- harness: "OpenCode server",
29116
- pid
29117
- })) ?? [];
29646
+ const blockingProcesses = migration?.blockingProcesses ?? migration?.serverPids.map((pid) => ({ kind: "process", pid })) ?? [];
29118
29647
  const fence = getSchemaFenceRejection();
29119
29648
  const reason = migration && blockingProcesses.length > 0 ? {
29120
29649
  kind: "migration_guard",
@@ -29665,9 +30194,7 @@ async function startPiMagicContextRuntime(pi, database, dbPath) {
29665
30194
  isCacheBusting,
29666
30195
  existingSystemPrompt: event.systemPrompt
29667
30196
  });
29668
- const composedPrompt = block ? `${event.systemPrompt}
29669
-
29670
- ${block}` : event.systemPrompt;
30197
+ const composedPrompt = composeMagicContextSystemPrompt(event.systemPrompt, block);
29671
30198
  if (!sessionId) {
29672
30199
  if (block)
29673
30200
  return { systemPrompt: composedPrompt };
@@ -29757,14 +30284,14 @@ ${block}` : event.systemPrompt;
29757
30284
  return;
29758
30285
  if (compactionOff)
29759
30286
  return;
29760
- if (db)
29761
- maybeDeliverChannel2Pi(pi, db, sessionId, "steer");
29762
30287
  const block = maybeChannel1ReminderForToolResult({
29763
30288
  db,
29764
30289
  sessionId,
29765
30290
  toolName: event.toolName,
29766
30291
  content: event.content
29767
30292
  });
30293
+ if (db)
30294
+ maybeDeliverChannel2Pi(pi, db, sessionId);
29768
30295
  if (!block)
29769
30296
  return;
29770
30297
  return { content: [...event.content, block] };