@cortexkit/pi-magic-context 0.37.0 → 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,6 +89,7 @@ import {
82
89
  createPrimer,
83
90
  createPromptSurfaceGuidanceEpochCache,
84
91
  createPromptSurfaceRuntime,
92
+ decideChannel1,
85
93
  decodeCachedM0UpgradeIdentity,
86
94
  deleteMemory,
87
95
  deleteUserMemoryCandidates,
@@ -91,6 +99,7 @@ import {
91
99
  describeError,
92
100
  dismissUserMemory,
93
101
  drainCommitBacklogForProject,
102
+ effectiveTailHygiene,
94
103
  embedBatchForProject,
95
104
  embedItemsForProject,
96
105
  embedPromotedFacts,
@@ -104,8 +113,10 @@ import {
104
113
  escalationBands,
105
114
  escapeXmlAttr,
106
115
  escapeXmlContent,
116
+ estimateImageTokensFromDataUrl,
107
117
  estimateTokens,
108
118
  estimateTrueRawMessageTokens,
119
+ evaluateChannel2,
109
120
  expandWorkspaceIdentitySetWithAliases,
110
121
  extractM0Block,
111
122
  extractTexts,
@@ -116,7 +127,6 @@ import {
116
127
  findPiFallbackToolOwnerTags,
117
128
  formatWindowDerivationLine,
118
129
  getActivePrimers,
119
- getActiveTagTokenAggregate,
120
130
  getActiveTagsBySession,
121
131
  getActiveToolTagsForAgeReclaim,
122
132
  getActiveUserMemories,
@@ -124,6 +134,7 @@ import {
124
134
  getAllStatusTagTokenTotalsFlat,
125
135
  getAutoSearchHintDecisions,
126
136
  getCachedAbsoluteMessageCount,
137
+ getChannel2NudgeClaim,
127
138
  getChannel2NudgeState,
128
139
  getCompactionModeRecord,
129
140
  getCompartments,
@@ -262,6 +273,7 @@ import {
262
273
  peelLeadingMcTagNotation,
263
274
  persistCachedM0,
264
275
  piModelRefToCanonical,
276
+ planEmergencyDrop,
265
277
  preloadTokenizer,
266
278
  prependTag,
267
279
  primeInMemoryTailRawMessageCache,
@@ -317,6 +329,7 @@ import {
317
329
  resolveModelRefForOmp,
318
330
  resolveModelRefForPi,
319
331
  resolveMuralWire,
332
+ resolveOutputReserve,
320
333
  resolvePiStableId,
321
334
  resolveProjectIdentity,
322
335
  resolveProjectIdentityForSession,
@@ -349,6 +362,7 @@ import {
349
362
  setStoragePrivatePermissionEnforcement,
350
363
  setTodoSnapshot,
351
364
  sourceNameForMemory,
365
+ stripChannel1ReminderSpans,
352
366
  stripMemoryMuralBlock,
353
367
  stripPersistedAssistantText,
354
368
  stripTagPrefix,
@@ -381,7 +395,7 @@ import {
381
395
  withMigrationLanguageDirective,
382
396
  withRawMessageProvider,
383
397
  withRawSessionMessageCache
384
- } from "./index-kvttksef.js";
398
+ } from "./index-6hs6yh6r.js";
385
399
  import {
386
400
  pushNotification
387
401
  } from "./index-hw34xmzk.js";
@@ -577,24 +591,44 @@ function isMagicContextHiddenAgentName(agent) {
577
591
  return false;
578
592
  }
579
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
+ }
580
616
  function formatFailClosedBlockingProcesses(processes) {
581
617
  const uniqueProcesses = new Map;
582
618
  for (const process2 of processes) {
583
- if (!process2.harness.trim() || !Number.isInteger(process2.pid) || process2.pid <= 0)
619
+ if (!Number.isInteger(process2.pid) || process2.pid <= 0)
584
620
  continue;
585
- uniqueProcesses.set(`${process2.harness}\x00${process2.pid}`, {
586
- harness: process2.harness.trim(),
587
- pid: process2.pid
588
- });
621
+ const kind = normalizeFailClosedProcessKind(process2);
622
+ uniqueProcesses.set(`${kind}\x00${process2.pid}`, { kind, pid: process2.pid });
589
623
  }
590
624
  const entries = [...uniqueProcesses.values()];
591
625
  const visible = entries.slice(0, MAX_FORMATTED_BLOCKING_PROCESSES);
592
- const rendered = visible.map(({ harness, pid }) => `${harness} (PID ${pid})`);
626
+ const rendered = visible.map(({ kind, pid }) => `${kind} (PID ${pid})`);
593
627
  const omitted = entries.length - visible.length;
594
628
  if (omitted > 0)
595
629
  rendered.push(`${omitted} more blocking process(es)`);
596
630
  if (rendered.length === 0)
597
- return "a live harness process";
631
+ return "a live process";
598
632
  if (rendered.length === 1)
599
633
  return rendered[0];
600
634
  const last = rendered.pop();
@@ -604,9 +638,9 @@ function formatFailClosedBlockingMessage(reason) {
604
638
  if (reason.kind === "migration_guard") {
605
639
  if (reason.unreadableFile) {
606
640
  const arm = reason.unreadableArm ?? "io";
607
- 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.`;
608
642
  return [
609
- `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.`,
610
644
  recovery,
611
645
  `Recovery: ${FAIL_CLOSED_DOCTOR_COMMAND}`
612
646
  ].join(" ");
@@ -4527,6 +4561,34 @@ function assertManifestCoversExactly(ids, expectedIds, rootName) {
4527
4561
  throw new Error(`${rootName} manifest missing id ${id}`);
4528
4562
  }
4529
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
+ }
4530
4592
 
4531
4593
  // ../plugin/src/features/magic-context/dreamer/module-apply.ts
4532
4594
  class DreamerModuleBusyError extends Error {
@@ -5845,9 +5907,19 @@ ${renderAnchors(args.anchors ?? [])}### Memory pool to classify
5845
5907
  ${renderPool2(args.memories)}`;
5846
5908
  }
5847
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
+ }
5848
5920
  function parseClassifyManifest(text) {
5849
5921
  const out = [];
5850
- const body = extractCompleteManifestBody(text, "classify");
5922
+ const body = classifyBody(text);
5851
5923
  for (const m of body.matchAll(/<memory\b([^>]*)\/?>/g)) {
5852
5924
  const attrs = m[1];
5853
5925
  const idMatch = attrs.match(/\bid\s*=\s*"(\d+)"/);
@@ -5880,9 +5952,18 @@ function parseClassifyManifest(text) {
5880
5952
  }
5881
5953
  out.push(entry);
5882
5954
  }
5955
+ if (out.length === 0 && body.trim().length > 0) {
5956
+ throw new Error(describeUnrecognizedManifestShape(text, "classify", "memory"));
5957
+ }
5883
5958
  assertNoDuplicateManifestIds(out.map((entry) => entry.id), "classify");
5884
5959
  return out;
5885
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
+ }
5886
5967
 
5887
5968
  // ../plugin/src/features/magic-context/dreamer/classify.ts
5888
5969
  var MIN_POOL_TO_CLASSIFY = 10;
@@ -6081,7 +6162,7 @@ async function classifyOneChunk(args, chunk, anchors, sliceMs, signal) {
6081
6162
  if (!text)
6082
6163
  throw new Error("classify returned no output");
6083
6164
  try {
6084
- parseClassifyManifest(text);
6165
+ validateClassifyManifest(text, new Set(chunk.map((candidate) => candidate.id)));
6085
6166
  } catch (error) {
6086
6167
  const providerFailure = providerOutputFailureFromInvalidManifest(messages, text);
6087
6168
  if (providerFailure)
@@ -6149,8 +6230,7 @@ async function runClassifyThroughModule(args, chunk, anchors, signal) {
6149
6230
  if (result.truncated === true) {
6150
6231
  throw new Error("classify returned length-capped output");
6151
6232
  }
6152
- const parsed = parseClassifyManifest(manifestText);
6153
- 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)));
6154
6234
  const rows = parsed.map((entry) => {
6155
6235
  const candidate = chunk.find((item) => item.id === entry.id);
6156
6236
  if (!candidate)
@@ -7947,11 +8027,33 @@ For each memory below, find the repo file(s) it makes a claim about, or mark it
7947
8027
  ${list}
7948
8028
  </memories>`;
7949
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
+ }
7950
8051
  function parseMapMemoriesManifest(text) {
7951
8052
  const out = [];
7952
- const body = extractCompleteManifestBody(text, "mappings");
7953
- 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"))) {
7954
8055
  const attrs = m[1];
8056
+ const inner = m[2];
7955
8057
  const idMatch = attrs.match(/\bid\s*=\s*"(\d+)"/);
7956
8058
  if (!idMatch)
7957
8059
  throw new Error("mappings manifest entry missing numeric id");
@@ -7960,24 +8062,67 @@ function parseMapMemoriesManifest(text) {
7960
8062
  throw new Error("mappings manifest entry missing numeric id");
7961
8063
  const independent = /\bindependent\s*=\s*"(?:true|1)"/i.test(attrs);
7962
8064
  const filesMatch = attrs.match(/\bfiles\s*=\s*"([^"]*)"/);
7963
- const files = filesMatch ? filesMatch[1].split(",").map((f) => f.trim()).filter(Boolean) : [];
7964
- 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"));
7965
8079
  }
7966
8080
  assertNoDuplicateManifestIds(out.map((entry) => entry.id), "mappings");
7967
8081
  return out;
7968
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
+ }
7969
8089
 
7970
8090
  // ../plugin/src/features/magic-context/dreamer/map-memories.ts
7971
8091
  var MAP_BATCH_SIZE = 80;
7972
- 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) {
7973
8107
  const active = getMemoriesByProject(db, projectIdentity);
7974
- const unmapped = new Set(getUnmappedMemoryIds(db, active.map((m) => m.id)));
7975
- return active.filter((m) => unmapped.has(m.id)).map((m) => ({
7976
- id: m.id,
7977
- category: m.category,
7978
- content: m.content,
7979
- candidates: extractMemoryCandidatePaths(m.content, repoDir)
7980
- }));
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];
7981
8126
  }
7982
8127
  async function mapMemories(args) {
7983
8128
  const result = {
@@ -7987,7 +8132,7 @@ async function mapMemories(args) {
7987
8132
  remaining: 0,
7988
8133
  complete: true
7989
8134
  };
7990
- const inputs = loadUnmappedInputs(args.db, args.projectIdentity, args.sessionDirectory);
8135
+ const inputs = selectMapMemoryInputs(args.db, args.projectIdentity, args.sessionDirectory);
7991
8136
  if (inputs.length === 0)
7992
8137
  return result;
7993
8138
  const batches = [];
@@ -8066,7 +8211,7 @@ async function mapOneBatch(args, batch, sliceMs, signal) {
8066
8211
  const text = extractLatestAssistantText(messages);
8067
8212
  if (!text)
8068
8213
  throw new Error("map-memories returned no output");
8069
- parseMapMemoriesManifest(text);
8214
+ validateMapMemoriesManifest(text, new Set(batch.map((memory) => memory.id)));
8070
8215
  return text;
8071
8216
  }
8072
8217
  });
@@ -8100,10 +8245,13 @@ async function applyBatchMappings(args, batch, manifestText) {
8100
8245
  return { mapped: 0, independent: 0 };
8101
8246
  const planned = [];
8102
8247
  for (const p of parsed) {
8103
- if (p.independent || p.files.length === 0) {
8248
+ if (p.independent) {
8104
8249
  planned.push({ id: p.id, files: [], independent: true });
8105
8250
  continue;
8106
8251
  }
8252
+ if (p.files.length === 0) {
8253
+ throw new Error(`mapping entry ${p.id} has no files and no independent sentinel`);
8254
+ }
8107
8255
  const normalized = await normalizeVerificationFiles({
8108
8256
  cwd: args.sessionDirectory,
8109
8257
  files: p.files
@@ -9364,9 +9512,22 @@ function attrOf(s, name) {
9364
9512
  function filesOf(s) {
9365
9513
  return (attrOf(s, "files") ?? "").split(",").map((f) => f.trim()).filter(Boolean);
9366
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
+ }
9367
9528
  function parseVerifyManifest(text) {
9368
9529
  const out = { verified: [], updated: [], archived: [] };
9369
- const body = extractCompleteManifestBody(text, "verify");
9530
+ const body = verifyBody(text);
9370
9531
  for (const m of body.matchAll(/<verified\b([^>]*)\/?>/g)) {
9371
9532
  const id = Number.parseInt(attrOf(m[1], "id") ?? "", 10);
9372
9533
  if (!Number.isInteger(id))
@@ -9385,9 +9546,19 @@ function parseVerifyManifest(text) {
9385
9546
  throw new Error("verify manifest entry missing numeric id");
9386
9547
  out.archived.push({ id, reason: attrOf(m[1], "reason") ?? "" });
9387
9548
  }
9388
- 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");
9389
9553
  return out;
9390
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
+ }
9391
9562
 
9392
9563
  // ../plugin/src/features/magic-context/dreamer/verify.ts
9393
9564
  var VERIFY_BATCH_SIZE = 50;
@@ -9539,7 +9710,7 @@ async function verifyOneBatch(args, batch, sliceMs, signal) {
9539
9710
  if (!text)
9540
9711
  throw new Error("verify returned no output");
9541
9712
  try {
9542
- parseVerifyManifest(text);
9713
+ validateVerifyManifest(text, new Set(batch.map((memory) => memory.id)));
9543
9714
  } catch (error) {
9544
9715
  const providerFailure = providerOutputFailureFromInvalidManifest(messages, text);
9545
9716
  if (providerFailure)
@@ -9759,6 +9930,18 @@ function loadActiveMemoryPromptMemories(db, projectIdentity) {
9759
9930
  const verificationById = getMemoryVerifications(db, memories.map((memory) => memory.id));
9760
9931
  return memories.map((memory) => toCuratePromptMemory(memory, verificationById));
9761
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
+ }
9762
9945
  function createDreamTaskExecutor(deps) {
9763
9946
  let parentSessionIdPromise;
9764
9947
  const resolveParentSessionId = () => {
@@ -9829,7 +10012,8 @@ function createDreamTaskExecutor(deps) {
9829
10012
  name: config.task,
9830
10013
  durationMs: Date.now() - startedAt,
9831
10014
  resultChars: 0,
9832
- ...error ? { error } : {},
10015
+ ...status === "failed" && error ? { error } : {},
10016
+ ...extra?.progress ? { progress: extra.progress } : {},
9833
10017
  backlog: (() => {
9834
10018
  const end = extra?.backlogAfter ?? getDreamTaskBacklog(db, projectIdentity, config.task);
9835
10019
  const processed = processedDreamTaskItems(backlogAtStart.pending, end.pending);
@@ -9972,11 +10156,12 @@ function createDreamTaskExecutor(deps) {
9972
10156
  const backlogAfter = config.task === "verify-broad" ? { pending: result.remaining, total: backlogAtStart.total } : undefined;
9973
10157
  if (!result.complete) {
9974
10158
  if (broadProgress && processed > 0) {
9975
- recordRun("completed", broadProgress, {
10159
+ recordRun("completed", null, {
10160
+ progress: broadProgress,
9976
10161
  memoryChanges: computeMemoryDelta(memoryBefore),
9977
10162
  backlogAfter
9978
10163
  });
9979
- return { status: "completed", error: broadProgress };
10164
+ return { status: "completed" };
9980
10165
  }
9981
10166
  const error = incompleteMessage(result.remaining);
9982
10167
  recordRun("failed", error, {
@@ -9985,11 +10170,12 @@ function createDreamTaskExecutor(deps) {
9985
10170
  });
9986
10171
  return { status: "failed", transient: true, error };
9987
10172
  }
9988
- recordRun("completed", broadProgress, {
10173
+ recordRun("completed", null, {
10174
+ progress: broadProgress,
9989
10175
  memoryChanges: computeMemoryDelta(memoryBefore),
9990
10176
  backlogAfter
9991
10177
  });
9992
- return broadProgress ? { status: "completed", error: broadProgress } : { status: "completed" };
10178
+ return { status: "completed" };
9993
10179
  }
9994
10180
  if (config.task === "classify-memories") {
9995
10181
  let moduleArgs;
@@ -10456,7 +10642,7 @@ async function runAgenticTask(config, ctx, helpers) {
10456
10642
  const text = extractLatestAssistantText(messages);
10457
10643
  if (!text)
10458
10644
  throw new Error("Dreamer returned no assistant output.");
10459
- return text;
10645
+ return task === "curate" ? validateCurateAssistantText(text) : text;
10460
10646
  }
10461
10647
  });
10462
10648
  if (leaseLost)
@@ -13275,6 +13461,21 @@ function replayCavemanCompression(sessionId, db, targets, tags) {
13275
13461
  return replayed;
13276
13462
  }
13277
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
+
13278
13479
  // ../plugin/src/hooks/magic-context/protected-tail-boundary.ts
13279
13480
  var ALPHA = 0.3;
13280
13481
  var FLOOR_RATIO = 0.08;
@@ -14160,132 +14361,13 @@ function checkCompartmentTrigger(db, sessionId, sessionMeta, usage, _previousPer
14160
14361
  };
14161
14362
  }
14162
14363
 
14163
- // ../plugin/src/hooks/magic-context/ctx-reduce-nudge.ts
14164
- var CHANNEL1_SENTINEL = "<system-reminder>";
14165
- var TOKENS_PER_BYTE = 0.25;
14166
- var CHANNEL1_FLOOR_TOKENS = 1e4;
14167
- var CHANNEL1_REFIRE_FLOOR_TOKENS = 1e4;
14168
- function channel1RefireTokens(workingWindowTokens) {
14169
- const scaled = Math.round(0.05 * Math.max(0, workingWindowTokens));
14170
- return Math.max(CHANNEL1_REFIRE_FLOOR_TOKENS, scaled);
14171
- }
14172
- var S_GENTLE = 0.2;
14173
- var S_FIRM = 0.4;
14174
- var S_URGENT = 0.65;
14175
- var CHANNEL1_PRESSURE_FLOOR = 0.8;
14176
- var LEVEL_RANK = { gentle: 1, firm: 2, urgent: 3 };
14177
- var DROP_SENTINELS = ["[dropped", "[truncated"];
14178
- function isDroppedToolOutput(output) {
14179
- const head = output.slice(0, 16);
14180
- return DROP_SENTINELS.some((s) => head.startsWith(s));
14181
- }
14182
- function toolOutputTokens(output) {
14183
- return Math.round(byteSize(output) * TOKENS_PER_BYTE);
14184
- }
14185
- function decideChannel1(input) {
14186
- const { undroppedTokens, workingWindowTokens, hasRecentReduce } = input;
14187
- const pressure = Math.min(1, Math.max(0, input.pressure));
14188
- const resetCycle = hasRecentReduce || undroppedTokens < input.lastNudgeUndropped;
14189
- const lastNudge = resetCycle ? 0 : input.lastNudgeUndropped;
14190
- const lastLevel = resetCycle ? "" : input.lastNudgeLevel;
14191
- const quiet = () => ({
14192
- fire: false,
14193
- level: "gentle",
14194
- undroppedTokens,
14195
- nextLastNudge: lastNudge,
14196
- nextLastNudgeLevel: lastLevel
14197
- });
14198
- if (hasRecentReduce)
14199
- return quiet();
14200
- if (undroppedTokens < CHANNEL1_FLOOR_TOKENS)
14201
- return quiet();
14202
- if (pressure < CHANNEL1_PRESSURE_FLOOR)
14203
- return quiet();
14204
- const denom = Math.max(input.estimatedInputTokens, 1);
14205
- const severity = Math.min(1, undroppedTokens / denom);
14206
- if (severity < S_GENTLE)
14207
- return quiet();
14208
- let level;
14209
- if (severity >= S_URGENT)
14210
- level = "urgent";
14211
- else if (severity >= S_FIRM)
14212
- level = "firm";
14213
- else
14214
- level = "gentle";
14215
- if (lastLevel === "") {
14216
- if (undroppedTokens < lastNudge + channel1RefireTokens(workingWindowTokens)) {
14217
- return quiet();
14218
- }
14219
- } else if (LEVEL_RANK[level] <= LEVEL_RANK[lastLevel]) {
14220
- return quiet();
14221
- }
14222
- return {
14223
- fire: true,
14224
- level,
14225
- undroppedTokens,
14226
- nextLastNudge: undroppedTokens,
14227
- nextLastNudgeLevel: level
14228
- };
14229
- }
14230
- function computePressure(input) {
14231
- const { lastInputTokens, turnToolTokens, contextLimit, executeThresholdPercentage } = input;
14232
- if (contextLimit <= 0 || executeThresholdPercentage <= 0)
14233
- return 0;
14234
- const estimatedInput = lastInputTokens + turnToolTokens;
14235
- const usagePercentage = estimatedInput / contextLimit * 100;
14236
- return usagePercentage / executeThresholdPercentage;
14237
- }
14238
- function approxThousands(tokens) {
14239
- return `${Math.round(tokens / 1000)}k`;
14240
- }
14241
- function formatOldestReclaimableHint(hint) {
14242
- if (!hint || hint.length === 0)
14243
- return "";
14244
- const rendered = hint.slice(0, 4).map((tag) => `§${tag.tagNumber}§ ${tag.toolName ?? "tool"}`).join(" · ");
14245
- return rendered.length > 0 ? `
14246
- oldest reclaimable: ${rendered}.` : "";
14247
- }
14248
- var CHANNEL2_USABLE_FRACTION = 1 / 3;
14249
- var CHANNEL2_MIN_RECLAIMABLE = 1e4;
14250
- function shouldTriggerChannel2(input) {
14251
- if (input.reclaimableTokens < CHANNEL2_MIN_RECLAIMABLE)
14252
- return false;
14253
- if (input.usableTokens <= 0)
14254
- return true;
14255
- return input.reclaimableTokens >= input.usableTokens * CHANNEL2_USABLE_FRACTION;
14256
- }
14257
- function buildChannel2Reminder(undroppedTokens, hint) {
14258
- const amount = approxThousands(undroppedTokens);
14259
- const hintText = formatOldestReclaimableHint(hint);
14260
- return `<system-reminder>
14261
- ` + `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}
14262
- ` + `</system-reminder>`;
14263
- }
14264
- function buildChannel1Reminder(level, undroppedTokens, hint) {
14265
- const amount = approxThousands(undroppedTokens);
14266
- const hintText = formatOldestReclaimableHint(hint);
14267
- let body;
14268
- switch (level) {
14269
- case "gentle":
14270
- 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.`;
14271
- break;
14272
- case "firm":
14273
- 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.`;
14274
- break;
14275
- case "urgent":
14276
- 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.`;
14277
- break;
14278
- }
14279
- return `
14280
-
14281
- <system-reminder>
14282
- ${body}${hintText}
14283
- </system-reminder>`;
14364
+ // ../plugin/src/hooks/magic-context/fold-execution-gate.ts
14365
+ function foldExecutesThisPass(foldDue, materialized) {
14366
+ return foldDue && materialized;
14284
14367
  }
14285
14368
 
14286
14369
  // ../plugin/src/hooks/magic-context/supersession-reclaim.ts
14287
14370
  var TODOWRITE_KEEP = 1;
14288
- var CTX_REDUCE_KEEP = 5;
14289
14371
  var ZERO_VALUE_META_TOOLS = new Set(["bash_status", "bash_kill"]);
14290
14372
  var CTX_NOTE_ZERO_VALUE_ACTIONS = new Set(["read", "dismiss"]);
14291
14373
  function buildSupersessionReclaimOps(input) {
@@ -14413,158 +14495,6 @@ function advanceToolReclaimWatermarkToCurrentMax(db, sessionId) {
14413
14495
 
14414
14496
  // ../plugin/src/shared/tag-transcript.ts
14415
14497
  import { createHash as createHash9 } from "node:crypto";
14416
-
14417
- // ../plugin/src/hooks/magic-context/image-token-estimate.ts
14418
- var IMAGE_TOKEN_DIVISOR = 750;
14419
- var IMAGE_FALLBACK_TOKENS = 1200;
14420
- var IMAGE_TOKEN_CAP = 4500;
14421
- function estimateImageTokensFromDataUrl(url) {
14422
- const comma = url.indexOf(",");
14423
- if (comma < 0)
14424
- return IMAGE_FALLBACK_TOKENS;
14425
- const header = url.slice(0, comma);
14426
- const payload = url.slice(comma + 1);
14427
- const sliceLen = Math.min(512, payload.length);
14428
- const preview = payload.slice(0, sliceLen);
14429
- let bytes;
14430
- try {
14431
- bytes = base64Decode(preview);
14432
- } catch {
14433
- return IMAGE_FALLBACK_TOKENS;
14434
- }
14435
- if (header.includes("image/png")) {
14436
- const dims = parsePngDimensions(bytes);
14437
- if (dims)
14438
- return clampImageTokens(Math.ceil(dims.w * dims.h / IMAGE_TOKEN_DIVISOR));
14439
- } else if (header.includes("image/jpeg") || header.includes("image/jpg")) {
14440
- const dims = parseJpegDimensions(bytes);
14441
- if (dims)
14442
- return clampImageTokens(Math.ceil(dims.w * dims.h / IMAGE_TOKEN_DIVISOR));
14443
- } else if (header.includes("image/webp")) {
14444
- const dims = parseWebpDimensions(bytes);
14445
- if (dims)
14446
- return clampImageTokens(Math.ceil(dims.w * dims.h / IMAGE_TOKEN_DIVISOR));
14447
- } else if (header.includes("image/gif")) {
14448
- const dims = parseGifDimensions(bytes);
14449
- if (dims)
14450
- return clampImageTokens(Math.ceil(dims.w * dims.h / IMAGE_TOKEN_DIVISOR));
14451
- }
14452
- return IMAGE_FALLBACK_TOKENS;
14453
- }
14454
- function clampImageTokens(n) {
14455
- if (n < 1)
14456
- return 1;
14457
- if (n > IMAGE_TOKEN_CAP)
14458
- return IMAGE_TOKEN_CAP;
14459
- return n;
14460
- }
14461
- function base64Decode(b64) {
14462
- const pad = b64.length % 4;
14463
- const padded = pad === 0 ? b64 : b64 + "=".repeat(4 - pad);
14464
- const binary = atob(padded);
14465
- const out = new Uint8Array(binary.length);
14466
- for (let i = 0;i < binary.length; i++)
14467
- out[i] = binary.charCodeAt(i);
14468
- return out;
14469
- }
14470
- function parsePngDimensions(b) {
14471
- if (b.length < 24)
14472
- return null;
14473
- 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)
14474
- return null;
14475
- const w = readUint32BE(b, 16);
14476
- const h = readUint32BE(b, 20);
14477
- if (!w || !h)
14478
- return null;
14479
- return { w, h };
14480
- }
14481
- function parseJpegDimensions(b) {
14482
- if (b.length < 4 || b[0] !== 255 || b[1] !== 216)
14483
- return null;
14484
- let i = 2;
14485
- while (i < b.length - 8) {
14486
- if (b[i] !== 255) {
14487
- i++;
14488
- continue;
14489
- }
14490
- const marker = b[i + 1];
14491
- if (marker === undefined)
14492
- break;
14493
- if (isSofMarker(marker)) {
14494
- const h = b[i + 5] << 8 | b[i + 6];
14495
- const w = b[i + 7] << 8 | b[i + 8];
14496
- if (w && h)
14497
- return { w, h };
14498
- return null;
14499
- }
14500
- if (marker === 216 || marker === 217 || marker === 1) {
14501
- i += 2;
14502
- continue;
14503
- }
14504
- const segLen = b[i + 2] << 8 | b[i + 3];
14505
- if (segLen < 2)
14506
- return null;
14507
- i += 2 + segLen;
14508
- }
14509
- return null;
14510
- }
14511
- function isSofMarker(m) {
14512
- if (m >= 192 && m <= 195)
14513
- return true;
14514
- if (m >= 197 && m <= 199)
14515
- return true;
14516
- if (m >= 201 && m <= 203)
14517
- return true;
14518
- if (m >= 205 && m <= 207)
14519
- return true;
14520
- return false;
14521
- }
14522
- function parseWebpDimensions(b) {
14523
- if (b.length < 30)
14524
- return null;
14525
- if (b[0] !== 82 || b[1] !== 73 || b[2] !== 70 || b[3] !== 70)
14526
- return null;
14527
- if (b[8] !== 87 || b[9] !== 69 || b[10] !== 66 || b[11] !== 80)
14528
- return null;
14529
- const variant = String.fromCharCode(b[12], b[13], b[14], b[15]);
14530
- if (variant === "VP8 ") {
14531
- const w = (b[26] | b[27] << 8) & 16383;
14532
- const h = (b[28] | b[29] << 8) & 16383;
14533
- if (w && h)
14534
- return { w, h };
14535
- } else if (variant === "VP8L") {
14536
- const b0 = b[21];
14537
- const b1 = b[22];
14538
- const b2 = b[23];
14539
- const b3 = b[24];
14540
- const w = 1 + ((b0 | b1 << 8) & 16383);
14541
- const h = 1 + ((b1 >> 6 | b2 << 2 | b3 << 10) & 16383);
14542
- if (w && h)
14543
- return { w, h };
14544
- } else if (variant === "VP8X") {
14545
- const w = 1 + (b[24] | b[25] << 8 | b[26] << 16);
14546
- const h = 1 + (b[27] | b[28] << 8 | b[29] << 16);
14547
- if (w && h)
14548
- return { w, h };
14549
- }
14550
- return null;
14551
- }
14552
- function parseGifDimensions(b) {
14553
- if (b.length < 10)
14554
- return null;
14555
- if (b[0] !== 71 || b[1] !== 73 || b[2] !== 70)
14556
- return null;
14557
- const w = b[6] | b[7] << 8;
14558
- const h = b[8] | b[9] << 8;
14559
- if (!w || !h)
14560
- return null;
14561
- return { w, h };
14562
- }
14563
- function readUint32BE(b, offset) {
14564
- return (b[offset] << 24 | b[offset + 1] << 16 | b[offset + 2] << 8 | b[offset + 3]) >>> 0;
14565
- }
14566
-
14567
- // ../plugin/src/shared/tag-transcript.ts
14568
14498
  var TEXT_TAG_IDENTITY_MARKER = ":mc-text-v1:";
14569
14499
  function textIdentityDigest(value) {
14570
14500
  return createHash9("sha256").update(value).digest("hex");
@@ -15583,435 +15513,76 @@ function recordPiTransformTiming(sample) {
15583
15513
  }
15584
15514
 
15585
15515
  // src/ctx-reduce-nudge-pi.ts
15586
- function sealDeliveredAfterUnconfirmedSend(db, sessionId) {
15587
- try {
15588
- if (getChannel2NudgeState(db, sessionId) === "delivered") {
15589
- 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;
15590
15538
  }
15591
- } catch {}
15592
- try {
15593
- setChannel2NudgeState(db, sessionId, "delivered");
15594
- return "sealed";
15595
- } catch {
15596
- return "stuck-claimed";
15597
15539
  }
15598
- }
15599
- var channel1StateBySession = new Map;
15600
- function setPiChannel1Baseline(sessionId, state2) {
15601
- channel1StateBySession.set(sessionId, state2);
15602
- }
15603
- function clearPiChannel1State(sessionId) {
15604
- channel1StateBySession.delete(sessionId);
15605
- }
15606
- function markPiChannel1Reduced(sessionId, db) {
15607
- const state2 = channel1StateBySession.get(sessionId);
15608
- if (state2)
15609
- state2.reducedSinceRefresh = true;
15610
- if (db)
15611
- resetLastNudgeCycle(db, sessionId);
15612
- }
15613
- function isPiTextContent(c) {
15614
- return c !== null && typeof c === "object" && c.type === "text" && typeof c.text === "string";
15615
- }
15616
- function toolResultText(content) {
15617
- let text = "";
15618
- for (const c of content) {
15619
- if (isPiTextContent(c))
15620
- text += c.text;
15621
- }
15622
- return text;
15623
- }
15624
- function jsonTokens(value) {
15625
- if (value === undefined || value === null)
15626
- return 0;
15627
- try {
15628
- return toolOutputTokens(JSON.stringify(value));
15629
- } catch {
15630
- 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);
15631
15559
  }
15560
+ return cleaned.trim();
15632
15561
  }
15633
- function textTokens(content) {
15634
- if (typeof content === "string")
15635
- return toolOutputTokens(content);
15636
- if (!Array.isArray(content))
15637
- return 0;
15638
- let tokens = 0;
15639
- for (const part of content) {
15640
- 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")
15641
15581
  continue;
15642
- const p = part;
15643
- if (typeof p.text === "string")
15644
- tokens += toolOutputTokens(p.text);
15645
- else if (typeof p.thinking === "string")
15646
- tokens += toolOutputTokens(p.thinking);
15647
- else if (p.type === "image")
15648
- tokens += 1200;
15649
- }
15650
- return tokens;
15651
- }
15652
- function computeTailTokenEstimatePi(messages) {
15653
- let tailToolTokens = 0;
15654
- let liveTailTokens = 0;
15655
- for (const raw of messages) {
15656
- if (!raw || typeof raw !== "object")
15582
+ const msg = message;
15583
+ if (msg.role !== "assistant")
15657
15584
  continue;
15658
- const msg = raw;
15659
- if (msg.role === "toolResult") {
15660
- const outputText = Array.isArray(msg.content) ? toolResultText(msg.content) : typeof msg.content === "string" ? msg.content : "";
15661
- const outputTokens = outputText && !isDroppedToolOutput(outputText) ? toolOutputTokens(outputText) : 0;
15662
- tailToolTokens += outputTokens;
15663
- liveTailTokens += outputTokens;
15664
- continue;
15665
- }
15666
- if (msg.role === "assistant" && Array.isArray(msg.content)) {
15667
- for (const part of msg.content) {
15668
- if (!part || typeof part !== "object")
15669
- continue;
15670
- const p = part;
15671
- if (p.type === "toolCall") {
15672
- if (typeof p.name === "string")
15673
- liveTailTokens += toolOutputTokens(p.name);
15674
- liveTailTokens += jsonTokens(p.arguments);
15675
- }
15676
- }
15677
- }
15678
- liveTailTokens += textTokens(msg.content);
15679
- }
15680
- return { tailToolTokens, liveTailTokens };
15681
- }
15682
- function maybeChannel1ReminderForToolResult(args) {
15683
- const { db, sessionId, toolName } = args;
15684
- const state2 = channel1StateBySession.get(sessionId);
15685
- if (!state2)
15686
- return null;
15687
- if (toolName === "ctx_reduce") {
15688
- state2.reducedSinceRefresh = true;
15689
- resetLastNudgeCycle(db, sessionId);
15690
- return null;
15691
- }
15692
- const text = toolResultText(args.content);
15693
- if (text.length === 0)
15694
- return null;
15695
- if (text.includes(CHANNEL1_SENTINEL))
15696
- return null;
15697
- state2.turnToolTokens += toolOutputTokens(text);
15698
- if (state2.reducedSinceRefresh)
15699
- return null;
15700
- const undroppedTokens = state2.tailToolTokens + state2.turnToolTokens;
15701
- const pressure = computePressure({
15702
- lastInputTokens: state2.lastInputTokens,
15703
- turnToolTokens: state2.turnToolTokens,
15704
- contextLimit: state2.contextLimit,
15705
- executeThresholdPercentage: state2.executeThresholdPercentage
15706
- });
15707
- const workingWindowTokens = Math.round(state2.contextLimit * state2.executeThresholdPercentage / 100);
15708
- const decision = decideChannel1({
15709
- undroppedTokens,
15710
- pressure,
15711
- estimatedInputTokens: state2.lastInputTokens + state2.turnToolTokens,
15712
- workingWindowTokens,
15713
- lastNudgeUndropped: getLastNudgeUndropped(db, sessionId),
15714
- lastNudgeLevel: getLastNudgeLevel(db, sessionId),
15715
- hasRecentReduce: false
15716
- });
15717
- setLastNudgeUndropped(db, sessionId, decision.nextLastNudge);
15718
- setLastNudgeLevel(db, sessionId, decision.nextLastNudgeLevel);
15719
- if (!decision.fire)
15720
- return null;
15721
- return {
15722
- type: "text",
15723
- text: buildChannel1Reminder(decision.level, decision.undroppedTokens, state2.oldestReclaimableToolTags)
15724
- };
15725
- }
15726
- var CHANNEL2_NUDGE_CUSTOM_TYPE = "magic-context:ceiling-nudge";
15727
- function maybeDeliverChannel2Pi(pi, db, sessionId, deliverAs = "followUp") {
15728
- let state2;
15729
- try {
15730
- state2 = getChannel2NudgeState(db, sessionId);
15731
- } catch {
15732
- return false;
15733
- }
15734
- if (state2 !== "pending")
15735
- return false;
15736
- const baseline = channel1StateBySession.get(sessionId);
15737
- if (!baseline)
15738
- return false;
15739
- if (baseline.reducedSinceRefresh)
15740
- return false;
15741
- const undropped = baseline.tailToolTokens + baseline.turnToolTokens;
15742
- if (!shouldTriggerChannel2({
15743
- reclaimableTokens: undropped,
15744
- usableTokens: baseline.usableTokens
15745
- })) {
15746
- try {
15747
- casChannel2NudgeState(db, sessionId, "pending", "");
15748
- } catch {}
15749
- return false;
15750
- }
15751
- if (!casChannel2NudgeState(db, sessionId, "pending", "claimed"))
15752
- return false;
15753
- try {
15754
- pi.sendMessage({
15755
- customType: CHANNEL2_NUDGE_CUSTOM_TYPE,
15756
- content: buildChannel2Reminder(undropped, baseline.oldestReclaimableToolTags),
15757
- display: false,
15758
- details: { kind: "channel-2-ceiling-nudge" }
15759
- }, { deliverAs });
15760
- } catch (error) {
15761
- try {
15762
- casChannel2NudgeState(db, sessionId, "claimed", "pending");
15763
- } catch (revertError) {
15764
- sessionLog(sessionId, "channel2 ceiling nudge delivery failed; pending restore was busy so the stale claim will heal later:", { deliveryError: error, revertError });
15765
- return false;
15766
- }
15767
- sessionLog(sessionId, "channel2 ceiling nudge delivery failed (will retry):", error);
15768
- return false;
15769
- }
15770
- try {
15771
- const confirmed = casChannel2NudgeState(db, sessionId, "claimed", "delivered");
15772
- if (confirmed) {
15773
- sessionLog(sessionId, "channel2 ceiling nudge delivered");
15774
- return true;
15775
- }
15776
- const outcome = sealDeliveredAfterUnconfirmedSend(db, sessionId);
15777
- if (outcome === "already-delivered") {
15778
- sessionLog(sessionId, "channel2 ceiling nudge duplicate window: our send returned after a sibling reclaimed the stale lease and already delivered");
15779
- } else if (outcome === "sealed") {
15780
- sessionLog(sessionId, "channel2 ceiling nudge sent but claim confirmation was lost; sealed delivered without an authoritative confirm");
15781
- } else {
15782
- sessionLog(sessionId, "channel2 ceiling nudge sent but claim confirmation was lost; lease stayed claimed and will heal later");
15783
- }
15784
- return false;
15785
- } catch (error) {
15786
- const outcome = sealDeliveredAfterUnconfirmedSend(db, sessionId);
15787
- if (outcome === "already-delivered") {
15788
- sessionLog(sessionId, "channel2 ceiling nudge duplicate window: our send returned after a sibling reclaimed the stale lease and already delivered");
15789
- } else if (outcome === "sealed") {
15790
- sessionLog(sessionId, "channel2 ceiling nudge sent but confirm failed:", error);
15791
- } else {
15792
- sessionLog(sessionId, "channel2 ceiling nudge sent but confirm failed; lease stayed claimed and will heal later:", error);
15793
- }
15794
- return false;
15795
- }
15796
- }
15797
-
15798
- // src/detect-recent-commit.ts
15799
- var COMMIT_LOOKBACK = 5;
15800
- function detectRecentCommit(messages) {
15801
- let assistantsScanned = 0;
15802
- for (let i = messages.length - 1;i >= 0; i--) {
15803
- const message = messages[i];
15804
- if (!message || typeof message !== "object" || !("role" in message) || message.role !== "assistant") {
15805
- continue;
15806
- }
15807
- assistantsScanned++;
15808
- if (assistantsScanned > COMMIT_LOOKBACK)
15809
- break;
15810
- if (!("content" in message))
15811
- continue;
15812
- const content = message.content;
15813
- if (!Array.isArray(content))
15814
- continue;
15815
- for (const part of content) {
15816
- if (part && typeof part === "object" && "type" in part && part.type === "text" && "text" in part && typeof part.text === "string") {
15817
- if (textMentionsRecentCommit(part.text)) {
15818
- return true;
15819
- }
15820
- }
15821
- }
15822
- }
15823
- return false;
15824
- }
15825
-
15826
- // ../plugin/src/hooks/magic-context/emergency-drop.ts
15827
- var TARGET_FRACTION = 0.3;
15828
- var TIER_RECENCY_RESERVE = 0.2;
15829
- var EMERGENCY_REARM_MIN_TOKENS = 2000;
15830
- var T1_TOOLS = new Set(["read", "todowrite", "task", "aft_outline", "aft_zoom"]);
15831
- var T2_TOOLS = new Set(["edit", "write", "apply_patch", "grep", "glob", "aft_search"]);
15832
- function normalizeToolName(toolName) {
15833
- if (!toolName)
15834
- return "";
15835
- let name = toolName.toLowerCase();
15836
- if (name.startsWith("mcp_"))
15837
- name = name.slice(4);
15838
- return name;
15839
- }
15840
- function resolveToolTier(toolName) {
15841
- const name = normalizeToolName(toolName);
15842
- if (T1_TOOLS.has(name))
15843
- return 1;
15844
- if (T2_TOOLS.has(name))
15845
- return 2;
15846
- return 3;
15847
- }
15848
- function tagReclaimBytes(tag) {
15849
- return tag.byteSize + tag.inputByteSize + tag.reasoningByteSize;
15850
- }
15851
- function estimateEmergencyDropReclaimTokens(tag) {
15852
- return Math.round(tagReclaimBytes(tag) * TOKENS_PER_BYTE);
15853
- }
15854
- function planEmergencyDrop(input) {
15855
- const {
15856
- tags,
15857
- floorTags,
15858
- maxTag,
15859
- protectedTags,
15860
- currentTotalInputTokens,
15861
- ceilingTokens,
15862
- priorInputSample,
15863
- hasPriorDrop
15864
- } = input;
15865
- const noop = (reason) => ({
15866
- shouldDrop: false,
15867
- tagNumbers: [],
15868
- reclaimTokens: 0,
15869
- reason
15870
- });
15871
- if (!Number.isFinite(ceilingTokens) || ceilingTokens <= 0) {
15872
- return noop("unknown-ceiling");
15873
- }
15874
- if (!Number.isFinite(currentTotalInputTokens) || currentTotalInputTokens <= 0) {
15875
- return noop("unknown-usage");
15876
- }
15877
- if (hasPriorDrop && currentTotalInputTokens === priorInputSample) {
15878
- return noop("same-input-sample (awaiting fresh usage after prior drop)");
15879
- }
15880
- let tailTokens = 0;
15881
- for (const tag of floorTags) {
15882
- if (tag.status !== "active")
15883
- continue;
15884
- tailTokens += estimateEmergencyDropReclaimTokens(tag);
15885
- }
15886
- const fixedFloor = Math.max(currentTotalInputTokens - tailTokens, 0);
15887
- const workingSpan = Math.max(ceilingTokens - fixedFloor, 0);
15888
- const target = fixedFloor + TARGET_FRACTION * workingSpan;
15889
- const reclaimTokens = Math.round(currentTotalInputTokens - target);
15890
- if (reclaimTokens <= EMERGENCY_REARM_MIN_TOKENS) {
15891
- return noop(`reclaim<=min (${reclaimTokens} <= ${EMERGENCY_REARM_MIN_TOKENS})`);
15892
- }
15893
- const protectedCutoff = maxTag - protectedTags;
15894
- const tierActive = { 1: [], 2: [] };
15895
- for (const tag of tags) {
15896
- if (tag.status !== "active" || tag.type !== "tool")
15897
- continue;
15898
- const tier = resolveToolTier(tag.toolName);
15899
- if (tier === 1 || tier === 2)
15900
- tierActive[tier].push(tag.tagNumber);
15901
- }
15902
- const reserved = new Set;
15903
- for (const tier of [1, 2]) {
15904
- const nums = tierActive[tier];
15905
- if (nums.length === 0)
15906
- continue;
15907
- nums.sort((a, b) => b - a);
15908
- const reserveCount = Math.ceil(TIER_RECENCY_RESERVE * nums.length);
15909
- for (let i = 0;i < reserveCount && i < nums.length; i++) {
15910
- reserved.add(nums[i]);
15911
- }
15912
- }
15913
- const byTier = { 1: [], 2: [], 3: [] };
15914
- for (const tag of tags) {
15915
- if (tag.status !== "active" || tag.type !== "tool")
15916
- continue;
15917
- if (tag.tagNumber > protectedCutoff)
15918
- continue;
15919
- const tier = resolveToolTier(tag.toolName);
15920
- if ((tier === 1 || tier === 2) && reserved.has(tag.tagNumber))
15921
- continue;
15922
- byTier[tier].push(tag);
15923
- }
15924
- const selected = [];
15925
- let reclaimed = 0;
15926
- outer:
15927
- for (const tier of [3, 2, 1]) {
15928
- const group = byTier[tier];
15929
- group.sort((a, b) => a.tagNumber - b.tagNumber);
15930
- for (const tag of group) {
15931
- selected.push(tag.tagNumber);
15932
- reclaimed += estimateEmergencyDropReclaimTokens(tag);
15933
- if (reclaimed >= reclaimTokens)
15934
- break outer;
15935
- }
15936
- }
15937
- if (selected.length === 0) {
15938
- return noop("no-candidates");
15939
- }
15940
- return {
15941
- shouldDrop: true,
15942
- tagNumbers: selected,
15943
- reclaimTokens,
15944
- reason: `tiered drop: ${selected.length} tags, reclaim≈${reclaimed}/${reclaimTokens} tokens (floor≈${fixedFloor}, ceiling=${Math.round(ceilingTokens)})`
15945
- };
15946
- }
15947
-
15948
- // ../plugin/src/hooks/magic-context/system-injection-stripper.ts
15949
- var SYSTEM_INJECTION_MARKERS = [
15950
- "<!-- OMO_INTERNAL_INITIATOR -->",
15951
- "[SYSTEM DIRECTIVE: MAGIC-CONTEXT",
15952
- "[SYSTEM DIRECTIVE: OH-MY-OPENCODE",
15953
- "[Category+Skill Reminder]",
15954
- "[EDIT ERROR - IMMEDIATE ACTION REQUIRED]",
15955
- "[task CALL FAILED - IMMEDIATE RETRY REQUIRED]",
15956
- "[EMERGENCY CONTEXT WINDOW WARNING]",
15957
- "Unstable background agent appears idle",
15958
- "**THE SUBAGENT JUST CLAIMED THIS TASK IS DONE."
15959
- ];
15960
- var SYSTEM_REMINDER_REGEX = /<system-reminder>[\s\S]*?<\/system-reminder>/gi;
15961
- var OMO_MARKER_REGEX = /<!-- OMO_INTERNAL_INITIATOR -->/g;
15962
- function stripSystemInjection(text) {
15963
- let hasInjection = false;
15964
- for (const marker of SYSTEM_INJECTION_MARKERS) {
15965
- if (text.includes(marker)) {
15966
- hasInjection = true;
15967
- break;
15968
- }
15969
- }
15970
- if (SYSTEM_REMINDER_REGEX.test(text))
15971
- hasInjection = true;
15972
- SYSTEM_REMINDER_REGEX.lastIndex = 0;
15973
- if (!hasInjection)
15974
- return null;
15975
- let cleaned = text;
15976
- cleaned = cleaned.replace(SYSTEM_REMINDER_REGEX, "");
15977
- cleaned = cleaned.replace(OMO_MARKER_REGEX, "");
15978
- cleaned = cleaned.replace(/\[SYSTEM DIRECTIVE: OH-MY-(?:OPENCODE|CLAUDE)[^\]]*\][\s\S]*?(?=\n\n(?!\s*[-*])|$)/g, "");
15979
- for (const marker of SYSTEM_INJECTION_MARKERS) {
15980
- if (marker.startsWith("<!-- ") || marker.startsWith("[SYSTEM DIRECTIVE"))
15981
- continue;
15982
- const idx = cleaned.indexOf(marker);
15983
- if (idx === -1)
15984
- continue;
15985
- const blockEnd = cleaned.indexOf(`
15986
-
15987
- `, idx + marker.length);
15988
- cleaned = blockEnd !== -1 ? cleaned.slice(0, idx) + cleaned.slice(blockEnd) : cleaned.slice(0, idx);
15989
- }
15990
- return cleaned.trim();
15991
- }
15992
-
15993
- // src/heuristic-cleanup-pi.ts
15994
- var DEDUP_SAFE_TOOLS = new Set([
15995
- "mcp_grep",
15996
- "mcp_read",
15997
- "mcp_glob",
15998
- "mcp_ast_grep_search",
15999
- "mcp_lsp_diagnostics",
16000
- "mcp_lsp_symbols",
16001
- "mcp_lsp_find_references",
16002
- "mcp_lsp_goto_definition",
16003
- "mcp_lsp_prepare_rename"
16004
- ]);
16005
- function buildPiToolFingerprints(messages, resolveStableId) {
16006
- const fingerprints = new Map;
16007
- for (let i = 0;i < messages.length; i++) {
16008
- const message = messages[i];
16009
- if (!message || typeof message !== "object")
16010
- continue;
16011
- const msg = message;
16012
- if (msg.role !== "assistant")
16013
- continue;
16014
- if (!Array.isArray(msg.content))
15585
+ if (!Array.isArray(msg.content))
16015
15586
  continue;
16016
15587
  const ownerMsgId = resolveStableId(message, i);
16017
15588
  if (!ownerMsgId)
@@ -16045,9 +15616,8 @@ function buildPiToolFingerprints(messages, resolveStableId) {
16045
15616
  }
16046
15617
  return fingerprints;
16047
15618
  }
16048
- function collectStaleReduceCallIds(messages, messageIdToMaxTag, toolAgeCutoff, resolveStableId) {
16049
- const composite = new Set;
16050
- const bareCallIds = new Set;
15619
+ function collectStaleReduceCallIds(messages, messageIdToMaxTag, ctxReduceTagNumbers, toolAgeCutoff, resolveStableId) {
15620
+ const reduceCalls = new Map;
16051
15621
  for (let i = 0;i < messages.length; i++) {
16052
15622
  const raw = messages[i];
16053
15623
  if (!raw || typeof raw !== "object")
@@ -16058,9 +15628,7 @@ function collectStaleReduceCallIds(messages, messageIdToMaxTag, toolAgeCutoff, r
16058
15628
  const stableId = resolveStableId(raw, i);
16059
15629
  if (!stableId)
16060
15630
  continue;
16061
- const maxTag = messageIdToMaxTag.get(stableId) ?? 0;
16062
- if (maxTag === 0 || maxTag > toolAgeCutoff)
16063
- continue;
15631
+ const ownerMaxTag = messageIdToMaxTag.get(stableId) ?? 0;
16064
15632
  for (const part of msg.content) {
16065
15633
  if (!part || typeof part !== "object")
16066
15634
  continue;
@@ -16071,10 +15639,35 @@ function collectStaleReduceCallIds(messages, messageIdToMaxTag, toolAgeCutoff, r
16071
15639
  continue;
16072
15640
  if (typeof p.id !== "string" || p.id.length === 0)
16073
15641
  continue;
16074
- composite.add(`${stableId}\x00${p.id}`);
16075
- 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
+ });
16076
15652
  }
16077
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
+ }
16078
15671
  return { composite, bareCallIds };
16079
15672
  }
16080
15673
  function applyPiHeuristicCleanup(sessionId, db, targets, piMessages, config, preloadedTags, resolveId) {
@@ -16137,7 +15730,7 @@ function applyPiHeuristicCleanup(sessionId, db, targets, piMessages, config, pre
16137
15730
  }
16138
15731
  setEmergencyDropSample(db, sessionId, emergency.currentTotalInputTokens);
16139
15732
  }
16140
- 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 };
16141
15734
  if (config.staleReduceStripEnabled && (staleReduce.composite.size > 0 || staleReduce.bareCallIds.size > 0)) {
16142
15735
  db.transaction(() => {
16143
15736
  for (const tag of tags) {
@@ -16235,42 +15828,770 @@ function applyPiHeuristicCleanup(sessionId, db, targets, piMessages, config, pre
16235
15828
  }
16236
15829
  }
16237
15830
  }
16238
- })();
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
+ }
16239
16338
  }
16240
- if (droppedTools > 0 || deduplicatedTools > 0 || droppedInjections > 0 || droppedStaleReduceCalls > 0) {
16241
- sessionLog(sessionId, `heuristic cleanup: dropped ${droppedTools} tool tags, stale ctx_reduce=${droppedStaleReduceCalls}, deduplicated ${deduplicatedTools} tool calls, dropped ${droppedInjections} system injections`);
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
+ }
16242
16360
  }
16243
- let compressedTextTags = 0;
16244
- let mutatedTextTags = 0;
16245
- if (config.caveman?.enabled) {
16246
- const cavemanResult = applyCavemanCleanup(sessionId, db, targets, tags, {
16247
- enabled: true,
16248
- minChars: config.caveman.minChars,
16249
- protectedTags: config.protectedTags
16250
- });
16251
- compressedTextTags = cavemanResult.compressedToLite + cavemanResult.compressedToFull + cavemanResult.compressedToUltra;
16252
- mutatedTextTags = cavemanResult.mutatedTextTags;
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;
16253
16399
  }
16254
16400
  return {
16255
- droppedTools,
16256
- deduplicatedTools,
16257
- droppedInjections,
16258
- droppedStaleReduceCalls,
16259
- emergencyDroppedTools,
16260
- compressedTextTags,
16261
- mutatedTextTags
16401
+ ...input.previous,
16402
+ turnDeltaU,
16403
+ turnDeltaT,
16404
+ evaluable: true,
16405
+ generationInvalidated: false,
16406
+ contentSignature: measured.contentSignature
16262
16407
  };
16263
16408
  }
16264
- function buildMessageIdToMaxTagFromTargets(targets) {
16265
- const byMessage = new Map;
16266
- for (const [tagNumber, target] of targets) {
16267
- const id = target.message?.info?.id;
16268
- if (typeof id !== "string" || id.length === 0)
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))
16269
16418
  continue;
16270
- if (tagNumber > (byMessage.get(id) ?? 0))
16271
- byMessage.set(id, tagNumber);
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
+ }
16272
16426
  }
16273
- return byMessage;
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;
16539
+ }
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);
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 });
16551
+ }
16552
+ return false;
16553
+ }
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;
16566
+ }
16567
+ }
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") {
16576
+ continue;
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
+ }
16593
+ }
16594
+ return false;
16274
16595
  }
