@remnic/core 9.3.741 → 9.3.742

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 (72) hide show
  1. package/dist/access-boundary.d.ts +2 -2
  2. package/dist/access-boundary.js +2 -2
  3. package/dist/access-cli.js +8 -8
  4. package/dist/access-http.d.ts +2 -2
  5. package/dist/access-http.js +6 -6
  6. package/dist/access-mcp.d.ts +2 -2
  7. package/dist/access-mcp.js +5 -5
  8. package/dist/access-operations-batch.js +3 -3
  9. package/dist/access-operations.d.ts +2 -2
  10. package/dist/access-operations.js +4 -4
  11. package/dist/{access-service-Cbk-Kv_A.d.ts → access-service-K8n12dXu.d.ts} +1 -1
  12. package/dist/access-service.d.ts +2 -2
  13. package/dist/access-service.js +1 -1
  14. package/dist/access-surface-catalog.d.ts +2 -2
  15. package/dist/{auto-sync-G3V5AN4C.js → auto-sync-XHSKKQAH.js} +2 -2
  16. package/dist/bootstrap.d.ts +1 -1
  17. package/dist/{chunk-DBVBV2RF.js → chunk-7ADHJ6SU.js} +3 -3
  18. package/dist/{chunk-VC7QELR6.js → chunk-7HUGLMSW.js} +346 -305
  19. package/dist/chunk-7HUGLMSW.js.map +1 -0
  20. package/dist/{chunk-QCO2QFLZ.js → chunk-AM7YKD7V.js} +3 -2
  21. package/dist/{chunk-QCO2QFLZ.js.map → chunk-AM7YKD7V.js.map} +1 -1
  22. package/dist/{chunk-OZECYVGI.js → chunk-C7LDPZJJ.js} +6 -4
  23. package/dist/{chunk-OZECYVGI.js.map → chunk-C7LDPZJJ.js.map} +1 -1
  24. package/dist/{chunk-4J53ZVPQ.js → chunk-EZZUNKMJ.js} +3 -3
  25. package/dist/{chunk-H3WSZWHK.js → chunk-GFJ5ABKS.js} +7 -6
  26. package/dist/chunk-GFJ5ABKS.js.map +1 -0
  27. package/dist/{chunk-LD6A7XG5.js → chunk-JMMSVRF4.js} +4 -4
  28. package/dist/{chunk-7Y5KKMIP.js → chunk-NHJYUIII.js} +3 -2
  29. package/dist/{chunk-7Y5KKMIP.js.map → chunk-NHJYUIII.js.map} +1 -1
  30. package/dist/{chunk-DGVM5SFL.js → chunk-PHRLJFWZ.js} +3 -2
  31. package/dist/{chunk-DGVM5SFL.js.map → chunk-PHRLJFWZ.js.map} +1 -1
  32. package/dist/{chunk-M5KLYHHI.js → chunk-QUNH5UZH.js} +2 -2
  33. package/dist/{chunk-3TUDKDTQ.js → chunk-UEIF7RWQ.js} +3 -3
  34. package/dist/{chunk-773DPI6T.js → chunk-V5RVMULT.js} +11 -8
  35. package/dist/chunk-V5RVMULT.js.map +1 -0
  36. package/dist/{chunk-XPOOY35N.js → chunk-W4H5A3TJ.js} +3 -2
  37. package/dist/chunk-W4H5A3TJ.js.map +1 -0
  38. package/dist/{cli-BQW2xKdb.d.ts → cli-BEOLy1xo.d.ts} +2 -2
  39. package/dist/cli.d.ts +3 -3
  40. package/dist/cli.js +8 -8
  41. package/dist/explicit-capture.d.ts +1 -1
  42. package/dist/graph-recall.js +1 -1
  43. package/dist/index.d.ts +4 -4
  44. package/dist/index.js +13 -13
  45. package/dist/lcm/engine.js +2 -2
  46. package/dist/lcm/index.js +2 -2
  47. package/dist/lcm/summarizer.js +1 -1
  48. package/dist/mcp-memory-inspector-app.d.ts +2 -2
  49. package/dist/operator-toolkit.js +1 -1
  50. package/dist/{orchestrator-BOAFN_Yr.d.ts → orchestrator-Dr-1v5EL.d.ts} +58 -0
  51. package/dist/orchestrator.d.ts +1 -1
  52. package/dist/orchestrator.js +4 -4
  53. package/package.json +2 -2
  54. package/src/cli.ts +2 -1
  55. package/src/graph-recall.ts +2 -1
  56. package/src/lcm/engine.ts +9 -6
  57. package/src/lcm/summarizer.ts +2 -1
  58. package/src/operator-toolkit.ts +2 -1
  59. package/src/orchestration/qmd-result-resolver.ts +377 -0
  60. package/src/orchestrator.ts +14 -279
  61. package/src/procedural/procedure-stats.ts +2 -1
  62. package/src/wearables/pipeline.ts +5 -3
  63. package/dist/chunk-773DPI6T.js.map +0 -1
  64. package/dist/chunk-H3WSZWHK.js.map +0 -1
  65. package/dist/chunk-VC7QELR6.js.map +0 -1
  66. package/dist/chunk-XPOOY35N.js.map +0 -1
  67. /package/dist/{auto-sync-G3V5AN4C.js.map → auto-sync-XHSKKQAH.js.map} +0 -0
  68. /package/dist/{chunk-DBVBV2RF.js.map → chunk-7ADHJ6SU.js.map} +0 -0
  69. /package/dist/{chunk-4J53ZVPQ.js.map → chunk-EZZUNKMJ.js.map} +0 -0
  70. /package/dist/{chunk-LD6A7XG5.js.map → chunk-JMMSVRF4.js.map} +0 -0
  71. /package/dist/{chunk-M5KLYHHI.js.map → chunk-QUNH5UZH.js.map} +0 -0
  72. /package/dist/{chunk-3TUDKDTQ.js.map → chunk-UEIF7RWQ.js.map} +0 -0
@@ -4,7 +4,7 @@ import {
4
4
  loadSyncState,
5
5
  syncWearableSource,
6
6
  wearableSourceLabel
7
- } from "./chunk-OZECYVGI.js";
7
+ } from "./chunk-C7LDPZJJ.js";
8
8
  import {
9
9
  CompressionGuidelineCoordinator
10
10
  } from "./chunk-WIMKOTNY.js";
@@ -19,7 +19,7 @@ import {
19
19
  } from "./chunk-7HYPN2GC.js";
20
20
  import {
21
21
  LcmEngine
22
- } from "./chunk-773DPI6T.js";
22
+ } from "./chunk-V5RVMULT.js";
23
23
  import {
24
24
  chunkTranscriptEntries
25
25
  } from "./chunk-TECVW3JP.js";
@@ -512,7 +512,7 @@ import {
512
512
  } from "./chunk-PVGDJXVK.js";
513
513
 
514
514
  // src/orchestrator.ts
515
- import path5 from "path";
515
+ import path6 from "path";
516
516
  import os2 from "os";
517
517
  import { createHash as createHash2, randomBytes } from "crypto";
518
518
  import { existsSync, readFileSync } from "fs";
@@ -2196,7 +2196,7 @@ var RecallRerankCoordinator = class _RecallRerankCoordinator {
2196
2196
  nsMap = buildMemoryWorthCounterMap(memories);
2197
2197
  this.memoryWorthCounterCache.set(ns, { at: nowMs, counters: nsMap });
2198
2198
  }
