@cortexkit/opencode-magic-context 0.42.1 → 0.42.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. package/dist/features/magic-context/dreamer/expire-memories.d.ts +15 -0
  2. package/dist/features/magic-context/dreamer/expire-memories.d.ts.map +1 -0
  3. package/dist/features/magic-context/dreamer/module-apply.d.ts +4 -2
  4. package/dist/features/magic-context/dreamer/module-apply.d.ts.map +1 -1
  5. package/dist/features/magic-context/dreamer/task-executor.d.ts.map +1 -1
  6. package/dist/features/magic-context/dreamer/task-gates.d.ts +6 -1
  7. package/dist/features/magic-context/dreamer/task-gates.d.ts.map +1 -1
  8. package/dist/features/magic-context/pi-content-decisions.d.ts.map +1 -1
  9. package/dist/features/magic-context/storage-meta-persisted.d.ts +4 -0
  10. package/dist/features/magic-context/storage-meta-persisted.d.ts.map +1 -1
  11. package/dist/hooks/magic-context/apply-operations.d.ts.map +1 -1
  12. package/dist/hooks/magic-context/compaction-marker-manager.d.ts +4 -6
  13. package/dist/hooks/magic-context/compaction-marker-manager.d.ts.map +1 -1
  14. package/dist/hooks/magic-context/lkg-persist.d.ts.map +1 -1
  15. package/dist/hooks/magic-context/lkg-slot.d.ts +2 -0
  16. package/dist/hooks/magic-context/lkg-slot.d.ts.map +1 -1
  17. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts +1 -0
  18. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
  19. package/dist/{index-1q9kay7n.js → index-953x7a79.js} +31 -24
  20. package/dist/index.js +318 -112
  21. package/dist/plugin/dream-timer-module-client.d.ts +2 -2
  22. package/dist/plugin/dream-timer-module-client.d.ts.map +1 -1
  23. package/dist/{recomp-orchestrator-m33b3rk9.js → recomp-orchestrator-5g8f5rhy.js} +1 -1
  24. package/dist/shared/transcript.d.ts +2 -1
  25. package/dist/shared/transcript.d.ts.map +1 -1
  26. package/package.json +1 -1
  27. package/src/shared/tag-transcript.ts +14 -7
  28. package/src/shared/transcript.ts +2 -1
