@cortexkit/opencode-magic-context 0.42.0 → 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 (93) hide show
  1. package/dist/config/project-security.d.ts +3 -2
  2. package/dist/config/project-security.d.ts.map +1 -1
  3. package/dist/config/schema/magic-context.d.ts +20 -0
  4. package/dist/config/schema/magic-context.d.ts.map +1 -1
  5. package/dist/features/magic-context/compartment-chunk-embedding.d.ts +8 -4
  6. package/dist/features/magic-context/compartment-chunk-embedding.d.ts.map +1 -1
  7. package/dist/features/magic-context/dreamer/classify.d.ts.map +1 -1
  8. package/dist/features/magic-context/dreamer/expire-memories.d.ts +15 -0
  9. package/dist/features/magic-context/dreamer/expire-memories.d.ts.map +1 -0
  10. package/dist/features/magic-context/dreamer/module-apply.d.ts +4 -2
  11. package/dist/features/magic-context/dreamer/module-apply.d.ts.map +1 -1
  12. package/dist/features/magic-context/dreamer/storage-dream-runs.d.ts.map +1 -1
  13. package/dist/features/magic-context/dreamer/task-executor.d.ts.map +1 -1
  14. package/dist/features/magic-context/dreamer/task-gates.d.ts +6 -1
  15. package/dist/features/magic-context/dreamer/task-gates.d.ts.map +1 -1
  16. package/dist/features/magic-context/memory/embedding-identity.d.ts.map +1 -1
  17. package/dist/features/magic-context/memory/embedding-local.d.ts.map +1 -1
  18. package/dist/features/magic-context/memory/embedding-model-match.d.ts +41 -0
  19. package/dist/features/magic-context/memory/embedding-model-match.d.ts.map +1 -0
  20. package/dist/features/magic-context/memory/embedding-openai.d.ts +7 -20
  21. package/dist/features/magic-context/memory/embedding-openai.d.ts.map +1 -1
  22. package/dist/features/magic-context/memory/embedding-provider.d.ts +2 -2
  23. package/dist/features/magic-context/memory/embedding-provider.d.ts.map +1 -1
  24. package/dist/features/magic-context/memory/embedding-synapse.d.ts +5 -4
  25. package/dist/features/magic-context/memory/embedding-synapse.d.ts.map +1 -1
  26. package/dist/features/magic-context/memory/embedding.d.ts.map +1 -1
  27. package/dist/features/magic-context/pi-content-decisions.d.ts.map +1 -1
  28. package/dist/features/magic-context/project-embedding-registry.d.ts.map +1 -1
  29. package/dist/features/magic-context/storage-meta-persisted.d.ts +4 -0
  30. package/dist/features/magic-context/storage-meta-persisted.d.ts.map +1 -1
  31. package/dist/hooks/magic-context/apply-operations.d.ts.map +1 -1
  32. package/dist/hooks/magic-context/command-handler.d.ts.map +1 -1
  33. package/dist/hooks/magic-context/compaction-marker-manager.d.ts +4 -6
  34. package/dist/hooks/magic-context/compaction-marker-manager.d.ts.map +1 -1
  35. package/dist/hooks/magic-context/compartment-runner-partial-recomp.d.ts.map +1 -1
  36. package/dist/hooks/magic-context/compartment-runner-recomp.d.ts.map +1 -1
  37. package/dist/hooks/magic-context/compartment-runner-validation.d.ts +1 -1
  38. package/dist/hooks/magic-context/compartment-runner-validation.d.ts.map +1 -1
  39. package/dist/hooks/magic-context/embed-session-state.d.ts +1 -1
  40. package/dist/hooks/magic-context/embed-session-state.d.ts.map +1 -1
  41. package/dist/hooks/magic-context/execute-status.d.ts +2 -0
  42. package/dist/hooks/magic-context/execute-status.d.ts.map +1 -1
  43. package/dist/hooks/magic-context/format-embed-failure.d.ts +2 -1
  44. package/dist/hooks/magic-context/format-embed-failure.d.ts.map +1 -1
  45. package/dist/hooks/magic-context/lkg-persist.d.ts.map +1 -1
  46. package/dist/hooks/magic-context/lkg-slot.d.ts +2 -0
  47. package/dist/hooks/magic-context/lkg-slot.d.ts.map +1 -1
  48. package/dist/hooks/magic-context/maintenance-authority.d.ts +2 -2
  49. package/dist/hooks/magic-context/maintenance-authority.d.ts.map +1 -1
  50. package/dist/hooks/magic-context/recomp-orchestrator.d.ts.map +1 -1
  51. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts +1 -0
  52. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
  53. package/dist/{index-c9hamh36.js → index-953x7a79.js} +564 -143
  54. package/dist/index.d.ts.map +1 -1
  55. package/dist/index.js +579 -217
  56. package/dist/plugin/dream-timer-module-client.d.ts +2 -2
  57. package/dist/plugin/dream-timer-module-client.d.ts.map +1 -1
  58. package/dist/plugin/embedding-bootstrap-helpers.d.ts.map +1 -1
  59. package/dist/plugin/embedding-routing.d.ts.map +1 -1
  60. package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
  61. package/dist/plugin/rpc-handlers.d.ts.map +1 -1
  62. package/dist/{recomp-orchestrator-3atsasjy.js → recomp-orchestrator-5g8f5rhy.js} +1 -1
  63. package/dist/shared/rpc-types.d.ts +10 -0
  64. package/dist/shared/rpc-types.d.ts.map +1 -1
  65. package/dist/shared/status-detail-text.d.ts +3 -1
  66. package/dist/shared/status-detail-text.d.ts.map +1 -1
  67. package/dist/shared/status-summary.d.ts +30 -0
  68. package/dist/shared/status-summary.d.ts.map +1 -0
  69. package/dist/shared/tail-hygiene-status.d.ts +1 -0
  70. package/dist/shared/tail-hygiene-status.d.ts.map +1 -1
  71. package/dist/shared/transcript.d.ts +2 -1
  72. package/dist/shared/transcript.d.ts.map +1 -1
  73. package/dist/shared/user-facing-codes.d.ts +191 -0
  74. package/dist/shared/user-facing-codes.d.ts.map +1 -0
  75. package/dist/tools/ctx-memory/tools.d.ts.map +1 -1
  76. package/dist/tools/ctx-note/tools.d.ts.map +1 -1
  77. package/dist/tools/ctx-reduce/tools.d.ts.map +1 -1
  78. package/package.json +1 -1
  79. package/src/config/project-security.test.ts +10 -2
  80. package/src/config/project-security.ts +12 -5
  81. package/src/config/schema/magic-context.test.ts +29 -0
  82. package/src/config/schema/magic-context.ts +24 -0
  83. package/src/shared/rpc-types.ts +10 -0
  84. package/src/shared/status-detail-text.test.ts +93 -24
  85. package/src/shared/status-detail-text.ts +9 -2
  86. package/src/shared/status-summary.ts +167 -0
  87. package/src/shared/tag-transcript.ts +14 -7
  88. package/src/shared/tail-hygiene-status.ts +8 -0
  89. package/src/shared/transcript.ts +2 -1
  90. package/src/shared/user-facing-codes.test.ts +140 -0
  91. package/src/shared/user-facing-codes.ts +276 -0
  92. package/src/tui/index.tsx +41 -8
  93. package/src/tui-compiled/index.tsx +660 -647
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,
@@ -372,6 +374,13 @@ import {
372
374
  hasLengthCappedOutput,
373
375
  setKeepSubagents,
374
376
  teardownChildSession,
377
+ renderUserFacingFailure,
378
+ userFacingFailureCode,
379
+ renderCapabilityRefusal,
380
+ capabilityRefusalCode,
381
+ renderDreamFailure,
382
+ dreamFailureCode,
383
+ renderEmbeddingFailure,
375
384
  getCompartmentEvents,
376
385
  SYNAPSE_DEFAULT_MODEL,
377
386
  toSynapseLaneDescriptor,
@@ -533,7 +542,7 @@ import {
533
542
  setRecompTerminal2,
534
543
  runManagedRecomp2,
535
544
  runManagedUpgrade2
536
- } from "./index-c9hamh36.js";
545
+ } from "./index-953x7a79.js";
537
546
  import {
538
547
  stripJsonComments,
539
548
  isPrototypePollutionKey,
@@ -9191,7 +9200,13 @@ var HARNESS_KEYS = PER_HARNESS_MODEL_KEYS;
9191
9200
  var HISTORIAN_USER_ONLY_FIELDS = PER_HARNESS_MIGRATION_INVENTORY.historian.migrated_execution;
9192
9201
  var PROMPT_SURFACE_USER_ONLY_FIELDS = ["guidance_override_path", "tool_descriptions"];
9193
9202
  var AGENT_ESCALATION_FIELDS = ["prompt", "permission", "tools"];
9194
- var EMBEDDING_DESTINATION_FIELDS = ["endpoint", "provider", "fallback_provider"];
9203
+ var EMBEDDING_USER_ONLY_FIELDS = [
9204
+ "endpoint",
9205
+ "provider",
9206
+ "fallback_provider",
9207
+ "query_instruction",
9208
+ "document_prefix"
9209
+ ];
9195
9210
  var PERCENTAGE_THRESHOLD_REASON = "security: a repository may only raise compaction thresholds above the user's effective value; it cannot force earlier historian work or cloned-repo cost escalation.";
9196
9211
  var TOKEN_THRESHOLD_REASON = "security: a repository may only raise execute_threshold_tokens above the user's trusted token threshold; it cannot force earlier historian work or cloned-repo cost escalation.";
9197
9212
  var TOKEN_THRESHOLD_INTRODUCTION_REASON = "security: a repository cannot introduce a new execute_threshold_tokens override when the user has no trusted token threshold for that key; that could force earlier historian work or cloned-repo cost escalation.";
@@ -9425,14 +9440,14 @@ function stripUnsafeProjectConfigFields(projectRaw) {
9425
9440
  const embedding = projectRaw.embedding;
9426
9441
  if (isPlainObject(embedding)) {
9427
9442
  const removed = [];
9428
- for (const field of EMBEDDING_DESTINATION_FIELDS) {
9443
+ for (const field of EMBEDDING_USER_ONLY_FIELDS) {
9429
9444
  if (field in embedding) {
9430
9445
  delete embedding[field];
9431
9446
  removed.push(field);
9432
9447
  }
9433
9448
  }
9434
9449
  if (removed.length > 0) {
9435
- warnings.push(`Ignoring embedding.${removed.join("/")} from project config ` + "(security: a repository cannot choose where private text is embedded).");
9450
+ warnings.push(`Ignoring embedding.${removed.join("/")} from project config ` + "(security: a repository cannot choose where or how private text is embedded).");
9436
9451
  }
9437
9452
  }
9438
9453
  for (const agentKey of HIDDEN_AGENT_KEYS) {
@@ -14925,12 +14940,12 @@ async function runClassifyThroughModule(args, chunk, anchors, signal) {
14925
14940
  });
14926
14941
  } catch (error) {
14927
14942
  if (isRustAuthorityDrainingError(error)) {
14928
- throw new Error("Rust memory authority is not ready; TypeScript fallback is disabled.");
14943
+ throw new Error(renderCapabilityRefusal("memory_write"));
14929
14944
  }
14930
14945
  throw error;
14931
14946
  }
14932
14947
  if (isRustAuthorityDrainingError(applied)) {
14933
- throw new Error("Rust memory authority is not ready; TypeScript fallback is disabled.");
14948
+ throw new Error(renderCapabilityRefusal("memory_write"));
14934
14949
  }
14935
14950
  const applyResult = applied?.result ?? applied;
14936
14951
  if (!applyResult || typeof applyResult !== "object") {
@@ -16880,6 +16895,116 @@ Output exactly JSON: {"met": false}`;
16880
16895
  }
16881
16896
  }
16882
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
+
16883
17008
  // src/features/magic-context/dreamer/maintain-docs-protected-enforcement.ts
16884
17009
  import { existsSync as existsSync7, readFileSync as readFileSync5, writeFileSync as writeFileSync4 } from "node:fs";
16885
17010
  import { join as join7 } from "node:path";
@@ -18168,14 +18293,7 @@ function unescapeXml2(value) {
18168
18293
 
18169
18294
  // src/features/magic-context/dreamer/storage-dream-runs.ts
18170
18295
  function formatDreamRunFailure(failure) {
18171
- const parts = [failure.failure_class];
18172
- if (failure.model_attempted)
18173
- parts.push(`model: ${failure.model_attempted}`);
18174
- if (failure.provider_error)
18175
- parts.push(failure.provider_error.split(/\r?\n/, 1)[0].trim());
18176
- else if (failure.timeout_ms !== null)
18177
- parts.push(`timeout: ${failure.timeout_ms}ms`);
18178
- return parts.join(" · ");
18296
+ return renderDreamFailure(failure.failure_class);
18179
18297
  }
18180
18298
  var insertDreamRunStatements = new WeakMap;
18181
18299
  var getDreamRunsByProjectStatements = new Map;
@@ -18196,14 +18314,25 @@ function countActiveMemories(db, projectPath) {
18196
18314
  const row = db.prepare("SELECT COUNT(*) AS cnt FROM memories WHERE project_path = ? AND status IN ('active','permanent')").get(projectPath);
18197
18315
  return row?.cnt ?? 0;
18198
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
+ }
18199
18327
  function countUnmappedActiveMemories(db, projectPath) {
18200
18328
  const row = db.prepare(`SELECT COUNT(*) AS cnt
18201
18329
  FROM memories m
18202
18330
  WHERE m.project_path = ?
18203
18331
  AND m.status IN ('active','permanent')
18332
+ AND (m.expires_at IS NULL OR m.expires_at > ?)
18204
18333
  AND NOT EXISTS (
18205
18334
  SELECT 1 FROM memory_verifications v WHERE v.memory_id = m.id
18206
- )`).get(projectPath);
18335
+ )`).get(projectPath, Date.now());
18207
18336
  return row?.cnt ?? 0;
18208
18337
  }
18209
18338
  function countCompartmentsSince(db, projectPath, since) {
@@ -18223,7 +18352,8 @@ function countMappedMemories(db, projectPath) {
18223
18352
  JOIN memory_verifications v ON v.memory_id = m.id
18224
18353
  WHERE m.project_path = ?
18225
18354
  AND m.status IN ('active','permanent')
18226
- 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());
18227
18357
  return row?.cnt ?? 0;
18228
18358
  }
18229
18359
  function countUnverifiedMappedMemories(db, projectPath) {
@@ -18232,8 +18362,9 @@ function countUnverifiedMappedMemories(db, projectPath) {
18232
18362
  JOIN memory_verifications v ON v.memory_id = m.id
18233
18363
  WHERE m.project_path = ?
18234
18364
  AND m.status IN ('active','permanent')
18365
+ AND (m.expires_at IS NULL OR m.expires_at > ?)
18235
18366
  AND v.file_path <> ''
18236
- AND v.verified_at = 0`).get(projectPath);
18367
+ AND v.verified_at = 0`).get(projectPath, Date.now());
18237
18368
  return row?.cnt ?? 0;
18238
18369
  }
18239
18370
  function countBroadCycleCandidates(db, projectPath, cycleStartAt) {
@@ -18241,22 +18372,24 @@ function countBroadCycleCandidates(db, projectPath, cycleStartAt) {
18241
18372
  FROM memories m
18242
18373
  WHERE m.project_path = ?
18243
18374
  AND m.status IN ('active','permanent')
18375
+ AND (m.expires_at IS NULL OR m.expires_at > ?)
18244
18376
  AND (
18245
18377
  SELECT MAX(v.verified_at)
18246
18378
  FROM memory_verifications v
18247
18379
  WHERE v.memory_id = m.id
18248
18380
  AND v.file_path <> ''
18249
- ) < ?`).get(projectPath, cycleStartAt);
18381
+ ) < ?`).get(projectPath, Date.now(), cycleStartAt);
18250
18382
  return row?.cnt ?? 0;
18251
18383
  }
18252
18384
  function countCueCandidates(db, projectPath) {
18253
18385
  if (!hasMuralCueColumns(db))
18254
- return countActiveMemories(db, projectPath);
18386
+ return countLiveMemories(db, projectPath);
18255
18387
  const row = db.prepare(`SELECT COUNT(*) AS cnt
18256
18388
  FROM memories
18257
18389
  WHERE project_path = ?
18258
18390
  AND status IN ('active','permanent')
18259
- 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());
18260
18393
  return row?.cnt ?? 0;
18261
18394
  }
18262
18395
  function countStalePrimers(db, projectPath) {
@@ -18268,16 +18401,6 @@ function countStalePrimers(db, projectPath) {
18268
18401
  OR last_observed_at > answer_refreshed_at)`).get(projectPath);
18269
18402
  return row?.cnt ?? 0;
18270
18403
  }
18271
- function countUnclassifiedActiveMemories(db, projectPath) {
18272
- if (!hasMemoryClassifiedAtColumn(db))
18273
- return countActiveMemories(db, projectPath);
18274
- const row = db.prepare(`SELECT COUNT(*) AS cnt
18275
- FROM memories
18276
- WHERE project_path = ?
18277
- AND status IN ('active','permanent')
18278
- AND classified_at IS NULL`).get(projectPath);
18279
- return row?.cnt ?? 0;
18280
- }
18281
18404
  function countPendingSmartNotes(db, projectPath) {
18282
18405
  const row = db.prepare("SELECT COUNT(*) AS cnt FROM notes WHERE project_path = ? AND type = 'smart' AND status = 'pending'").get(projectPath);
18283
18406
  return row?.cnt ?? 0;
@@ -18293,7 +18416,7 @@ function countActivePrimers(db, projectPath) {
18293
18416
  function getDreamTaskBacklog(db, projectPath, task, options = {}) {
18294
18417
  switch (task) {
18295
18418
  case "map-memories": {
18296
- const total = countActiveMemories(db, projectPath);
18419
+ const total = countLiveMemories(db, projectPath);
18297
18420
  return { pending: countUnmappedActiveMemories(db, projectPath), total };
18298
18421
  }
18299
18422
  case "verify": {
@@ -18309,16 +18432,19 @@ function getDreamTaskBacklog(db, projectPath, task, options = {}) {
18309
18432
  return { pending, total };
18310
18433
  }
18311
18434
  case "curate": {
18312
- const total = countActiveMemories(db, projectPath);
18435
+ const total = countLiveMemories(db, projectPath);
18313
18436
  return { pending: total, total };
18314
18437
  }
18315
18438
  case "compress-cues": {
18316
- const total = countActiveMemories(db, projectPath);
18439
+ const total = countLiveMemories(db, projectPath);
18317
18440
  return { pending: countCueCandidates(db, projectPath), total };
18318
18441
  }
18319
18442
  case "classify-memories": {
18320
- const total = countActiveMemories(db, projectPath);
18321
- return { pending: countUnclassifiedActiveMemories(db, projectPath), total };
18443
+ const total = countLiveMemories(db, projectPath);
18444
+ return {
18445
+ pending: countLiveMemories(db, projectPath, { unclassifiedOnly: true }),
18446
+ total
18447
+ };
18322
18448
  }
18323
18449
  case "retrospective": {
18324
18450
  const pending = countProjectSessionsSince(db, projectPath, options.retrospectiveWatermarkMs ?? null);
@@ -18363,15 +18489,15 @@ function evaluateTaskGate(task, ctx) {
18363
18489
  case "map-memories":
18364
18490
  return countUnmappedActiveMemories(db, project) > 0;
18365
18491
  case "verify":
18366
- return countActiveMemories(db, project) > 0;
18492
+ return countLiveMemories(db, project) > 0;
18367
18493
  case "verify-broad":
18368
- 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;
18369
18495
  case "curate":
18370
18496
  return countActiveMemories(db, project) > 0;
18371
18497
  case "compress-cues":
18372
- return countActiveMemories(db, project) > 0;
18498
+ return countLiveMemories(db, project) > 0;
18373
18499
  case "classify-memories":
18374
- return countActiveMemories(db, project) > 0;
18500
+ return countLiveMemories(db, project) > 0;
18375
18501
  case "retrospective":
18376
18502
  return countProjectSessionsSince(db, project, ctx.retrospectiveWatermarkMs ?? null) > 0;
18377
18503
  case "maintain-docs":
@@ -19109,6 +19235,9 @@ function inspectCurateMemoryOperations(messages) {
19109
19235
  }
19110
19236
  return summary;
19111
19237
  }
19238
+ function formatExpiredArchiveProgress(count) {
19239
+ return `curate: archived ${count} expired ${count === 1 ? "memory" : "memories"}`;
19240
+ }
19112
19241
  function formatCurateMemoryOperations(actions) {
19113
19242
  const actionCounts = new Map;
19114
19243
  for (const action of actions)
@@ -19159,7 +19288,7 @@ function createDreamTaskExecutor(deps) {
19159
19288
  };
19160
19289
  const parent = await resolveParentSessionId();
19161
19290
  let moduleRoute;
19162
- 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") {
19163
19292
  try {
19164
19293
  moduleRoute = await resolveDreamerModuleRoute({
19165
19294
  db,
@@ -19488,13 +19617,15 @@ function createDreamTaskExecutor(deps) {
19488
19617
  parent,
19489
19618
  recordRun,
19490
19619
  computeMemoryDelta,
19491
- reportProgress
19620
+ reportProgress,
19621
+ leaseAcquisition,
19622
+ moduleRoute
19492
19623
  });
19493
19624
  } catch (error) {
19494
19625
  const { transient, brief } = classifyFailure(error);
19495
19626
  const failure = dreamRunFailureDetail(error);
19496
19627
  recordRun("failed", brief, { failure });
19497
- log(`[dreamer] task ${config.task} failed (transient=${transient}): ${brief}`);
19628
+ log(`[dreamer] task ${config.task} failed code=${dreamFailureCode(failure.failure_class)} (transient=${transient}): ${brief}`);
19498
19629
  return {
19499
19630
  status: "failed",
19500
19631
  transient,
@@ -19789,17 +19920,6 @@ async function runAgenticTask(config, ctx, helpers) {
19789
19920
  architecture: existsSync9(`${docsDir}/ARCHITECTURE.md`),
19790
19921
  structure: existsSync9(`${docsDir}/STRUCTURE.md`)
19791
19922
  } : undefined;
19792
- let curateMemories;
19793
- if (task === "curate") {
19794
- curateMemories = loadActiveMemoryPromptMemories(db, projectIdentity);
19795
- log(`[dreamer] curate pool: in_scope=${curateMemories.length}`);
19796
- }
19797
- const taskPrompt = buildDreamTaskPrompt(task, {
19798
- projectPath: projectIdentity,
19799
- lastDreamAt: lastRunAt ? String(lastRunAt) : null,
19800
- existingDocs,
19801
- curate: curateMemories ? { memories: curateMemories } : undefined
19802
- });
19803
19923
  const abortController = new AbortController;
19804
19924
  let leaseLost = false;
19805
19925
  const heartbeat = startLeaseHeartbeat(db, holderId, leaseKey, () => {
@@ -19808,7 +19928,37 @@ async function runAgenticTask(config, ctx, helpers) {
19808
19928
  }, ctx.leaseAcquisition);
19809
19929
  let childSessionId = null;
19810
19930
  let promptSettled = false;
19931
+ let expiredArchived = 0;
19811
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
+ });
19812
19962
  const createResponse = await createChildSessionWithFence({
19813
19963
  client: deps.client,
19814
19964
  db,
@@ -19900,6 +20050,7 @@ async function runAgenticTask(config, ctx, helpers) {
19900
20050
  }
19901
20051
  const curateOutput = task === "curate" ? run.validated : undefined;
19902
20052
  const progress = [
20053
+ expiredArchived > 0 ? formatExpiredArchiveProgress(expiredArchived) : null,
19903
20054
  curateOutput && curateOutput.memoryOperations.completedActions.length > 0 ? formatCurateMemoryOperations(curateOutput.memoryOperations.completedActions) : null,
19904
20055
  curateRefused > 0 ? `curate: refused ${curateRefused} unsafe mutation(s)` : null
19905
20056
  ].filter((value) => Boolean(value)).join("; ");
@@ -20916,7 +21067,13 @@ function createDreamTimerModuleClient(moduleClient) {
20916
21067
  }
20917
21068
  return moduleClient.authorityStatus(args);
20918
21069
  } : undefined,
20919
- 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
20920
21077
  };
20921
21078
  }
20922
21079
 
@@ -20931,6 +21088,8 @@ var EMBEDDING_AFFECTING_KEYS = new Set([
20931
21088
  "embedding.truncate",
20932
21089
  "embedding.max_input_tokens",
20933
21090
  "embedding.query_input_type",
21091
+ "embedding.query_instruction",
21092
+ "embedding.document_prefix",
20934
21093
  "embedding.fallback_provider",
20935
21094
  "subc",
20936
21095
  "subc.connection_file",
@@ -21044,6 +21203,8 @@ function fallbackConfig(config, provider) {
21044
21203
  const apiKey = typeof raw.api_key === "string" ? raw.api_key.trim() : "";
21045
21204
  const inputType = typeof raw.input_type === "string" ? raw.input_type.trim() : "";
21046
21205
  const queryInputType = typeof raw.query_input_type === "string" ? raw.query_input_type.trim() : "";
21206
+ const queryInstruction = typeof raw.query_instruction === "string" || raw.query_instruction === false ? raw.query_instruction : undefined;
21207
+ const documentPrefix = typeof raw.document_prefix === "string" ? raw.document_prefix : undefined;
21047
21208
  const truncate = typeof raw.truncate === "string" ? raw.truncate.trim() : "";
21048
21209
  const maxInputTokens = typeof raw.max_input_tokens === "number" ? raw.max_input_tokens : undefined;
21049
21210
  if (provider === "off")
@@ -21056,6 +21217,8 @@ function fallbackConfig(config, provider) {
21056
21217
  ...apiKey ? { api_key: apiKey } : {},
21057
21218
  ...inputType ? { input_type: inputType } : {},
21058
21219
  ...queryInputType ? { query_input_type: queryInputType } : {},
21220
+ ...queryInstruction !== undefined ? { query_instruction: queryInstruction } : {},
21221
+ ...documentPrefix !== undefined ? { document_prefix: documentPrefix } : {},
21059
21222
  ...truncate ? { truncate } : {},
21060
21223
  ...maxInputTokens !== undefined ? { max_input_tokens: maxInputTokens } : {}
21061
21224
  };
@@ -22217,7 +22380,8 @@ function getEmbedDrainUiStatus(sessionId, progress) {
22217
22380
  if (embedPauseBySession.has(sessionId)) {
22218
22381
  return { status: "paused" };
22219
22382
  }
22220
- if (progress?.kind === "embed" && progress.phase === "recomp") {
22383
+ const activeRun = embedRunStateBySession.get(sessionId);
22384
+ if (activeRun && !activeRun.signal.aborted || progress?.kind === "embed" && progress.phase === "recomp") {
22221
22385
  return { status: "running" };
22222
22386
  }
22223
22387
  if (progress?.kind === "embed" && (progress.phase === "failed" || progress.phase === "skipped") && progress.message) {
@@ -24793,10 +24957,122 @@ function formatCacheTtlDisplay(display) {
24793
24957
  // src/shared/rust-mode-status.ts
24794
24958
  var RUST_MODE_HOST_PATHS_LINE = "Host backends → MODULE: ctx_memory, ctx_note; historian: module-side";
24795
24959
 
24796
- // src/shared/status-detail-text.ts
24960
+ // src/shared/status-summary.ts
24961
+ function statusSummaryFromDetail(detail) {
24962
+ const compressionState = detail.compaction_enabled === false ? "off" : detail.historianRunning || detail.compartmentInProgress || detail.recompProgress?.phase === "recomp" && detail.recompProgress.kind !== "embed" ? "compressing" : detail.compartmentCount > 0 ? "ready" : "waiting";
24963
+ const warnings = [];
24964
+ if (detail.lastTransformError)
24965
+ warnings.push("transform_update_failed");
24966
+ if ((detail.historianFailureCount ?? 0) > 0)
24967
+ warnings.push("historian_unavailable");
24968
+ if ((detail.configParseFailures?.length ?? 0) > 0)
24969
+ warnings.push("configuration_warning");
24970
+ if (detail.embedding?.state === "stopped")
24971
+ warnings.push("embedding_unavailable");
24972
+ if ((detail.loggerDiagnostics?.swallowedWriteCount ?? 0) > 0) {
24973
+ warnings.push("status_log_unavailable");
24974
+ }
24975
+ return {
24976
+ inputTokens: detail.inputTokens,
24977
+ usableContextTokens: detail.contextLimit,
24978
+ usagePercentage: detail.usagePercentage,
24979
+ cacheLifetime: formatCacheTtlDisplay({
24980
+ value: detail.cacheTtl,
24981
+ source: detail.cacheTtlSource ?? "session",
24982
+ modelKey: detail.cacheTtlModelKey
24983
+ }).replace(/^Cache TTL:\s*/, ""),
24984
+ automaticCompressionThreshold: detail.compaction_enabled === false ? null : detail.executeThreshold,
24985
+ compression: {
24986
+ state: compressionState,
24987
+ historyBlockCount: detail.compartmentCount
24988
+ },
24989
+ reclaimable: {
24990
+ toolOutputCount: detail.tailHygiene?.reclaimableToolOutputCount ?? 0,
24991
+ tokens: detail.tailHygiene?.u ?? 0
24992
+ },
24993
+ memoryCount: detail.memoryCount,
24994
+ noteCount: (detail.sessionNoteCount ?? 0) + (detail.readySmartNoteCount ?? 0),
24995
+ embedding: detail.embedding ?? {
24996
+ state: "waiting",
24997
+ indexed: 0,
24998
+ total: 0
24999
+ },
25000
+ warnings: [...new Set(warnings)]
25001
+ };
25002
+ }
24797
25003
  function formatCount(value) {
24798
25004
  return Math.round(value).toLocaleString();
24799
25005
  }
25006
+ function compressionText(summary) {
25007
+ const historyBlocks = `${summary.compression.historyBlockCount} history block${summary.compression.historyBlockCount === 1 ? "" : "s"}`;
25008
+ switch (summary.compression.state) {
25009
+ case "off":
25010
+ return "Off";
25011
+ case "compressing":
25012
+ return `Compressing history · ${historyBlocks}`;
25013
+ case "ready":
25014
+ return `Ready · ${historyBlocks}`;
25015
+ case "waiting":
25016
+ return "Waiting for enough conversation history";
25017
+ }
25018
+ }
25019
+ function reclaimableText(summary) {
25020
+ const count = Math.max(0, Math.floor(summary.reclaimable.toolOutputCount));
25021
+ if (count === 0)
25022
+ return "none";
25023
+ const outputs = `${count} spent tool output${count === 1 ? "" : "s"}`;
25024
+ return `${outputs} (~${Math.round(Math.max(0, summary.reclaimable.tokens) / 1000)}k tokens)`;
25025
+ }
25026
+ function embeddingText(summary) {
25027
+ if (summary.embedding.state === "off")
25028
+ return "Off";
25029
+ const coverage = `${formatCount(summary.embedding.indexed)} / ${formatCount(summary.embedding.total)} history blocks indexed`;
25030
+ switch (summary.embedding.state) {
25031
+ case "running":
25032
+ return `Running · ${coverage}`;
25033
+ case "paused":
25034
+ return `Paused · ${coverage}`;
25035
+ case "stopped":
25036
+ return `Paused after an issue · ${coverage}`;
25037
+ case "ready":
25038
+ return `Ready · ${coverage}`;
25039
+ case "waiting":
25040
+ return `Waiting · ${coverage}`;
25041
+ }
25042
+ }
25043
+ function renderUserStatusSummary(summary, style) {
25044
+ const context = `${summary.usagePercentage.toFixed(1)}% of usable context (${formatCount(summary.inputTokens)} / ${summary.usableContextTokens > 0 ? formatCount(summary.usableContextTokens) : "?"} tokens)`;
25045
+ const values = [
25046
+ ["Context", context],
25047
+ ["Cache lifetime", summary.cacheLifetime],
25048
+ [
25049
+ "Automatic compression",
25050
+ summary.automaticCompressionThreshold === null ? "Off" : `at ${summary.automaticCompressionThreshold.toFixed(1)}% of usable context`
25051
+ ],
25052
+ ["History compression", compressionText(summary)],
25053
+ ["Reclaimable", reclaimableText(summary)],
25054
+ [
25055
+ "Memory",
25056
+ `${formatCount(summary.memoryCount)} memories · ${formatCount(summary.noteCount)} notes`
25057
+ ],
25058
+ ["Search indexing", embeddingText(summary)]
25059
+ ];
25060
+ const lines = style === "markdown" ? [
25061
+ "## Magic Context Status",
25062
+ "",
25063
+ ...values.map(([label, value]) => `- **${label}:** ${value}`)
25064
+ ] : ["Magic Context Status", ...values.map(([label, value]) => `${label}: ${value}`)];
25065
+ for (const warning of summary.warnings) {
25066
+ lines.push(style === "markdown" ? `- **Warning:** ${renderUserFacingFailure(warning)}` : `Warning: ${renderUserFacingFailure(warning)}`);
25067
+ }
25068
+ return lines.join(`
25069
+ `);
25070
+ }
25071
+
25072
+ // src/shared/status-detail-text.ts
25073
+ function formatCount2(value) {
25074
+ return Math.round(value).toLocaleString();
25075
+ }
24800
25076
  function formatCacheLane(detail) {
24801
25077
  if (detail.cacheNeverExpires)
24802
25078
  return `never expires; TTL ${detail.cacheTtl}`;
@@ -24807,7 +25083,10 @@ function formatCacheLane(detail) {
24807
25083
  return `live (${Math.round(detail.cacheRemainingMs / 1000)}s remaining); TTL ${detail.cacheTtl}`;
24808
25084
  }
24809
25085
  function formatStatusDetailMarkdown(detail) {
24810
- const usableLimit = detail.contextLimit > 0 ? `${formatCount(detail.contextLimit)} usable tokens` : "? usable tokens";
25086
+ return renderUserStatusSummary(statusSummaryFromDetail(detail), "markdown");
25087
+ }
25088
+ function formatStatusDiagnosticsMarkdown(detail) {
25089
+ const usableLimit = detail.contextLimit > 0 ? `${formatCount2(detail.contextLimit)} usable tokens` : "? usable tokens";
24811
25090
  const historianState = detail.historianRunning ? "running" : "idle";
24812
25091
  const historianDetails = [
24813
25092
  detail.boundaryPresent === undefined ? undefined : `boundary ${detail.boundaryPresent ? "present" : "absent"}`,
@@ -24825,19 +25104,19 @@ function formatStatusDetailMarkdown(detail) {
24825
25104
  "",
24826
25105
  `- **Mode:** ${mode}`,
24827
25106
  `- **Active profile:** ${detail.activeProfile ?? "none"}`,
24828
- `- **Usage:** ${detail.usagePercentage.toFixed(1)}% (${formatCount(detail.inputTokens)} / ${usableLimit})`,
25107
+ `- **Usage:** ${detail.usagePercentage.toFixed(1)}% (${formatCount2(detail.inputTokens)} / ${usableLimit})`,
24829
25108
  `- **${formatCacheTtlDisplay({ value: detail.cacheTtl, source: detail.cacheTtlSource ?? "session", modelKey: detail.cacheTtlModelKey })}**; ${formatCacheLane(detail)}`,
24830
25109
  `- **Historian:** ${[historianState, ...historianDetails].join("; ")}`,
24831
25110
  ...detail.hostBackendsModuleSide ? [`- ${RUST_MODE_HOST_PATHS_LINE}`] : [],
24832
- `- **Memory:** ${formatCount(detail.memoryCount)} active; ${formatCount(detail.memoryBlockCount)} injected`,
24833
- `- **Tags:** ${formatCount(detail.activeTags)} active, ${formatCount(detail.droppedTags)} dropped; ${formatCount(detail.pendingOpsCount)} pending drops`,
25111
+ `- **Memory:** ${formatCount2(detail.memoryCount)} active; ${formatCount2(detail.memoryBlockCount)} injected`,
25112
+ `- **Tags:** ${formatCount2(detail.activeTags)} active, ${formatCount2(detail.droppedTags)} dropped; ${formatCount2(detail.pendingOpsCount)} pending drops`,
24834
25113
  `- **Execute threshold:** ${detail.executeThreshold.toFixed(1)}%${detail.executeThresholdClamped ? " (clamped)" : ""}`
24835
25114
  ];
24836
25115
  if (detail.recompProgress?.phase === "recomp") {
24837
- lines.push(`- **${detail.recompProgress.kind === "embed" ? "Embed" : "Historian"} progress:** ${formatCount(detail.recompProgress.processedMessages)} / ${formatCount(detail.recompProgress.totalMessages)}`);
25116
+ lines.push(`- **${detail.recompProgress.kind === "embed" ? "Embed" : "Historian"} progress:** ${formatCount2(detail.recompProgress.processedMessages)} / ${formatCount2(detail.recompProgress.totalMessages)}`);
24838
25117
  }
24839
25118
  if (detail.lastTransformError) {
24840
- lines.push(`- **Last transform error:** ${detail.lastTransformError}`);
25119
+ lines.push(`- **Warning:** ${renderUserFacingFailure("transform_update_failed")}`);
24841
25120
  }
24842
25121
  return lines.join(`
24843
25122
  `);
@@ -24858,7 +25137,8 @@ function resolveTailHygieneStatus(tsBaseline, rustBaseline) {
24858
25137
  evaluable: rustBaseline.evaluable === true,
24859
25138
  generationInvalidated: rustBaseline.generation_invalidated === true,
24860
25139
  baselineGeneration: Math.max(0, finiteNumber(rustBaseline.baseline_generation)),
24861
- computedAt: Math.max(0, finiteNumber(rustBaseline.computed_at_ms))
25140
+ computedAt: Math.max(0, finiteNumber(rustBaseline.computed_at_ms)),
25141
+ reclaimableToolOutputCount: Math.max(0, Math.floor(finiteNumber(rustBaseline.reclaimable_tool_output_count)))
24862
25142
  };
24863
25143
  }
24864
25144
  if (tsBaseline === undefined)
@@ -24872,7 +25152,8 @@ function resolveTailHygieneStatus(tsBaseline, rustBaseline) {
24872
25152
  evaluable: tsBaseline.evaluable && !tsBaseline.generationInvalidated,
24873
25153
  generationInvalidated: tsBaseline.generationInvalidated,
24874
25154
  baselineGeneration: Math.max(0, tsBaseline.baselineGeneration),
24875
- computedAt: Math.max(0, tsBaseline.computedAt)
25155
+ computedAt: Math.max(0, tsBaseline.computedAt),
25156
+ reclaimableToolOutputCount: tsBaseline.baselineParts.filter((part) => part.kind === "toolOutput" && part.uTokens > 0).length
24876
25157
  };
24877
25158
  }
24878
25159
  function formatTailHygiene(status) {
@@ -25313,7 +25594,7 @@ function executeStatus(db, sessionId, executeThresholdPercentageConfig = DEFAULT
25313
25594
  `- Drops: ${pendingOps.length}`,
25314
25595
  `- Total queued: ${pendingOps.length}`,
25315
25596
  "",
25316
- ...meta.lastTransformError ? ["### Last Transform Error", `- ${meta.lastTransformError}`, ""] : [],
25597
+ ...meta.lastTransformError ? ["### Warning", `- ${renderUserFacingFailure("transform_update_failed")}`, ""] : [],
25317
25598
  "### Cache TTL",
25318
25599
  `- ${formatCacheTtlDisplay(ttlDisplay)}`,
25319
25600
  `- Last response: ${meta.lastResponseTime > 0 ? `${Math.round(elapsed / 1000)}s ago` : "never"}`,
@@ -25352,6 +25633,30 @@ ${c.content}
25352
25633
  }
25353
25634
  const budgetTokens = historyBudgetPercentage && displayContextLimit > 0 ? Math.floor(displayContextLimit * (Math.min(executeThresholdPercentage, 80) / 100) * historyBudgetPercentage) : null;
25354
25635
  const budgetUsage = budgetTokens ? (historyBlockTokens / budgetTokens * 100).toFixed(0) : null;
25636
+ if (display?.diagnostics === false) {
25637
+ return renderUserStatusSummary({
25638
+ inputTokens: displayInputTokens,
25639
+ usableContextTokens: displayContextLimit,
25640
+ usagePercentage: displayPercentage,
25641
+ cacheLifetime: formatCacheTtlDisplay(ttlDisplay).replace(/^Cache TTL:\s*/, ""),
25642
+ automaticCompressionThreshold: display?.compactionEnabled === false ? null : thresholdDetail.percentage,
25643
+ compression: {
25644
+ state: meta.compartmentInProgress ? "compressing" : compartments.length > 0 ? "ready" : "waiting",
25645
+ historyBlockCount: compartments.length
25646
+ },
25647
+ reclaimable: {
25648
+ toolOutputCount: tailHygiene?.reclaimableToolOutputCount ?? 0,
25649
+ tokens: tailHygiene?.u ?? 0
25650
+ },
25651
+ memoryCount: 0,
25652
+ noteCount: 0,
25653
+ embedding: { state: "waiting", indexed: 0, total: 0 },
25654
+ warnings: [
25655
+ ...meta.lastTransformError ? ["transform_update_failed"] : [],
25656
+ ...parseFailureLines.length > 0 ? ["configuration_warning"] : []
25657
+ ]
25658
+ }, "markdown");
25659
+ }
25355
25660
  lines.push("", "### History Compression", `- Compartments: ${compartments.length}`, `- History block: ~${historyBlockTokens.toLocaleString()} tokens`, ...budgetTokens ? [
25356
25661
  `- History budget: ~${budgetTokens.toLocaleString()} tokens (${budgetUsage}% used)`,
25357
25662
  `- Older compartments demote tiers automatically at render time to fit the budget`
@@ -25371,14 +25676,14 @@ ${c.content}
25371
25676
  return lines.join(`
25372
25677
  `);
25373
25678
  } catch (error) {
25374
- sessionLog(sessionId, "ctx-status failed:", error);
25375
- return `Error: Failed to read context status. ${getErrorMessage(error)}`;
25679
+ sessionLog(sessionId, `ctx-status failed code=${userFacingFailureCode("status_unavailable")}: ${getErrorMessage(error)}`);
25680
+ return `Error: ${renderUserFacingFailure("status_unavailable")}`;
25376
25681
  }
25377
25682
  }
25378
25683
 
25379
25684
  // src/hooks/magic-context/maintenance-authority.ts
25380
- var RUST_SESSION_UPGRADE_REFUSAL = "Session upgrade is unavailable while Rust transform authority is active. The module owns compartment and memory state; switch authority through the documented drain flow before upgrading.";
25381
- var RUST_PARTIAL_RECOMP_REFUSAL = "Partial recomp is unavailable while Rust transform authority is active. The module supports only a full-session recomp; no state was changed.";
25685
+ var RUST_SESSION_UPGRADE_REFUSAL = renderCapabilityRefusal("session_upgrade");
25686
+ var RUST_PARTIAL_RECOMP_REFUSAL = renderCapabilityRefusal("partial_history");
25382
25687
 
25383
25688
  // src/hooks/magic-context/command-handler.ts
25384
25689
  var recompConfirmationBySession = new Map;
@@ -25449,7 +25754,10 @@ function parseWrapupArgs(raw) {
25449
25754
  return { ok: true, messagesToKeep };
25450
25755
  }
25451
25756
  var commandArgumentValidators = {
25452
- "ctx-status": (raw) => raw.trim() === "",
25757
+ "ctx-status": (raw) => {
25758
+ const mode = raw.trim().toLowerCase();
25759
+ return mode === "" || mode === "diagnostics";
25760
+ },
25453
25761
  "ctx-recomp": (raw) => parseRecompArgs(raw).kind !== "error",
25454
25762
  "ctx-wrapup": (raw) => parseWrapupArgs(raw).ok,
25455
25763
  "ctx-session-upgrade": (raw) => raw.trim() === "",
@@ -25524,11 +25832,11 @@ ${summary || "Nothing to compact."}`;
25524
25832
  case "retryable":
25525
25833
  return `## Magic Wrapup — Partial
25526
25834
 
25527
- ${summary || "Wrapup made progress but stopped before the keep watermark."} Run /ctx-wrapup again to continue.`;
25835
+ ${renderCapabilityRefusal("history_compression")}`;
25528
25836
  default:
25529
25837
  return `## Magic Wrapup — Failed
25530
25838
 
25531
- ${summary || "Wrapup failed; try /ctx-wrapup again."}${rounds > 0 ? ` (${rounds} round${rounds === 1 ? "" : "s"})` : ""}`;
25839
+ ${renderCapabilityRefusal("history_compression")}`;
25532
25840
  }
25533
25841
  }
25534
25842
  switch (disposition) {
@@ -25539,7 +25847,7 @@ Recomp started. Rebuilding the compressed history from raw session history now;
25539
25847
  case "already_in_progress":
25540
25848
  return `## Magic Recomp — Skipped
25541
25849
 
25542
- Historian recomp is already running for this session. Wait for it to finish, then try /ctx-recomp again.`;
25850
+ History compression is already running for this session. Wait for it to finish, then try /ctx-recomp again.`;
25543
25851
  case "nothing_to_do":
25544
25852
  return `## Magic Recomp
25545
25853
 
@@ -25547,7 +25855,7 @@ Nothing to rebuild: this session has no published compartments.`;
25547
25855
  default:
25548
25856
  return `## Magic Recomp — Failed
25549
25857
 
25550
- ${summary || "Historian recomp failed; try /ctx-recomp again."}`;
25858
+ ${renderCapabilityRefusal("history_compression")}`;
25551
25859
  }
25552
25860
  }
25553
25861
  function formatRustStatusText(value) {
@@ -25656,8 +25964,15 @@ Unknown task "${requested}". Valid tasks: ${CANONICAL_DREAM_TASKS.join(", ")}.`,
25656
25964
  formatDreamTaskBacklogs(backlogBefore, backlogTasks)
25657
25965
  ].join(`
25658
25966
  `), dreamNotificationParams);
25659
- const summary = await deps.dreamer.runManual(task);
25660
- await deps.sendNotification(sessionId, summarizeManualDream(summary), dreamNotificationParams);
25967
+ try {
25968
+ const summary = await deps.dreamer.runManual(task);
25969
+ await deps.sendNotification(sessionId, summarizeManualDream(summary), dreamNotificationParams);
25970
+ } catch (error) {
25971
+ sessionLog(sessionId, `ctx-dream failed code=${userFacingFailureCode("dream_unknown")}`, error);
25972
+ await deps.sendNotification(sessionId, `## /ctx-dream
25973
+
25974
+ ${renderUserFacingFailure("dream_unknown")}`, dreamNotificationParams);
25975
+ }
25661
25976
  throwSentinel("CTX-DREAM");
25662
25977
  }
25663
25978
  function createMagicContextCommandHandler(deps) {
@@ -25756,7 +26071,8 @@ Embedding status is unavailable.`;
25756
26071
  });
25757
26072
  result = value.armed === false ? "No pending operations to flush." : "Flushed: Changes take effect on next message.";
25758
26073
  } catch (error) {
25759
- result = `Error: Failed to flush context operations. ${error instanceof Error ? error.message : String(error)}`;
26074
+ sessionLog(sessionId, `ctx-flush failed code=${capabilityRefusalCode("context_cleanup")}`, error);
26075
+ result = renderCapabilityRefusal("context_cleanup");
25760
26076
  }
25761
26077
  } else {
25762
26078
  result = executeFlush(deps.db, sessionId);
@@ -25769,6 +26085,7 @@ Embedding status is unavailable.`;
25769
26085
  }
25770
26086
  }
25771
26087
  if (isStatus) {
26088
+ const statusDiagnostics = input.arguments.trim().toLowerCase() === "diagnostics";
25772
26089
  let rustStatus;
25773
26090
  if (rustMode) {
25774
26091
  try {
@@ -25782,7 +26099,7 @@ Embedding status is unavailable.`;
25782
26099
  }
25783
26100
  }
25784
26101
  if (isTuiConnected2(sessionId)) {
25785
- pushNotification2("action", { action: "show-status-dialog" }, sessionId);
26102
+ pushNotification2("action", { action: "show-status-dialog", diagnostics: statusDiagnostics }, sessionId);
25786
26103
  sessionLog(sessionId, "command ctx-status: pushed show-status-dialog to TUI");
25787
26104
  throwSentinel(input.command);
25788
26105
  }
@@ -25792,9 +26109,9 @@ Embedding status is unavailable.`;
25792
26109
  if (rustMode && !rustStatus) {
25793
26110
  combinedStatus = `## Magic Status — Unavailable
25794
26111
 
25795
- Rust module status could not be read. Canonical session usage, tags, and compartments live in mc-store, so context.db mirror values are intentionally omitted.`;
26112
+ ${renderUserFacingFailure("status_unavailable")}`;
25796
26113
  } else if (detail) {
25797
- combinedStatus = formatStatusDetailMarkdown(detail);
26114
+ combinedStatus = statusDiagnostics ? formatStatusDiagnosticsMarkdown(detail) : formatStatusDetailMarkdown(detail);
25798
26115
  } else {
25799
26116
  const liveModelKey = deps.getLiveModelKey?.(sessionId);
25800
26117
  const liveContextLimit = deps.getContextLimit?.(sessionId);
@@ -25808,12 +26125,14 @@ Rust module status could not be read. Canonical session usage, tags, and compart
25808
26125
  } : undefined, windowGeometry, tailHygiene, undefined, Boolean(rustMode), {
25809
26126
  cacheTtlConfig: deps.cacheTtlConfig ?? "5m",
25810
26127
  cacheTtlConfigured: deps.cacheTtlConfigured === true,
25811
- configParseFailures: deps.configParseFailures ?? []
26128
+ configParseFailures: deps.configParseFailures ?? [],
26129
+ diagnostics: statusDiagnostics,
26130
+ compactionEnabled: !deps.compactionOff
25812
26131
  });
25813
- const moduleStatus = rustStatus ? `
26132
+ const moduleStatus = rustStatus && statusDiagnostics ? `
25814
26133
 
25815
26134
  ${formatRustStatusText(rustStatus)}` : "";
25816
- const modeStatus = deps.compactionOff ? `**Compaction:** disabled (${COMPACTION_ENABLED_PATH}: false) — native compaction owns the context window.
26135
+ const modeStatus = deps.compactionOff && statusDiagnostics ? `**Compaction:** disabled (${COMPACTION_ENABLED_PATH}: false) — native compaction owns the context window.
25817
26136
 
25818
26137
  ` : "";
25819
26138
  combinedStatus = `${modeStatus}${statusOutput}${moduleStatus}`;
@@ -25822,7 +26141,7 @@ ${formatRustStatusText(rustStatus)}` : "";
25822
26141
  sessionLog(sessionId, "shared ctx-status detail failed; using compatibility text:", error);
25823
26142
  combinedStatus = rustMode ? `## Magic Status — Unavailable
25824
26143
 
25825
- Rust module status failed while formatting. Canonical session usage, tags, and compartments live in mc-store, so context.db mirror values are intentionally omitted.` : executeStatus(deps.db, sessionId);
26144
+ ${renderUserFacingFailure("status_unavailable")}` : executeStatus(deps.db, sessionId);
25826
26145
  }
25827
26146
  result += result ? `
25828
26147
 
@@ -25853,9 +26172,10 @@ Starting wrapup…`, {});
25853
26172
  }, MAX_WRAPUP_REQUEST_BUDGET_MS);
25854
26173
  result = formatRustOperationMessage("wrapup", value);
25855
26174
  } catch (error) {
26175
+ sessionLog(sessionId, `ctx-wrapup failed code=${capabilityRefusalCode("history_compression")}`, error);
25856
26176
  result = `## Magic Wrapup — Failed
25857
26177
 
25858
- ${error instanceof Error ? error.message : String(error)}`;
26178
+ ${renderCapabilityRefusal("history_compression")}`;
25859
26179
  }
25860
26180
  } else if (!deps.executeWrapup) {
25861
26181
  result = `## Magic Wrapup
@@ -25889,9 +26209,10 @@ ${RUST_PARTIAL_RECOMP_REFUSAL}`;
25889
26209
  });
25890
26210
  result = formatRustOperationMessage("recomp", value);
25891
26211
  } catch (error) {
26212
+ sessionLog(sessionId, `ctx-recomp failed code=${capabilityRefusalCode("history_compression")}`, error);
25892
26213
  result = `## Magic Recomp — Failed
25893
26214
 
25894
- ${error instanceof Error ? error.message : String(error)}`;
26215
+ ${renderCapabilityRefusal("history_compression")}`;
25895
26216
  }
25896
26217
  } else if (isTuiConnected2(sessionId)) {
25897
26218
  pushNotification2("action", { action: "show-recomp-dialog" }, sessionId);
@@ -28697,6 +29018,7 @@ function buildStatusDetail(db, sessionId, directory, modelKey, config, liveSessi
28697
29018
  lastResponseTime: 0,
28698
29019
  lastNudgeTokens: 0,
28699
29020
  lastTransformError: null,
29021
+ historianFailureCount: 0,
28700
29022
  isSubagent: false,
28701
29023
  pendingOps: [],
28702
29024
  contextLimit: 0,
@@ -28742,6 +29064,7 @@ function buildStatusDetail(db, sessionId, directory, modelKey, config, liveSessi
28742
29064
  detail.lastResponseTime = Number(meta.last_response_time ?? 0);
28743
29065
  detail.lastNudgeTokens = Number(meta.last_nudge_tokens ?? 0);
28744
29066
  detail.lastTransformError = meta.last_transform_error ? String(meta.last_transform_error) : null;
29067
+ detail.historianFailureCount = Number(meta.historian_failure_count ?? 0);
28745
29068
  detail.isSubagent = Boolean(meta.is_subagent);
28746
29069
  persistedCacheTtl = typeof meta.cache_ttl === "string" && meta.cache_ttl.length > 0 ? meta.cache_ttl : "5m";
28747
29070
  persistedModelKey = typeof meta.last_observed_model_key === "string" && meta.last_observed_model_key.length > 0 ? meta.last_observed_model_key : null;
@@ -28821,6 +29144,19 @@ function buildStatusDetail(db, sessionId, directory, modelKey, config, liveSessi
28821
29144
  detail.cacheExpired = detail.cacheRemainingMs === 0;
28822
29145
  }
28823
29146
  }
29147
+ if (base.projectIdentity) {
29148
+ try {
29149
+ const coverage = getEmbeddingCoverageStatus(db, base.projectIdentity, sessionId);
29150
+ const runState = getEmbedDrainUiStatus(sessionId, base.recompProgress ?? undefined).status;
29151
+ detail.embedding = {
29152
+ state: !coverage.enabled ? "off" : runState !== "idle" ? runState : coverage.session.total > 0 && coverage.session.embedded >= coverage.session.total ? "ready" : "waiting",
29153
+ indexed: coverage.session.embedded,
29154
+ total: coverage.session.total
29155
+ };
29156
+ } catch {
29157
+ detail.embedding = { state: "waiting", indexed: 0, total: 0 };
29158
+ }
29159
+ }
28824
29160
  try {
28825
29161
  const histTokens = base.compartmentTokens + base.factTokens;
28826
29162
  detail.historyBlockTokens = histTokens;
@@ -29158,7 +29494,7 @@ function registerRpcHandlers(rpcServer, args) {
29158
29494
  const db = getDb();
29159
29495
  if (!db)
29160
29496
  return { ok: false, error: "db unavailable" };
29161
- const { runManagedRecomp } = await import("./recomp-orchestrator-3atsasjy.js");
29497
+ const { runManagedRecomp } = await import("./recomp-orchestrator-5g8f5rhy.js");
29162
29498
  const { sendIgnoredMessage } = await import("./send-session-notification-1qeqkswb.js");
29163
29499
  log(`[rpc] recomp requested for session ${sessionId}`);
29164
29500
  const ctx = await buildManagedCtx(db);
@@ -29177,7 +29513,7 @@ function registerRpcHandlers(rpcServer, args) {
29177
29513
  const db = getDb();
29178
29514
  if (!db)
29179
29515
  return { ok: false, error: "db unavailable" };
29180
- const { runManagedUpgrade } = await import("./recomp-orchestrator-3atsasjy.js");
29516
+ const { runManagedUpgrade } = await import("./recomp-orchestrator-5g8f5rhy.js");
29181
29517
  const { sendIgnoredMessage } = await import("./send-session-notification-1qeqkswb.js");
29182
29518
  log(`[rpc] session-upgrade requested for session ${sessionId}`);
29183
29519
  const ctx = await buildManagedCtx(db);
@@ -30225,13 +30561,38 @@ function parsePersistedLkgSlot(row) {
30225
30561
  const jsonPrefix = record.json_prefix;
30226
30562
  const lastInputMessageId = record.last_input_message_id;
30227
30563
  const capturedAt = record.captured_at;
30228
- 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);
30229
30580
  const inputContentDigests = parseStringArray(record.input_content_digests);
30230
30581
  const modelKey = parseNullableString(record.model_key);
30231
30582
  const providerKey = parseNullableString(record.provider_key);
30232
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) {
30233
30584
  return;
30234
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
+ }
30235
30596
  let inputContentSignatures;
30236
30597
  if (record.input_content_signatures !== null && record.input_content_signatures !== undefined) {
30237
30598
  const parsed = parseStringArray(record.input_content_signatures);
@@ -30250,6 +30611,8 @@ function parsePersistedLkgSlot(row) {
30250
30611
  };
30251
30612
  if (inputContentSignatures)
30252
30613
  slot.inputContentSignatures = inputContentSignatures;
30614
+ if (piOutputEntryIds)
30615
+ slot.piOutputEntryIds = piOutputEntryIds;
30253
30616
  const rowVersion = parseNullableInteger(record.row_version);
30254
30617
  if (rowVersion !== undefined)
30255
30618
  slot.rowVersion = rowVersion;
@@ -30275,7 +30638,11 @@ function saveLkgSlotToDb(db, sessionId, slot) {
30275
30638
  provider_key = excluded.provider_key,
30276
30639
  captured_at = excluded.captured_at,
30277
30640
  row_version = excluded.row_version,
30278
- 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);
30279
30646
  return true;
30280
30647
  } catch (error) {
30281
30648
  sessionLog(sessionId, "LKG snapshot persistence failed (in-memory slot retained):", error);
@@ -31759,7 +32126,7 @@ function applyHeuristicCleanup(sessionId, db, targets, messageTagNumbers, config
31759
32126
  emergencyReclaimedTokens += estimateEmergencyDropReclaimTokens(tag);
31760
32127
  }
31761
32128
  }
31762
- })();
32129
+ }).immediate();
31763
32130
  sessionLog(sessionId, `emergency tiered drop: ${plan.reason}`);
31764
32131
  } else {
31765
32132
  sessionLog(sessionId, `emergency tiered drop skipped: ${plan.reason}`);
@@ -31806,7 +32173,7 @@ function applyHeuristicCleanup(sessionId, db, targets, messageTagNumbers, config
31806
32173
  }
31807
32174
  }
31808
32175
  }
31809
- })();
32176
+ }).immediate();
31810
32177
  }
31811
32178
  const allMessages = Array.from(messageTagNumbers.keys());
31812
32179
  const toolFingerprints = buildToolFingerprints(allMessages);
@@ -31845,7 +32212,7 @@ function applyHeuristicCleanup(sessionId, db, targets, messageTagNumbers, config
31845
32212
  }
31846
32213
  }
31847
32214
  }
31848
- })();
32215
+ }).immediate();
31849
32216
  }
31850
32217
  if (droppedTools > 0 || deduplicatedTools > 0 || droppedInjections > 0) {
31851
32218
  sessionLog(sessionId, `heuristic cleanup: dropped ${droppedTools} tool tags, deduplicated ${deduplicatedTools} tool calls, dropped ${droppedInjections} system injections`);
@@ -32110,78 +32477,93 @@ function buildReplacementContent(tagId) {
32110
32477
  }
32111
32478
  function applyPendingOperations(sessionId, db, targets, protectedTagIds, preloadedTags, preloadedPendingOps, syntheticPendingOps = [], editMarkerTagIds = new Set) {
32112
32479
  let didMutateMessage = false;
32113
- db.transaction(() => {
32114
- const tags = preloadedTags ?? getTagsBySession(db, sessionId);
32115
- const tagStatusById = new Map(tags.map((tag) => [tag.tagNumber, tag.status]));
32116
- const tagTypeById = new Map(tags.map((tag) => [tag.tagNumber, tag.type]));
32117
- const pendingOps = preloadedPendingOps ?? getPendingOps(db, sessionId);
32118
- const opsToApply = [
32119
- ...pendingOps.map((op) => ({ op, synthetic: false })),
32120
- ...syntheticPendingOps.map((op) => ({ op, synthetic: true }))
32121
- ];
32122
- 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));
32123
- for (const { op: pendingOp, synthetic } of opsToApply) {
32124
- const tagStatus = tagStatusById.get(pendingOp.tagId);
32125
- if (tagStatus === "compacted" || tagStatus === "dropped") {
32126
- if (!synthetic)
32127
- removePendingOp(db, sessionId, pendingOp.tagId);
32128
- continue;
32129
- }
32130
- if (protectedTagIds.has(pendingOp.tagId)) {
32131
- continue;
32132
- }
32133
- const target = targets.get(pendingOp.tagId);
32134
- const isToolTag = tagTypeById.get(pendingOp.tagId) === "tool";
32135
- if (synthetic) {
32136
- 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);
32137
32500
  continue;
32138
- }
32139
- let shouldPersistDrop = false;
32140
- if (isToolTag) {
32141
- if (editMarkerTagIds.has(pendingOp.tagId)) {
32142
- const markResult = target?.editMarker?.() ?? "absent";
32143
- if (markResult === "incomplete" || markResult === "absent") {
32144
- continue;
32145
- }
32146
- didMutateMessage = true;
32147
- updateTagDropMode(db, sessionId, pendingOp.tagId, "edit_marker");
32148
- shouldPersistDrop = true;
32149
- } else if (skeletonWindow.has(pendingOp.tagId)) {
32150
- const truncResult = target?.truncate?.() ?? "absent";
32151
- 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)
32152
32509
  continue;
32153
- }
32154
- 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
+ }
32155
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;
32156
32541
  }
32157
- updateTagDropMode(db, sessionId, pendingOp.tagId, "truncated");
32158
- shouldPersistDrop = true;
32159
- } else {
32160
- const dropResult = target?.drop?.() ?? "absent";
32161
- if (dropResult === "incomplete" || synthetic && dropResult !== "removed") {
32162
- continue;
32163
- }
32164
- if (dropResult === "removed") {
32542
+ } else if (target) {
32543
+ const changed = target.setContent(buildReplacementContent(pendingOp.tagId));
32544
+ if (changed)
32165
32545
  didMutateMessage = true;
32166
- }
32167
- updateTagDropMode(db, sessionId, pendingOp.tagId, "full");
32546
+ shouldPersistDrop = true;
32547
+ } else if (!synthetic) {
32168
32548
  shouldPersistDrop = true;
32169
32549
  }
32170
- } else if (target) {
32171
- const changed = target.setContent(buildReplacementContent(pendingOp.tagId));
32172
- if (changed)
32173
- didMutateMessage = true;
32174
- shouldPersistDrop = true;
32175
- } else if (!synthetic) {
32176
- shouldPersistDrop = true;
32550
+ if (!shouldPersistDrop)
32551
+ continue;
32552
+ updateTagStatus(db, sessionId, pendingOp.tagId, "dropped");
32553
+ if (!synthetic)
32554
+ removePendingOp(db, sessionId, pendingOp.tagId);
32177
32555
  }
32178
- if (!shouldPersistDrop)
32179
- continue;
32180
- updateTagStatus(db, sessionId, pendingOp.tagId, "dropped");
32181
- if (!synthetic)
32182
- 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;
32183
32561
  }
32184
- })();
32562
+ throw error;
32563
+ } finally {
32564
+ if (admitted)
32565
+ logSlowWriteTransaction("apply_pending_operations", startedAt);
32566
+ }
32185
32567
  return didMutateMessage;
32186
32568
  }
32187
32569
  function applyFlushedStatuses(sessionId, db, targets, preloadedTags) {
@@ -32978,7 +33360,8 @@ function runRustModePostprocess(args) {
32978
33360
  db: args.db,
32979
33361
  sessionId: args.sessionId,
32980
33362
  tagger: args.tagger,
32981
- ctxReduceAvailability: args.ctxReduceAvailability
33363
+ ctxReduceAvailability: args.ctxReduceAvailability,
33364
+ isCacheBustingPass: args.materializedBoundary != null
32982
33365
  });
32983
33366
  for (const anchor of getNoteNudgeAnchors(args.db, args.sessionId)) {
32984
33367
  appendReminderToUserMessageById(args.messages, anchor.messageId, anchor.text);
@@ -33073,6 +33456,13 @@ function dropMarkerSummaryTag(db, sessionId, summaryMessageId) {
33073
33456
  updateTagStatus(db, sessionId, tagNumber, "dropped");
33074
33457
  }
33075
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
+ }
33076
33466
  const retainedMessages = [];
33077
33467
  const staleSummaryIds = new Set;
33078
33468
  for (const message of messages) {
@@ -33770,7 +34160,8 @@ async function runPostTransformPhase(args) {
33770
34160
  db: args.db,
33771
34161
  sessionId: args.sessionId,
33772
34162
  tagger: args.tagger,
33773
- ctxReduceAvailability: args.ctxReduceAvailability
34163
+ ctxReduceAvailability: args.ctxReduceAvailability,
34164
+ isCacheBustingPass
33774
34165
  });
33775
34166
  }
33776
34167
  const deferredHistoryDrainEligible = historyWasConsumedThisPass && args.deferredHistoryWasPendingAtPassStart && !suppressV12HistoryDrain;
@@ -38238,37 +38629,10 @@ function createEventHandler2(deps) {
38238
38629
  }
38239
38630
 
38240
38631
  // src/hooks/magic-context/format-embed-failure.ts
38241
- function formatEmbedFailureSummary(embedded, remaining, failure) {
38242
- const compartment = `compartment${embedded === 1 ? "" : "s"}`;
38243
- if (!failure) {
38244
- return `Embedded ${embedded} ${compartment}; ${remaining} could not be embedded (the provider returned no result). Run /ctx-embed start again to retry them.`;
38245
- }
38246
- const retry = " Run /ctx-embed start again to retry them.";
38247
- switch (failure.class) {
38248
- case "substitution_rejected":
38249
- return `Embedded ${embedded} ${compartment}; ${remaining} rejected: ${failure.reason}. Fix: set embedding.model to the served spelling.`;
38250
- case "http_error": {
38251
- const fix = failure.reason.startsWith("HTTP 401") || failure.reason.startsWith("HTTP 403") ? " Fix: check embedding.api_key." : failure.reason.startsWith("HTTP 402") ? " Fix: check provider quota or billing." : failure.reason.startsWith("HTTP 404") ? " Fix: check embedding.endpoint and embedding.model." : failure.retryable ? retry : " Fix: check embedding.endpoint, embedding.model, and credentials.";
38252
- return `Embedded ${embedded} ${compartment}; ${remaining} failed: ${failure.reason}.${fix}`;
38253
- }
38254
- case "invalid_envelope":
38255
- return `Embedded ${embedded} ${compartment}; ${remaining} failed: ${failure.reason}. Fix: configure an OpenAI-compatible embedding endpoint that returns data[].embedding.`;
38256
- case "certification_refusal":
38257
- return `Embedded ${embedded} ${compartment}; ${remaining} rejected: ${failure.reason}. Fix: recertify SYNAPSE or configure embedding.fallback_provider, then run /ctx-embed start again.`;
38258
- case "credential_required":
38259
- return `Embedded ${embedded} ${compartment}; ${remaining} rejected: ${failure.reason}. Fix: reauthenticate SYNAPSE, then run /ctx-embed start again.`;
38260
- case "local_binding_missing":
38261
- return `Embedded ${embedded} ${compartment}; ${remaining} failed: ${failure.reason}. Fix: run \`npx @cortexkit/magic-context@latest doctor\` to verify the WASM fallback. On Intel macOS, onnxruntime-node@1.23.0 may be pinned manually for optional native speed.`;
38262
- case "local_fs_unavailable":
38263
- return `Embedded ${embedded} ${compartment}; ${remaining} failed: ${failure.reason}. Fix: update or reinstall Magic Context so its Node WASM bundle can persist the model, then run /ctx-embed start again.`;
38264
- case "local_download_failure":
38265
- return `Embedded ${embedded} ${compartment}; ${remaining} failed: ${failure.reason}. Fix: check network/proxy access to the model host.${retry}`;
38266
- case "local_runtime_error":
38267
- return `Embedded ${embedded} ${compartment}; ${remaining} failed: ${failure.reason}. Fix: run \`npx @cortexkit/magic-context@latest doctor\` for local runtime diagnostics.`;
38268
- case "empty_result":
38269
- case "transport_error":
38270
- return `Embedded ${embedded} ${compartment}; ${remaining} failed: ${failure.reason}.${failure.retryable ? retry : ""}`;
38271
- }
38632
+ function formatEmbedFailureSummary(embedded, remaining, failure, style = "markdown") {
38633
+ const historyBlocks = `history block${embedded === 1 ? "" : "s"}`;
38634
+ const progress = `Indexed ${embedded} ${historyBlocks}; ${remaining} remain.`;
38635
+ return `${progress} ${renderEmbeddingFailure(failure?.class ?? "empty_result", style)}`;
38272
38636
  }
38273
38637
 
38274
38638
  // src/hooks/magic-context/text-complete.ts
@@ -40702,13 +41066,9 @@ function normalizeCategory(category) {
40702
41066
  const trimmed = category?.trim();
40703
41067
  return trimmed ? trimmed : undefined;
40704
41068
  }
40705
- function memoryAuthorityRefusal(args, cause) {
40706
- const readiness = "Rust memory authority is not ready.";
40707
- const refusal = (args.action === "write" || args.action === "update" || args.action === "merge") && typeof args.content === "string" ? `Error: ${readiness} Write REFUSED and NOT saved; RESEND the same call after authority is ready; the Rust module typically recovers in seconds-to-minutes.
40708
- Content to resend:
40709
- ${args.content}` : `Error: ${readiness} Request REFUSED and NOT applied; RESEND the same call after authority is ready; the Rust module typically recovers in seconds-to-minutes.`;
40710
- return cause ? `${cause}
40711
- ${refusal}` : refusal;
41069
+ function memoryAuthorityRefusal(args) {
41070
+ const isMutation = args.action !== undefined && ["write", "update", "archive", "merge"].includes(args.action);
41071
+ return renderCapabilityRefusal(isMutation ? "memory_write" : "memory_access");
40712
41072
  }
40713
41073
  function moduleMemoryText(response, args) {
40714
41074
  let value = response;
@@ -40990,14 +41350,14 @@ function createCtxMemoryTool(deps) {
40990
41350
  }) ?? null;
40991
41351
  } catch (error) {
40992
41352
  if (marker) {
40993
- const detail = error instanceof Error ? error.message : String(error);
40994
- return memoryAuthorityRefusal(args, `Error: Rust memory authority is unavailable. ${detail}`);
41353
+ sessionLog(toolContext.sessionID, "ctx_memory capability refusal", error);
41354
+ return memoryAuthorityRefusal(args);
40995
41355
  }
40996
41356
  }
40997
41357
  if (authorityState === "MODULE") {
40998
41358
  const memoryBackend = deps.rustToolBackends?.memory;
40999
41359
  if (!memoryBackend) {
41000
- return "Error: Rust memory authority is active, but this module transport does not support ctx_memory.";
41360
+ return memoryAuthorityRefusal(args);
41001
41361
  }
41002
41362
  try {
41003
41363
  const commandId = toolCallIdFromContext(toolContext);
@@ -41024,13 +41384,13 @@ function createCtxMemoryTool(deps) {
41024
41384
  ids: moduleArgs.ids,
41025
41385
  reason: moduleArgs.reason
41026
41386
  }), moduleArgs);
41027
- return text ?? "Error: Rust module returned an invalid ctx_memory response.";
41387
+ return text ?? memoryAuthorityRefusal(args);
41028
41388
  } catch (error) {
41029
41389
  if (isRustAuthorityDrainingError(error)) {
41030
41390
  return memoryAuthorityRefusal(args);
41031
41391
  }
41032
- const detail = error instanceof Error ? error.message : String(error);
41033
- return memoryAuthorityRefusal(args, `Error: Rust module ctx_memory failed. ${detail}`);
41392
+ sessionLog(toolContext.sessionID, "ctx_memory capability refusal", error);
41393
+ return memoryAuthorityRefusal(args);
41034
41394
  }
41035
41395
  }
41036
41396
  if (marker || authorityState === "PREPARING" || authorityState === "DRAINING") {
@@ -41961,14 +42321,9 @@ ${footer}` : ""}`);
41961
42321
  }
41962
42322
  return sections;
41963
42323
  }
41964
- function noteAuthorityRefusal(args, action) {
41965
- const readiness = "Rust notes authority is not ready.";
41966
- if ((action === "write" || action === "update") && typeof args.content === "string") {
41967
- return `Error: ${readiness} Write REFUSED and NOT saved; RESEND after authority is ready.
41968
- Content to resend:
41969
- ${args.content}`;
41970
- }
41971
- return `Error: ${readiness} Request REFUSED and NOT applied; RESEND after authority is ready.`;
42324
+ function noteAuthorityRefusal(_args, action) {
42325
+ const isMutation = action === "write" || action === "update" || action === "dismiss";
42326
+ return renderCapabilityRefusal(isMutation ? "note_change" : "note_access");
41972
42327
  }
41973
42328
  function moduleNoteText(response, args, action) {
41974
42329
  let value = response;
@@ -42066,19 +42421,20 @@ function createCtxNoteTool(deps) {
42066
42421
  });
42067
42422
  } catch (error) {
42068
42423
  if (marker) {
42069
- return `Error: Rust notes authority is unavailable. ${error instanceof Error ? error.message : String(error)}`;
42424
+ sessionLog(sessionId, "ctx_note capability refusal", error);
42425
+ return noteAuthorityRefusal(args, action);
42070
42426
  }
42071
42427
  }
42072
42428
  }
42073
42429
  if (notesAuthority === "MODULE") {
42074
42430
  const rustNote = deps.rustToolBackends?.note;
42075
42431
  if (!rustNote || !projectIdentity) {
42076
- return "Error: Rust notes authority is active, but this module transport does not support ctx_note.";
42432
+ return noteAuthorityRefusal(args, action);
42077
42433
  }
42078
42434
  let compilation;
42079
42435
  if ((action === "write" || action === "update") && surfaceCondition) {
42080
42436
  if (deps.rustToolBackends?.noteEvaluationAvailable?.(projectIdentity) !== true) {
42081
- return "Error: Smart-note evaluation is unavailable for this Rust-authority project; the note was not written.";
42437
+ return renderCapabilityRefusal("smart_note_condition");
42082
42438
  }
42083
42439
  compilation = await compileSurfaceCondition(surfaceCondition, {
42084
42440
  projectPath: toolContext.directory
@@ -42104,7 +42460,7 @@ function createCtxNoteTool(deps) {
42104
42460
  try {
42105
42461
  const text = moduleNoteText(await rustNote(request), args, action);
42106
42462
  if (text === null) {
42107
- return "Error: Rust module returned an invalid ctx_note response.";
42463
+ return noteAuthorityRefusal(args, action);
42108
42464
  }
42109
42465
  if (text.startsWith("Error:"))
42110
42466
  return text;
@@ -42119,7 +42475,8 @@ wake plane active — create a scheduled wake instead; stored as a plain note.`;
42119
42475
  if (isRustAuthorityDrainingError(error)) {
42120
42476
  return noteAuthorityRefusal(args, action);
42121
42477
  }
42122
- return `Error: Rust module ctx_note failed. ${error instanceof Error ? error.message : String(error)}`;
42478
+ sessionLog(sessionId, "ctx_note capability refusal", error);
42479
+ return noteAuthorityRefusal(args, action);
42123
42480
  }
42124
42481
  }
42125
42482
  if (marker || notesAuthority === "PREPARING" || notesAuthority === "DRAINING") {
@@ -42375,7 +42732,8 @@ function createCtxReduceTool(deps) {
42375
42732
  const error = record && "error" in record ? record.error : undefined;
42376
42733
  const errorRecord = error !== null && typeof error === "object" ? error : undefined;
42377
42734
  const message = (typeof error === "string" && error.trim() ? error : undefined) ?? (typeof errorRecord?.message === "string" && errorRecord.message.trim() ? errorRecord.message : undefined) ?? (typeof record?.message === "string" && record.message.trim() ? record.message : "module rejected agent_drops.append");
42378
- return `Error: Failed to queue ctx_reduce operations. ${message}`;
42735
+ sessionLog(sessionId, "ctx_reduce capability refusal", message);
42736
+ return renderCapabilityRefusal("context_cleanup");
42379
42737
  }
42380
42738
  const queued = typeof record.queued === "number" ? record.queued : 0;
42381
42739
  if (queued <= 0) {
@@ -42383,7 +42741,8 @@ function createCtxReduceTool(deps) {
42383
42741
  }
42384
42742
  return `Queued: drop ${formatRawDropForAck(args.drop)}.`;
42385
42743
  } catch (error) {
42386
- return `Error: Failed to queue ctx_reduce operations. ${getErrorMessage(error)}`;
42744
+ sessionLog(sessionId, "ctx_reduce capability refusal", error);
42745
+ return renderCapabilityRefusal("context_cleanup");
42387
42746
  }
42388
42747
  }
42389
42748
  let dropIds = [];
@@ -43454,6 +43813,9 @@ var server = async (ctx) => {
43454
43813
  return;
43455
43814
  recordToolDefinition(lastChatContext.providerID, lastChatContext.modelID, lastChatContext.agentName, typedInput.toolID, typeof typedOutput.description === "string" ? typedOutput.description : "", typedOutput.parameters);
43456
43815
  },
43816
+ "tool.execute.before": async (input, output) => {
43817
+ await magicContextRuntime.magicContext?.["tool.execute.before"]?.(input, output);
43818
+ },
43457
43819
  "tool.execute.after": async (input, output) => {
43458
43820
  await magicContextRuntime.magicContext?.["tool.execute.after"]?.(input, output);
43459
43821
  },