@remnic/core 9.3.602 → 9.3.604

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
@@ -182,7 +182,7 @@ import {
182
182
  saveTaxonomy,
183
183
  validateSlug,
184
184
  validateTaxonomy
185
- } from "./chunk-MTGOAU7A.js";
185
+ } from "./chunk-OEIRQ7DB.js";
186
186
  import "./chunk-5RIRL3XL.js";
187
187
  import {
188
188
  migrateFromEngram,
@@ -227,8 +227,8 @@ import {
227
227
  buildResponseGuidanceRecallSection,
228
228
  shouldRecallResponseGuidance
229
229
  } from "./chunk-OZKZ2TRP.js";
230
- import "./chunk-5SQ5CQJP.js";
231
- import "./chunk-75O6YQ63.js";
230
+ import "./chunk-HSVJGWYS.js";
231
+ import "./chunk-G6R5UD3Q.js";
232
232
  import "./chunk-5IZL4DCV.js";
233
233
  import "./chunk-X7XN6YU4.js";
234
234
  import "./chunk-452WDNFO.js";
@@ -26,7 +26,7 @@ import {
26
26
  sanitizeSessionKeyForFilename,
27
27
  shouldFilterLifecycleRecallCandidate,
28
28
  summarizeGraphShadowComparison
29
- } from "./chunk-MTGOAU7A.js";
29
+ } from "./chunk-OEIRQ7DB.js";
30
30
  import "./chunk-5RIRL3XL.js";
31
31
  import "./chunk-KVEVLBKC.js";
32
32
  import "./chunk-BFBF3XEF.js";
@@ -55,8 +55,8 @@ import "./chunk-46GJIW5M.js";
55
55
  import "./chunk-XJNBEDFE.js";
56
56
  import "./chunk-DLJ4IR6M.js";
57
57
  import "./chunk-OZKZ2TRP.js";
58
- import "./chunk-5SQ5CQJP.js";
59
- import "./chunk-75O6YQ63.js";
58
+ import "./chunk-HSVJGWYS.js";
59
+ import "./chunk-G6R5UD3Q.js";
60
60
  import "./chunk-5IZL4DCV.js";
61
61
  import "./chunk-X7XN6YU4.js";
62
62
  import "./chunk-452WDNFO.js";
@@ -7,8 +7,8 @@ import {
7
7
  runDirectAgent,
8
8
  runTemporalAgent,
9
9
  shouldRunAgent
10
- } from "./chunk-5SQ5CQJP.js";
11
- import "./chunk-75O6YQ63.js";
10
+ } from "./chunk-HSVJGWYS.js";
11
+ import "./chunk-G6R5UD3Q.js";
12
12
  import "./chunk-PVGDJXVK.js";
13
13
  import "./chunk-2ODBA7MQ.js";
14
14
  import "./chunk-PZ5AY32C.js";
package/dist/schemas.d.ts CHANGED
@@ -275,12 +275,12 @@ declare const EntityMentionSchema: z.ZodObject<{
275
275
  title: z.ZodString;
276
276
  facts: z.ZodArray<z.ZodString, "many">;
277
277
  }, "strip", z.ZodTypeAny, {
278
- key: string;
279
278
  title: string;
279
+ key: string;
280
280
  facts: string[];
281
281
  }, {
282
- key: string;
283
282
  title: string;
283
+ key: string;
284
284
  facts: string[];
285
285
  }>, "many">>>;