package/dist/index.js CHANGED
@@ -296,6 +296,8 @@ import {
296
296
  clearDetectedContextLimit,
297
297
  getPersistedCompactionMarkerState,
298
298
  setPersistedCompactionMarkerState,
299
+ getDeferredClearedCompactionMarkerState,
300
+ retireDeferredClearedCompactionMarkerState,
299
301
  getStrippedPlaceholderIds,
300
302
  applyStrippedPlaceholderDelta,
301
303
  removeStrippedPlaceholderId,
@@ -540,7 +542,7 @@ import {
540
542
  setRecompTerminal2,
541
543
  runManagedRecomp2,
542
544
  runManagedUpgrade2
543
- } from "./index-1q9kay7n.js";
545
+ } from "./index-953x7a79.js";
544
546
  import {
545
547
  stripJsonComments,
546
548
  isPrototypePollutionKey,
@@ -16893,6 +16895,116 @@ Output exactly JSON: {"met": false}`;
16893
16895
  }
16894
16896
  }
16895
16897
 
16898
+ // src/features/magic-context/dreamer/expire-memories.ts
16899
+ var MODULE_ARCHIVE_BATCH_SIZE = 100;
16900
+ var EXPIRED_ARCHIVE_REASON = "expired";
16901
+ function getExpiredActiveMemoryIds(db, projectIdentity, now = Date.now()) {
16902
+ const rows = db.prepare(`SELECT id
16903
+ FROM memories
16904
+ WHERE project_path = ?
16905
+ AND status = 'active'
16906
+ AND expires_at IS NOT NULL
16907
+ AND expires_at <= ?
16908
+ ORDER BY id`).all(projectIdentity, now);
16909
+ return rows.map((row) => row.id);
16910
+ }
16911
+ function assertSuccessfulModuleArchive(response) {
16912
+ const result = response && typeof response === "object" && "result" in response ? response.result : response;
16913
+ if (result && typeof result === "object") {
16914
+ const record = result;
16915
+ if (record.ok === false || record.error) {
16916
+ throw new Error("module rejected expired-memory archive");
16917
+ }
16918
+ }
16919
+ }
16920
+ async function archiveExpiredThroughModule(args) {
16921
+ if (!args.moduleRoute.moduleClient.mirrorPull) {
16922
+ throw new DreamerModuleFailureError("mirror.pull expired archive", new Error("Rust dreamer client omitted the memory mirror route"));
16923
+ }
16924
+ for (let offset = 0;offset < args.expiredContextIds.length; offset += MODULE_ARCHIVE_BATCH_SIZE) {
16925
+ if (!leaseOwnershipMatches(args.db, args.holderId, args.leaseAcquisition.generation, args.leaseKey)) {
16926
+ throw new Error("Dream lease lost before expired-memory archive");
16927
+ }
16928
+ const contextBatch = args.expiredContextIds.slice(offset, offset + MODULE_ARCHIVE_BATCH_SIZE);
16929
+ const identities = getModuleMemoryIdentities(args.db, args.projectIdentity, contextBatch);
16930
+ if (identities.size !== contextBatch.length) {
16931
+ throw new DreamerModuleFailureError("ctx_memory expired archive", new Error("expired memory is missing its module mirror identity"));
16932
+ }
16933
+ const moduleBatch = contextBatch.map((id) => {
16934
+ const identity = identities.get(id);
16935
+ if (!identity)
16936
+ throw new Error(`missing module identity for expired memory ${id}`);
16937
+ return identity.moduleId;
16938
+ });
16939
+ try {
16940
+ const response = await args.moduleRoute.moduleClient.call({
16941
+ sessionId: args.moduleRoute.moduleSessionId,
16942
+ projectRoot: args.moduleRoute.moduleProjectRoot,
16943
+ method: "ctx_memory",
16944
+ body: {
16945
+ name: "ctx_memory",
16946
+ arguments: {
16947
+ action: "archive",
16948
+ memory_project: args.projectIdentity,
16949
+ ids: moduleBatch,
16950
+ reason: EXPIRED_ARCHIVE_REASON,
16951
+ command_id: `${args.moduleRoute.moduleCommandId}:expire:${offset / MODULE_ARCHIVE_BATCH_SIZE}`
16952
+ }
16953
+ }
16954
+ });
16955
+ assertSuccessfulModuleArchive(response);
16956
+ } catch (error) {
16957
+ throw new DreamerModuleFailureError("ctx_memory expired archive", error);
16958
+ }
16959
+ }
16960
+ const mirrorPull = args.moduleRoute.moduleClient.mirrorPull;
16961
+ const drained = await drainMirrorPages({
16962
+ db: args.db,
16963
+ module: {
16964
+ mirrorPull: (request) => mirrorPull({ ...request, projectRoot: args.moduleRoute.moduleProjectRoot })
16965
+ },
16966
+ domain: "memories",
16967
+ limit: 1000
16968
+ });
16969
+ if (!drained.complete) {
16970
+ throw new DreamerModuleFailureError("mirror.pull expired archive", new Error("memory mirror did not reach the module cursor"));
16971
+ }
16972
+ if (!leaseOwnershipMatches(args.db, args.holderId, args.leaseAcquisition.generation, args.leaseKey)) {
16973
+ throw new Error("Dream lease lost during expired-memory archive");
16974
+ }
16975
+ return args.expiredContextIds.length;
16976
+ }
16977
+ async function archiveExpiredMemories(args) {
16978
+ const expiredContextIds = getExpiredActiveMemoryIds(args.db, args.projectIdentity, args.now);
16979
+ if (expiredContextIds.length === 0) {
16980
+ if (!leaseOwnershipMatches(args.db, args.holderId, args.leaseAcquisition.generation, args.leaseKey)) {
16981
+ throw new Error("Dream lease lost before expired-memory probe");
16982
+ }
16983
+ return 0;
16984
+ }
16985
+ if (args.moduleRoute) {
16986
+ return archiveExpiredThroughModule({
16987
+ ...args,
16988
+ expiredContextIds,
16989
+ moduleRoute: args.moduleRoute
16990
+ });
16991
+ }
16992
+ const selectedIds = new Set(expiredContextIds);
16993
+ return runLeaseGuardedWrite(args.db, args.holderId, args.leaseKey, () => {
16994
+ const stillExpired = getExpiredActiveMemoryIds(args.db, args.projectIdentity, args.now).filter((id) => selectedIds.has(id));
16995
+ for (const id of stillExpired) {
16996
+ archiveMemory(args.db, id, EXPIRED_ARCHIVE_REASON);
16997
+ queueMemoryMutation(args.db, {
16998
+ projectPath: args.projectIdentity,
16999
+ mutationType: "archive",
17000
+ targetMemoryId: id,
17001
+ queuedAt: args.now
17002
+ });
17003
+ }
17004
+ return stillExpired.length;
17005
+ });
17006
+ }
17007
+
16896
17008
  // src/features/magic-context/dreamer/maintain-docs-protected-enforcement.ts
16897
17009
  import { existsSync as existsSync7, readFileSync as readFileSync5, writeFileSync as writeFileSync4 } from "node:fs";
16898
17010
  import { join as join7 } from "node:path";
@@ -18202,14 +18314,25 @@ function countActiveMemories(db, projectPath) {
18202
18314
  const row = db.prepare("SELECT COUNT(*) AS cnt FROM memories WHERE project_path = ? AND status IN ('active','permanent')").get(projectPath);
18203
18315
  return row?.cnt ?? 0;
18204
18316
  }
18317
+ function countLiveMemories(db, projectPath, options = {}) {
18318
+ const unclassified = options.unclassifiedOnly && hasMemoryClassifiedAtColumn(db);
18319
+ const row = db.prepare(`SELECT COUNT(*) AS cnt
18320
+ FROM memories
18321
+ WHERE project_path = ?
18322
+ AND status IN ('active','permanent')
18323
+ AND (expires_at IS NULL OR expires_at > ?)
18324
+ ${unclassified ? "AND classified_at IS NULL" : ""}`).get(projectPath, Date.now());
18325
+ return row?.cnt ?? 0;
18326
+ }
18205
18327
  function countUnmappedActiveMemories(db, projectPath) {
18206
18328
  const row = db.prepare(`SELECT COUNT(*) AS cnt
18207
18329
  FROM memories m
18208
18330
  WHERE m.project_path = ?
18209
18331
  AND m.status IN ('active','permanent')
18332
+ AND (m.expires_at IS NULL OR m.expires_at > ?)
18210
18333
  AND NOT EXISTS (
18211
18334
  SELECT 1 FROM memory_verifications v WHERE v.memory_id = m.id
18212
- )`).get(projectPath);
18335
+ )`).get(projectPath, Date.now());
18213
18336
  return row?.cnt ?? 0;