2199
- for (const [path6, c] of nsMap) counters.set(path6, c);
2199
+ for (const [path7, c] of nsMap) counters.set(path7, c);
2200
2200
  } catch (err) {
2201
2201
  log.debug("memory-worth: failed to read namespace, skipping", {
2202
2202
  namespace: ns,
@@ -2281,7 +2281,7 @@ var RecallRerankCoordinator = class _RecallRerankCoordinator {
2281
2281
  namespaces,
2282
2282
  {
2283
2283
  readNamespaceMemories: async (ns) => (await this.getStorage(ns)).readAllMemories(),
2284
- readMemoryFrontmatter: async (path6) => {
2284
+ readMemoryFrontmatter: async (path7) => {
2285
2285
  if (!fallbackReader) {
2286
2286
  for (const ns of namespaces) {
2287
2287
  try {
@@ -2292,7 +2292,7 @@ var RecallRerankCoordinator = class _RecallRerankCoordinator {
2292
2292
  }
2293
2293
  }
2294
2294
  if (!fallbackReader) return null;
2295
- const memory = await this.readQmdResultMemory(path6, fallbackReader, namespaces);
2295
+ const memory = await this.readQmdResultMemory(path7, fallbackReader, namespaces);
2296
2296
  return memory ? memory.frontmatter : null;
2297
2297
  }
2298
2298
  },
@@ -2391,6 +2391,257 @@ var RecallRerankCoordinator = class _RecallRerankCoordinator {
2391
2391
  }
2392
2392
  };
2393
2393
 
2394
+ // src/orchestration/qmd-result-resolver.ts
2395
+ import path4 from "path";
2396
+ function qmdCollectionPathParts(resultPath) {
2397
+ if (!resultPath || path4.isAbsolute(resultPath)) return null;
2398
+ const normalized = resultPath.replace(/\\/g, "/").replace(/^\/+/, "");
2399
+ const slashIndex = normalized.indexOf("/");
2400
+ if (slashIndex <= 0 || slashIndex >= normalized.length - 1) return null;
2401
+ const collection = normalized.slice(0, slashIndex);
2402
+ if (/^\d{4}-\d{2}-\d{2}$/.test(collection)) return null;
2403
+ return {
2404
+ collection,
2405
+ relativePath: normalized.slice(slashIndex + 1)
2406
+ };
2407
+ }
2408
+ function qmdResultPathCandidates(storageDir, resultPath) {
2409
+ const candidates = /* @__PURE__ */ new Set();
2410
+ const storageRoot = path4.resolve(storageDir);
2411
+ const addCandidate = (candidate) => {
2412
+ const resolved = path4.resolve(candidate);
2413
+ if (isPathInsideStorageRoot(storageRoot, resolved)) {
2414
+ candidates.add(resolved);
2415
+ }
2416
+ };
2417
+ const addRelativeCandidates = (relativePath) => {
2418
+ const normalized = relativePath.replace(/\\/g, "/").replace(/^\/+/, "");
2419
+ if (!normalized) return;
2420
+ addCandidate(path4.join(storageRoot, normalized));
2421
+ if (/^\d{4}-\d{2}-\d{2}\//.test(normalized)) {
2422
+ addCandidate(path4.join(storageRoot, "facts", normalized));
2423
+ }
2424
+ };
2425
+ if (path4.isAbsolute(resultPath)) {
2426
+ addCandidate(resultPath);
2427
+ } else {
2428
+ addRelativeCandidates(resultPath);
2429
+ }
2430
+ return [...candidates];
2431
+ }
2432
+ function storageDirOrNull(storage) {
2433
+ const dir = storage.dir;
2434
+ return typeof dir === "string" && dir.length > 0 ? dir : null;
2435
+ }
2436
+ var QmdResultResolver = class {
2437
+ getConfig;
2438
+ storageFor;
2439
+ storageDirNamespace;
2440
+ qmdCollectionNamespaceFromPrefix;
2441
+ namespaceFromPath;
2442
+ constructor(options) {
2443
+ this.getConfig = options.getConfig;
2444
+ this.storageFor = options.storageFor;
2445
+ this.storageDirNamespace = options.storageDirNamespace;
2446
+ this.qmdCollectionNamespaceFromPrefix = options.qmdCollectionNamespaceFromPrefix;
2447
+ this.namespaceFromPath = options.namespaceFromPath;
2448
+ }
2449
+ async readQmdResultMemory(resultPath, fallbackStorage, recallNamespaces = []) {
2450
+ const parts = qmdCollectionPathParts(resultPath);
2451
+ const fallbackStorageDir = storageDirOrNull(fallbackStorage);
2452
+ const config = this.getConfig();
2453
+ const coldCollection = config.qmdColdCollection ?? "openclaw-engram-cold";
2454
+ if (parts && parts.collection === coldCollection) {
2455
+ const storages = [];
2456
+ const seenStorageDirs = /* @__PURE__ */ new Set();
2457
+ const addStorage = (storage) => {
2458
+ const storageDir = storageDirOrNull(storage);
2459
+ const storageKey = storageDir ? path4.resolve(storageDir) : `storage-without-dir-${storages.length}`;
2460
+ if (seenStorageDirs.has(storageKey)) return;
2461
+ seenStorageDirs.add(storageKey);
2462
+ storages.push(storage);
2463
+ };
2464
+ const fallbackNamespace = fallbackStorageDir !== null ? this.storageDirNamespace(fallbackStorageDir) : config.defaultNamespace;
2465
+ if (recallNamespaces.length === 0 || !resolveNamespaceCapabilities(config).namespaces || recallNamespaces.includes(fallbackNamespace)) {
2466
+ addStorage(fallbackStorage);
2467
+ }
2468
+ if (recallNamespaces.length > 0) {
2469
+ for (const namespace of recallNamespaces) {
2470
+ try {
2471
+ addStorage(await this.storageFor(namespace));
2472
+ } catch (err) {
2473
+ log.debug("qmd cold result namespace storage lookup skipped", {
2474
+ path: resultPath,
2475
+ namespace,
2476
+ error: err.message
2477
+ });
2478
+ }
2479
+ }
2480
+ }
2481
+ for (const storage of storages) {
2482
+ const storageDir = storageDirOrNull(storage);
2483
+ if (!storageDir) {
2484
+ const memory = await storage.readMemoryByPath(resultPath);
2485
+ if (memory) return memory;
2486
+ continue;
2487
+ }
2488
+ try {
2489
+ const coldRoot = path4.join(storageDir, "cold");
2490
+ for (const candidate of qmdResultPathCandidates(
2491
+ coldRoot,
2492
+ parts.relativePath
2493
+ )) {
2494
+ const memory = await storage.readMemoryByPath(candidate);
2495
+ if (memory) return memory;
2496
+ }
2497
+ } catch (err) {
2498
+ if (err instanceof SecureStoreLockedError) throw err;
2499
+ log.debug("qmd cold result path lookup failed open", {
2500
+ path: resultPath,
2501
+ collection: coldCollection,
2502
+ error: err.message
2503
+ });
2504
+ }
2505
+ }
2506
+ return null;
2507
+ }
2508
+ const collectionNamespace = parts ? this.qmdCollectionNamespaceFromPrefix(parts.collection) : null;
2509
+ if (parts && collectionNamespace) {
2510
+ try {
2511
+ const collectionStorage = await this.storageFor(collectionNamespace);
2512
+ for (const candidate of qmdResultPathCandidates(
2513
+ collectionStorage.dir,
2514
+ parts.relativePath
2515
+ )) {
2516
+ const memory = await collectionStorage.readMemoryByPath(candidate);
2517
+ if (memory) return memory;
2518
+ }
2519
+ return null;
2520
+ } catch (err) {
2521
+ if (err instanceof SecureStoreLockedError) throw err;
2522
+ log.debug("qmd result namespace path lookup failed open", {
2523
+ path: resultPath,
2524
+ namespace: collectionNamespace,
2525
+ error: err.message
2526
+ });
2527
+ return null;
2528
+ }
2529
+ }
2530
+ if (path4.isAbsolute(resultPath)) {
2531
+ if (!fallbackStorageDir) {
2532
+ return await fallbackStorage.readMemoryByPath(resultPath);
2533
+ }
2534
+ const ownerStorage = await this.storageForAbsoluteQmdResultPath(
2535
+ resultPath,
2536
+ fallbackStorage,
2537
+ recallNamespaces
2538
+ );
2539
+ if (!ownerStorage) return null;
2540
+ for (const candidate of qmdResultPathCandidates(
2541
+ ownerStorage.dir,
2542
+ resultPath
2543
+ )) {
2544
+ const memory = await ownerStorage.storage.readMemoryByPath(candidate);
2545
+ if (memory) return memory;
2546
+ }
2547
+ return null;
2548
+ }
2549
+ if (!fallbackStorageDir) {
2550
+ return await fallbackStorage.readMemoryByPath(resultPath);
2551
+ }
2552
+ for (const candidate of qmdResultPathCandidates(
2553
+ fallbackStorageDir,
2554
+ resultPath
2555
+ )) {
2556
+ const memory = await fallbackStorage.readMemoryByPath(candidate);
2557
+ if (memory) return memory;
2558
+ }
2559
+ return null;
2560
+ }
2561
+ async resolveColdQmdResultForRecall(result, fallbackStorage, recallNamespaces = []) {
2562
+ const memory = await this.readQmdResultMemory(
2563
+ result.path,
2564
+ fallbackStorage,
2565
+ recallNamespaces
2566
+ );
2567
+ if (!memory) return null;
2568
+ let ownerNamespace = null;
2569
+ if (path4.isAbsolute(memory.path)) {
2570
+ const ownerStorage = await this.storageForAbsoluteQmdResultPath(
2571
+ memory.path,
2572
+ fallbackStorage,
2573
+ recallNamespaces
2574
+ );
2575
+ ownerNamespace = ownerStorage?.namespace ?? null;
2576
+ if (!ownerNamespace && resolveNamespaceCapabilities(this.getConfig()).namespaces) return null;
2577
+ }
2578
+ ownerNamespace ??= this.namespaceFromPath(memory.path);
2579
+ if (recallNamespaces.length > 0 && !recallNamespaces.includes(ownerNamespace)) {
2580
+ return null;
2581
+ }
2582
+ return {
2583
+ namespace: ownerNamespace,
2584
+ result: {
2585
+ ...result,
2586
+ docid: result.docid || memory.frontmatter.id,
2587
+ path: memory.path,
2588
+ snippet: result.snippet || memory.content.slice(0, 400)
2589
+ }
2590
+ };
2591
+ }
2592
+ async storageForAbsoluteQmdResultPath(resultPath, fallbackStorage, recallNamespaces = []) {
2593
+ const resolvedPath = path4.resolve(resultPath);
2594
+ const config = this.getConfig();
2595
+ const memoryRoot = path4.resolve(config.memoryDir);
2596
+ const namespacesRoot = path4.join(memoryRoot, "namespaces");
2597
+ const fallbackStorageDir = storageDirOrNull(fallbackStorage);
2598
+ const matches = [];
2599
+ const seenDirs = /* @__PURE__ */ new Set();
2600
+ const maybeAddStorage = (storage, namespace) => {
2601
+ const storageDir = storageDirOrNull(storage);
2602
+ if (!storageDir) return;
2603
+ const candidateRoot = path4.resolve(storageDir);
2604
+ if (seenDirs.has(candidateRoot)) return;
2605
+ if (!isPathInsideStorageRoot(candidateRoot, resolvedPath)) return;
2606
+ if (candidateRoot === memoryRoot && isPathInsideStorageRoot(namespacesRoot, resolvedPath)) {
2607
+ return;
2608
+ }
2609
+ seenDirs.add(candidateRoot);
2610
+ matches.push({ storage, dir: candidateRoot, namespace });
2611
+ };
2612
+ const fallbackNamespace = fallbackStorageDir !== null ? this.storageDirNamespace(fallbackStorageDir) : config.defaultNamespace;
2613
+ maybeAddStorage(fallbackStorage, fallbackNamespace);
2614
+ const candidateNamespaces = /* @__PURE__ */ new Set();
2615
+ candidateNamespaces.add(config.defaultNamespace);
2616
+ candidateNamespaces.add(config.sharedNamespace);
2617
+ for (const ns of recallNamespaces) {
2618
+ candidateNamespaces.add(ns);
2619
+ }
2620
+ if (isPathInsideStorageRoot(namespacesRoot, resolvedPath)) {
2621
+ const relativeToNamespaces = path4.relative(namespacesRoot, resolvedPath);
2622
+ const [namespaceSegment] = relativeToNamespaces.split(/[\\/]/);
2623
+ if (namespaceSegment) {
2624
+ candidateNamespaces.add(
2625
+ namespaceIdentityFromToken(namespaceSegment) ?? namespaceSegment
2626
+ );
2627
+ }
2628
+ }
2629
+ for (const policy of config.namespacePolicies ?? []) {
2630
+ candidateNamespaces.add(policy.name);
2631
+ }
2632
+ for (const ns of candidateNamespaces) {
2633
+ if (!ns) continue;
2634
+ try {
2635
+ maybeAddStorage(await this.storageFor(ns), ns);
2636
+ } catch {
2637
+ continue;
2638
+ }
2639
+ }
2640
+ matches.sort((a, b) => b.dir.length - a.dir.length);
2641
+ return matches[0] ?? null;
2642
+ }
2643
+ };
2644
+
2394
2645
  // src/maintenance/pattern-reinforcement.ts
2395
2646
  function patternReinforcementKey(content) {
2396
2647
  return content.trim().toLowerCase().replace(/\s+/g, " ").slice(0, 200);
@@ -2724,7 +2975,7 @@ function generateResolverDocument(taxonomy) {
2724
2975
 
2725
2976
  // src/taxonomy/taxonomy-loader.ts
2726
2977
  import { readFile, mkdir as mkdir2, writeFile as writeFile2 } from "fs/promises";
2727
- import path4 from "path";
2978
+ import path5 from "path";
2728
2979
  var TAXONOMY_DIR = ".taxonomy";
2729
2980
  var TAXONOMY_FILE = "taxonomy.json";
2730
2981
  var MAX_SLUG_LENGTH = 32;
@@ -2822,7 +3073,7 @@ function validateTaxonomy(taxonomy) {
2822
3073
  }
2823
3074
  }
2824
3075
  async function loadTaxonomy(memoryDir) {
2825
- const taxonomyPath = path4.join(memoryDir, TAXONOMY_DIR, TAXONOMY_FILE);
3076
+ const taxonomyPath = path5.join(memoryDir, TAXONOMY_DIR, TAXONOMY_FILE);
2826
3077
  let raw;
2827
3078
  try {
2828
3079
  raw = await readFile(taxonomyPath, "utf-8");
@@ -2872,16 +3123,16 @@ async function loadTaxonomy(memoryDir) {
2872
3123
  }
2873
3124
  async function saveTaxonomy(memoryDir, taxonomy) {
2874
3125
  validateTaxonomy(taxonomy);
2875
- const dir = path4.join(memoryDir, TAXONOMY_DIR);
3126
+ const dir = path5.join(memoryDir, TAXONOMY_DIR);
2876
3127
  await mkdir2(dir, { recursive: true });
2877
- const filePath = path4.join(dir, TAXONOMY_FILE);
3128
+ const filePath = path5.join(dir, TAXONOMY_FILE);
2878
3129
  await writeFile2(filePath, JSON.stringify(taxonomy, null, 2) + "\n", "utf-8");
2879
3130
  }
2880
3131
  function getTaxonomyDir(memoryDir) {
2881
- return path4.join(memoryDir, TAXONOMY_DIR);
3132
+ return path5.join(memoryDir, TAXONOMY_DIR);
2882
3133
  }
2883
3134
  function getTaxonomyFilePath(memoryDir) {
2884
- return path4.join(memoryDir, TAXONOMY_DIR, TAXONOMY_FILE);
3135
+ return path5.join(memoryDir, TAXONOMY_DIR, TAXONOMY_FILE);
2885
3136
  }
2886
3137
 
2887
3138
  // src/wearables/registry.ts
@@ -3781,42 +4032,6 @@ async function raceRecallAbort(promise, signal, message = "recall aborted") {
3781
4032
  }
3782
4033
  }
3783
4034
  }
3784
- function qmdCollectionPathParts(resultPath) {
3785
- if (!resultPath || path5.isAbsolute(resultPath)) return null;
3786
- const normalized = resultPath.replace(/\\/g, "/").replace(/^\/+/, "");
3787
- const slashIndex = normalized.indexOf("/");
3788
- if (slashIndex <= 0 || slashIndex >= normalized.length - 1) return null;
3789
- const collection = normalized.slice(0, slashIndex);
3790
- if (/^\d{4}-\d{2}-\d{2}$/.test(collection)) return null;
3791
- return {
3792
- collection,
3793
- relativePath: normalized.slice(slashIndex + 1)
3794
- };
3795
- }
3796
- function qmdResultPathCandidates(storageDir, resultPath) {
3797
- const candidates = /* @__PURE__ */ new Set();
3798
- const storageRoot = path5.resolve(storageDir);
3799
- const addCandidate = (candidate) => {
3800
- const resolved = path5.resolve(candidate);
3801
- if (isPathInsideStorageRoot(storageRoot, resolved)) {
3802
- candidates.add(resolved);
3803
- }
3804
- };
3805
- const addRelativeCandidates = (relativePath) => {
3806
- const normalized = relativePath.replace(/\\/g, "/").replace(/^\/+/, "");
3807
- if (!normalized) return;
3808
- addCandidate(path5.join(storageRoot, normalized));
3809
- if (/^\d{4}-\d{2}-\d{2}\//.test(normalized)) {
3810
- addCandidate(path5.join(storageRoot, "facts", normalized));
3811
- }
3812
- };
3813
- if (path5.isAbsolute(resultPath)) {
3814
- addCandidate(resultPath);
3815
- } else {
3816
- addRelativeCandidates(resultPath);
3817
- }
3818
- return [...candidates];
3819
- }
3820
4035
  var COMPACTION_SIGNAL_MAX_AGE_MS = 60 * 60 * 1e3;
3821
4036
  var DEFAULT_QMD_STARTUP_COLLECTION_CHECK_TIMEOUT_MS = 1e4;
3822
4037
  function normalizeIanaTimeZone(value) {
@@ -3927,7 +4142,7 @@ async function qmdStartupCollectionCheckWithTimeout(promise, controller, label)
3927
4142
  return await Promise.race([checkedPromise, timeoutPromise]);
3928
4143
  }
3929
4144
  function defaultWorkspaceDir() {
3930
- return path5.join(os2.homedir(), ".openclaw", "workspace");
4145
+ return path6.join(os2.homedir(), ".openclaw", "workspace");
3931
4146
  }
3932
4147
  function sanitizeSessionKeyForFilename(sessionKey) {
3933
4148
  const readable = sessionKey.replace(/[^a-zA-Z0-9._-]/g, "_");
@@ -4204,11 +4419,11 @@ function mergeGraphExpandedResults(primary, expanded) {
4204
4419
  return Array.from(mergedByPath.values());
4205
4420
  }
4206
4421
  function graphPathRelativeToStorage(storageDir, candidatePath) {
4207
- const absolutePath = path5.isAbsolute(candidatePath) ? candidatePath : path5.resolve(storageDir, candidatePath);
4208
- const rel = path5.relative(storageDir, absolutePath);
4422
+ const absolutePath = path6.isAbsolute(candidatePath) ? candidatePath : path6.resolve(storageDir, candidatePath);
4423
+ const rel = path6.relative(storageDir, absolutePath);
4209
4424
  if (!rel || rel === ".") return null;
4210
4425
  if (rel.startsWith("..")) return null;
4211
- return rel.split(path5.sep).join("/");
4426
+ return rel.split(path6.sep).join("/");
4212
4427
  }
4213
4428
  function normalizeGraphActivationScore(score) {
4214
4429
  const bounded = Number.isFinite(score) && score > 0 ? score : 0;
@@ -4353,7 +4568,7 @@ function buildMemoryPathById(allMemsForGraph, storageDir) {
4353
4568
  for (const mem of allMemsForGraph ?? []) {
4354
4569
  const id = mem.frontmatter.id;
4355
4570
  if (!id) continue;
4356
- pathById.set(id, path5.relative(storageDir, mem.path));
4571
+ pathById.set(id, path6.relative(storageDir, mem.path));
4357
4572
  }
4358
4573
  return pathById;
4359
4574
  }
@@ -4361,7 +4576,7 @@ function appendMemoryToGraphContext(options) {
4361
4576
  if (!Array.isArray(options.allMemsForGraph)) return;
4362
4577
  const nowIso = (/* @__PURE__ */ new Date()).toISOString();
4363
4578
  options.allMemsForGraph.push({
4364
- path: path5.join(options.storageDir, options.memoryRelPath),
4579
+ path: path6.join(options.storageDir, options.memoryRelPath),
4365
4580
  content: options.content,
4366
4581
  frontmatter: {
4367
4582
  id: options.memoryId,
@@ -4381,16 +4596,16 @@ function resolvePersistedMemoryRelativePath(options) {
4381
4596
  const persisted = options.pathById.get(options.memoryId);
4382
4597
  if (persisted) return persisted;
4383
4598
  if (options.category === "correction") {
4384
- return path5.join("corrections", `${options.memoryId}.md`);
4599
+ return path6.join("corrections", `${options.memoryId}.md`);
4385
4600
  }
4386
4601
  const subtree = categoryDirName(options.category);
4387
4602
  const idParts = options.memoryId.split("-");
4388
4603
  const maybeTimestamp = Number(idParts[1]);
4389
4604
  if (Number.isFinite(maybeTimestamp) && maybeTimestamp > 0) {
4390
4605
  const day = new Date(maybeTimestamp).toISOString().slice(0, 10);
4391
- return path5.join(subtree, day, `${options.memoryId}.md`);
4606
+ return path6.join(subtree, day, `${options.memoryId}.md`);
4392
4607
  }
4393
- return path5.join(subtree, `${options.memoryId}.md`);
4608
+ return path6.join(subtree, `${options.memoryId}.md`);
4394
4609
  }
4395
4610
  var Orchestrator = class _Orchestrator {
4396
4611
  storage;
@@ -4552,6 +4767,7 @@ var Orchestrator = class _Orchestrator {
4552
4767
  */
4553
4768
  conversationIndexCoordinator;
4554
4769
  recallRerankCoordinator;
4770
+ qmdResultResolver;
4555
4771
  heartbeatObserverChains = /* @__PURE__ */ new Map();
4556
4772
  recentExtractionFingerprints = /* @__PURE__ */ new Map();
4557
4773
  consolidationObservers = /* @__PURE__ */ new Set();
@@ -4844,7 +5060,7 @@ var Orchestrator = class _Orchestrator {
4844
5060
  const defaultNs = normalizeNamespaceIdentity(this.config.defaultNamespace);
4845
5061
  if (ns !== defaultNs && !isSafeRouteNamespace(ns)) return;
4846
5062
  if (!this.storageDirMatchesNamespaceHint(ns, storageDir)) return;
4847
- const resolvedStorageDir = path5.resolve(storageDir);
5063
+ const resolvedStorageDir = path6.resolve(storageDir);
4848
5064
  let hints = this.namespaceStorageDirHints.get(resolvedStorageDir);
4849
5065
  if (!hints) {
4850
5066
  hints = /* @__PURE__ */ new Set();
@@ -4855,21 +5071,21 @@ var Orchestrator = class _Orchestrator {
4855
5071
  storageDirMatchesNamespaceHint(namespace, storageDir) {
4856
5072
  const ns = normalizeNamespaceIdentity(namespace);
4857
5073
  if (!ns) return false;
4858
- const resolvedStorageDir = path5.resolve(storageDir);
4859
- const resolvedMemoryDir = path5.resolve(this.config.memoryDir);
5074
+ const resolvedStorageDir = path6.resolve(storageDir);
5075
+ const resolvedMemoryDir = path6.resolve(this.config.memoryDir);
4860
5076
  const defaultNs = normalizeNamespaceIdentity(this.config.defaultNamespace);
4861
5077
  if (resolvedStorageDir === resolvedMemoryDir) return ns === defaultNs;
4862
- const resolvedNamespacesDir = path5.join(resolvedMemoryDir, "namespaces");
5078
+ const resolvedNamespacesDir = path6.join(resolvedMemoryDir, "namespaces");
4863
5079
  if (!isPathInsideStorageRoot(resolvedNamespacesDir, resolvedStorageDir)) return false;
4864
- const rawRoot = path5.resolve(resolvedNamespacesDir, ns);
4865
- const tokenRoot = path5.resolve(resolvedNamespacesDir, namespaceIdentityToken(ns));
5080
+ const rawRoot = path6.resolve(resolvedNamespacesDir, ns);
5081
+ const tokenRoot = path6.resolve(resolvedNamespacesDir, namespaceIdentityToken(ns));
4866
5082
  return resolvedStorageDir === rawRoot || resolvedStorageDir === tokenRoot;
4867
5083
  }
4868
5084
  namespaceStorageDirHintOwnershipRank(record, resolvedStorageDir, configured) {
4869
- if (resolvedStorageDir === path5.resolve(this.config.memoryDir)) {
5085
+ if (resolvedStorageDir === path6.resolve(this.config.memoryDir)) {
4870
5086
  return record.namespace === normalizeNamespaceIdentity(this.config.defaultNamespace) ? 0 : 3;
4871
5087
  }
4872
- const leaf = path5.basename(resolvedStorageDir);
5088
+ const leaf = path6.basename(resolvedStorageDir);
4873
5089
  const tokenOwnsRoot = namespaceIdentityToken(record.namespace) === leaf;
4874
5090
  if (tokenOwnsRoot && configured.has(record.namespace)) return 0;
4875
5091
  if (record.namespace === leaf) return 1;
@@ -4897,7 +5113,7 @@ var Orchestrator = class _Orchestrator {
4897
5113
  loadNamespaceStorageDirHintsFromCatalog() {
4898
5114
  if (this.namespaceStorageDirHintsLoaded || !this.namespaceCatalog.enabled) return;
4899
5115
  this.namespaceStorageDirHintsLoaded = true;
4900
- const catalogPath = path5.join(this.config.memoryDir, "state", "namespaces.jsonl");
5116
+ const catalogPath = path6.join(this.config.memoryDir, "state", "namespaces.jsonl");
4901
5117
  if (!existsSync(catalogPath)) return;
4902
5118
  let body;
4903
5119
  try {
@@ -4934,7 +5150,7 @@ var Orchestrator = class _Orchestrator {
4934
5150
  if (!this.storageDirMatchesNamespaceHint(record.namespace, record.storageDir)) {
4935
5151
  continue;
4936
5152
  }
4937
- const resolvedStorageDir = path5.resolve(record.storageDir);
5153
+ const resolvedStorageDir = path6.resolve(record.storageDir);
4938
5154
  const current = preferredByStorageDir.get(resolvedStorageDir);
4939
5155
  preferredByStorageDir.set(
4940
5156
  resolvedStorageDir,
@@ -5198,7 +5414,7 @@ var Orchestrator = class _Orchestrator {
5198
5414
  this.config = config;
5199
5415
  this.profiler = new ProfilingCollector({
5200
5416
  enabled: resolvePipelineProcessingCapabilities(this.config).profiling,
5201
- storageDir: config.profilingStorageDir || path5.join(config.memoryDir, "profiling"),
5417
+ storageDir: config.profilingStorageDir || path6.join(config.memoryDir, "profiling"),
5202
5418
  maxTraces: config.profilingMaxTraces
5203
5419
  });
5204
5420
  this.namespaceCatalog = new NamespaceCatalog(config);
@@ -5268,7 +5484,7 @@ var Orchestrator = class _Orchestrator {
5268
5484
  this.compounding = resolveConsolidationCapabilities(config).compounding ? new CompoundingEngine(config, this.storage) : void 0;
5269
5485
  this.buffer = new SmartBuffer(config, this.storage);
5270
5486
  this.transcript = new TranscriptManager(config);
5271
- this.conversationIndexDir = path5.join(
5487
+ this.conversationIndexDir = path6.join(
5272
5488
  config.memoryDir,
5273
5489
  "conversation-index",
5274
5490
  "chunks"
@@ -5310,6 +5526,13 @@ var Orchestrator = class _Orchestrator {
5310
5526
  getStorage: (namespace) => this.getStorage(namespace),
5311
5527
  fastChatCompletion: (messages, options) => this.fastChatCompletion(messages, options)
5312
5528
  });
5529
+ this.qmdResultResolver = new QmdResultResolver({
5530
+ getConfig: () => this.config,
5531
+ storageFor: (namespace) => this.storageRouter.storageFor(namespace),
5532
+ storageDirNamespace: (storageDir) => this.storageDirNamespace(storageDir),
5533
+ qmdCollectionNamespaceFromPrefix: (prefix) => this.qmdCollectionNamespaceFromPrefix(prefix),
5534
+ namespaceFromPath: (p) => this.namespaceFromPath(p)
5535
+ });
5313
5536
  this.sessionObserver = new SessionObserverState({
5314
5537
  memoryDir: config.memoryDir,
5315
5538
  debounceMs: config.sessionObserverDebounceMs ?? 12e4,
@@ -5374,7 +5597,7 @@ var Orchestrator = class _Orchestrator {
5374
5597
  saveContentHashIndexes: () => this.saveContentHashIndexes()
5375
5598
  });
5376
5599
  this.threading = new ThreadingManager(
5377
- path5.join(config.memoryDir, "threads"),
5600
+ path6.join(config.memoryDir, "threads"),
5378
5601
  config.threadingGapMinutes
5379
5602
  );
5380
5603
  const lifecycleCaps = resolveMemoryLifecycleCapabilities(config);
@@ -5697,7 +5920,7 @@ var Orchestrator = class _Orchestrator {
5697
5920
  const files = await readdir2(wsDir).catch(() => []);
5698
5921
  for (const f of files) {
5699
5922
  if (!f.startsWith(".compaction-reset-signal-")) continue;
5700
- const fp = path5.join(wsDir, f);
5923
+ const fp = path6.join(wsDir, f);
5701
5924
  const s = await stat(fp).catch(() => null);
5702
5925
  if (s && Date.now() - s.mtimeMs >= COMPACTION_SIGNAL_MAX_AGE_MS) {
5703
5926
  await unlink(fp).catch(() => {
@@ -5915,7 +6138,7 @@ var Orchestrator = class _Orchestrator {
5915
6138
  if (signal.aborted) return;
5916
6139
  if (!this.wearablesAutoSyncHandle && this.config.wearables.enabled && this.config.wearables.autoSyncEnabled && Object.values(this.config.wearables.sources).some((source) => source.enabled)) {
5917
6140
  try {
5918
- const { startWearablesAutoSync } = await import("./auto-sync-G3V5AN4C.js");
6141
+ const { startWearablesAutoSync } = await import("./auto-sync-XHSKKQAH.js");
5919
6142
  if (signal.aborted) return;
5920
6143
  this.wearablesAutoSyncHandle = startWearablesAutoSync(
5921
6144
  {
@@ -6206,15 +6429,15 @@ ${doc.content}` : doc.content,
6206
6429
  this.lastFileHygieneRunAtMs = now;
6207
6430
  if (hygiene.rotateEnabled) {
6208
6431
  for (const rel of hygiene.rotatePaths) {
6209
- const abs = path5.isAbsolute(rel) ? rel : path5.join(this.config.workspaceDir, rel);
6432
+ const abs = path6.isAbsolute(rel) ? rel : path6.join(this.config.workspaceDir, rel);
6210
6433
  try {
6211
6434
  const raw = await readFile2(abs, "utf-8");
6212
6435
  if (raw.length > hygiene.rotateMaxBytes) {
6213
- const archiveDir = path5.join(
6436
+ const archiveDir = path6.join(
6214
6437
  this.config.workspaceDir,
6215
6438
  hygiene.archiveDir
6216
6439
  );
6217
- const base = path5.basename(abs);
6440
+ const base = path6.basename(abs);
6218
6441
  const prefix = base.toUpperCase().replace(/\.MD$/i, "").replace(/[^A-Z0-9]+/g, "-") || "FILE";
6219
6442
  const { newContent } = await rotateMarkdownFileToArchive({
6220
6443
  filePath: abs,
@@ -6239,8 +6462,8 @@ ${doc.content}` : doc.content,
6239
6462
  log.warn(w.message);
6240
6463
  }
6241
6464
  if (hygiene.warningsLogEnabled && warnings.length > 0) {
6242
- const fp = path5.join(this.config.memoryDir, hygiene.warningsLogPath);
6243
- await mkdir3(path5.dirname(fp), { recursive: true });
6465
+ const fp = path6.join(this.config.memoryDir, hygiene.warningsLogPath);
6466
+ await mkdir3(path6.dirname(fp), { recursive: true });
6244
6467
  const stamp = (/* @__PURE__ */ new Date()).toISOString();
6245
6468
  const block = `
6246
6469
 
@@ -6379,7 +6602,7 @@ ${doc.content}` : doc.content,
6379
6602
  for (const categoryDir of RECALL_FALLBACK_DIRS) {
6380
6603
  if (memoryRootReal === null) break;
6381
6604
  for (const date of datesToScan) {
6382
- const dateDir = path5.join(storage.dir, categoryDir, date);
6605
+ const dateDir = path6.join(storage.dir, categoryDir, date);
6383
6606
  try {
6384
6607
  const dirStat = await lstat(dateDir);
6385
6608
  if (dirStat.isSymbolicLink() || !dirStat.isDirectory()) continue;
@@ -6388,7 +6611,7 @@ ${doc.content}` : doc.content,
6388
6611
  for (const entry of entries) {
6389
6612
  if (entry.isSymbolicLink()) continue;
6390
6613
  if (!entry.name.endsWith(".md")) continue;
6391
- const fullPath = path5.join(dateDir, entry.name);
6614
+ const fullPath = path6.join(dateDir, entry.name);
6392
6615
  try {
6393
6616
  assertPathInsideRoot(memoryRootReal, await realpath(fullPath), fullPath);
6394
6617
  const raw = await readFile2(fullPath, "utf-8");
@@ -6410,7 +6633,7 @@ ${doc.content}` : doc.content,
6410
6633
  facts.push({
6411
6634
  path: fullPath,
6412
6635
  frontmatter: {
6413
- id: fm.id || path5.basename(entry.name, ".md"),
6636
+ id: fm.id || path6.basename(entry.name, ".md"),
6414
6637
  category: fm.category || "fact",
6415
6638
  created,
6416
6639
  updated: fm.updated || created,
@@ -6433,13 +6656,13 @@ ${doc.content}` : doc.content,
6433
6656
  return a.frontmatter.created < b.frontmatter.created ? -1 : 1;
6434
6657
  });
6435
6658
  const hourlySummaries = [];
6436
- const hourlyBaseDir = path5.join(storage.dir, "summaries", "hourly");
6659
+ const hourlyBaseDir = path6.join(storage.dir, "summaries", "hourly");
6437
6660
  try {
6438
6661
  const sessionKeys = await readdir2(hourlyBaseDir, { withFileTypes: true });
6439
6662
  for (const sk of sessionKeys) {
6440
6663
  if (!sk.isDirectory()) continue;
6441
6664
  for (const date of datesToScan) {
6442
- const summaryFile = path5.join(hourlyBaseDir, sk.name, `${date}.md`);
6665
+ const summaryFile = path6.join(hourlyBaseDir, sk.name, `${date}.md`);
6443
6666
  try {
6444
6667
  const raw = await readFile2(summaryFile, "utf-8");
6445
6668
  const filtered = filterHourlySummaryMarkdownForLocalDay(
@@ -6543,7 +6766,7 @@ ${doc.content}` : doc.content,
6543
6766
  }
6544
6767
  async getLastGraphRecallSnapshot(namespace) {
6545
6768
  const storage = await this.getStorage(namespace);
6546
- const snapshotPath = path5.join(
6769
+ const snapshotPath = path6.join(
6547
6770
  storage.dir,
6548
6771
  "state",
6549
6772
  "last_graph_recall.json"
@@ -6582,7 +6805,7 @@ ${doc.content}` : doc.content,
6582
6805
  }
6583
6806
  async getLastIntentSnapshot(namespace) {
6584
6807
  const storage = await this.getStorage(namespace);
6585
- const snapshotPath = path5.join(storage.dir, "state", "last_intent.json");
6808
+ const snapshotPath = path6.join(storage.dir, "state", "last_intent.json");
6586
6809
  try {
6587
6810
  const raw = await readFile2(snapshotPath, "utf-8");
6588
6811
  const parsed = JSON.parse(raw);
@@ -6615,7 +6838,7 @@ ${doc.content}` : doc.content,
6615
6838
  }
6616
6839
  async getLastQmdRecallSnapshot(namespace) {
6617
6840
  const storage = await this.getStorage(namespace);
6618
- const snapshotPath = path5.join(
6841
+ const snapshotPath = path6.join(
6619
6842
  storage.dir,
6620
6843
  "state",
6621
6844
  "last_qmd_recall.json"
@@ -7499,7 +7722,7 @@ ${doc.content}` : doc.content,
7499
7722
  resolvedPath = resolvedCold.result.path;
7500
7723
  resolvedResult = resolvedCold.result;
7501
7724
  }
7502
- if (!path5.isAbsolute(resolvedPath)) {
7725
+ if (!path6.isAbsolute(resolvedPath)) {
7503
7726
  resolvedAmbiguousSeeds.set(result.path, null);
7504
7727
  return null;
7505
7728
  }
@@ -7524,7 +7747,7 @@ ${doc.content}` : doc.content,
7524
7747
  }
7525
7748
  continue;
7526
7749
  }
7527
- if (path5.isAbsolute(result.path)) {
7750
+ if (path6.isAbsolute(result.path)) {
7528
7751
  const resolved = await resolveAmbiguousSeedOwner(result, null);
7529
7752
  if (resolved) {
7530
7753
  addResultForNamespace(resolved.namespace, resolved.result);
@@ -7567,7 +7790,7 @@ ${doc.content}` : doc.content,
7567
7790
  0
7568
7791
  );
7569
7792
  seedPaths.push(
7570
- ...seedRelativePaths.map((rel) => path5.join(storage.dir, rel))
7793
+ ...seedRelativePaths.map((rel) => path6.join(storage.dir, rel))
7571
7794
  );
7572
7795
  const seedSet = new Set(seedRelativePaths);
7573
7796
  const expanded = await this.graphIndexFor(storage).spreadingActivation(
@@ -7583,7 +7806,7 @@ ${doc.content}` : doc.content,
7583
7806
  for (const candidate of expanded.slice(0, perNamespaceExpandedCap)) {
7584
7807
  if (deadlineExpired()) break;
7585
7808
  if (seedSet.has(candidate.path)) continue;
7586
- const memoryPath = path5.resolve(storage.dir, candidate.path);
7809
+ const memoryPath = path6.resolve(storage.dir, candidate.path);
7587
7810
  const memory = await storage.readMemoryByPath(memoryPath);
7588
7811
  if (deadlineExpired()) break;
7589
7812
  if (!memory) continue;
@@ -7608,7 +7831,7 @@ ${doc.content}` : doc.content,
7608
7831
  path: memory.path,
7609
7832
  score,
7610
7833
  namespace,
7611
- seed: path5.resolve(storage.dir, candidate.seed),
7834
+ seed: path6.resolve(storage.dir, candidate.seed),
7612
7835
  hopDepth: candidate.hopDepth,
7613
7836
  decayedWeight: candidate.decayedWeight,
7614
7837
  graphType: candidate.graphType,
@@ -7629,12 +7852,12 @@ ${doc.content}` : doc.content,
7629
7852
  }
7630
7853
  async recordLastGraphRecallSnapshot(options) {
7631
7854
  try {
7632
- const snapshotPath = path5.join(
7855
+ const snapshotPath = path6.join(
7633
7856
  options.storage.dir,
7634
7857
  "state",
7635
7858
  "last_graph_recall.json"
7636
7859
  );
7637
- await mkdir3(path5.dirname(snapshotPath), { recursive: true });
7860
+ await mkdir3(path6.dirname(snapshotPath), { recursive: true });
7638
7861
  const now = (/* @__PURE__ */ new Date()).toISOString();
7639
7862
  const totalSeedCount = options.seedPaths.length;
7640
7863
  const totalExpandedCount = options.expandedPaths.length;
@@ -7668,12 +7891,12 @@ ${doc.content}` : doc.content,
7668
7891
  }
7669
7892
  async recordLastIntentSnapshot(options) {
7670
7893
  try {
7671
- const snapshotPath = path5.join(
7894
+ const snapshotPath = path6.join(
7672
7895
  options.storage.dir,
7673
7896
  "state",
7674
7897
  "last_intent.json"
7675
7898
  );
7676
- await mkdir3(path5.dirname(snapshotPath), { recursive: true });
7899
+ await mkdir3(path6.dirname(snapshotPath), { recursive: true });
7677
7900
  await writeFile3(
7678
7901
  snapshotPath,
7679
7902
  JSON.stringify(options.snapshot, null, 2),
@@ -7685,12 +7908,12 @@ ${doc.content}` : doc.content,
7685
7908
  }
7686
7909
  async recordLastQmdRecallSnapshot(options) {
7687
7910
  try {
7688
- const snapshotPath = path5.join(
7911
+ const snapshotPath = path6.join(
7689
7912
  options.storage.dir,
7690
7913
  "state",
7691
7914
  "last_qmd_recall.json"
7692
7915
  );
7693
- await mkdir3(path5.dirname(snapshotPath), { recursive: true });
7916
+ await mkdir3(path6.dirname(snapshotPath), { recursive: true });
7694
7917
  await writeFile3(
7695
7918
  snapshotPath,
7696
7919
  JSON.stringify(options.snapshot, null, 2),
@@ -7705,8 +7928,8 @@ ${doc.content}` : doc.content,
7705
7928
  const stateDir = await this.resolveStateDirForNamespace(
7706
7929
  options.namespace
7707
7930
  );
7708
- const snapshotPath = path5.join(stateDir, "last_intent.json");
7709
- await mkdir3(path5.dirname(snapshotPath), { recursive: true });
7931
+ const snapshotPath = path6.join(stateDir, "last_intent.json");
7932
+ await mkdir3(path6.dirname(snapshotPath), { recursive: true });
7710
7933
  await writeFile3(
7711
7934
  snapshotPath,
7712
7935
  JSON.stringify(options.snapshot, null, 2),
@@ -7718,12 +7941,12 @@ ${doc.content}` : doc.content,
7718
7941
  }
7719
7942
  async resolveStateDirForNamespace(namespace) {
7720
7943
  if (!resolveNamespaceCapabilities(this.config).namespaces) {
7721
- return path5.join(this.config.memoryDir, "state");
7944
+ return path6.join(this.config.memoryDir, "state");
7722
7945
  }
7723
7946
  if (namespace !== this.config.defaultNamespace) {
7724
- return path5.join(this.config.memoryDir, "namespaces", namespace, "state");
7947
+ return path6.join(this.config.memoryDir, "namespaces", namespace, "state");
7725
7948
  }
7726
- const candidate = path5.join(
7949
+ const candidate = path6.join(
7727
7950
  this.config.memoryDir,
7728
7951
  "namespaces",
7729
7952
  this.config.defaultNamespace
@@ -7731,11 +7954,11 @@ ${doc.content}` : doc.content,
7731
7954
  try {
7732
7955
  const candidateStat = await stat(candidate);
7733
7956
  if (candidateStat.isDirectory()) {
7734
- return path5.join(candidate, "state");
7957
+ return path6.join(candidate, "state");
7735
7958
  }
7736
7959
  } catch {
7737
7960
  }
7738
- return path5.join(this.config.memoryDir, "state");
7961
+ return path6.join(this.config.memoryDir, "state");
7739
7962
  }
7740
7963
  buildGraphRecallRankedResults(results, sourceLabelResolver, limit = 64) {
7741
7964
  return results.slice(0, limit).map((result) => ({
@@ -8137,7 +8360,7 @@ ${doc.content}` : doc.content,
8137
8360
  const graphExpandedResultPaths = /* @__PURE__ */ new Set();
8138
8361
  const graphSourceLabelsForPath = (resultPath) => {
8139
8362
  const labels = [];
8140
- const normalizedPath = resultPath.split(path5.sep).join("/");
8363
+ const normalizedPath = resultPath.split(path6.sep).join("/");
8141
8364
  const isEntityPath = normalizedPath.startsWith("entities/") || normalizedPath.includes("/entities/");
8142
8365
  if (graphBaselinePaths.has(resultPath)) labels.push("baseline");
8143
8366
  if (graphExpandedResultPaths.has(resultPath))
@@ -8287,7 +8510,7 @@ ${doc.content}` : doc.content,
8287
8510
  profileStorageNamespaces.map((namespace) => this.storageRouter.storageFor(namespace))
8288
8511
  );
8289
8512
  const emptyProfileStorage = new Proxy(
8290
- { dir: path5.join(this.config.memoryDir, ".empty-scope-profile") },
8513
+ { dir: path6.join(this.config.memoryDir, ".empty-scope-profile") },
8291
8514
  {
8292
8515
  get(target, prop) {
8293
8516
  if (prop in target) return target[prop];
@@ -9763,11 +9986,11 @@ ${formatted}`;
9763
9986
  if (!resolveRecallAuxiliaryCapabilities(this.config).compactionReset) return null;
9764
9987
  const workspaceDir = compactionWorkspaceDir || this.config.workspaceDir || defaultWorkspaceDir();
9765
9988
  const safeSessionKey = sanitizeSessionKeyForFilename(effectiveSessionKey);
9766
- const signalPath = path5.join(
9989
+ const signalPath = path6.join(
9767
9990
  workspaceDir,
9768
9991
  `.compaction-reset-signal-${safeSessionKey}`
9769
9992
  );
9770
- const bootPath = path5.join(workspaceDir, "BOOT.md");
9993
+ const bootPath = path6.join(workspaceDir, "BOOT.md");
9771
9994
  try {
9772
9995
  const signalStat = await stat(signalPath).catch(() => null);
9773
9996
  if (!signalStat) return null;
@@ -14369,7 +14592,7 @@ ${normalized}`).digest("hex");
14369
14592
  const allMems = allMemsForGraph ?? [];
14370
14593
  for (const m of allMems) {
14371
14594
  if (m.frontmatter.entityRef === entityRef) {
14372
- const rel = path5.relative(storage.dir, m.path);
14595
+ const rel = path6.relative(storage.dir, m.path);
14373
14596
  if (rel !== memoryRelPath) entitySiblings.push(rel);
14374
14597
  }
14375
14598
  }
@@ -14693,7 +14916,7 @@ ${normalized}`).digest("hex");
14693
14916
  }
14694
14917
  if (resolveConsolidationCapabilities(this.config).semanticConsolidation) {
14695
14918
  try {
14696
- const stateFilePath = path5.join(
14919
+ const stateFilePath = path6.join(
14697
14920
  this.config.memoryDir,
14698
14921
  "state",
14699
14922
  "semantic-consolidation-last-run.json"
@@ -14741,7 +14964,7 @@ ${normalized}`).digest("hex");
14741
14964
  );
14742
14965
  }
14743
14966
  if (semResult.errors === 0 || semResult.memoriesArchived > 0) {
14744
- const stateDir = path5.join(this.config.memoryDir, "state");
14967
+ const stateDir = path6.join(this.config.memoryDir, "state");
14745
14968
  await mkdir3(stateDir, { recursive: true });
14746
14969
  await writeFile3(
14747
14970
  stateFilePath,
@@ -15052,198 +15275,16 @@ ${reflectionsContent.trim()}
15052
15275
  }
15053
15276
  return null;
15054
15277
  }
15278
+ // Issue #1526 seam 11: QMD result-resolution methods moved to QmdResultResolver.
15279
+ // Thin delegation keeps the private API stable for callers + tests.
15055
15280
  async readQmdResultMemory(resultPath, fallbackStorage, recallNamespaces = []) {
15056
- const parts = qmdCollectionPathParts(resultPath);
15057
- const storageDirFor = (storage) => typeof storage.dir === "string" && storage.dir ? storage.dir : null;
15058
- const fallbackStorageDir = storageDirFor(fallbackStorage);
15059
- const coldCollection = this.config.qmdColdCollection ?? "openclaw-engram-cold";
15060
- if (parts && parts.collection === coldCollection) {
15061
- const storages = [];
15062
- const seenStorageDirs = /* @__PURE__ */ new Set();
15063
- const addStorage = (storage) => {
15064
- const storageDir = storageDirFor(storage);
15065
- const storageKey = storageDir ? path5.resolve(storageDir) : `storage-without-dir-${storages.length}`;
15066
- if (seenStorageDirs.has(storageKey)) return;
15067
- seenStorageDirs.add(storageKey);
15068
- storages.push(storage);
15069
- };
15070
- const fallbackNamespace = fallbackStorageDir !== null ? this.storageDirNamespace(fallbackStorageDir) : this.config.defaultNamespace;
15071
- if (recallNamespaces.length === 0 || !resolveNamespaceCapabilities(this.config).namespaces || recallNamespaces.includes(fallbackNamespace)) {
15072
- addStorage(fallbackStorage);
15073
- }
15074
- if (recallNamespaces.length > 0) {
15075
- for (const namespace of recallNamespaces) {
15076
- try {
15077
- addStorage(await this.storageRouter.storageFor(namespace));
15078
- } catch (err) {
15079
- log.debug("qmd cold result namespace storage lookup skipped", {
15080
- path: resultPath,
15081
- namespace,
15082
- error: err.message
15083
- });
15084
- }
15085
- }
15086
- }
15087
- for (const storage of storages) {
15088
- const storageDir = storageDirFor(storage);
15089
- if (!storageDir) {
15090
- const memory = await storage.readMemoryByPath(resultPath);
15091
- if (memory) return memory;
15092
- continue;
15093
- }
15094
- try {
15095
- const coldRoot = path5.join(storageDir, "cold");
15096
- for (const candidate of qmdResultPathCandidates(
15097
- coldRoot,
15098
- parts.relativePath
15099
- )) {
15100
- const memory = await storage.readMemoryByPath(candidate);
15101
- if (memory) return memory;
15102
- }
15103
- } catch (err) {
15104
- if (err instanceof SecureStoreLockedError) throw err;
15105
- log.debug("qmd cold result path lookup failed open", {
15106
- path: resultPath,
15107
- collection: coldCollection,
15108
- error: err.message
15109
- });
15110
- }
15111
- }
15112
- return null;
15113
- }
15114
- const collectionNamespace = parts ? this.qmdCollectionNamespaceFromPrefix(parts.collection) : null;
15115
- if (parts && collectionNamespace) {
15116
- try {
15117
- const collectionStorage = await this.storageRouter.storageFor(collectionNamespace);
15118
- for (const candidate of qmdResultPathCandidates(
15119
- collectionStorage.dir,
15120
- parts.relativePath
15121
- )) {
15122
- const memory = await collectionStorage.readMemoryByPath(candidate);
15123
- if (memory) return memory;
15124
- }
15125
- return null;
15126
- } catch (err) {
15127
- if (err instanceof SecureStoreLockedError) throw err;
15128
- log.debug("qmd result namespace path lookup failed open", {
15129
- path: resultPath,
15130
- namespace: collectionNamespace,
15131
- error: err.message
15132
- });
15133
- return null;
15134
- }
15135
- }
15136
- if (path5.isAbsolute(resultPath)) {
15137
- if (!fallbackStorageDir) {
15138
- return await fallbackStorage.readMemoryByPath(resultPath);
15139
- }
15140
- const ownerStorage = await this.storageForAbsoluteQmdResultPath(
15141
- resultPath,
15142
- fallbackStorage,
15143
- recallNamespaces
15144
- );
15145
- if (!ownerStorage) return null;
15146
- for (const candidate of qmdResultPathCandidates(
15147
- ownerStorage.dir,
15148
- resultPath
15149
- )) {
15150
- const memory = await ownerStorage.storage.readMemoryByPath(candidate);
15151
- if (memory) return memory;
15152
- }
15153
- return null;
15154
- }
15155
- if (!fallbackStorageDir) {
15156
- return await fallbackStorage.readMemoryByPath(resultPath);
15157
- }
15158
- for (const candidate of qmdResultPathCandidates(
15159
- fallbackStorageDir,
15160
- resultPath
15161
- )) {
15162
- const memory = await fallbackStorage.readMemoryByPath(candidate);
15163
- if (memory) return memory;
15164
- }
15165
- return null;
15281
+ return this.qmdResultResolver.readQmdResultMemory(resultPath, fallbackStorage, recallNamespaces);
15166
15282
  }
15167
15283
  async resolveColdQmdResultForRecall(result, fallbackStorage, recallNamespaces = []) {
15168
- const memory = await this.readQmdResultMemory(
15169
- result.path,
15170
- fallbackStorage,
15171
- recallNamespaces
15172
- );
15173
- if (!memory) return null;
15174
- let ownerNamespace = null;
15175
- if (path5.isAbsolute(memory.path)) {
15176
- const ownerStorage = await this.storageForAbsoluteQmdResultPath(
15177
- memory.path,
15178
- fallbackStorage,
15179
- recallNamespaces
15180
- );
15181
- ownerNamespace = ownerStorage?.namespace ?? null;
15182
- if (!ownerNamespace && resolveNamespaceCapabilities(this.config).namespaces) return null;
15183
- }
15184
- ownerNamespace ??= this.namespaceFromPath(memory.path);
15185
- if (recallNamespaces.length > 0 && !recallNamespaces.includes(ownerNamespace)) {
15186
- return null;
15187
- }
15188
- return {
15189
- namespace: ownerNamespace,
15190
- result: {
15191
- ...result,
15192
- docid: result.docid || memory.frontmatter.id,
15193
- path: memory.path,
15194
- snippet: result.snippet || memory.content.slice(0, 400)
15195
- }
15196
- };
15284
+ return this.qmdResultResolver.resolveColdQmdResultForRecall(result, fallbackStorage, recallNamespaces);
15197
15285
  }
15198
15286
  async storageForAbsoluteQmdResultPath(resultPath, fallbackStorage, recallNamespaces = []) {
15199
- const resolvedPath = path5.resolve(resultPath);
15200
- const memoryRoot = path5.resolve(this.config.memoryDir);
15201
- const namespacesRoot = path5.join(memoryRoot, "namespaces");
15202
- const fallbackStorageDir = typeof fallbackStorage.dir === "string" && fallbackStorage.dir ? fallbackStorage.dir : null;
15203
- const matches = [];
15204
- const seenDirs = /* @__PURE__ */ new Set();
15205
- const maybeAddStorage = (storage, namespace) => {
15206
- const storageDir = typeof storage.dir === "string" && storage.dir ? storage.dir : null;
15207
- if (!storageDir) return;
15208
- const candidateRoot = path5.resolve(storageDir);
15209
- if (seenDirs.has(candidateRoot)) return;
15210
- if (!isPathInsideStorageRoot(candidateRoot, resolvedPath)) return;
15211
- if (candidateRoot === memoryRoot && isPathInsideStorageRoot(namespacesRoot, resolvedPath)) {
15212
- return;
15213
- }
15214
- seenDirs.add(candidateRoot);
15215
- matches.push({ storage, dir: candidateRoot, namespace });
15216
- };
15217
- const fallbackNamespace = fallbackStorageDir !== null ? this.storageDirNamespace(fallbackStorageDir) : this.config.defaultNamespace;
15218
- maybeAddStorage(fallbackStorage, fallbackNamespace);
15219
- const candidateNamespaces = /* @__PURE__ */ new Set();
15220
- candidateNamespaces.add(this.config.defaultNamespace);
15221
- candidateNamespaces.add(this.config.sharedNamespace);
15222
- for (const ns of recallNamespaces) {
15223
- candidateNamespaces.add(ns);
15224
- }
15225
- if (isPathInsideStorageRoot(namespacesRoot, resolvedPath)) {
15226
- const relativeToNamespaces = path5.relative(namespacesRoot, resolvedPath);
15227
- const [namespaceSegment] = relativeToNamespaces.split(/[\\/]/);
15228
- if (namespaceSegment) {
15229
- candidateNamespaces.add(
15230
- namespaceIdentityFromToken(namespaceSegment) ?? namespaceSegment
15231
- );
15232
- }
15233
- }
15234
- for (const policy of this.config.namespacePolicies ?? []) {
15235
- candidateNamespaces.add(policy.name);
15236
- }
15237
- for (const ns of candidateNamespaces) {
15238
- if (!ns) continue;
15239
- try {
15240
- maybeAddStorage(await this.storageRouter.storageFor(ns), ns);
15241
- } catch {
15242
- continue;
15243
- }
15244
- }
15245
- matches.sort((a, b) => b.dir.length - a.dir.length);
15246
- return matches[0] ?? null;
15287
+ return this.qmdResultResolver.storageForAbsoluteQmdResultPath(resultPath, fallbackStorage, recallNamespaces);
15247
15288
  }
15248
15289
  // Issue #1526: recall-rerank methods moved to RecallRerankCoordinator.
15249
15290
  // Thin delegation keeps the private API stable for callers + tests.
@@ -15336,12 +15377,12 @@ ${reflectionsContent.trim()}
15336
15377
  */
15337
15378
  semanticDedupScopeFor(targetStorage) {
15338
15379
  if (!resolveNamespaceCapabilities(this.config).namespaces) return {};
15339
- const memoryDir = path5.resolve(this.config.memoryDir);
15340
- const storageDir = path5.resolve(targetStorage.dir);
15380
+ const memoryDir = path6.resolve(this.config.memoryDir);
15381
+ const storageDir = path6.resolve(targetStorage.dir);
15341
15382
  if (storageDir === memoryDir) {
15342
15383
  return { pathExcludePrefixes: ["namespaces/"] };
15343
15384
  }
15344
- let rel = path5.relative(memoryDir, storageDir);
15385
+ let rel = path6.relative(memoryDir, storageDir);
15345
15386
  if (!rel || rel.startsWith("..")) {
15346
15387
  log.debug(
15347
15388
  `semantic dedup: target storage dir ${storageDir} is outside memoryDir ${memoryDir}; scoping lookup to absolute path prefix`
@@ -15360,7 +15401,7 @@ ${reflectionsContent.trim()}
15360
15401
  if (hits.length === 0) return [];
15361
15402
  const results = [];
15362
15403
  for (const hit of hits) {
15363
- const fullPath = path5.isAbsolute(hit.path) ? hit.path : path5.join(this.config.memoryDir, hit.path);
15404
+ const fullPath = path6.isAbsolute(hit.path) ? hit.path : path6.join(this.config.memoryDir, hit.path);
15364
15405
  const memory = await this.storage.readMemoryByPath(fullPath);
15365
15406
  if (!memory) continue;
15366
15407
  results.push({
@@ -15557,7 +15598,7 @@ ${reflectionsContent.trim()}
15557
15598
  const storage = await this.storageRouter.storageFor(namespace);
15558
15599
  const storageDir = typeof storage.dir === "string" && storage.dir ? storage.dir : null;
15559
15600
  if (!storageDir) continue;
15560
- const recallRoot = path5.resolve(storageDir);
15601
+ const recallRoot = path6.resolve(storageDir);
15561
15602
  if (seenRecallRoots.has(recallRoot)) continue;
15562
15603
  seenRecallRoots.add(recallRoot);
15563
15604
  recallRoots.push(recallRoot);
@@ -15581,8 +15622,8 @@ ${reflectionsContent.trim()}
15581
15622
  if (resolvedCold) scopedResults.push(resolvedCold.result);
15582
15623
  continue;
15583
15624
  }
15584
- if (path5.isAbsolute(result.path)) {
15585
- const resolvedPath = path5.resolve(result.path);
15625
+ if (path6.isAbsolute(result.path)) {
15626
+ const resolvedPath = path6.resolve(result.path);
15586
15627
  if (recallRoots.some(
15587
15628
  (recallRoot) => isPathInsideStorageRoot(recallRoot, resolvedPath)
15588
15629
  )) {
@@ -16516,4 +16557,4 @@ export {
16516
16557
  resolvePersistedMemoryRelativePath,
16517
16558
  Orchestrator
16518
16559
  };
16519
- //# sourceMappingURL=chunk-VC7QELR6.js.map
16560
+ //# sourceMappingURL=chunk-7HUGLMSW.js.map