16275
16596
 
16276
16597
  // src/inject-compartments-pi.ts
@@ -16465,6 +16786,9 @@ var EMPTY_PI_HARD_SIGNALS = {
16465
16786
  function renderBudgetIdentityPi(state2) {
16466
16787
  return `m${state2.injectionBudgetTokens ?? DEFAULT_MEMORY_BUDGET_TOKENS}-h${state2.historyBudgetTokens ?? DEFAULT_HISTORY_BUDGET_TOKENS}`;
16467
16788
  }
16789
+ function piMaterializeMismatch(reason, signal, cached, current) {
16790
+ return { value: true, reason, mismatch: { signal, cached, current } };
16791
+ }
16468
16792
  var injectionTokenCountsBySession = new Map;
16469
16793
  var cachedMuralBySession = new Map;
16470
16794
  function rememberPiMuralPayload(sessionId, dataUrl, contentHash) {
@@ -16637,38 +16961,41 @@ function mustMaterializePi(state2, db, currentCompartmentsOverride) {
16637
16961
  return { value: true, reason: "cache_invalid" };
16638
16962
  }
16639
16963
  if (cached.compartmentRenderEpoch !== current.compartmentRenderEpoch) {
16640
- return { value: true, reason: "compartment_render_epoch" };
16964
+ return piMaterializeMismatch("compartment_render_epoch", "compartmentRenderEpoch", cached.compartmentRenderEpoch, current.compartmentRenderEpoch);
16641
16965
  }
16642
- if (cached.muralEnabled !== current.muralEnabled || cached.renderBudgetIdentity !== current.renderBudgetIdentity) {
16643
- 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);
16644
16971
  }
16645
16972
  const hard = state2.hardSignals ?? EMPTY_PI_HARD_SIGNALS;
16646
16973
  const canonicalHardModelKey = piModelRefToCanonical(hard.modelKey);
16647
16974
  const canonicalCachedModelKey = piModelRefToCanonical(meta.cachedM0ModelKey ?? "");
16648
16975
  if (canonicalHardModelKey !== "" && canonicalHardModelKey !== canonicalCachedModelKey) {
16649
- return { value: true, reason: "model_change" };
16976
+ return piMaterializeMismatch("model_change", "modelKey", canonicalCachedModelKey, canonicalHardModelKey);
16650
16977
  }
16651
16978
  if (hard.systemHash !== "" && hard.systemHash !== (meta.cachedM0SystemHash ?? "")) {
16652
- return { value: true, reason: "system_hash" };
16979
+ return piMaterializeMismatch("system_hash", "systemHash", meta.cachedM0SystemHash ?? "", hard.systemHash);
16653
16980
  }
16654
16981
  if (meta.cachedM0ProjectIdentity !== null && meta.cachedM0ProjectIdentity !== state2.projectIdentity) {
16655
- return { value: true, reason: "project_change" };
16982
+ return piMaterializeMismatch("project_change", "projectIdentity", meta.cachedM0ProjectIdentity, state2.projectIdentity);
16656
16983
  }
16657
16984
  if (hard.cacheExpired && hard.lastResponseTime > 0 && hard.lastResponseTime > (meta.cachedM0MaterializedAt ?? 0)) {
16658
- return { value: true, reason: "ttl_idle" };
16985
+ return piMaterializeMismatch("ttl_idle", "lastResponseTimeAfterMaterialization", meta.cachedM0MaterializedAt ?? 0, hard.lastResponseTime);
16659
16986
  }
16660
16987
  if (cached.upgradeState !== current.upgradeState) {
16661
- return { value: true, reason: "renderer_upgrade" };
16988
+ return piMaterializeMismatch("renderer_upgrade", "upgradeState", cached.upgradeState, current.upgradeState);
16662
16989
  }
16663
16990
  if (current.workspaceFingerprint !== null || (meta.cachedM0WorkspaceFingerprint ?? null) !== null) {
16664
16991
  if (current.workspaceFingerprint !== (meta.cachedM0WorkspaceFingerprint ?? null)) {
16665
- return { value: true, reason: "project_memory_change" };
16992
+ return piMaterializeMismatch("project_memory_change", "workspaceFingerprint", meta.cachedM0WorkspaceFingerprint ?? null, current.workspaceFingerprint);
16666
16993
  }
16667
16994
  } else if (current.projectMemoryEpoch !== (meta.cachedM0ProjectMemoryEpoch ?? 0)) {
16668
- return { value: true, reason: "project_memory_change" };
16995
+ return piMaterializeMismatch("project_memory_change", "projectMemoryEpoch", meta.cachedM0ProjectMemoryEpoch ?? 0, current.projectMemoryEpoch);
16669
16996
  }
16670
16997
  if (current.maxMutationId !== (meta.cachedM0MaxMutationId ?? 0)) {
16671
- return { value: true, reason: "pending_mutations" };
16998
+ return piMaterializeMismatch("pending_mutations", "maxMutationId", meta.cachedM0MaxMutationId ?? 0, current.maxMutationId);
16672
16999
  }
16673
17000
  return { value: false, reason: null };
16674
17001
  }