18214
18337
  }
18215
18338
  function countCompartmentsSince(db, projectPath, since) {
@@ -18229,7 +18352,8 @@ function countMappedMemories(db, projectPath) {
18229
18352
  JOIN memory_verifications v ON v.memory_id = m.id
18230
18353
  WHERE m.project_path = ?
18231
18354
  AND m.status IN ('active','permanent')
18232
- AND v.file_path <> ''`).get(projectPath);
18355
+ AND (m.expires_at IS NULL OR m.expires_at > ?)
18356
+ AND v.file_path <> ''`).get(projectPath, Date.now());
18233
18357
  return row?.cnt ?? 0;
18234
18358
  }
18235
18359
  function countUnverifiedMappedMemories(db, projectPath) {
@@ -18238,8 +18362,9 @@ function countUnverifiedMappedMemories(db, projectPath) {
18238
18362
  JOIN memory_verifications v ON v.memory_id = m.id
18239
18363
  WHERE m.project_path = ?
18240
18364
  AND m.status IN ('active','permanent')
18365
+ AND (m.expires_at IS NULL OR m.expires_at > ?)
18241
18366
  AND v.file_path <> ''
18242
- AND v.verified_at = 0`).get(projectPath);
18367
+ AND v.verified_at = 0`).get(projectPath, Date.now());
18243
18368
  return row?.cnt ?? 0;
18244
18369
  }
18245
18370
  function countBroadCycleCandidates(db, projectPath, cycleStartAt) {
@@ -18247,22 +18372,24 @@ function countBroadCycleCandidates(db, projectPath, cycleStartAt) {
18247
18372
  FROM memories m
18248
18373
  WHERE m.project_path = ?
18249
18374
  AND m.status IN ('active','permanent')
18375
+ AND (m.expires_at IS NULL OR m.expires_at > ?)
18250
18376
  AND (
18251
18377
  SELECT MAX(v.verified_at)
18252
18378
  FROM memory_verifications v
18253
18379
  WHERE v.memory_id = m.id
18254
18380
  AND v.file_path <> ''
18255
- ) < ?`).get(projectPath, cycleStartAt);
18381
+ ) < ?`).get(projectPath, Date.now(), cycleStartAt);
18256
18382
  return row?.cnt ?? 0;
18257
18383
  }
18258
18384
  function countCueCandidates(db, projectPath) {
18259
18385
  if (!hasMuralCueColumns(db))
18260
- return countActiveMemories(db, projectPath);
18386
+ return countLiveMemories(db, projectPath);
18261
18387
  const row = db.prepare(`SELECT COUNT(*) AS cnt
18262
18388
  FROM memories
18263
18389
  WHERE project_path = ?
18264
18390
  AND status IN ('active','permanent')
18265
- AND (mural_cue IS NULL OR mural_cue_hash IS NULL OR updated_at > mural_cue_at)`).get(projectPath);
18391
+ AND (expires_at IS NULL OR expires_at > ?)
18392
+ AND (mural_cue IS NULL OR mural_cue_hash IS NULL OR updated_at > mural_cue_at)`).get(projectPath, Date.now());
18266
18393
  return row?.cnt ?? 0;
18267
18394
  }
18268
18395
  function countStalePrimers(db, projectPath) {
@@ -18274,16 +18401,6 @@ function countStalePrimers(db, projectPath) {
18274
18401
  OR last_observed_at > answer_refreshed_at)`).get(projectPath);
18275
18402
  return row?.cnt ?? 0;
18276
18403
  }
