@joshuaswarren/openclaw-engram 8.3.21 → 8.3.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -4373,7 +4373,7 @@ function parseContinuityIncident(raw) {
4373
4373
  const body = match[2] ?? "";
4374
4374
  const id = typeof frontmatter.id === "string" ? frontmatter.id : "";
4375
4375
  const stateRaw = frontmatter.state;
4376
- const state = stateRaw === "closed" ? "closed" : stateRaw === "open" ? "open" : "open";
4376
+ const state = stateRaw === "closed" ? "closed" : "open";
4377
4377
  const openedAt = typeof frontmatter.openedAt === "string" ? frontmatter.openedAt : "";
4378
4378
  const updatedAt = typeof frontmatter.updatedAt === "string" ? frontmatter.updatedAt : openedAt;
4379
4379
  const symptom = parseSection(body, "Symptom");
@@ -5590,8 +5590,9 @@ ${memory.content}
5590
5590
  await writeFile2(filePath, serializeContinuityIncident(incident), "utf-8");
5591
5591
  return { ...incident, filePath };
5592
5592
  }
5593
- async readContinuityIncidents(limit = 200) {
5594
- const cappedLimit = Math.max(0, Math.floor(limit));
5593
+ async readContinuityIncidents(limit = 200, state = "all") {
5594
+ const normalizedLimit = Number.isFinite(limit) ? Math.floor(limit) : 0;
5595
+ const cappedLimit = Math.max(0, normalizedLimit);
5595
5596
  if (cappedLimit === 0) return [];
5596
5597
  try {
5597
5598
  const candidates = await this.readContinuityIncidentFileNames();
@@ -5602,7 +5603,9 @@ ${memory.content}
5602
5603
  try {
5603
5604
  const raw = await readFile2(filePath, "utf-8");
5604
5605
  const parsed = parseContinuityIncident(raw);
5605
- if (parsed) incidents.push({ ...parsed, filePath });
5606
+ if (!parsed) continue;
5607
+ if (state !== "all" && parsed.state !== state) continue;
5608
+ incidents.push({ ...parsed, filePath });
5606
5609
  } catch {
5607
5610
  }
5608
5611
  }
@@ -5672,7 +5675,11 @@ ${memory.content}
5672
5675
  async findContinuityIncidentFilePathById(id) {
5673
5676
  const fileNames = await this.readContinuityIncidentFileNames();
5674
5677
  const directMatch = fileNames.find((name) => name.endsWith(`-${id}.md`));
5675
- if (directMatch) return path4.join(this.identityIncidentsDir, directMatch);
5678
+ if (directMatch) {
5679
+ const directPath = path4.join(this.identityIncidentsDir, directMatch);
5680
+ const parsed = await this.readContinuityIncidentFile(directPath);
5681
+ if (parsed?.id === id) return directPath;
5682
+ }
5676
5683
  for (const fileName of fileNames) {
5677
5684
  const filePath = path4.join(this.identityIncidentsDir, fileName);
5678
5685
  const parsed = await this.readContinuityIncidentFile(filePath);
@@ -8238,7 +8245,10 @@ var LastRecallStore = class {
8238
8245
  recordedAt: now,
8239
8246
  queryHash,
8240
8247
  queryLen: opts.query.length,
8241
- memoryIds: opts.memoryIds
8248
+ memoryIds: opts.memoryIds,
8249
+ identityInjectionMode: opts.identityInjection?.mode,
8250
+ identityInjectedChars: opts.identityInjection?.injectedChars,
8251
+ identityInjectionTruncated: opts.identityInjection?.truncated
8242
8252
  };
8243
8253
  this.state[opts.sessionKey] = snapshot;
8244
8254
  const keys = Object.keys(this.state);
@@ -10625,7 +10635,7 @@ var CompoundingEngine = class {
10625
10635
  const weekId = opts?.weekId ?? isoWeekId(/* @__PURE__ */ new Date());
10626
10636
  const entries = await this.readFeedbackEntriesForWeek(weekId);
10627
10637
  const mistakes = this.buildMistakes(entries);
10628
- const continuity = await this.readContinuityAuditReferences(weekId);
10638
+ const continuity = this.config.continuityAuditEnabled ? await this.readContinuityAuditReferences(weekId) : { monthId: monthIdFromIsoWeek(weekId), weeklyPath: null, monthlyPath: null };
10629
10639
  const reportPath = path21.join(this.weeklyDir, `${weekId}.md`);
10630
10640
  const md = this.formatWeeklyReport(weekId, entries, mistakes.patterns, continuity);
10631
10641
  await writeFile14(reportPath, md, "utf-8");
@@ -10637,14 +10647,13 @@ var CompoundingEngine = class {
10637
10647
  const period = opts?.period === "monthly" ? "monthly" : "weekly";
10638
10648
  const key = opts?.key?.trim() || (period === "weekly" ? isoWeekId(/* @__PURE__ */ new Date()) : isoMonthId(/* @__PURE__ */ new Date()));
10639
10649
  const nowIso = (/* @__PURE__ */ new Date()).toISOString();
10640
- const [anchorPresent, improvementLoopPresent, incidents, mistakes] = await Promise.all([
10650
+ const [anchorPresent, improvementLoopPresent, openIncidents, closedIncidents, mistakes] = await Promise.all([
10641
10651
  this.readNonEmptyFile(this.identityAnchorPath),
10642
10652
  this.readNonEmptyFile(this.identityImprovementLoopsPath),
10643
- this.readContinuityIncidents(),
10653
+ this.readContinuityIncidents(200, "open"),
10654
+ this.readContinuityIncidents(200, "closed"),
10644
10655
  this.readMistakes()
10645
10656
  ]);
10646
- const openIncidents = incidents.filter((i) => i.state === "open");
10647
- const closedIncidents = incidents.filter((i) => i.state === "closed");
10648
10657
  const hardeningCandidates = [];
10649
10658
  if (!anchorPresent) {
10650
10659
  hardeningCandidates.push("Create/update identity anchor baseline and verify recovery injection path.");
@@ -10803,17 +10812,23 @@ var CompoundingEngine = class {
10803
10812
  return false;
10804
10813
  }
10805
10814
  }
10806
- async readContinuityIncidents() {
10815
+ async readContinuityIncidents(limit = 200, state) {
10816
+ const normalizedLimit = Number.isFinite(limit) ? limit : 0;
10817
+ const cappedLimit = Math.max(0, Math.floor(normalizedLimit));
10818
+ if (cappedLimit === 0) return [];
10807
10819
  const incidents = [];
10808
10820
  try {
10809
10821
  const names = await readdir10(this.identityIncidentsDir);
10810
10822
  const files = names.filter((n) => n.endsWith(".md")).sort().reverse();
10811
10823
  for (const file of files) {
10824
+ if (incidents.length >= cappedLimit) break;
10812
10825
  const filePath = path21.join(this.identityIncidentsDir, file);
10813
10826
  try {
10814
10827
  const raw = await readFile15(filePath, "utf-8");
10815
10828
  const parsed = parseContinuityIncident(raw);
10816
- if (parsed) incidents.push(parsed);
10829
+ if (!parsed) continue;
10830
+ if (state && parsed.state !== state) continue;
10831
+ incidents.push(parsed);
10817
10832
  } catch {
10818
10833
  }
10819
10834
  }
@@ -10971,6 +10986,22 @@ function resolveEffectiveRecallMode(options) {
10971
10986
  }
10972
10987
  return plannedMode;
10973
10988
  }
10989
+ function hasIdentityRecoveryIntent(prompt) {
10990
+ const text = typeof prompt === "string" ? prompt.toLowerCase() : "";
10991
+ if (!text) return false;
10992
+ return /\b(identity|continuity|recover(?:y|ing|ed)?|incident|drift|restore|regress(?:ion|ed|ing)?)\b/i.test(
10993
+ text
10994
+ );
10995
+ }
10996
+ function resolveEffectiveIdentityInjectionMode(options) {
10997
+ if (options.configuredMode === "recovery_only" && !hasIdentityRecoveryIntent(options.prompt)) {
10998
+ return { mode: "recovery_only", shouldInject: false };
10999
+ }
11000
+ if (options.recallMode === "minimal" && options.configuredMode === "full") {
11001
+ return { mode: "minimal", shouldInject: true };
11002
+ }
11003
+ return { mode: options.configuredMode, shouldInject: true };
11004
+ }
10974
11005
  function computeArtifactCandidateFetchLimit(targetCount) {
10975
11006
  const cappedTarget = Math.max(0, targetCount);
10976
11007
  if (cappedTarget === 0) return 0;
@@ -11822,6 +11853,9 @@ var Orchestrator = class _Orchestrator {
11822
11853
  let impressionRecorded = false;
11823
11854
  let recallSource = "none";
11824
11855
  let recalledMemoryCount = 0;
11856
+ let identityInjectionModeUsed = "none";
11857
+ let identityInjectedChars = 0;
11858
+ let identityInjectionTruncated = false;
11825
11859
  timings.queryPolicy = `${queryPolicy.promptShape}/${queryPolicy.retrievalBudgetMode}${queryPolicy.skipConversationRecall ? "/skip-conv" : ""}`;
11826
11860
  const recallMode = resolveEffectiveRecallMode({
11827
11861
  plannerEnabled: this.config.recallPlannerEnabled,
@@ -11866,6 +11900,9 @@ var Orchestrator = class _Orchestrator {
11866
11900
  recalledMemoryCount,
11867
11901
  injected: false,
11868
11902
  contextChars: 0,
11903
+ identityInjectionMode: identityInjectionModeUsed,
11904
+ identityInjectedChars,
11905
+ identityInjectionTruncated,
11869
11906
  durationMs: Date.now() - recallStart,
11870
11907
  timings: { ...timings }
11871
11908
  });
@@ -11899,6 +11936,16 @@ var Orchestrator = class _Orchestrator {
11899
11936
  timings.profile = `${Date.now() - t0}ms`;
11900
11937
  return profile2 || null;
11901
11938
  })();
11939
+ const identityContinuityPromise = (async () => {
11940
+ const t0 = Date.now();
11941
+ const section = await this.buildIdentityContinuitySection({
11942
+ storage: profileStorage,
11943
+ recallMode,
11944
+ prompt: retrievalQuery
11945
+ });
11946
+ timings.identityContinuity = `${Date.now() - t0}ms`;
11947
+ return section;
11948
+ })();
11902
11949
  const knowledgeIndexPromise = (async () => {
11903
11950
  if (!this.config.knowledgeIndexEnabled) return null;
11904
11951
  const t0 = Date.now();
@@ -11956,9 +12003,10 @@ var Orchestrator = class _Orchestrator {
11956
12003
  timings.qmd = `${Date.now() - t0}ms`;
11957
12004
  return { memoryResultsLists: [filteredResults], globalResults: [] };
11958
12005
  })();
11959
- const [sharedCtx, profile, kiResult, artifacts, qmdResult] = await Promise.all([
12006
+ const [sharedCtx, profile, identityContinuity, kiResult, artifacts, qmdResult] = await Promise.all([
11960
12007
  sharedContextPromise,
11961
12008
  profilePromise,
12009
+ identityContinuityPromise,
11962
12010
  knowledgeIndexPromise,
11963
12011
  artifactsPromise,
11964
12012
  qmdPromise
@@ -11967,6 +12015,12 @@ var Orchestrator = class _Orchestrator {
11967
12015
  if (profile) sections.push(`## User Profile
11968
12016
 
11969
12017
  ${profile}`);
12018
+ if (identityContinuity) {
12019
+ sections.push(identityContinuity.section);
12020
+ identityInjectionModeUsed = identityContinuity.mode;
12021
+ identityInjectedChars = identityContinuity.injectedChars;
12022
+ identityInjectionTruncated = identityContinuity.truncated;
12023
+ }
11970
12024
  if (kiResult?.result) {
11971
12025
  sections.push(kiResult.result);
11972
12026
  log.debug(`Knowledge Index: ${kiResult.result.split("\n").length - 4} entities, ${kiResult.result.length} chars${kiResult.cached ? " (cached)" : ""}`);
@@ -12078,7 +12132,12 @@ ${tmtNode.summary}`);
12078
12132
  results: memoryResults,
12079
12133
  sections,
12080
12134
  retrievalQuery,
12081
- sessionKey
12135
+ sessionKey,
12136
+ identityInjection: {
12137
+ mode: identityInjectionModeUsed,
12138
+ injectedChars: identityInjectedChars,
12139
+ truncated: identityInjectionTruncated
12140
+ }
12082
12141
  });
12083
12142
  impressionRecorded = true;
12084
12143
  } else {
@@ -12101,7 +12160,12 @@ ${tmtNode.summary}`);
12101
12160
  results: scoped,
12102
12161
  sections,
12103
12162
  retrievalQuery,
12104
- sessionKey
12163
+ sessionKey,
12164
+ identityInjection: {
12165
+ mode: identityInjectionModeUsed,
12166
+ injectedChars: identityInjectedChars,
12167
+ truncated: identityInjectionTruncated
12168
+ }
12105
12169
  });
12106
12170
  impressionRecorded = true;
12107
12171
  } else {
@@ -12118,7 +12182,12 @@ ${tmtNode.summary}`);
12118
12182
  results: longTerm,
12119
12183
  sections,
12120
12184
  retrievalQuery,
12121
- sessionKey
12185
+ sessionKey,
12186
+ identityInjection: {
12187
+ mode: identityInjectionModeUsed,
12188
+ injectedChars: identityInjectedChars,
12189
+ truncated: identityInjectionTruncated
12190
+ }
12122
12191
  });
12123
12192
  impressionRecorded = true;
12124
12193
  }
@@ -12164,7 +12233,12 @@ ${tmtNode.summary}`);
12164
12233
  results: scoped,
12165
12234
  sections,
12166
12235
  retrievalQuery,
12167
- sessionKey
12236
+ sessionKey,
12237
+ identityInjection: {
12238
+ mode: identityInjectionModeUsed,
12239
+ injectedChars: identityInjectedChars,
12240
+ truncated: identityInjectionTruncated
12241
+ }
12168
12242
  });
12169
12243
  impressionRecorded = true;
12170
12244
  } else {
@@ -12199,7 +12273,12 @@ ${tmtNode.summary}`);
12199
12273
  results: recent,
12200
12274
  sections,
12201
12275
  retrievalQuery,
12202
- sessionKey
12276
+ sessionKey,
12277
+ identityInjection: {
12278
+ mode: identityInjectionModeUsed,
12279
+ injectedChars: identityInjectedChars,
12280
+ truncated: identityInjectionTruncated
12281
+ }
12203
12282
  });
12204
12283
  impressionRecorded = true;
12205
12284
  } else {
@@ -12216,7 +12295,12 @@ ${tmtNode.summary}`);
12216
12295
  results: longTerm,
12217
12296
  sections,
12218
12297
  retrievalQuery,
12219
- sessionKey
12298
+ sessionKey,
12299
+ identityInjection: {
12300
+ mode: identityInjectionModeUsed,
12301
+ injectedChars: identityInjectedChars,
12302
+ truncated: identityInjectionTruncated
12303
+ }
12220
12304
  });
12221
12305
  impressionRecorded = true;
12222
12306
  }
@@ -12235,7 +12319,12 @@ ${tmtNode.summary}`);
12235
12319
  results: longTerm,
12236
12320
  sections,
12237
12321
  retrievalQuery,
12238
- sessionKey
12322
+ sessionKey,
12323
+ identityInjection: {
12324
+ mode: identityInjectionModeUsed,
12325
+ injectedChars: identityInjectedChars,
12326
+ truncated: identityInjectionTruncated
12327
+ }
12239
12328
  });
12240
12329
  impressionRecorded = true;
12241
12330
  }
@@ -12374,7 +12463,16 @@ _Context: ${topQuestion.context}_`);
12374
12463
  const timingParts = Object.entries(timings).map(([k, v]) => `${k}=${v}`).join(", ");
12375
12464
  log.debug(`recall: ${timingParts}`);
12376
12465
  if (!impressionRecorded && sessionKey && this.config.recordEmptyRecallImpressions) {
12377
- this.lastRecall.record({ sessionKey, query: retrievalQuery, memoryIds: [] }).catch((err) => log.debug(`last recall record failed: ${err}`));
12466
+ this.lastRecall.record({
12467
+ sessionKey,
12468
+ query: retrievalQuery,
12469
+ memoryIds: [],
12470
+ identityInjection: {
12471
+ mode: identityInjectionModeUsed,
12472
+ injectedChars: identityInjectedChars,
12473
+ truncated: identityInjectionTruncated
12474
+ }
12475
+ }).catch((err) => log.debug(`last recall record failed: ${err}`));
12378
12476
  }
12379
12477
  const context = sections.length === 0 ? "" : sections.join("\n\n---\n\n");
12380
12478
  this.emitTrace({
@@ -12395,6 +12493,9 @@ _Context: ${topQuestion.context}_`);
12395
12493
  recalledMemoryCount,
12396
12494
  injected: context.length > 0,
12397
12495
  contextChars: context.length,
12496
+ identityInjectionMode: identityInjectionModeUsed,
12497
+ identityInjectedChars,
12498
+ identityInjectionTruncated,
12398
12499
  durationMs: Date.now() - recallStart,
12399
12500
  timings: { ...timings }
12400
12501
  });
@@ -13490,6 +13591,86 @@ ${snippet}`;
13490
13591
 
13491
13592
  ${lines.join("\n\n")}`;
13492
13593
  }
13594
+ summarizeIdentityText(raw, maxLines, maxChars) {
13595
+ const lines = raw.replace(/\r/g, "").split("\n").map((line) => line.trim()).filter((line) => line.length > 0 && !line.startsWith("#"));
13596
+ const compact = lines.slice(0, Math.max(1, maxLines)).join(" ");
13597
+ if (compact.length <= maxChars) return compact;
13598
+ return `${compact.slice(0, Math.max(0, maxChars - 1))}\u2026`;
13599
+ }
13600
+ formatOpenIncidentLine(incident, includeDetails) {
13601
+ const base = `[${incident.id}] ${incident.symptom.trim()}`;
13602
+ if (!includeDetails) return `- ${base}`;
13603
+ const parts = [base];
13604
+ if (incident.suspectedCause) parts.push(`cause: ${incident.suspectedCause.trim()}`);
13605
+ if (incident.triggerWindow) parts.push(`window: ${incident.triggerWindow.trim()}`);
13606
+ return `- ${parts.join(" | ")}`;
13607
+ }
13608
+ trimIdentitySection(content, maxChars) {
13609
+ if (maxChars <= 0) return { text: "", truncated: false };
13610
+ if (content.length <= maxChars) return { text: content, truncated: false };
13611
+ const suffix = "\n\n...(identity continuity trimmed)";
13612
+ if (maxChars <= suffix.length) {
13613
+ return { text: content.slice(0, maxChars), truncated: true };
13614
+ }
13615
+ const headroom = Math.max(0, maxChars - suffix.length);
13616
+ return { text: `${content.slice(0, headroom)}${suffix}`, truncated: true };
13617
+ }
13618
+ async buildIdentityContinuitySection(options) {
13619
+ if (!this.config.identityContinuityEnabled) return null;
13620
+ if (this.config.identityMaxInjectChars <= 0) return null;
13621
+ const resolved = resolveEffectiveIdentityInjectionMode({
13622
+ configuredMode: this.config.identityInjectionMode,
13623
+ recallMode: options.recallMode,
13624
+ prompt: options.prompt
13625
+ });
13626
+ if (!resolved.shouldInject) return null;
13627
+ const [anchorRaw, loopsRaw, incidents] = await Promise.all([
13628
+ options.storage.readIdentityAnchor(),
13629
+ options.storage.readIdentityImprovementLoops(),
13630
+ options.storage.readContinuityIncidents(200)
13631
+ ]);
13632
+ const openIncidents = incidents.filter((incident) => incident.state === "open");
13633
+ const lines = [];
13634
+ if (resolved.mode === "full") {
13635
+ lines.push("## Identity Continuity");
13636
+ if (anchorRaw && anchorRaw.trim().length > 0) {
13637
+ lines.push("", "### Anchor", "", anchorRaw.trim());
13638
+ }
13639
+ if (loopsRaw && loopsRaw.trim().length > 0) {
13640
+ lines.push("", "### Improvement Loops", "", loopsRaw.trim());
13641
+ }
13642
+ lines.push("", "### Open Incidents", "");
13643
+ if (openIncidents.length === 0) {
13644
+ lines.push("- none");
13645
+ } else {
13646
+ lines.push(
13647
+ ...openIncidents.slice(0, 5).map((incident) => this.formatOpenIncidentLine(incident, true))
13648
+ );
13649
+ }
13650
+ } else {
13651
+ const anchorSummary = anchorRaw ? this.summarizeIdentityText(anchorRaw, 3, 320) : "";
13652
+ const loopsSummary = loopsRaw ? this.summarizeIdentityText(loopsRaw, 2, 240) : "";
13653
+ lines.push("## Identity Continuity Signals", "");
13654
+ if (anchorSummary) lines.push(`- anchor: ${anchorSummary}`);
13655
+ if (loopsSummary) lines.push(`- loops: ${loopsSummary}`);
13656
+ if (openIncidents.length === 0) {
13657
+ lines.push("- incidents: 0 open");
13658
+ } else {
13659
+ lines.push(`- incidents: ${openIncidents.length} open`);
13660
+ lines.push(...openIncidents.slice(0, 2).map((incident) => this.formatOpenIncidentLine(incident, false)));
13661
+ }
13662
+ }
13663
+ const body = lines.join("\n").trim();
13664
+ if (!body) return null;
13665
+ const { text, truncated } = this.trimIdentitySection(body, this.config.identityMaxInjectChars);
13666
+ if (!text) return null;
13667
+ return {
13668
+ section: text,
13669
+ mode: resolved.mode,
13670
+ injectedChars: text.length,
13671
+ truncated
13672
+ };
13673
+ }
13493
13674
  emitTrace(event) {
13494
13675
  try {
13495
13676
  const cb = globalThis.__openclawEngramTrace;
@@ -13503,7 +13684,12 @@ ${lines.join("\n\n")}`;
13503
13684
  this.trackMemoryAccess(memoryIds);
13504
13685
  if (options.sessionKey) {
13505
13686
  const unique = Array.from(new Set(memoryIds)).slice(0, 40);
13506
- this.lastRecall.record({ sessionKey: options.sessionKey, query: options.retrievalQuery, memoryIds: unique }).catch((err) => log.debug(`last recall record failed: ${err}`));
13687
+ this.lastRecall.record({
13688
+ sessionKey: options.sessionKey,
13689
+ query: options.retrievalQuery,
13690
+ memoryIds: unique,
13691
+ identityInjection: options.identityInjection
13692
+ }).catch((err) => log.debug(`last recall record failed: ${err}`));
13507
13693
  }
13508
13694
  options.sections.push(this.formatQmdResults(options.title, options.results));
13509
13695
  }
@@ -14030,11 +14216,11 @@ function mergeIdentityAnchor(existingRaw, updates) {
14030
14216
  const sections = new Map(parsed.sections);
14031
14217
  for (const sectionName of IDENTITY_ANCHOR_SECTION_ORDER) {
14032
14218
  const merged = mergeAnchorSection(sections.get(sectionName), updates[sectionName]);
14033
- if (merged) {
14034
- sections.set(sectionName, merged);
14035
- } else if (!sections.has(sectionName)) {
14219
+ if (!sections.has(sectionName) && !merged) {
14036
14220
  sections.set(sectionName, "");
14221
+ continue;
14037
14222
  }
14223
+ sections.set(sectionName, merged);
14038
14224
  }
14039
14225
  const finalOrder = [];
14040
14226
  for (const sectionName of IDENTITY_ANCHOR_SECTION_ORDER) {
@@ -14335,8 +14521,7 @@ ${formatContinuityIncidentSummary(closed)}`);
14335
14521
  const state = params.state === "closed" || params.state === "all" ? params.state : "open";
14336
14522
  const limitRaw = typeof params.limit === "number" ? params.limit : 25;
14337
14523
  const limit = Math.max(1, Math.min(200, Math.floor(limitRaw)));
14338
- const incidents = await orchestrator.storage.readContinuityIncidents(limit);
14339
- const filtered = state === "all" ? incidents : incidents.filter((incident) => incident.state === state);
14524
+ const filtered = await orchestrator.storage.readContinuityIncidents(limit, state);
14340
14525
  if (filtered.length === 0) {
14341
14526
  return toolResult(`No continuity incidents found for state=${state}.`);
14342
14527
  }
@@ -14497,6 +14682,7 @@ NOTE: You did not provide sessionKey; under concurrency this may not match your
14497
14682
  "",
14498
14683
  `Recorded at: ${snap.recordedAt}`,
14499
14684
  `Query hash: ${snap.queryHash} (len=${snap.queryLen})`,
14685
+ `Identity injection: mode=${snap.identityInjectionMode ?? "none"}, chars=${snap.identityInjectedChars ?? 0}, truncated=${snap.identityInjectionTruncated === true ? "yes" : "no"}`,
14500
14686
  `Memories (${snap.memoryIds.length}):`,
14501
14687
  ...snap.memoryIds.map((id) => `- ${id}`)
14502
14688
  ].join("\n")
@@ -16246,8 +16432,7 @@ function registerCli(api, orchestrator) {
16246
16432
  const stateRaw = String(options.state ?? "open").toLowerCase();
16247
16433
  const state = stateRaw === "closed" || stateRaw === "all" ? stateRaw : "open";
16248
16434
  const limit = Math.max(1, Math.min(200, parseInt(String(options.limit ?? "25"), 10) || 25));
16249
- const incidents = await orchestrator.storage.readContinuityIncidents(limit);
16250
- const filtered = state === "all" ? incidents : incidents.filter((incident) => incident.state === state);
16435
+ const filtered = await orchestrator.storage.readContinuityIncidents(limit, state);
16251
16436
  if (filtered.length === 0) {
16252
16437
  console.log(`No continuity incidents found for state=${state}.`);
16253
16438
  return;