@@ -17233,6 +17560,10 @@ function prependM0M1Messages(piMessages, m0, m1, mural) {
17233
17560
  function injectM0M1Pi(state2, db, piMessages, entryIds, recomputeM1ThisPass = false) {
17234
17561
  const currentCompartments = getRenderableCompartmentsPi(db, state2);
17235
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
+ }
17236
17567
  let m0 = "";
17237
17568
  let m1 = PI_M1_PLACEHOLDER;
17238
17569
  let markers = null;
@@ -17445,16 +17776,17 @@ function resolvePiWindowGeometry(args) {
17445
17776
  return;
17446
17777
  const providerID = args.model?.provider ?? "unknown";
17447
17778
  const modelID = args.model?.id ?? "unknown";
17779
+ const outputReserveOverride = resolveOutputReserve(providerID, modelID, args.reserveConfig);
17448
17780
  const result = deriveWindowGeometry(providerID, modelID, {
17449
17781
  context,
17450
17782
  output: args.model?.maxTokens
17451
17783
  }, {
17452
17784
  overlay: resolveWindowOverlayFacts(providerID, modelID, getWindowOverlay()),
17453
17785
  contextCap: isSaneLimit2(args.detectedContextLimit) ? args.detectedContextLimit : undefined,
17454
- reserveConfig: args.reserveConfig,
17786
+ outputReserveOverride,
17455
17787
  harness: "pi"
17456
17788
  });
17457
- if (!result || !isSaneLimit2(persistedUsable))
17789
+ if (!result || outputReserveOverride !== undefined || !isSaneLimit2(persistedUsable))
17458
17790
  return result;
17459
17791
  const usableSoft = Math.round(persistedUsable);
17460
17792
  return {
@@ -22011,6 +22343,11 @@ function buildMagicContextBlock(opts) {
22011
22343
  return null;
22012
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);
22013
22345
  }
22346
+ function composeMagicContextSystemPrompt(basePrompt, block) {
22347
+ return block ? `${basePrompt}
22348
+
22349
+ ${block}` : basePrompt;
22350
+ }
22014
22351
  var DATE_PATTERN = /Today's date: .+/;
22015
22352
  function processSystemPromptForCache(args) {
22016
22353
  const { db, sessionId, systemPrompt, isCacheBusting } = args;
@@ -22891,6 +23228,7 @@ var injectM0M1PiForRun = injectM0M1Pi;
22891
23228
  var persistReasoningWatermarkForRun = updateSessionMeta;
22892
23229
  var persistStableIdSchemeForRun = updateSessionMeta;
22893
23230
  var afterFallbackAdoptionForTests;
23231
+ var mutationGateObserverForTests;
22894
23232
  var DEFAULT_CLEAR_REASONING_AGE = 50;
22895
23233
  var PI_STABLE_ID_SCHEME = 1;
22896
23234
  var lastEmergencyNotificationAtMs = new Map;
@@ -24011,6 +24349,7 @@ function registerPiContextHandler(pi, baseOptions) {
24011
24349
  logTransformTiming(sessionId, "historianScheduling", tHistorianScheduling);
24012
24350
  const tPostTransform = performance.now();
24013
24351
  let outputMessages = result.messages;
24352
+ let assertTailHygieneLastWriter;
24014
24353
  const tNoteNudges = performance.now();
24015
24354
  try {
24016
24355
  if (!options.compactionOff) {
@@ -24074,60 +24413,61 @@ function registerPiContextHandler(pi, baseOptions) {
24074
24413
  try {
24075
24414
  const sessionMetaForCh1 = getOrCreateSessionMeta(options.db, sessionId);
24076
24415
  if (!options.compactionOff && !sessionMetaForCh1.isSubagent) {
24077
- const resolvedExecuteThresholdPct = resolveExecuteThreshold(schedulerConfig.executeThresholdPercentage ?? 65, liveModelBySession.get(sessionId), 65, {
24078
- tokensConfig: schedulerConfig.executeThresholdTokens,
24079
- contextLimit: usageContextLimit ?? 0
24080
- });
24081
- const historyBudgetTokens = resolveHistoryBudgetTokensForPi({
24082
- historyBudgetPercentage: options.historian?.historyBudgetPercentage,
24083
- usagePercentage,
24084
- usageInputTokens,
24085
- usageContextLimit,
24086
- executeThresholdPercentage: schedulerConfig.executeThresholdPercentage,
24087
- executeThresholdTokens: schedulerConfig.executeThresholdTokens,
24088
- 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)
24089
24427
  });
24090
- let tailToolTokens;
24091
- let liveTailTokens;
24092
- try {
24093
- const agg = getActiveTagTokenAggregate(options.db, sessionId, options.protectedTags ?? 20);
24094
- tailToolTokens = agg.toolOutput;
24095
- liveTailTokens = agg.conversation + agg.toolCall;
24096
- } catch {
24097
- const estimate = computeTailTokenEstimatePi(outputMessages);
24098
- tailToolTokens = estimate.tailToolTokens;
24099
- liveTailTokens = estimate.liveTailTokens;
24100
- }
24101
- const executeThresholdTokensPi = Math.round((usageContextLimit ?? 0) * resolvedExecuteThresholdPct / 100);
24102
- const usableTokensPi = Math.max(0, executeThresholdTokensPi - usageInputTokens + liveTailTokens);
24103
- resetLastNudgeCycleIfTailShrank(options.db, sessionId, tailToolTokens);
24104
- const oldestReclaimableToolTags = getOldestActiveUnprotectedToolTags(options.db, sessionId, options.protectedTags ?? 20);
24105
- setPiChannel1Baseline(sessionId, {
24106
- tailToolTokens,
24107
- historyBudgetTokens: historyBudgetTokens ?? 0,
24108
- contextLimit: usageContextLimit ?? 0,
24109
- executeThresholdPercentage: resolvedExecuteThresholdPct,
24110
- lastInputTokens: usageInputTokens,
24111
- turnToolTokens: 0,
24112
- 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,
24113
24433
  reducedSinceRefresh: false,
24114
24434
  oldestReclaimableToolTags
24115
- });
24116
- if (usageContextLimit && usageContextLimit > 0 && resolvedExecuteThresholdPct > 0) {
24117
- const channel2ShouldTrigger = shouldTriggerChannel2({
24118
- reclaimableTokens: tailToolTokens,
24119
- usableTokens: usableTokensPi
24120
- });
24121
- 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) {
24122
24449
  casChannel2NudgeState(options.db, sessionId, "", "pending");
24123
24450
  } else {
24124
24451
  casChannel2NudgeState(options.db, sessionId, "pending", "");
24125
24452
  }
24126
24453
  }
24454
+ assertTailHygieneLastWriter = () => assertPiTailHygieneContentUnchanged({
24455
+ messages: outputMessages,
24456
+ tags,
24457
+ protectedTags,
24458
+ stableId,
24459
+ syntheticLeadingCount: result.syntheticLeadingCount,
24460
+ expectedSignature: baseline.contentSignature
24461
+ });
24127
24462
  } else {
24128
24463
  clearPiChannel1State(sessionId);
24129
24464
  }
24130
24465
  } catch (err) {
24466
+ const stale = getPiChannel1Baseline(sessionId);
24467
+ if (stale) {
24468
+ stale.evaluable = false;
24469
+ stale.generationInvalidated = true;
24470
+ }
24131
24471
  sessionLog(sessionId, `channel1 baseline / channel2 trigger failed: ${err instanceof Error ? err.message : String(err)}`);
24132
24472
  }
24133
24473
  logTransformTiming(sessionId, "channelNudgeAccounting", tChannelAccounting);
@@ -24163,6 +24503,9 @@ function registerPiContextHandler(pi, baseOptions) {
24163
24503
  extra: `messages=${outputMessages.length} targets=${result.targetCount}`
24164
24504
  });
24165
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
+ }
24166
24509
  return { messages: outputMessages };
24167
24510
  } catch (err) {
24168
24511
  if (isFailClosedBlockingError(err) && !baseOptions.compactionOff)
@@ -24704,19 +25047,49 @@ async function runPipeline(args) {
24704
25047
  lastResponseTime: hardMeta.lastResponseTime
24705
25048
  };
24706
25049
  })() : undefined;
24707
- const m0HardFoldThisPass = args.injection && piHardSignals ? mustMaterializePi({
25050
+ const piM0State = args.injection && piHardSignals ? {
24708
25051
  sessionId: args.sessionId,
24709
25052
  projectIdentity: args.projectIdentity,
24710
25053
  projectDirectory: args.projectDirectory,
24711
25054
  memoryEnabled: args.injection.memoryEnabled,
25055
+ injectDocs: args.injection.injectDocs,
24712
25056
  injectionBudgetTokens: args.injection.injectionBudgetTokens,
24713
25057
  historyBudgetTokens: args.injection.historyBudgetTokens,
24714
- hardSignals: piHardSignals
24715
- }, 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
+ }
24716
25089
  const historianRunning = inFlightHistorian.has(args.sessionId);
24717
- const bypassHistorianGate = args.forceMaterialization === true || m0HardFoldThisPass;
25090
+ const bypassHistorianGate = args.forceMaterialization === true || foldExecutedThisPass;
24718
25091
  const hasPendingMaterializeSignal = hasPendingMaterialization(args.sessionId);
24719
- 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);
24720
25093
  const tFallbackIdentity = performance.now();
24721
25094
  const hasFallbackMessageTags = hasPiFallbackMessageTags(args.db, args.sessionId);
24722
25095
  const entryFingerprintByMessageId = buildEntryFingerprintMap(args.messages, stableIdResolver, args.reusableMessageIds, hasFallbackMessageTags);
@@ -24771,15 +25144,22 @@ async function runPipeline(args) {
24771
25144
  }
24772
25145
  const deferredMaterializationWasPending = deferredMaterializationSessions.has(args.sessionId);
24773
25146
  const deferredHistoryRefreshWasPending = deferredHistoryWasPendingAtPassStart;
24774
- const shouldReadPendingOps = !args.compactionOff && (args.schedulerDecision === "execute" || args.forceMaterialization || hasPendingMaterializeSignal || m0HardFoldThisPass || historianRunning);
25147
+ const shouldReadPendingOps = !args.compactionOff && (args.schedulerDecision === "execute" || args.forceMaterialization || hasPendingMaterializeSignal || foldExecutedThisPass || historianRunning);
24775
25148
  const pendingOps = shouldReadPendingOps ? getPendingOps(args.db, args.sessionId) : [];
24776
25149
  const pendingOperationTags = pendingOps.length > 0 ? getTagsForPendingOperations(args.db, args.sessionId, pendingOps.map((operation) => operation.tagId), args.protectedTags, RECENT_TOOL_SKELETON_WINDOW) : [];
24777
- const baseShouldApplyPendingOps = args.schedulerDecision === "execute" || args.forceMaterialization || hasPendingMaterializeSignal || m0HardFoldThisPass;
25150
+ const baseShouldApplyPendingOps = args.schedulerDecision === "execute" || args.forceMaterialization || hasPendingMaterializeSignal || foldExecutedThisPass;
24778
25151
  const deferredMaterialize = canConsumeDeferredLate && deferredMaterializationWasPending;
24779
25152
  const deferredHistoryRefresh = canConsumeDeferredLate && deferredHistoryRefreshWasPending;
24780
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
+ });
24781
25161
  if (shouldApplyPendingOps) {
24782
- 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})`;
24783
25163
  sessionLog(args.sessionId, `pending ops WILL APPLY — reason=${applyReason}, pendingOps=${pendingOps.length}, context=${args.contextUsage.percentage.toFixed(1)}%`);
24784
25164
  try {
24785
25165
  const tApplyPending = performance.now();
@@ -24857,7 +25237,7 @@ async function runPipeline(args) {
24857
25237
  const activeTags = getActiveTagsBySession(args.db, args.sessionId);
24858
25238
  logTransformTiming(args.sessionId, "getActiveTagsBySession", tActiveTags, `count=${activeTags.length}`);
24859
25239
  if (shouldRunHeuristics) {
24860
- 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})`;
24861
25241
  sessionLog(args.sessionId, `heuristics WILL RUN — reason=${reason}, context=${args.contextUsage.percentage.toFixed(1)}%, turn=n/a`);