18277
- function countUnclassifiedActiveMemories(db, projectPath) {
18278
- if (!hasMemoryClassifiedAtColumn(db))
18279
- return countActiveMemories(db, projectPath);
18280
- const row = db.prepare(`SELECT COUNT(*) AS cnt
18281
- FROM memories
18282
- WHERE project_path = ?
18283
- AND status IN ('active','permanent')
18284
- AND classified_at IS NULL`).get(projectPath);
18285
- return row?.cnt ?? 0;
18286
- }
18287
18404
  function countPendingSmartNotes(db, projectPath) {
18288
18405
  const row = db.prepare("SELECT COUNT(*) AS cnt FROM notes WHERE project_path = ? AND type = 'smart' AND status = 'pending'").get(projectPath);
18289
18406
  return row?.cnt ?? 0;
@@ -18299,7 +18416,7 @@ function countActivePrimers(db, projectPath) {
18299
18416
  function getDreamTaskBacklog(db, projectPath, task, options = {}) {
18300
18417
  switch (task) {
18301
18418
  case "map-memories": {
18302
- const total = countActiveMemories(db, projectPath);
18419
+ const total = countLiveMemories(db, projectPath);
18303
18420
  return { pending: countUnmappedActiveMemories(db, projectPath), total };
18304
18421
  }
18305
18422
  case "verify": {
@@ -18315,16 +18432,19 @@ function getDreamTaskBacklog(db, projectPath, task, options = {}) {
18315
18432
  return { pending, total };
18316
18433
  }
18317
18434
  case "curate": {
18318
- const total = countActiveMemories(db, projectPath);
18435
+ const total = countLiveMemories(db, projectPath);
18319
18436
  return { pending: total, total };
18320
18437
  }
18321
18438
  case "compress-cues": {
18322
- const total = countActiveMemories(db, projectPath);
18439
+ const total = countLiveMemories(db, projectPath);
18323
18440
  return { pending: countCueCandidates(db, projectPath), total };
18324
18441
  }
18325
18442
  case "classify-memories": {
18326
- const total = countActiveMemories(db, projectPath);
18327
- return { pending: countUnclassifiedActiveMemories(db, projectPath), total };
18443
+ const total = countLiveMemories(db, projectPath);
18444
+ return {
18445
+ pending: countLiveMemories(db, projectPath, { unclassifiedOnly: true }),
18446
+ total
18447
+ };
18328
18448
  }
18329
18449
  case "retrospective": {
18330
18450
  const pending = countProjectSessionsSince(db, projectPath, options.retrospectiveWatermarkMs ?? null);
@@ -18369,15 +18489,15 @@ function evaluateTaskGate(task, ctx) {
18369
18489
  case "map-memories":
18370
18490
  return countUnmappedActiveMemories(db, project) > 0;
18371
18491
  case "verify":
18372
- return countActiveMemories(db, project) > 0;
18492
+ return countLiveMemories(db, project) > 0;
18373
18493
  case "verify-broad":
18374
- return getTaskScheduleState(db, project, "verify-broad")?.lastBroadRunAt != null || countActiveMemories(db, project) > 0;
18494
+ return getTaskScheduleState(db, project, "verify-broad")?.lastBroadRunAt != null || countLiveMemories(db, project) > 0;
18375
18495
  case "curate":
18376
18496
  return countActiveMemories(db, project) > 0;
18377
18497
  case "compress-cues":
18378
- return countActiveMemories(db, project) > 0;
18498
+ return countLiveMemories(db, project) > 0;
18379
18499
  case "classify-memories":
18380
- return countActiveMemories(db, project) > 0;
18500
+ return countLiveMemories(db, project) > 0;
18381
18501
  case "retrospective":
18382
18502
  return countProjectSessionsSince(db, project, ctx.retrospectiveWatermarkMs ?? null) > 0;
18383
18503
  case "maintain-docs":
@@ -19115,6 +19235,9 @@ function inspectCurateMemoryOperations(messages) {
19115
19235
  }
19116
19236
  return summary;
19117
19237
  }
19238
+ function formatExpiredArchiveProgress(count) {
19239
+ return `curate: archived ${count} expired ${count === 1 ? "memory" : "memories"}`;
19240
+ }
19118
19241
  function formatCurateMemoryOperations(actions) {
19119
19242
  const actionCounts = new Map;
19120
19243
  for (const action of actions)
@@ -19165,7 +19288,7 @@ function createDreamTaskExecutor(deps) {
19165
19288
  };
19166
19289
  const parent = await resolveParentSessionId();
19167
19290
  let moduleRoute;
19168
- if (config.task === "map-memories" || config.task === "compress-cues" || config.task === "classify-memories" || config.task === "verify" || config.task === "verify-broad" || config.task === "retrospective") {
19291
+ if (config.task === "curate" || config.task === "map-memories" || config.task === "compress-cues" || config.task === "classify-memories" || config.task === "verify" || config.task === "verify-broad" || config.task === "retrospective") {
19169
19292
  try {
19170
19293
  moduleRoute = await resolveDreamerModuleRoute({
19171
19294
  db,
@@ -19494,7 +19617,9 @@ function createDreamTaskExecutor(deps) {
19494
19617
  parent,
19495
19618
  recordRun,
19496
19619
  computeMemoryDelta,
19497
- reportProgress
19620
+ reportProgress,
19621
+ leaseAcquisition,
19622
+ moduleRoute
19498
19623
  });
19499
19624
  } catch (error) {
19500
19625
  const { transient, brief } = classifyFailure(error);
@@ -19795,17 +19920,6 @@ async function runAgenticTask(config, ctx, helpers) {
19795
19920
  architecture: existsSync9(`${docsDir}/ARCHITECTURE.md`),
19796
19921
  structure: existsSync9(`${docsDir}/STRUCTURE.md`)
19797
19922
  } : undefined;
19798
- let curateMemories;
19799
- if (task === "curate") {
19800
- curateMemories = loadActiveMemoryPromptMemories(db, projectIdentity);
19801
- log(`[dreamer] curate pool: in_scope=${curateMemories.length}`);
19802
- }
19803
- const taskPrompt = buildDreamTaskPrompt(task, {
19804
- projectPath: projectIdentity,
19805
- lastDreamAt: lastRunAt ? String(lastRunAt) : null,
19806
- existingDocs,
19807
- curate: curateMemories ? { memories: curateMemories } : undefined
19808
- });
19809
19923
  const abortController = new AbortController;
19810
19924
  let leaseLost = false;
19811
19925
  const heartbeat = startLeaseHeartbeat(db, holderId, leaseKey, () => {
@@ -19814,7 +19928,37 @@ async function runAgenticTask(config, ctx, helpers) {
19814
19928
  }, ctx.leaseAcquisition);
19815
19929
  let childSessionId = null;
19816
19930
  let promptSettled = false;
19931
+ let expiredArchived = 0;
19817
19932
  try {
19933
+ let curateMemories;
19934
+ if (task === "curate") {
19935
+ expiredArchived = await archiveExpiredMemories({
19936
+ db,
19937
+ projectIdentity,
19938
+ holderId,
19939
+ leaseKey,
19940
+ leaseAcquisition: helpers.leaseAcquisition,
19941
+ moduleRoute: helpers.moduleRoute
19942
+ });
19943
+ if (leaseLost)
19944
+ throw new Error("Dream lease lost during expired-memory archive");
19945
+ curateMemories = loadActiveMemoryPromptMemories(db, projectIdentity);
19946
+ log(`[dreamer] curate pool: in_scope=${curateMemories.length} expired_archived=${expiredArchived}`);
19947
+ if (curateMemories.length === 0 && expiredArchived > 0) {
19948
+ const progress = formatExpiredArchiveProgress(expiredArchived);
19949
+ helpers.recordRun("completed", null, {
19950
+ memoryChanges: helpers.computeMemoryDelta(memoryBefore),
19951
+ progress
19952
+ });
19953
+ return { status: "completed", detail: progress };
19954
+ }
19955
+ }
19956
+ const taskPrompt = buildDreamTaskPrompt(task, {
19957
+ projectPath: projectIdentity,
19958
+ lastDreamAt: lastRunAt ? String(lastRunAt) : null,
19959
+ existingDocs,
19960
+ curate: curateMemories ? { memories: curateMemories } : undefined
19961
+ });
19818
19962
  const createResponse = await createChildSessionWithFence({
19819
19963
  client: deps.client,
19820
19964
  db,
@@ -19906,6 +20050,7 @@ async function runAgenticTask(config, ctx, helpers) {
19906
20050
  }
19907
20051
  const curateOutput = task === "curate" ? run.validated : undefined;
19908
20052
  const progress = [
20053
+ expiredArchived > 0 ? formatExpiredArchiveProgress(expiredArchived) : null,
19909
20054
  curateOutput && curateOutput.memoryOperations.completedActions.length > 0 ? formatCurateMemoryOperations(curateOutput.memoryOperations.completedActions) : null,
19910
20055
  curateRefused > 0 ? `curate: refused ${curateRefused} unsafe mutation(s)` : null
19911
20056
  ].filter((value) => Boolean(value)).join("; ");
@@ -20922,7 +21067,13 @@ function createDreamTimerModuleClient(moduleClient) {
20922
21067
  }
20923
21068
  return moduleClient.authorityStatus(args);
20924
21069
  } : undefined,
20925
- call: (args) => moduleClient.call(args)
21070
+ call: (args) => moduleClient.call(args),
21071
+ mirrorPull: moduleClient.mirrorPull ? (args) => {
21072
+ if (!moduleClient.mirrorPull) {
21073
+ throw new Error("Rust module mirror route became unavailable");
21074
+ }
21075
+ return moduleClient.mirrorPull(args);
21076
+ } : undefined
20926
21077
  };
20927
21078
  }
20928
21079
 
@@ -29343,7 +29494,7 @@ function registerRpcHandlers(rpcServer, args) {
29343
29494
  const db = getDb();
29344
29495
  if (!db)
29345
29496
  return { ok: false, error: "db unavailable" };
29346
- const { runManagedRecomp } = await import("./recomp-orchestrator-m33b3rk9.js");
29497
+ const { runManagedRecomp } = await import("./recomp-orchestrator-5g8f5rhy.js");
29347
29498
  const { sendIgnoredMessage } = await import("./send-session-notification-1qeqkswb.js");
29348
29499
  log(`[rpc] recomp requested for session ${sessionId}`);
29349
29500
  const ctx = await buildManagedCtx(db);
@@ -29362,7 +29513,7 @@ function registerRpcHandlers(rpcServer, args) {
29362
29513
  const db = getDb();
29363
29514
  if (!db)
29364
29515
  return { ok: false, error: "db unavailable" };
29365
- const { runManagedUpgrade } = await import("./recomp-orchestrator-m33b3rk9.js");
29516
+ const { runManagedUpgrade } = await import("./recomp-orchestrator-5g8f5rhy.js");
29366
29517
  const { sendIgnoredMessage } = await import("./send-session-notification-1qeqkswb.js");
29367
29518
  log(`[rpc] session-upgrade requested for session ${sessionId}`);
29368
29519
  const ctx = await buildManagedCtx(db);
@@ -30410,13 +30561,38 @@ function parsePersistedLkgSlot(row) {
30410
30561
  const jsonPrefix = record.json_prefix;
30411
30562
  const lastInputMessageId = record.last_input_message_id;
30412
30563
  const capturedAt = record.captured_at;
30413
- const inputIdSeq = parseStringArray(record.input_id_seq);
30564
+ let inputIdsRaw = record.input_id_seq;
30565
+ let piOutputEntryIds;
30566
+ if (typeof inputIdsRaw === "string") {
30567
+ try {
30568
+ const metadata = JSON.parse(inputIdsRaw);
30569
+ if (metadata && !Array.isArray(metadata) && metadata.version === 1 && Array.isArray(metadata.piOutputEntryIds)) {
30570
+ if (!metadata.piOutputEntryIds.every((id) => id === null || typeof id === "string" && id.length > 0))
30571
+ return;
30572
+ piOutputEntryIds = metadata.piOutputEntryIds;
30573
+ inputIdsRaw = JSON.stringify(metadata.inputIds);
30574
+ }
30575
+ } catch {
30576
+ return;
30577
+ }
30578
+ }
30579
+ const inputIdSeq = parseStringArray(inputIdsRaw);
30414
30580
  const inputContentDigests = parseStringArray(record.input_content_digests);
30415
30581
  const modelKey = parseNullableString(record.model_key);
30416
30582
  const providerKey = parseNullableString(record.provider_key);
30417
30583
  if (typeof jsonPrefix !== "string" || typeof lastInputMessageId !== "string" || lastInputMessageId.length === 0 || typeof capturedAt !== "number" || !Number.isFinite(capturedAt) || inputIdSeq === null || inputContentDigests === null || inputContentDigests.length !== inputIdSeq.length || modelKey === undefined || providerKey === undefined) {
30418
30584
  return;
30419
30585
  }
30586
+ if (piOutputEntryIds) {
30587
+ try {
30588
+ const output = JSON.parse(jsonPrefix);
30589
+ const inputs = new Set(inputIdSeq);
30590
+ if (!Array.isArray(output) || output.length !== piOutputEntryIds.length || piOutputEntryIds.some((id) => id !== null && !inputs.has(id)))
30591
+ return;
30592
+ } catch {
30593
+ return;
30594
+ }
30595
+ }
30420
30596
  let inputContentSignatures;
30421
30597
  if (record.input_content_signatures !== null && record.input_content_signatures !== undefined) {
30422
30598
  const parsed = parseStringArray(record.input_content_signatures);
@@ -30435,6 +30611,8 @@ function parsePersistedLkgSlot(row) {
30435
30611
  };
30436
30612
  if (inputContentSignatures)
30437
30613
  slot.inputContentSignatures = inputContentSignatures;
30614
+ if (piOutputEntryIds)
30615
+ slot.piOutputEntryIds = piOutputEntryIds;
30438
30616
  const rowVersion = parseNullableInteger(record.row_version);
30439
30617
  if (rowVersion !== undefined)
30440
30618
  slot.rowVersion = rowVersion;
@@ -30460,7 +30638,11 @@ function saveLkgSlotToDb(db, sessionId, slot) {
30460
30638
  provider_key = excluded.provider_key,
30461
30639
  captured_at = excluded.captured_at,
30462
30640
  row_version = excluded.row_version,
30463
- capture_sequence = excluded.capture_sequence`).run(sessionId, slot.jsonPrefix, JSON.stringify(slot.inputIdSeq), JSON.stringify(slot.inputContentDigests), slot.inputContentSignatures ? JSON.stringify(slot.inputContentSignatures) : null, slot.lastInputMessageId, slot.modelKey, slot.providerKey, slot.capturedAt, slot.rowVersion ?? null, slot.captureSequence ?? null);
30641
+ capture_sequence = excluded.capture_sequence`).run(sessionId, slot.jsonPrefix, JSON.stringify(slot.piOutputEntryIds ? {
30642
+ version: 1,
30643
+ inputIds: slot.inputIdSeq,
30644
+ piOutputEntryIds: slot.piOutputEntryIds
30645
+ } : slot.inputIdSeq), JSON.stringify(slot.inputContentDigests), slot.inputContentSignatures ? JSON.stringify(slot.inputContentSignatures) : null, slot.lastInputMessageId, slot.modelKey, slot.providerKey, slot.capturedAt, slot.rowVersion ?? null, slot.captureSequence ?? null);
30464
30646
  return true;
30465
30647
  } catch (error) {
30466
30648
  sessionLog(sessionId, "LKG snapshot persistence failed (in-memory slot retained):", error);
@@ -31944,7 +32126,7 @@ function applyHeuristicCleanup(sessionId, db, targets, messageTagNumbers, config
31944
32126
  emergencyReclaimedTokens += estimateEmergencyDropReclaimTokens(tag);
31945
32127
  }
31946
32128
  }
31947
- })();
32129
+ }).immediate();
31948
32130
  sessionLog(sessionId, `emergency tiered drop: ${plan.reason}`);
31949
32131
  } else {
31950
32132
  sessionLog(sessionId, `emergency tiered drop skipped: ${plan.reason}`);
@@ -31991,7 +32173,7 @@ function applyHeuristicCleanup(sessionId, db, targets, messageTagNumbers, config
31991
32173
  }
31992
32174
  }
31993
32175
  }
31994
- })();
32176
+ }).immediate();
31995
32177
  }
31996
32178
  const allMessages = Array.from(messageTagNumbers.keys());
31997
32179
  const toolFingerprints = buildToolFingerprints(allMessages);
@@ -32030,7 +32212,7 @@ function applyHeuristicCleanup(sessionId, db, targets, messageTagNumbers, config
32030
32212
  }
32031
32213
  }
32032
32214
  }
32033
- })();
32215
+ }).immediate();
32034
32216
  }