286
286
  }, "strip", z.ZodTypeAny, {
@@ -288,8 +288,8 @@ declare const EntityMentionSchema: z.ZodObject<{
288
288
  name: string;
289
289
  facts: string[];
290
290
  structuredSections?: {
291
- key: string;
292
291
  title: string;
292
+ key: string;
293
293
  facts: string[];
294
294
  }[] | null | undefined;
295
295
  promptedByQuestion?: string | null | undefined;
@@ -298,8 +298,8 @@ declare const EntityMentionSchema: z.ZodObject<{
298
298
  name: string;
299
299
  facts: string[];
300
300
  structuredSections?: {
301
- key: string;
302
301
  title: string;
302
+ key: string;
303
303
  facts: string[];
304
304
  }[] | null | undefined;
305
305
  promptedByQuestion?: string | null | undefined;
@@ -584,12 +584,12 @@ declare const ProactiveExtractionResultSchema: z.ZodObject<{
584
584
  title: z.ZodString;
585
585
  facts: z.ZodArray<z.ZodString, "many">;
586
586
  }, "strip", z.ZodTypeAny, {
587
- key: string;
588
587
  title: string;
588
+ key: string;
589
589
  facts: string[];
590
590
  }, {
591
- key: string;
592
591
  title: string;
592
+ key: string;
593
593
  facts: string[];
594
594
  }>, "many">>>;
595
595
  }, "strip", z.ZodTypeAny, {
@@ -597,8 +597,8 @@ declare const ProactiveExtractionResultSchema: z.ZodObject<{
597
597
  name: string;
598
598
  facts: string[];
599
599
  structuredSections?: {
600
- key: string;
601
600
  title: string;
601
+ key: string;
602
602
  facts: string[];
603
603
  }[] | null | undefined;
604
604
  promptedByQuestion?: string | null | undefined;
@@ -607,8 +607,8 @@ declare const ProactiveExtractionResultSchema: z.ZodObject<{
607
607
  name: string;
608
608
  facts: string[];
609
609
  structuredSections?: {
610
- key: string;
611
610
  title: string;
611
+ key: string;
612
612
  facts: string[];
613
613
  }[] | null | undefined;
614
614
  promptedByQuestion?: string | null | undefined;
@@ -665,8 +665,8 @@ declare const ProactiveExtractionResultSchema: z.ZodObject<{
665
665
  name: string;
666
666
  facts: string[];
667
667
  structuredSections?: {
668
- key: string;
669
668
  title: string;
669
+ key: string;
670
670
  facts: string[];
671
671
  }[] | null | undefined;
672
672
  promptedByQuestion?: string | null | undefined;
@@ -714,8 +714,8 @@ declare const ProactiveExtractionResultSchema: z.ZodObject<{
714
714
  name: string;
715
715
  facts: string[];
716
716
  structuredSections?: {
717
- key: string;
718
717
  title: string;
718
+ key: string;
719
719
  facts: string[];
720
720
  }[] | null | undefined;
721
721
  promptedByQuestion?: string | null | undefined;
@@ -952,12 +952,12 @@ declare const ExtractionResultSchema: z.ZodObject<{
952
952
  title: z.ZodString;
953
953
  facts: z.ZodArray<z.ZodString, "many">;
954
954
  }, "strip", z.ZodTypeAny, {
955
- key: string;
956
955
  title: string;
956
+ key: string;
957
957
  facts: string[];
958
958
  }, {
959
- key: string;
960
959
  title: string;
960
+ key: string;
961
961
  facts: string[];
962
962
  }>, "many">>>;
963
963
  }, "strip", z.ZodTypeAny, {
@@ -965,8 +965,8 @@ declare const ExtractionResultSchema: z.ZodObject<{
965
965
  name: string;
966
966
  facts: string[];
967
967
  structuredSections?: {
968
- key: string;
969
968
  title: string;
969
+ key: string;
970
970
  facts: string[];
971
971
  }[] | null | undefined;
972
972
  promptedByQuestion?: string | null | undefined;
@@ -975,8 +975,8 @@ declare const ExtractionResultSchema: z.ZodObject<{
975
975
  name: string;
976
976
  facts: string[];
977
977
  structuredSections?: {
978
- key: string;
979
978
  title: string;
979
+ key: string;
980
980
  facts: string[];
981
981
  }[] | null | undefined;
982
982
  promptedByQuestion?: string | null | undefined;
@@ -1047,8 +1047,8 @@ declare const ExtractionResultSchema: z.ZodObject<{
1047
1047
  name: string;
1048
1048
  facts: string[];
1049
1049
  structuredSections?: {
1050
- key: string;
1051
1050
  title: string;
1051
+ key: string;
1052
1052
  facts: string[];
1053
1053
  }[] | null | undefined;
1054
1054
  promptedByQuestion?: string | null | undefined;
@@ -1102,8 +1102,8 @@ declare const ExtractionResultSchema: z.ZodObject<{
1102
1102
  name: string;
1103
1103
  facts: string[];
1104
1104
  structuredSections?: {
1105
- key: string;
1106
1105
  title: string;
1106
+ key: string;
1107
1107
  facts: string[];
1108
1108
  }[] | null | undefined;
1109
1109
  promptedByQuestion?: string | null | undefined;
@@ -1172,12 +1172,12 @@ declare const ConsolidationResultSchema: z.ZodObject<{
1172
1172
  title: z.ZodString;
1173
1173
  facts: z.ZodArray<z.ZodString, "many">;
1174
1174
  }, "strip", z.ZodTypeAny, {
1175
- key: string;
1176
1175
  title: string;
1176
+ key: string;
1177
1177
  facts: string[];
1178
1178
  }, {
1179
- key: string;
1180
1179
  title: string;
1180
+ key: string;
1181
1181
  facts: string[];
1182
1182
  }>, "many">>>;
1183
1183
  }, "strip", z.ZodTypeAny, {
@@ -1185,8 +1185,8 @@ declare const ConsolidationResultSchema: z.ZodObject<{
1185
1185
  name: string;
1186
1186
  facts: string[];
1187
1187
  structuredSections?: {
1188
- key: string;
1189
1188
  title: string;
1189
+ key: string;
1190
1190
  facts: string[];
1191
1191
  }[] | null | undefined;
1192
1192
  promptedByQuestion?: string | null | undefined;
@@ -1195,8 +1195,8 @@ declare const ConsolidationResultSchema: z.ZodObject<{
1195
1195
  name: string;
1196
1196
  facts: string[];
1197
1197
  structuredSections?: {
1198
- key: string;
1199
1198
  title: string;
1199
+ key: string;
1200
1200
  facts: string[];
1201
1201
  }[] | null | undefined;
1202
1202
  promptedByQuestion?: string | null | undefined;
@@ -1215,8 +1215,8 @@ declare const ConsolidationResultSchema: z.ZodObject<{
1215
1215
  name: string;
1216
1216
  facts: string[];
1217
1217
  structuredSections?: {
1218
- key: string;
1219
1218
  title: string;
1219
+ key: string;
1220
1220
  facts: string[];
1221
1221
  }[] | null | undefined;
1222
1222
  promptedByQuestion?: string | null | undefined;
@@ -1235,8 +1235,8 @@ declare const ConsolidationResultSchema: z.ZodObject<{
1235
1235
  name: string;
1236
1236
  facts: string[];
1237
1237
  structuredSections?: {
1238
- key: string;
1239
1238
  title: string;
1239
+ key: string;
1240
1240
  facts: string[];
1241
1241
  }[] | null | undefined;
1242
1242
  promptedByQuestion?: string | null | undefined;
@@ -11,7 +11,7 @@ import {
11
11
  recencyWindowBoundsFromPrompt,
12
12
  recencyWindowFromPrompt,
13
13
  resolvePromptTagPrefilterAsync
14
- } from "./chunk-75O6YQ63.js";
14
+ } from "./chunk-G6R5UD3Q.js";
15
15
  import "./chunk-PZ5AY32C.js";
16
16
  export {
17
17
  clearIndexes,
@@ -313,13 +313,13 @@ declare const CapsuleBlockSchema: z.ZodObject<{
313
313
  peerProfiles: boolean;
314
314
  }>;
315
315
  }, "strip", z.ZodTypeAny, {
316
+ schemaVersion: string;
316
317
  includes: {
317
318
  procedural: boolean;
318
319
  taxonomy: boolean;
319
320
  identityAnchors: boolean;
320
321
  peerProfiles: boolean;
321
322
  };
322
- schemaVersion: string;
323
323
  id: string;
324
324
  description: string;
325
325
  version: string;
@@ -334,13 +334,13 @@ declare const CapsuleBlockSchema: z.ZodObject<{
334
334
  directAnswerEnabled: boolean;
335
335
  };
336
336
  }, {
337
+ schemaVersion: string;
337
338
  includes: {
338
339
  procedural: boolean;
339
340
  taxonomy: boolean;
340
341
  identityAnchors: boolean;
341
342
  peerProfiles: boolean;
342
343
  };
343
- schemaVersion: string;
344
344
  id: string;
345
345
  description: string;
346
346
  version: string;
@@ -464,13 +464,13 @@ declare const ExportManifestV2Schema: z.ZodObject<{
464
464
  peerProfiles: boolean;
465
465
  }>;
466
466
  }, "strip", z.ZodTypeAny, {
467
+ schemaVersion: string;
467
468
  includes: {
468
469
  procedural: boolean;
469
470
  taxonomy: boolean;
470
471
  identityAnchors: boolean;
471
472
  peerProfiles: boolean;
472
473
  };
473
- schemaVersion: string;
474
474
  id: string;
475
475
  description: string;
476
476
  version: string;
@@ -485,13 +485,13 @@ declare const ExportManifestV2Schema: z.ZodObject<{
485
485
  directAnswerEnabled: boolean;
486
486
  };
487
487
  }, {
488
+ schemaVersion: string;
488
489
  includes: {
489
490
  procedural: boolean;
490
491
  taxonomy: boolean;
491
492
  identityAnchors: boolean;
492
493
  peerProfiles: boolean;
493
494
  };
494
- schemaVersion: string;
495
495
  id: string;
496
496
  description: string;
497
497
  version: string;
@@ -518,13 +518,13 @@ declare const ExportManifestV2Schema: z.ZodObject<{
518
518
  pluginVersion: string;
519
519
  includesTranscripts: boolean;
520
520
  capsule: {
521
+ schemaVersion: string;
521
522
  includes: {
522
523
  procedural: boolean;
523
524
  taxonomy: boolean;
524
525
  identityAnchors: boolean;
525
526
  peerProfiles: boolean;
526
527
  };
527
- schemaVersion: string;
528
528
  id: string;
529
529
  description: string;
530
530
  version: string;
@@ -551,13 +551,13 @@ declare const ExportManifestV2Schema: z.ZodObject<{
551
551
  pluginVersion: string;
552
552
  includesTranscripts: boolean;
553
553
  capsule: {
554
+ schemaVersion: string;
554
555
  includes: {
555
556
  procedural: boolean;
556
557
  taxonomy: boolean;
557
558
  identityAnchors: boolean;
558
559
  peerProfiles: boolean;
559
560
  };
560
- schemaVersion: string;
561
561
  id: string;
562
562
  description: string;
563
563
  version: string;
@@ -683,13 +683,13 @@ declare const ExportBundleV2Schema: z.ZodObject<{
683
683
  peerProfiles: boolean;
684
684
  }>;
685
685
  }, "strip", z.ZodTypeAny, {
686
+ schemaVersion: string;
686
687
  includes: {
687
688
  procedural: boolean;
688
689
  taxonomy: boolean;
689
690
  identityAnchors: boolean;
690
691
  peerProfiles: boolean;
691
692
  };
692
- schemaVersion: string;
693
693
  id: string;
694
694
  description: string;
695
695
  version: string;
@@ -704,13 +704,13 @@ declare const ExportBundleV2Schema: z.ZodObject<{
704
704
  directAnswerEnabled: boolean;
705
705
  };
706
706
  }, {
707
+ schemaVersion: string;
707
708
  includes: {
708
709
  procedural: boolean;
709
710
  taxonomy: boolean;
710
711
  identityAnchors: boolean;
711
712
  peerProfiles: boolean;
712
713
  };
713
- schemaVersion: string;
714
714
  id: string;
715
715
  description: string;
716
716
  version: string;
@@ -737,13 +737,13 @@ declare const ExportBundleV2Schema: z.ZodObject<{
737
737
  pluginVersion: string;
738
738
  includesTranscripts: boolean;
739
739
  capsule: {
740
+ schemaVersion: string;
740
741
  includes: {
741
742
  procedural: boolean;
742
743
  taxonomy: boolean;
743
744
  identityAnchors: boolean;
744
745
  peerProfiles: boolean;
745
746
  };
746
- schemaVersion: string;
747
747
  id: string;
748
748
  description: string;
749
749
  version: string;
@@ -770,13 +770,13 @@ declare const ExportBundleV2Schema: z.ZodObject<{
770
770
  pluginVersion: string;
771
771
  includesTranscripts: boolean;
772
772
  capsule: {
773
+ schemaVersion: string;
773
774
  includes: {
774
775
  procedural: boolean;
775
776
  taxonomy: boolean;
776
777
  identityAnchors: boolean;
777
778
  peerProfiles: boolean;
778
779
  };
779
- schemaVersion: string;
780
780
  id: string;
781
781
  description: string;
782
782
  version: string;
@@ -815,13 +815,13 @@ declare const ExportBundleV2Schema: z.ZodObject<{
815
815
  pluginVersion: string;
816
816
  includesTranscripts: boolean;
817
817
  capsule: {
818
+ schemaVersion: string;
818
819
  includes: {
819
820
  procedural: boolean;
820
821
  taxonomy: boolean;
821
822
  identityAnchors: boolean;
822
823
  peerProfiles: boolean;
823
824
  };
824
- schemaVersion: string;
825
825
  id: string;
826
826
  description: string;
827
827
  version: string;
@@ -854,13 +854,13 @@ declare const ExportBundleV2Schema: z.ZodObject<{
854
854
  pluginVersion: string;
855
855
  includesTranscripts: boolean;
856
856
  capsule: {
857
+ schemaVersion: string;
857
858
  includes: {
858
859
  procedural: boolean;
859
860
  taxonomy: boolean;
860
861
  identityAnchors: boolean;
861
862
  peerProfiles: boolean;
862
863
  };
863
- schemaVersion: string;
864
864
  id: string;
865
865
  description: string;
866
866
  version: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remnic/core",
3
- "version": "9.3.602",
3
+ "version": "9.3.604",
4
4
  "description": "Framework-agnostic Remnic memory engine — orchestrator, storage, extraction, search, trust zones",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -953,7 +953,8 @@ function applyQueryAwareCandidateFilter(
953
953
  candidates: QmdSearchResult[],
954
954
  candidatePaths: Set<string> | null,
955
955
  ): QmdSearchResult[] {
956
- if (!candidatePaths || candidatePaths.size === 0) return candidates;
956
+ if (!candidatePaths) return candidates;
957
+ if (candidatePaths.size === 0) return [];
957
958
  const filtered = candidates.filter((candidate) =>
958
959
  candidatePaths.has(candidate.path),
959
960
  );
@@ -5316,7 +5317,7 @@ export class Orchestrator {
5316
5317
  paths: Set<string> | null,
5317
5318
  recallNamespaces: string[],
5318
5319
  ): Set<string> | null {
5319
- if (!paths || paths.size === 0) return null;
5320
+ if (!paths) return null;
5320
5321
  const scoped = new Set<string>();
5321
5322
  for (const memoryPath of paths) {
5322
5323
  if (!memoryPath || isArtifactMemoryPath(memoryPath)) continue;
@@ -5328,7 +5329,7 @@ export class Orchestrator {
5328
5329
  }
5329
5330
  scoped.add(memoryPath);
5330
5331
  }
5331
- return scoped.size > 0 ? scoped : null;
5332
+ return scoped;
5332
5333
  }
5333
5334
 
5334
5335
  private async buildQueryAwarePrefilter(
@@ -5376,7 +5377,14 @@ export class Orchestrator {
5376
5377
  let combination: QueryAwarePrefilter["combination"] = "none";
5377
5378
  let filteredToFullSearch = false;
5378
5379
 
5379
- if (temporalCandidates && tagCandidates) {
5380
+ if (
5381
+ tagSignals.matchedTags.length > 0 &&
5382
+ tagCandidates !== null &&
5383
+ tagCandidates.size === 0
5384
+ ) {
5385
+ candidatePaths = tagCandidates;
5386
+ combination = "tag";
5387
+ } else if (temporalCandidates !== null && tagCandidates !== null) {
5380
5388
  const intersection = new Set(
5381
5389
  Array.from(temporalCandidates).filter((memoryPath) =>
5382
5390
  tagCandidates.has(memoryPath),
@@ -5389,10 +5397,10 @@ export class Orchestrator {
5389
5397
  candidatePaths = new Set([...temporalCandidates, ...tagCandidates]);
5390
5398
  combination = "union";
5391
5399
  }
5392
- } else if (temporalCandidates) {
5400
+ } else if (temporalCandidates !== null) {
5393
5401
  candidatePaths = temporalCandidates;
5394
5402
  combination = "temporal";
5395
- } else if (tagCandidates) {
5403
+ } else if (tagCandidates !== null) {
5396
5404
  candidatePaths = tagCandidates;
5397
5405
  combination = "tag";
5398
5406
  }
@@ -5565,6 +5573,10 @@ export class Orchestrator {
5565
5573
  })),
5566
5574
  });
5567
5575
  };
5576
+ if (queryAwarePrefilter.candidatePaths?.size === 0) {
5577
+ await emitDebugSnapshot([], fetchLimit);
5578
+ return [];
5579
+ }
5568
5580
 
5569
5581
  for (let attempt = 0; attempt < MAX_ATTEMPTS; attempt += 1) {
5570
5582
  throwIfRecallAborted(options.abortSignal);
@@ -7778,6 +7790,15 @@ export class Orchestrator {
7778
7790
  );
7779
7791
  const staleQmdFallback =
7780
7792
  cachedQmd?.source === "stale" ? cachedQmd : null;
7793
+ const queryAwarePrefilter = await queryAwarePrefilterPromise;
7794
+ const queryAwarePrefilterIsEmpty =
7795
+ queryAwarePrefilter.candidatePaths?.size === 0;
7796
+ const emptyQueryAwareQmdResult: Exclude<QmdPhaseResult, null> = {
7797
+ memoryResultsLists: [[]],
7798
+ globalResults: [],
7799
+ preAugmentTopScore: 0,
7800
+ maxSpecializedScore: 0,
7801
+ };
7781
7802
  if (cachedQmd?.source === "fresh") {
7782
7803
  recordRecallSectionMetric({
7783
7804
  section: "qmd",
@@ -7788,6 +7809,9 @@ export class Orchestrator {
7788
7809
  success: true,
7789
7810
  timing: `${Math.max(0, Math.round(cachedQmd.ageMs))}ms-cache`,
7790
7811
  });
7812
+ if (queryAwarePrefilterIsEmpty) {
7813
+ return emptyQueryAwareQmdResult;
7814
+ }
7791
7815
  return cachedQmd.value;
7792
7816
  }
7793
7817
 
@@ -7808,6 +7832,9 @@ export class Orchestrator {
7808
7832
  success: true,
7809
7833
  timing: `stale-cache(reprobe-cooldown:${Math.max(0, Math.round(staleQmdFallback.ageMs))}ms)`,
7810
7834
  });
7835
+ if (queryAwarePrefilterIsEmpty) {
7836
+ return emptyQueryAwareQmdResult;
7837
+ }
7811
7838
  return staleQmdFallback.value;
7812
7839
  }
7813
7840
  recordRecallSectionMetric({
@@ -7834,6 +7861,9 @@ export class Orchestrator {
7834
7861
  success: true,
7835
7862
  timing: `stale-cache(reprobe-failed:${Math.max(0, Math.round(staleQmdFallback.ageMs))}ms)`,
7836
7863
  });
7864
+ if (queryAwarePrefilterIsEmpty) {
7865
+ return emptyQueryAwareQmdResult;
7866
+ }
7837
7867
  return staleQmdFallback.value;
7838
7868
  }
7839
7869
  recordRecallSectionMetric({
@@ -7853,11 +7883,11 @@ export class Orchestrator {
7853
7883
  log.info(`QMD re-probe succeeded: ${this.qmd.debugStatus()}`);
7854
7884
  }
7855
7885
 
7856
- const queryAwarePrefilter = await queryAwarePrefilterPromise;
7857
7886
  const maxPerAgent = this.config.parallelMaxResultsPerAgent;
7858
7887
  const specializedAgentPromise: Promise<
7859
7888
  [ParallelSearchResult[], ParallelSearchResult[]]
7860
7889
  > | null =
7890
+ !queryAwarePrefilterIsEmpty &&
7861
7891
  this.config.parallelRetrievalEnabled && maxPerAgent > 0
7862
7892
  ? Promise.all([
7863
7893
  shouldRunAgent("direct", retrievalQuery, 0)
@@ -7981,6 +8011,9 @@ export class Orchestrator {
7981
8011
  success: true,
7982
8012
  timing: `stale-cache(${err instanceof Error ? err.message : String(err)})`,
7983
8013
  });
8014
+ if (queryAwarePrefilterIsEmpty) {
8015
+ return emptyQueryAwareQmdResult;
8016
+ }
7984
8017
  return staleQmdFallback.value;
7985
8018
  }
7986
8019
  throw err;
@@ -9462,6 +9495,7 @@ export class Orchestrator {
9462
9495
  // When the gate rejects, all recall pathways are skipped to prevent
9463
9496
  // low-relevance results from polluting context.
9464
9497
  const queryAwarePrefilter = await queryAwarePrefilterPromise;
9498
+ if (queryAwarePrefilter.candidatePaths?.size !== 0) {
9465
9499
  const embeddingResults = await this.searchEmbeddingFallback(
9466
9500
  retrievalQuery,
9467
9501
  embeddingFetchLimit,
@@ -9566,6 +9600,7 @@ export class Orchestrator {
9566
9600
  impressionRecorded = true;
9567
9601
  }
9568
9602
  }
9603
+ }
9569
9604
  }
9570
9605
 
9571
9606
  if (globalResults.length > 0) {
@@ -9607,6 +9642,7 @@ export class Orchestrator {
9607
9642
  } else if (recallResultLimit > 0 && !this.qmd.isAvailable()) {
9608
9643
  // Fallback: embeddings first, then recency-only.
9609
9644
  const queryAwarePrefilter = await queryAwarePrefilterPromise;
9645
+ if (queryAwarePrefilter.candidatePaths?.size !== 0) {
9610
9646
  const embeddingResults = await this.searchEmbeddingFallback(
9611
9647
  retrievalQuery,
9612
9648
  embeddingFetchLimit,
@@ -9922,6 +9958,7 @@ export class Orchestrator {
9922
9958
  }
9923
9959
  }
9924
9960
  }
9961
+ }
9925
9962
 
9926
9963
  if (isDisagreementPrompt(prompt)) {
9927
9964
  this.appendRecallSection(
@@ -15553,6 +15590,7 @@ export class Orchestrator {
15553
15590
  throwIfRecallAborted(abortSignal);
15554
15591
  const cappedLimit = Math.max(0, limit);
15555
15592
  if (cappedLimit === 0) return [];
15593
+ if (queryAwarePrefilter?.candidatePaths?.size === 0) return [];
15556
15594
 
15557
15595
  const scopedSeedResults = queryAwarePrefilter?.candidatePaths?.size
15558
15596
  ? await this.searchScopedMemoryCandidates(
@@ -15639,6 +15677,11 @@ export class Orchestrator {
15639
15677
  /** Issue #681 — when true, bypass graphTraversalConfidenceFloor. */
15640
15678
  includeLowConfidence?: boolean;
15641
15679
  }): Promise<QmdSearchResult[]> {
15680
+ if (options.queryAwarePrefilter?.candidatePaths?.size === 0) {
15681
+ if (options.xrayPoolSizeSink) options.xrayPoolSizeSink.size = 0;
15682
+ return [];
15683
+ }
15684
+
15642
15685
  const coldQmdEnabled = this.config.qmdColdTierEnabled === true;
15643
15686
  const coldCollection =
15644
15687
  this.config.qmdColdCollection ?? "openclaw-engram-cold";
@@ -15953,7 +15996,7 @@ export class Orchestrator {
15953
15996
  // Intersect with result paths first so out-of-scope paths don't exhaust the budget
15954
15997
  const scoped = new Set(Array.from(s).filter((p) => resultPaths.has(p)));
15955
15998
  if (maxCandidates === 0 || scoped.size <= maxCandidates)
15956
- return scoped.size > 0 ? scoped : null;
15999
+ return scoped;
15957
16000
  return new Set(Array.from(scoped).slice(0, maxCandidates));
15958
16001
  };
15959
16002
  if (temporalFromDate !== null) {
@@ -6,7 +6,12 @@ import { join } from "node:path";
6
6
  import test from "node:test";
7
7
  import { setTimeout as delay } from "node:timers/promises";
8
8
 
9
- import { queryByDateRangeAsync, queryByTagsAsync } from "./temporal-index.js";
9
+ import {
10
+ indexMemory,
11
+ queryByDateRangeAsync,
12
+ queryByTagsAsync,
13
+ resolvePromptTagPrefilterAsync,
14
+ } from "./temporal-index.js";
10
15
 
11
16
  async function runIndexWorker(moduleUrl: string, memoryDir: string, workerId: number, count: number): Promise<void> {
12
17
  const workerSource = `
@@ -189,3 +194,27 @@ test("temporal index writers fail open on symlink lock blockers", async () => {
189
194
  assert.equal(dateMatches, null);
190
195
  assert.deepEqual(tagMatches, new Set(["/tmp/remnic-temporal-worker-101-memory-0.md"]));
191
196
  });
197
+
198
+ test("tag queries distinguish missing index from valid no-match results", async () => {
199
+ const memoryDir = await mkdtemp(join(tmpdir(), "remnic-temporal-index-tag-miss-"));
200
+
201
+ const unavailableMatches = await queryByTagsAsync(memoryDir, ["beta"]);
202
+ assert.equal(unavailableMatches, null);
203
+
204
+ indexMemory(memoryDir, "/tmp/remnic-temporal-alpha-memory.md", "2026-03-11T12:00:00.000Z", ["alpha"]);
205
+
206
+ const matchingPaths = await queryByTagsAsync(memoryDir, ["alpha"]);
207
+ assert.deepEqual(matchingPaths, new Set(["/tmp/remnic-temporal-alpha-memory.md"]));
208
+
209
+ const noMatchPaths = await queryByTagsAsync(memoryDir, ["beta"]);
210
+ assert.deepEqual(noMatchPaths, new Set());
211
+
212
+ const promptPrefilter = await resolvePromptTagPrefilterAsync(memoryDir, "find #beta notes");
213
+ assert.deepEqual(promptPrefilter.matchedTags, ["beta"]);
214
+ assert.deepEqual(promptPrefilter.paths, new Set());
215
+
216
+ const noFilterPrefilter = await resolvePromptTagPrefilterAsync(memoryDir, "find project notes");
217
+ assert.deepEqual(noFilterPrefilter.matchedTags, []);
218
+ assert.deepEqual(noFilterPrefilter.expandedTags, []);
219
+ assert.equal(noFilterPrefilter.paths, null);
220
+ });