24862
25242
  } else {
24863
25243
  const reason = args.heuristics === undefined ? "disabled" : "scheduler_defer";
@@ -25041,17 +25421,12 @@ async function runPipeline(args) {
25041
25421
  if (args.injection) {
25042
25422
  try {
25043
25423
  const tInjection = performance.now();
25044
- injectionResult = injectM0M1PiForRun({
25045
- sessionId: args.sessionId,
25046
- projectIdentity: args.projectIdentity,
25047
- projectDirectory: args.projectDirectory,
25048
- memoryEnabled: args.injection.memoryEnabled,
25049
- injectDocs: args.injection.injectDocs,
25050
- injectionBudgetTokens: args.injection.injectionBudgetTokens,
25051
- historyBudgetTokens: args.injection.historyBudgetTokens,
25052
- hardSignals: piHardSignals,
25053
- muralEnabled: args.injection.muralEnabled === true
25054
- }, 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;
25055
25430
  if (args.temporalAwareness && injectionResult.skippedVisibleMessages > 0) {
25056
25431
  const firstRetainedMessage = args.messages[injectionResult.syntheticLeadingCount];
25057
25432
  stripPiLeadingTemporalMarker(firstRetainedMessage);
@@ -26794,9 +27169,19 @@ function updateStatusLine(ctx, deps, force = false) {
26794
27169
  }
26795
27170
  function renderStatusText(ctx, db, sessionId) {
26796
27171
  const usage = ctx.getContextUsage?.();
26797
- const inputTokens = typeof usage?.tokens === "number" ? usage.tokens : undefined;
26798
- const pct = typeof usage?.percent === "number" ? usage.percent : undefined;
26799
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;
26800
27185
  const state2 = renderHistorianState(meta, recompSessions.has(sessionId));
26801
27186
  return `mc: ${inputTokens === undefined ? "--" : fmt(inputTokens)} (${pct === undefined ? "--" : `${Math.round(pct)}%`}) · ${state2}`;
26802
27187
  }
@@ -26816,7 +27201,10 @@ function renderHistorianState(meta, recompActive) {
26816
27201
  }
26817
27202
  function readSessionMetaStatus(db, sessionId) {
26818
27203
  try {
26819
- 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);
26820
27208
  } catch {
26821
27209
  return;
26822
27210
  }
@@ -27597,6 +27985,44 @@ function formatThresholdClampNote(opts) {
27597
27985
  return ` [clamped: ${opts.configuredValue}% > ${opts.maxPercentage}%]`;
27598
27986
  }
27599
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
+
27600
28026
  // ../plugin/src/shared/format-bytes.ts
27601
28027
  function formatBytes(bytes) {
27602
28028
  if (bytes < 1024)
@@ -27625,7 +28051,7 @@ function formatExecuteThreshold(detail, contextLimit) {
27625
28051
  }
27626
28052
  return `${percentage}%${clampNote}`;
27627
28053
  }
27628
- function executeStatus(db, sessionId, protectedTags, executeThresholdPercentageConfig = DEFAULT_EXECUTE_THRESHOLD_PERCENTAGE, liveModelKey, historyBudgetPercentage, commitClusterTrigger, executeThresholdTokens, contextLimit, dreamer, windowGeometry) {
28054
+ function executeStatus(db, sessionId, protectedTags, executeThresholdPercentageConfig = DEFAULT_EXECUTE_THRESHOLD_PERCENTAGE, liveModelKey, historyBudgetPercentage, commitClusterTrigger, executeThresholdTokens, contextLimit, dreamer, windowGeometry, tailHygiene) {
27629
28055
  const thresholdDetail = resolveExecuteThresholdDetail(executeThresholdPercentageConfig, liveModelKey, DEFAULT_EXECUTE_THRESHOLD_PERCENTAGE, {
27630
28056
  tokensConfig: executeThresholdTokens,
27631
28057
  contextLimit,
@@ -27680,6 +28106,9 @@ function executeStatus(db, sessionId, protectedTags, executeThresholdPercentageC
27680
28106
  `**Protected tags:** ${protectedTags}`,
27681
28107
  `**Subagent session:** ${meta.isSubagent}`
27682
28108
  ];
28109
+ if (tailHygiene !== undefined) {
28110
+ lines.push("", "### Tail Hygiene", `- Reclaimable / eligible: ${formatTailHygiene(tailHygiene)}`, "- Reasoning is excluded from both terms.");
28111
+ }
27683
28112
  if (dreamer?.backlog && Object.keys(dreamer.backlog).length > 0) {
27684
28113
  lines.push("", "### Dreamer", ...dreamer.progress ? [
27685
28114
  `- Running: ${dreamer.progress.task} — ${dreamer.progress.processed}/${dreamer.progress.total} processed`
@@ -27787,7 +28216,7 @@ ${c.content}
27787
28216
  // package.json
27788
28217
  var package_default = {
27789
28218
  name: "@cortexkit/pi-magic-context",
27790
- version: "0.37.0",
28219
+ version: "0.38.0",
27791
28220
  type: "module",
27792
28221
  description: "Pi and OMP coding agent extension for Magic Context — cross-session memory and context management",
27793
28222
  main: "dist/index.js",
@@ -27838,8 +28267,9 @@ var package_default = {
27838
28267
  },
27839
28268
  devDependencies: {
27840
28269
  "@biomejs/biome": "^2.5.1",
27841
- "@earendil-works/pi-coding-agent": "^0.80.2",
27842
- "@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",
27843
28273
  "@types/better-sqlite3": "^7.6.13",
27844
28274
  "@types/bun": "^1.3.10",
27845
28275
  "@types/node": "^22.20.0",
@@ -27956,9 +28386,12 @@ function renderInner(s, theme, innerWidth) {
27956
28386
  lines.push("");
27957
28387
  lines.push(`Context ${theme.fg(pctColor, theme.bold(`${s.usagePercentage.toFixed(1)}%`))} · ${fmt2(s.inputTokens)} / ${s.contextLimit > 0 ? fmt2(s.contextLimit) : "?"} tokens`);
27958
28388
  if (s.windowGeometry) {
27959
- lines.push(formatWindowDerivationLine(s.inputTokens, s.windowGeometry));
28389
+ lines.push(formatWindowDerivationLine(s.inputTokens, s.windowGeometry).replace(/^Context:.* — window /, "Window "));
27960
28390
  }
27961
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
+ }
27962
28395
  lines.push(renderBar(s, innerWidth));
27963
28396
  for (const seg of breakdownSegments(s)) {
27964
28397
  const pct = (seg.tokens / (s.inputTokens || 1) * 100).toFixed(1);
@@ -27966,6 +28399,7 @@ function renderInner(s, theme, innerWidth) {
27966
28399
  const right = theme.fg("muted", `${fmt2(seg.tokens)} (${pct}%)`);
27967
28400
  lines.push(`${left} ${right}`);
27968
28401
  }
28402
+ lines.push("* Conversation includes model Reasoning; hygiene excludes it.");
27969
28403
  lines.push("");
27970
28404
  lines.push(`Counts: ${s.compartmentCount} compartments · ${s.memoryCount} memories (${s.memoryBlockCount} injected) · ${s.sessionNoteCount + s.readySmartNoteCount} notes`);
27971
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"}`)}` : ""}`);
@@ -28075,6 +28509,7 @@ ${safeStringify(tool.parameters)}`);
28075
28509
  } catch {}
28076
28510
  const conversationTokens = Math.max(0, inputTokens - systemPromptTokens - compartmentTokens - factTokens - memoryTokens - docsTokens - profileTokens - toolCallTokens - toolDefinitionTokens);
28077
28511
  const workMetrics = getSessionWorkMetrics(deps.db, sessionId);
28512
+ const tailHygiene = resolveTailHygieneStatus(getPiChannel1Baseline(sessionId));
28078
28513
  const modelKey = ctx.model ? `${ctx.model.provider}/${ctx.model.id}` : undefined;
28079
28514
  const threshold = resolveExecuteThresholdDetail(deps.executeThresholdPercentage ?? 65, modelKey, 65, {
28080
28515
  tokensConfig: deps.executeThresholdTokens,
@@ -28148,6 +28583,7 @@ ${safeStringify(tool.parameters)}`);
28148
28583
  conversationTokens,
28149
28584
  toolCallTokens,
28150
28585
  toolDefinitionTokens,
28586
+ ...tailHygiene === undefined ? {} : { tailHygiene },
28151
28587
  newWorkTokens: workMetrics.newWorkTokens,
28152
28588
  totalInputTokens: workMetrics.totalInputTokens,
28153
28589
  upgradeNeededCount: safeRead(() => countCompartmentsNeedingUpgrade(deps.db, sessionId), 0),
@@ -28195,7 +28631,7 @@ function breakdownSegments(s) {
28195
28631
  });
28196
28632
  if (s.conversationTokens > 0)
28197
28633
  segs.push({
28198
- label: "Conversation",
28634
+ label: "Conversation*",
28199
28635
  tokens: s.conversationTokens,
28200
28636
  color: COLORS.conversation
28201
28637
  });
@@ -28326,7 +28762,7 @@ No active Pi session is available.`,
28326
28762
  const usableContextLimit = windowGeometry?.usableSoft;
28327
28763
  const statusText = executeStatus(currentDeps.db, sessionId, currentDeps.protectedTags ?? 20, currentDeps.executeThresholdPercentage, modelKey, currentDeps.historyBudgetPercentage, currentDeps.commitClusterTrigger, currentDeps.executeThresholdTokens, usableContextLimit, {
28328
28764
  backlog: getDreamTaskBacklogs(currentDeps.db, currentDeps.projectIdentity, CANONICAL_DREAM_TASKS)
28329
- }, windowGeometry);
28765
+ }, windowGeometry, resolveTailHygieneStatus(getPiChannel1Baseline(sessionId)));
28330
28766
  const details = buildStatusDetails(currentDeps, sessionId);
28331
28767
  sendCtxStatusMessage(pi, { title: "/ctx-status", text: statusText, level: "info" }, details);
28332
28768
  } catch (error) {
@@ -29207,10 +29643,7 @@ async function src_default(pi) {
29207
29643
  return;
29208
29644
  }
29209
29645
  const migration = getMigrationOnOpenRefusal();
29210
- const blockingProcesses = migration?.serverPids.map((pid) => ({
29211
- harness: "OpenCode server",
29212
- pid
29213
- })) ?? [];
29646
+ const blockingProcesses = migration?.blockingProcesses ?? migration?.serverPids.map((pid) => ({ kind: "process", pid })) ?? [];
29214
29647
  const fence = getSchemaFenceRejection();
29215
29648
  const reason = migration && blockingProcesses.length > 0 ? {
29216
29649
  kind: "migration_guard",
@@ -29761,9 +30194,7 @@ async function startPiMagicContextRuntime(pi, database, dbPath) {
29761
30194
  isCacheBusting,
29762
30195
  existingSystemPrompt: event.systemPrompt
29763
30196
  });
29764
- const composedPrompt = block ? `${event.systemPrompt}
29765
-
29766
- ${block}` : event.systemPrompt;
30197
+ const composedPrompt = composeMagicContextSystemPrompt(event.systemPrompt, block);
29767
30198
  if (!sessionId) {
29768
30199
  if (block)
29769
30200
  return { systemPrompt: composedPrompt };
@@ -29853,14 +30284,14 @@ ${block}` : event.systemPrompt;
29853
30284
  return;
29854
30285
  if (compactionOff)
29855
30286
  return;
29856
- if (db)
29857
- maybeDeliverChannel2Pi(pi, db, sessionId, "steer");
29858
30287
  const block = maybeChannel1ReminderForToolResult({
29859
30288
  db,
29860
30289
  sessionId,
29861
30290
  toolName: event.toolName,
29862
30291
  content: event.content
29863
30292
  });
30293
+ if (db)
30294
+ maybeDeliverChannel2Pi(pi, db, sessionId);
29864
30295
  if (!block)
29865
30296
  return;
29866
30297
  return { content: [...event.content, block] };