32035
32217
  if (droppedTools > 0 || deduplicatedTools > 0 || droppedInjections > 0) {
32036
32218
  sessionLog(sessionId, `heuristic cleanup: dropped ${droppedTools} tool tags, deduplicated ${deduplicatedTools} tool calls, dropped ${droppedInjections} system injections`);
@@ -32295,78 +32477,93 @@ function buildReplacementContent(tagId) {
32295
32477
  }
32296
32478
  function applyPendingOperations(sessionId, db, targets, protectedTagIds, preloadedTags, preloadedPendingOps, syntheticPendingOps = [], editMarkerTagIds = new Set) {
32297
32479
  let didMutateMessage = false;
32298
- db.transaction(() => {
32299
- const tags = preloadedTags ?? getTagsBySession(db, sessionId);
32300
- const tagStatusById = new Map(tags.map((tag) => [tag.tagNumber, tag.status]));
32301
- const tagTypeById = new Map(tags.map((tag) => [tag.tagNumber, tag.type]));
32302
- const pendingOps = preloadedPendingOps ?? getPendingOps(db, sessionId);
32303
- const opsToApply = [
32304
- ...pendingOps.map((op) => ({ op, synthetic: false })),
32305
- ...syntheticPendingOps.map((op) => ({ op, synthetic: true }))
32306
- ];
32307
- const skeletonWindow = new Set(tags.filter((tag) => tag.type === "tool").map((tag) => tag.tagNumber).sort((left, right) => right - left).slice(0, RECENT_TOOL_SKELETON_WINDOW));
32308
- for (const { op: pendingOp, synthetic } of opsToApply) {
32309
- const tagStatus = tagStatusById.get(pendingOp.tagId);
32310
- if (tagStatus === "compacted" || tagStatus === "dropped") {
32311
- if (!synthetic)
32312
- removePendingOp(db, sessionId, pendingOp.tagId);
32313
- continue;
32314
- }
32315
- if (protectedTagIds.has(pendingOp.tagId)) {
32316
- continue;
32317
- }
32318
- const target = targets.get(pendingOp.tagId);
32319
- const isToolTag = tagTypeById.get(pendingOp.tagId) === "tool";
32320
- if (synthetic) {
32321
- if (!isToolTag || target?.canDrop?.() !== true)
32480
+ let admitted = false;
32481
+ let startedAt = 0;
32482
+ try {
32483
+ db.transaction(() => {
32484
+ admitted = true;
32485
+ startedAt = performance.now();
32486
+ const tags = preloadedTags ?? getTagsBySession(db, sessionId);
32487
+ const tagStatusById = new Map(tags.map((tag) => [tag.tagNumber, tag.status]));
32488
+ const tagTypeById = new Map(tags.map((tag) => [tag.tagNumber, tag.type]));
32489
+ const pendingOps = preloadedPendingOps ?? getPendingOps(db, sessionId);
32490
+ const opsToApply = [
32491
+ ...pendingOps.map((op) => ({ op, synthetic: false })),
32492
+ ...syntheticPendingOps.map((op) => ({ op, synthetic: true }))
32493
+ ];
32494
+ const skeletonWindow = new Set(tags.filter((tag) => tag.type === "tool").map((tag) => tag.tagNumber).sort((left, right) => right - left).slice(0, RECENT_TOOL_SKELETON_WINDOW));
32495
+ for (const { op: pendingOp, synthetic } of opsToApply) {
32496
+ const tagStatus = tagStatusById.get(pendingOp.tagId);
32497
+ if (tagStatus === "compacted" || tagStatus === "dropped") {
32498
+ if (!synthetic)
32499
+ removePendingOp(db, sessionId, pendingOp.tagId);
32322
32500
  continue;
32323
- }
32324
- let shouldPersistDrop = false;
32325
- if (isToolTag) {
32326
- if (editMarkerTagIds.has(pendingOp.tagId)) {
32327
- const markResult = target?.editMarker?.() ?? "absent";
32328
- if (markResult === "incomplete" || markResult === "absent") {
32329
- continue;
32330
- }
32331
- didMutateMessage = true;
32332
- updateTagDropMode(db, sessionId, pendingOp.tagId, "edit_marker");
32333
- shouldPersistDrop = true;
32334
- } else if (skeletonWindow.has(pendingOp.tagId)) {
32335
- const truncResult = target?.truncate?.() ?? "absent";
32336
- if (truncResult === "incomplete" || synthetic && truncResult !== "truncated") {
32501
+ }
32502
+ if (protectedTagIds.has(pendingOp.tagId)) {
32503
+ continue;
32504
+ }
32505
+ const target = targets.get(pendingOp.tagId);
32506
+ const isToolTag = tagTypeById.get(pendingOp.tagId) === "tool";
32507
+ if (synthetic) {
32508
+ if (!isToolTag || target?.canDrop?.() !== true)
32337
32509
  continue;
32338
- }
32339
- if (truncResult === "truncated") {
32510
+ }
32511
+ let shouldPersistDrop = false;
32512
+ if (isToolTag) {
32513
+ if (editMarkerTagIds.has(pendingOp.tagId)) {
32514
+ const markResult = target?.editMarker?.() ?? "absent";
32515
+ if (markResult === "incomplete" || markResult === "absent") {
32516
+ continue;
32517
+ }
32340
32518
  didMutateMessage = true;
32519
+ updateTagDropMode(db, sessionId, pendingOp.tagId, "edit_marker");
32520
+ shouldPersistDrop = true;
32521
+ } else if (skeletonWindow.has(pendingOp.tagId)) {
32522
+ const truncResult = target?.truncate?.() ?? "absent";
32523
+ if (truncResult === "incomplete" || synthetic && truncResult !== "truncated") {
32524
+ continue;
32525
+ }
32526
+ if (truncResult === "truncated") {
32527
+ didMutateMessage = true;
32528
+ }
32529
+ updateTagDropMode(db, sessionId, pendingOp.tagId, "truncated");
32530
+ shouldPersistDrop = true;
32531
+ } else {
32532
+ const dropResult = target?.drop?.() ?? "absent";
32533
+ if (dropResult === "incomplete" || synthetic && dropResult !== "removed") {
32534
+ continue;
32535
+ }
32536
+ if (dropResult === "removed") {
32537
+ didMutateMessage = true;
32538
+ }
32539
+ updateTagDropMode(db, sessionId, pendingOp.tagId, "full");
32540
+ shouldPersistDrop = true;
32341
32541
  }
32342
- updateTagDropMode(db, sessionId, pendingOp.tagId, "truncated");
32343
- shouldPersistDrop = true;
32344
- } else {
32345
- const dropResult = target?.drop?.() ?? "absent";
32346
- if (dropResult === "incomplete" || synthetic && dropResult !== "removed") {
32347
- continue;
32348
- }
32349
- if (dropResult === "removed") {
32542
+ } else if (target) {
32543
+ const changed = target.setContent(buildReplacementContent(pendingOp.tagId));
32544
+ if (changed)
32350
32545
  didMutateMessage = true;
32351
- }
32352
- updateTagDropMode(db, sessionId, pendingOp.tagId, "full");
32546
+ shouldPersistDrop = true;
32547
+ } else if (!synthetic) {
32353
32548
  shouldPersistDrop = true;
32354
32549
  }
32355
- } else if (target) {
32356
- const changed = target.setContent(buildReplacementContent(pendingOp.tagId));
32357
- if (changed)
32358
- didMutateMessage = true;
32359
- shouldPersistDrop = true;
32360
- } else if (!synthetic) {
32361
- shouldPersistDrop = true;
32550
+ if (!shouldPersistDrop)
32551
+ continue;
32552
+ updateTagStatus(db, sessionId, pendingOp.tagId, "dropped");
32553
+ if (!synthetic)
32554
+ removePendingOp(db, sessionId, pendingOp.tagId);
32362
32555
  }
32363
- if (!shouldPersistDrop)
32364
- continue;
32365
- updateTagStatus(db, sessionId, pendingOp.tagId, "dropped");
32366
- if (!synthetic)
32367
- removePendingOp(db, sessionId, pendingOp.tagId);
32556
+ }).immediate();
32557
+ } catch (error) {
32558
+ if (!admitted && /database (?:table )?is locked|sqlite_(busy|locked)/i.test(String(error))) {
32559
+ sessionLog(sessionId, "pending operations write admission busy; retaining prior bytes for retry");
32560
+ return false;
32368
32561
  }
32369
- })();
32562
+ throw error;
32563
+ } finally {
32564
+ if (admitted)
32565
+ logSlowWriteTransaction("apply_pending_operations", startedAt);
32566
+ }
32370
32567
  return didMutateMessage;
32371
32568
  }
32372
32569
  function applyFlushedStatuses(sessionId, db, targets, preloadedTags) {
@@ -33163,7 +33360,8 @@ function runRustModePostprocess(args) {
33163
33360
  db: args.db,
33164
33361
  sessionId: args.sessionId,
33165
33362
  tagger: args.tagger,
33166
- ctxReduceAvailability: args.ctxReduceAvailability
33363
+ ctxReduceAvailability: args.ctxReduceAvailability,
33364
+ isCacheBustingPass: args.materializedBoundary != null
33167
33365
  });
33168
33366
  for (const anchor of getNoteNudgeAnchors(args.db, args.sessionId)) {
33169
33367
  appendReminderToUserMessageById(args.messages, anchor.messageId, anchor.text);
@@ -33258,6 +33456,13 @@ function dropMarkerSummaryTag(db, sessionId, summaryMessageId) {
33258
33456
  updateTagStatus(db, sessionId, tagNumber, "dropped");
33259
33457
  }
33260
33458
  function reconcileMarkerRepresentation(messages, persistedMarkerState, options) {
33459
+ if (persistedMarkerState === null) {
33460
+ if (options.isCacheBustingPass === true) {
33461
+ retireDeferredClearedCompactionMarkerState(options.db, options.sessionId);
33462
+ } else {
33463
+ persistedMarkerState = getDeferredClearedCompactionMarkerState(options.db, options.sessionId);
33464
+ }
33465
+ }
33261
33466
  const retainedMessages = [];
33262
33467
  const staleSummaryIds = new Set;
33263
33468
  for (const message of messages) {
@@ -33955,7 +34160,8 @@ async function runPostTransformPhase(args) {
33955
34160
  db: args.db,
33956
34161
  sessionId: args.sessionId,
33957
34162
  tagger: args.tagger,
33958
- ctxReduceAvailability: args.ctxReduceAvailability
34163
+ ctxReduceAvailability: args.ctxReduceAvailability,
34164
+ isCacheBustingPass
33959
34165
  });
33960
34166
  }
33961
34167
  const deferredHistoryDrainEligible = historyWasConsumedThisPass && args.deferredHistoryWasPendingAtPassStart && !suppressV12HistoryDrain;