@remnic/core 9.69.31 → 9.69.32

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 (132) hide show
  1. package/dist/access-admin-ops-surface.d.ts +2 -2
  2. package/dist/access-admin-ops-surface.js +4 -4
  3. package/dist/access-authorization-probe.d.ts +2 -2
  4. package/dist/access-authorization-probe.js +5 -5
  5. package/dist/access-boundary.d.ts +2 -2
  6. package/dist/access-boundary.js +4 -4
  7. package/dist/access-cli.js +20 -20
  8. package/dist/access-extraction-force-flush.d.ts +2 -2
  9. package/dist/access-extraction-force-flush.js +4 -4
  10. package/dist/access-http-briefing.d.ts +2 -2
  11. package/dist/access-http-briefing.js +5 -5
  12. package/dist/access-http-lcm-compaction.d.ts +2 -2
  13. package/dist/access-http-lifecycle-flush.d.ts +2 -2
  14. package/dist/access-http-offline-stream.d.ts +2 -2
  15. package/dist/access-http-query.js +4 -4
  16. package/dist/access-http.d.ts +3 -3
  17. package/dist/access-http.js +14 -14
  18. package/dist/access-identity-continuity-surface.d.ts +1 -1
  19. package/dist/access-identity-continuity-surface.js +4 -4
  20. package/dist/access-lcm-surface.d.ts +2 -2
  21. package/dist/access-lcm-surface.js +4 -4
  22. package/dist/access-mcp.d.ts +2 -2
  23. package/dist/access-mcp.js +9 -9
  24. package/dist/access-namespace-preflight.js +4 -4
  25. package/dist/access-observe-transcript.d.ts +1 -1
  26. package/dist/access-observe-write-surface.d.ts +2 -2
  27. package/dist/access-observe-write-surface.js +4 -4
  28. package/dist/access-offline-manifest.d.ts +1 -1
  29. package/dist/access-operations-batch.js +5 -5
  30. package/dist/access-operations.d.ts +7 -7
  31. package/dist/access-operations.js +8 -8
  32. package/dist/access-recall-concurrency.d.ts +2 -2
  33. package/dist/access-recall-concurrency.js +4 -4
  34. package/dist/access-recall-response.d.ts +2 -2
  35. package/dist/access-recall-response.js +4 -4
  36. package/dist/access-recall-surface.d.ts +2 -2
  37. package/dist/access-recall-surface.js +4 -4
  38. package/dist/access-schema.d.ts +91 -91
  39. package/dist/{access-service-Cv8Rizo0.d.ts → access-service-CCpOuS46.d.ts} +65 -65
  40. package/dist/access-service-helpers.d.ts +2 -2
  41. package/dist/access-service.d.ts +2 -2
  42. package/dist/access-service.js +4 -4
  43. package/dist/access-surface-catalog.d.ts +2 -2
  44. package/dist/access-surface-catalog.js +6 -6
  45. package/dist/bootstrap.d.ts +1 -1
  46. package/dist/briefing-window.d.ts +25 -5
  47. package/dist/briefing-window.js +4 -1
  48. package/dist/briefing.js +2 -2
  49. package/dist/buffer.js +2 -2
  50. package/dist/{chunk-SMOFBBPU.js → chunk-2GPE5UCR.js} +2 -2
  51. package/dist/{chunk-IA2YSHTX.js → chunk-42SDNZCU.js} +8 -8
  52. package/dist/{chunk-W64HKJJM.js → chunk-5N53UBH2.js} +2 -2
  53. package/dist/{chunk-T7CJQVRZ.js → chunk-6H5JYDOM.js} +2 -2
  54. package/dist/chunk-6JMQR72P.js +134 -0
  55. package/dist/chunk-6JMQR72P.js.map +1 -0
  56. package/dist/{chunk-X74UAWSI.js → chunk-C4OTC6WY.js} +2 -2
  57. package/dist/{chunk-PLBW64UM.js → chunk-CZYYJZB6.js} +10 -11
  58. package/dist/chunk-CZYYJZB6.js.map +1 -0
  59. package/dist/{chunk-JDDXXZWW.js → chunk-GQOMZ3MK.js} +2 -2
  60. package/dist/{chunk-SH2ZWEWB.js → chunk-HG6HXVHQ.js} +3 -3
  61. package/dist/{chunk-OGELWNYC.js → chunk-ITPS5DDH.js} +3 -3
  62. package/dist/{chunk-EYMOJ3J6.js → chunk-LPECRQO4.js} +2 -2
  63. package/dist/{chunk-666OOKB7.js → chunk-M75RYSHS.js} +2 -2
  64. package/dist/{chunk-5ABN4WVL.js → chunk-MYMNC6O5.js} +4 -4
  65. package/dist/{chunk-KLMESRPV.js → chunk-NAXDPKVM.js} +2 -2
  66. package/dist/{chunk-OXNU333D.js → chunk-Q3O3VKRB.js} +2 -2
  67. package/dist/{chunk-ENMTJRXA.js → chunk-QMGXMJ2O.js} +2 -2
  68. package/dist/{chunk-PEOTOFH5.js → chunk-TIT2C6WX.js} +2 -2
  69. package/dist/{chunk-U34EHBPL.js → chunk-VED2YHUD.js} +2 -2
  70. package/dist/{chunk-RAVRDTP7.js → chunk-XQ2Q43XD.js} +3 -1
  71. package/dist/chunk-XQ2Q43XD.js.map +1 -0
  72. package/dist/{chunk-7DUFJAOE.js → chunk-Z4PCVRTN.js} +3 -3
  73. package/dist/{cli-B_YwqoIr.d.ts → cli-NEEdq5Rt.d.ts} +2 -2
  74. package/dist/cli.d.ts +3 -3
  75. package/dist/cli.js +15 -15
  76. package/dist/deep-recall-http-glue.d.ts +2 -2
  77. package/dist/deep-recall-mcp-tools.d.ts +2 -2
  78. package/dist/explicit-capture.d.ts +1 -1
  79. package/dist/external-wiki-access.d.ts +2 -2
  80. package/dist/external-wiki-access.js +5 -5
  81. package/dist/external-wiki-mcp-tools.d.ts +2 -2
  82. package/dist/extraction.js +3 -3
  83. package/dist/index.d.ts +681 -681
  84. package/dist/index.js +20 -20
  85. package/dist/mcp-memory-inspector-app.d.ts +2 -2
  86. package/dist/memory-subject-cli.d.ts +2 -2
  87. package/dist/memory-subject.d.ts +2 -2
  88. package/dist/{orchestrator-DgyvFfPR.d.ts → orchestrator-kqSzGv7e.d.ts} +48 -64
  89. package/dist/orchestrator.d.ts +1 -1
  90. package/dist/orchestrator.js +20 -20
  91. package/dist/{public-http-D6d4W8x-.d.ts → public-http-CW3l0g3P.d.ts} +1 -1
  92. package/dist/schemas.d.ts +176 -176
  93. package/dist/shared-context/manager.d.ts +6 -6
  94. package/dist/source-agent-qualifier.js +2 -2
  95. package/dist/support-passport/index.d.ts +5 -5
  96. package/dist/support-passport/index.js +7 -7
  97. package/dist/transfer/types.d.ts +78 -78
  98. package/dist/who-knows-cli.d.ts +2 -2
  99. package/dist/who-knows.d.ts +2 -2
  100. package/package.json +2 -2
  101. package/src/briefing-window.test.ts +554 -0
  102. package/src/briefing-window.ts +201 -12
  103. package/src/briefing.test.ts +2 -1
  104. package/src/orchestration/extraction-shutdown.ts +2 -10
  105. package/src/orchestration/graph-recall-coordinator.ts +19 -16
  106. package/src/orchestration/namespace-read-fanout.ts +2 -5
  107. package/src/orchestration/orchestrator-helpers.ts +2 -0
  108. package/src/orchestration/recall-internal-deps.ts +1 -5
  109. package/src/orchestration/recall-search-pipeline.ts +1 -4
  110. package/src/orchestrator.ts +1 -3
  111. package/dist/chunk-PLBW64UM.js.map +0 -1
  112. package/dist/chunk-RAVRDTP7.js.map +0 -1
  113. package/dist/chunk-UBCBDJOB.js +0 -22
  114. package/dist/chunk-UBCBDJOB.js.map +0 -1
  115. package/src/orchestration/graph-recall-seam.ts +0 -19
  116. /package/dist/{chunk-SMOFBBPU.js.map → chunk-2GPE5UCR.js.map} +0 -0
  117. /package/dist/{chunk-IA2YSHTX.js.map → chunk-42SDNZCU.js.map} +0 -0
  118. /package/dist/{chunk-W64HKJJM.js.map → chunk-5N53UBH2.js.map} +0 -0
  119. /package/dist/{chunk-T7CJQVRZ.js.map → chunk-6H5JYDOM.js.map} +0 -0
  120. /package/dist/{chunk-X74UAWSI.js.map → chunk-C4OTC6WY.js.map} +0 -0
  121. /package/dist/{chunk-JDDXXZWW.js.map → chunk-GQOMZ3MK.js.map} +0 -0
  122. /package/dist/{chunk-SH2ZWEWB.js.map → chunk-HG6HXVHQ.js.map} +0 -0
  123. /package/dist/{chunk-OGELWNYC.js.map → chunk-ITPS5DDH.js.map} +0 -0
  124. /package/dist/{chunk-EYMOJ3J6.js.map → chunk-LPECRQO4.js.map} +0 -0
  125. /package/dist/{chunk-666OOKB7.js.map → chunk-M75RYSHS.js.map} +0 -0
  126. /package/dist/{chunk-5ABN4WVL.js.map → chunk-MYMNC6O5.js.map} +0 -0
  127. /package/dist/{chunk-KLMESRPV.js.map → chunk-NAXDPKVM.js.map} +0 -0
  128. /package/dist/{chunk-OXNU333D.js.map → chunk-Q3O3VKRB.js.map} +0 -0
  129. /package/dist/{chunk-ENMTJRXA.js.map → chunk-QMGXMJ2O.js.map} +0 -0
  130. /package/dist/{chunk-PEOTOFH5.js.map → chunk-TIT2C6WX.js.map} +0 -0
  131. /package/dist/{chunk-U34EHBPL.js.map → chunk-VED2YHUD.js.map} +0 -0
  132. /package/dist/{chunk-7DUFJAOE.js.map → chunk-Z4PCVRTN.js.map} +0 -0
@@ -1,27 +1,216 @@
1
1
  import { log } from "./logger.js";
2
2
  import type { MemoryFile } from "./types.js";
3
+ import { isAbortError } from "./abort-error.js";
4
+ import type { CorpusReadOptions } from "./corpus-read-cancellation.js";
5
+ import type { ParsedBriefingWindow } from "./briefing.js";
6
+
3
7
  type BriefingMemoryReader = {
4
8
  readMemoriesWindow?: (options: { updatedAfter?: Date }) => Promise<{ memories: MemoryFile[] }>;
5
- readAllMemories: () => Promise<MemoryFile[]>;
9
+ readAllMemories: ((options?: CorpusReadOptions) => Promise<MemoryFile[]>) & {
10
+ supportsAbortSignal?: boolean;
11
+ };
12
+ supportsAbortSignal?: boolean;
13
+ supportsCancellation?: boolean;
14
+ cancellable?: boolean;
6
15
  };
7
- import type { ParsedBriefingWindow } from "./briefing.js";
16
+
17
+ /**
18
+ * Deadline for the legacy full-read fallback (issue #2779). Storage doubles
19
+ * that predate `readMemoriesWindow()` can only answer with a full-corpus
20
+ * `readAllMemories()`, which is unbounded work; on a large corpus that read
21
+ * alone can outlast the 60s MCP client timeout. Arm an AbortController with
22
+ * this budget (well under 60s, leaving room for entity reads and follow-ups)
23
+ * and fail open with an empty read. The deadline reaches the read as an
24
+ * abort signal (the #2307 corpus-read contract), so the scan stops at its
25
+ * next boundary instead of being abandoned to run on in the background.
26
+ */
27
+ export const BRIEFING_FULL_READ_FALLBACK_MS = 30_000;
28
+
29
+ /** Options for {@link safeReadMemories}. */
30
+ export interface SafeReadMemoriesOptions {
31
+ /** Test seam overriding {@link BRIEFING_FULL_READ_FALLBACK_MS}. */
32
+ fallbackDeadlineMs?: number;
33
+ }
34
+
35
+ type BriefingReadMode = "windowed" | "full-read-fallback";
36
+ type BriefingReadOutcome = "success" | "timeout" | "error";
37
+
38
+ /** Internal marker: the fallback deadline fired and the read was aborted. */
39
+ class BriefingReadTimedOut extends Error {
40
+ constructor(readonly deadlineMs: number) {
41
+ super("briefing full-read fallback timed out");
42
+ this.name = "BriefingReadTimedOut";
43
+ }
44
+ }
45
+
46
+ /** Internal marker: the adapter's readAllMemories predates the signal contract. */
47
+ class LegacyReadUnsupported extends Error {
48
+ constructor() {
49
+ super("readAllMemories does not accept an abort signal");
50
+ this.name = "LegacyReadUnsupported";
51
+ }
52
+ }
53
+
54
+ const SAFE_ERROR_CLASSES: Record<string, true> = {
55
+ Error: true,
56
+ TypeError: true,
57
+ RangeError: true,
58
+ ReferenceError: true,
59
+ SyntaxError: true,
60
+ URIError: true,
61
+ EvalError: true,
62
+ AggregateError: true,
63
+ AbortError: true,
64
+ TimeoutError: true,
65
+ SystemError: true,
66
+ BriefingReadTimedOut: true,
67
+ LegacyReadUnsupported: true,
68
+ StorageError: true,
69
+ EngramAccessInputError: true,
70
+ };
71
+
72
+ /**
73
+ * Sanitize adapter-controlled Error.name before structured discriminator logs
74
+ * (issue #2827). Allow-lists known system/remnic error names and maps any
75
+ * unrecognized or backend-controlled names to a safe bounded class ("CustomError").
76
+ */
77
+ function errorClass(err: unknown): string {
78
+ if (err instanceof Error) {
79
+ const name = err.name;
80
+ if (typeof name === "string" && SAFE_ERROR_CLASSES[name] === true) {
81
+ return name;
82
+ }
83
+ return "CustomError";
84
+ }
85
+ return typeof err === "string"
86
+ ? "string"
87
+ : typeof err === "object" && err !== null
88
+ ? "object"
89
+ : typeof err;
90
+ }
91
+
92
+ function bestEffortLog(level: "info" | "warn", message: string): void {
93
+ try {
94
+ log[level](message);
95
+ } catch {
96
+ // Diagnostics must never turn a successful or fail-open briefing read into
97
+ // a request failure when a host logger transport is unavailable.
98
+ }
99
+ }
100
+
101
+ /**
102
+ * One structured, content-free discriminator per briefing memory read
103
+ * (issue #2779): `mode`, `durationMs`, `count` when known, `outcome`, and on
104
+ * failure a safe error class — never error messages or memory content.
105
+ */
106
+ function logBriefingMemoryRead(
107
+ mode: BriefingReadMode,
108
+ outcome: BriefingReadOutcome,
109
+ durationMs: number,
110
+ resultCount: number | undefined,
111
+ errClass: string | undefined,
112
+ ): void {
113
+ const fields = [
114
+ `mode=${mode}`,
115
+ `durationMs=${durationMs}`,
116
+ ...(resultCount === undefined ? [] : [`count=${resultCount}`]),
117
+ `outcome=${outcome}`,
118
+ ...(errClass === undefined ? [] : [`err=${errClass}`]),
119
+ ];
120
+ bestEffortLog("info", `briefing: memory read ${fields.join(" ")}`);
121
+ }
8
122
 
9
123
  /** Read only the memories needed by a briefing, with compatibility fallback. */
10
124
  export async function safeReadMemories(
11
125
  storage: BriefingMemoryReader,
12
- window: ParsedBriefingWindow
126
+ window: ParsedBriefingWindow,
127
+ options: SafeReadMemoriesOptions = {},
13
128
  ): Promise<MemoryFile[]> {
129
+ const startedAt = Date.now();
130
+ const mode: BriefingReadMode =
131
+ typeof storage.readMemoriesWindow === "function" ? "windowed" : "full-read-fallback";
132
+ let outcome: BriefingReadOutcome = "error";
133
+ let resultCount: number | undefined;
134
+ let errClass: string | undefined;
14
135
  try {
15
- // A briefing only needs memories inside its lookback window. Avoid parsing
16
- // the full corpus on cache misses; keep the full-read fallback for custom
17
- // StorageManager-compatible callers that predate readMemoriesWindow().
18
- if (typeof storage.readMemoriesWindow === "function") {
19
- const result = await storage.readMemoriesWindow({ updatedAfter: window.from });
20
- return result.memories;
21
- }
22
- return await storage.readAllMemories();
136
+ const memories = await readBriefingMemories(storage, window, mode, options);
137
+ outcome = "success";
138
+ resultCount = memories.length;
139
+ return memories;
23
140
  } catch (err) {
24
- log.warn(`briefing: read memories failed: ${err}`);
141
+ if (err instanceof BriefingReadTimedOut) {
142
+ outcome = "timeout";
143
+ bestEffortLog(
144
+ "warn",
145
+ `briefing: memory read mode=full-read-fallback timed out after ${err.deadlineMs}ms — ` +
146
+ `returning no memories (storage adapter lacks readMemoriesWindow; upgrade it to ` +
147
+ `windowed or signal-aware reads)`,
148
+ );
149
+ } else if (err instanceof LegacyReadUnsupported) {
150
+ errClass = errorClass(err);
151
+ bestEffortLog(
152
+ "warn",
153
+ `briefing: memory read mode=full-read-fallback refused: readAllMemories() takes no abort ` +
154
+ `signal, so its scan could not be stopped at the deadline — returning no memories ` +
155
+ `(upgrade the storage adapter to readMemoriesWindow or a signal-aware readAllMemories)`,
156
+ );
157
+ } else {
158
+ errClass = errorClass(err);
159
+ bestEffortLog("warn", `briefing: read memories failed (${errClass}) — returning no memories`);
160
+ }
25
161
  return [];
162
+ } finally {
163
+ logBriefingMemoryRead(mode, outcome, Date.now() - startedAt, resultCount, errClass);
164
+ }
165
+ }
166
+
167
+ async function readBriefingMemories(
168
+ storage: BriefingMemoryReader,
169
+ window: ParsedBriefingWindow,
170
+ mode: BriefingReadMode,
171
+ options: SafeReadMemoriesOptions,
172
+ ): Promise<MemoryFile[]> {
173
+ // A briefing only needs memories inside its lookback window. Avoid parsing
174
+ // the full corpus on cache misses; keep the full-read fallback for custom
175
+ // StorageManager-compatible callers that predate readMemoriesWindow().
176
+ if (mode === "windowed") {
177
+ const result = await storage.readMemoriesWindow!({ updatedAfter: window.from });
178
+ return result.memories;
179
+ }
180
+ // Refuse legacy adapters that do not explicitly declare cancellation support (#2827).
181
+ // Require affirmative cancellation support (`true` on one explicit marker) before fallback.
182
+ // Do not rely on Function.length, which is zero for default/rest/bound functions.
183
+ const isCancellable =
184
+ storage.supportsAbortSignal === true ||
185
+ storage.supportsCancellation === true ||
186
+ storage.cancellable === true ||
187
+ storage.readAllMemories?.supportsAbortSignal === true;
188
+ if (!isCancellable) {
189
+ throw new LegacyReadUnsupported();
190
+ }
191
+ const deadlineMs = options.fallbackDeadlineMs ?? BRIEFING_FULL_READ_FALLBACK_MS;
192
+ const controller = new AbortController();
193
+ let deadlineFired = false;
194
+ const timer = setTimeout(() => {
195
+ deadlineFired = true;
196
+ controller.abort();
197
+ }, deadlineMs);
198
+ try {
199
+ // Direct await, no Promise.race: the signal IS the deadline. A
200
+ // signal-aware read settles on abort (AbortError at its next scan
201
+ // boundary, #2307), so nothing is left scanning in the background once
202
+ // this function returns.
203
+ const memories = await storage.readAllMemories({ abortSignal: controller.signal });
204
+ if (deadlineFired) {
205
+ // A double that resolves partial rows instead of rejecting on abort
206
+ // must not have them served as a complete corpus.
207
+ throw new BriefingReadTimedOut(deadlineMs);
208
+ }
209
+ return memories;
210
+ } catch (err) {
211
+ if (isAbortError(err) && deadlineFired) throw new BriefingReadTimedOut(deadlineMs);
212
+ throw err;
213
+ } finally {
214
+ clearTimeout(timer);
26
215
  }
27
216
  }
@@ -963,7 +963,8 @@ test("buildBriefing excludes support passport records from generated context", a
963
963
  content: "Public project update",
964
964
  };
965
965
  const storage = {
966
- readAllMemories: async () => [privateMemory, publicMemory],
966
+ supportsAbortSignal: true,
967
+ readAllMemories: async (_options?: { abortSignal?: AbortSignal }) => [privateMemory, publicMemory],
967
968
  readAllEntityFiles: async () => [],
968
969
  } as unknown as StorageManager;
969
970
 
@@ -1,16 +1,8 @@
1
1
  import { log } from "../logger.js";
2
2
 
3
- export interface ExtractionDrainPort {
4
- pauseAndDrain(): Promise<boolean>;
5
- }
6
-
7
- export interface DependencyPropagationShutdownPort {
8
- shutdown(): Promise<void>;
9
- }
10
-
11
3
  export async function drainExtractionAndShutdownDependencyPropagation(
12
- extractionQueue: ExtractionDrainPort,
13
- dependencyPropagationDelivery: DependencyPropagationShutdownPort | undefined,
4
+ extractionQueue: { pauseAndDrain(): Promise<boolean> },
5
+ dependencyPropagationDelivery: { shutdown(): Promise<void> } | undefined,
14
6
  ): Promise<unknown | undefined> {
15
7
  let extractionDrainError: unknown;
16
8
  try {
@@ -56,6 +56,24 @@ export interface GraphRecallShadowComparison {
56
56
  averageOverlapDelta: number;
57
57
  }
58
58
 
59
+ export interface GraphRecallExpansionOptions {
60
+ memoryResults: QmdSearchResult[];
61
+ recallNamespaces: string[];
62
+ recallResultLimit: number;
63
+ /** Query-time instant used for graph-path invalidity checks. */
64
+ asOf?: string;
65
+ asOfMs?: number;
66
+ deadlineAtMs?: number | null;
67
+ /** Issue #681 — when true, bypass graphTraversalConfidenceFloor. */
68
+ includeLowConfidence?: boolean;
69
+ }
70
+
71
+ export interface GraphRecallExpansionResult {
72
+ merged: QmdSearchResult[];
73
+ seedPaths: string[];
74
+ expandedPaths: GraphRecallExpandedEntry[];
75
+ seedResults: QmdSearchResult[];
76
+ }
59
77
  // ---------------------------------------------------------------------------
60
78
  // Utility functions (moved from orchestrator.ts; re-exported for callers)
61
79
  // ---------------------------------------------------------------------------
@@ -193,22 +211,7 @@ export class GraphRecallCoordinator {
193
211
  }
194
212
 
195
213
 
196
- async expandResultsViaGraph(options: {
197
- memoryResults: QmdSearchResult[];
198
- recallNamespaces: string[];
199
- recallResultLimit: number;
200
- /** Query-time instant used for graph-path invalidity checks. */
201
- asOf?: string;
202
- asOfMs?: number;
203
- deadlineAtMs?: number | null;
204
- /** Issue #681 — when true, bypass graphTraversalConfidenceFloor. */
205
- includeLowConfidence?: boolean;
206
- }): Promise<{
207
- merged: QmdSearchResult[];
208
- seedPaths: string[];
209
- expandedPaths: GraphRecallExpandedEntry[];
210
- seedResults: QmdSearchResult[];
211
- }> {
214
+ async expandResultsViaGraph(options: GraphRecallExpansionOptions): Promise<GraphRecallExpansionResult> {
212
215
  const config = this.getConfig();
213
216
  const parsedAsOfMs =
214
217
  typeof options.asOf === "string" ? Date.parse(options.asOf) : Number.NaN;
@@ -23,7 +23,7 @@ import { NamespaceCatalog } from "../namespaces/catalog.js";
23
23
  import { namespaceIdentityFromToken, namespaceIdentityToken, normalizeNamespaceIdentity } from "../namespaces/identity.js";
24
24
  import { NamespaceSearchRouter } from "../namespaces/search.js";
25
25
  import { NamespaceStorageRouter } from "../namespaces/storage.js";
26
- import { mergeArtifactRecallCandidates, tokenizeRecallQuery } from "./orchestrator-helpers.js";
26
+ import { ARTIFACT_STATUS_CACHE_TTL_MS, mergeArtifactRecallCandidates, tokenizeRecallQuery } from "./orchestrator-helpers.js";
27
27
  import { qmdCollectionPathParts } from "./qmd-result-resolver.js";
28
28
  import { qmdCollectionNamespaceFromPrefix as computeQmdCollectionNamespaceFromPrefix } from "./orchestrator-namespace-scope.js";
29
29
  import { resolveNamespaceFromStorageDir } from "../scopes/scope-plan.js";
@@ -31,9 +31,6 @@ import { checkCorpusReadAbort, type CorpusReadOptions } from "../corpus-read-can
31
31
  import type { ArtifactRecallOptions } from "./recall-search-prefilter.js";
32
32
  import type { SearchBackend, SearchExecutionOptions, SearchQueryOptions } from "../search/port.js";
33
33
  import type { MemoryFile, PluginConfig, QmdSearchResult } from "../types.js";
34
- import {
35
- Orchestrator,
36
- } from "../orchestrator.js";
37
34
 
38
35
  export interface NamespaceReadFanoutDeps {
39
36
  readonly artifactSourceStatusCache: WeakMap<StorageManager, { loadedAtMs: number; statusVersion: number; statuses: Map<string, "active" | "superseded" | "archived" | "missing"> }>;
@@ -257,7 +254,7 @@ export class NamespaceReadFanoutCoordinator {
257
254
  const isFresh =
258
255
  snapshot !== undefined &&
259
256
  Date.now() - snapshot.loadedAtMs <=
260
- Orchestrator.ARTIFACT_STATUS_CACHE_TTL_MS &&
257
+ ARTIFACT_STATUS_CACHE_TTL_MS &&
261
258
  snapshot.statusVersion === currentStatusVersion;
262
259
 
263
260
  const rebuildSnapshot = async () => {
@@ -32,6 +32,8 @@ import { type BufferTurn, type MemoryActionEvent, type MemoryFile, type MemoryFr
32
32
  import { categoryDirName } from "../utils/category-dir.js";
33
33
  import { parseFlexibleIsoTimestamp } from "../utils/iso-timestamp.js";
34
34
 
35
+ /** Freshness window for the artifact source status cache read by NamespaceReadFanoutCoordinator. */
36
+ export const ARTIFACT_STATUS_CACHE_TTL_MS = 60_000;
35
37
  export interface BulkImportBatchIngestResult {
36
38
  attemptedTurnCount: number;
37
39
  extractionCount: number;
@@ -35,11 +35,7 @@ import type { TrustZoneSearchResult } from "../trust-zones.js";
35
35
  import type { CodingContext, EngramTraceEvent, IdentityInjectionMode, MemoryFile, MemoryIntent, PluginConfig, QmdSearchResult, RecallPlanMode, RecallSectionConfig } from "../types.js";
36
36
  import type { VerifiedEpisodeResult } from "../verified-recall.js";
37
37
  import type { WorkProductLedgerSearchResult } from "../work-product-ledger.js";
38
- import type { GraphRecallRankedResult, GraphRecallShadowComparison } from "./graph-recall-coordinator.js";
39
- import type {
40
- GraphRecallExpansionOptions,
41
- GraphRecallExpansionResult,
42
- } from "./graph-recall-seam.js";
38
+ import type { GraphRecallExpansionOptions, GraphRecallExpansionResult, GraphRecallRankedResult, GraphRecallShadowComparison } from "./graph-recall-coordinator.js";
43
39
  import type { RecallRerankCoordinator, RecallResultPartitionSink } from "./recall-rerank-coordinator.js";
44
40
  import type { ArtifactRecallOptions } from "./recall-search-prefilter.js";
45
41
  import type { RecallSectionAppendOptions, RecallSectionBuckets } from "./recall-section-coordinator.js";
@@ -28,10 +28,7 @@ import { NamespaceStorageRouter } from "../namespaces/storage.js";
28
28
  import { NegativeExampleStore } from "../negative.js";
29
29
  import { qmdCollectionPathParts } from "./qmd-result-resolver.js";
30
30
  import type { RecallRerankCoordinator, RecallResultPartitionSink } from "./recall-rerank-coordinator.js";
31
- import type {
32
- GraphRecallExpansionOptions,
33
- GraphRecallExpansionResult,
34
- } from "./graph-recall-seam.js";
31
+ import type { GraphRecallExpansionOptions, GraphRecallExpansionResult } from "./graph-recall-coordinator.js";
35
32
  import { RelevanceStore } from "../relevance.js";
36
33
  import { RerankCache, rerankLocalOrNoop, reorderByRankedKeys } from "../rerank.js";
37
34
  import type { SearchBackend, SearchDegradation, SearchExecutionOptions, SearchQueryOptions } from "../search/port.js";
@@ -132,7 +132,7 @@ import { isDependencyPropagationEnabled } from "./orchestration/dependency-propa
132
132
  import { createDependencyPropagationReplayReconciliation } from "./orchestration/dependency-propagation-replay-reconciliation.js";
133
133
  import { RecallInternalCoordinator } from "./orchestration/recall-internal.js";
134
134
  import { RecallSearchPipelineCoordinator } from "./orchestration/recall-search-pipeline.js";
135
- import type { GraphRecallExpansionOptions, GraphRecallExpansionResult } from "./orchestration/graph-recall-seam.js";
135
+ import type { GraphRecallExpansionOptions, GraphRecallExpansionResult } from "./orchestration/graph-recall-coordinator.js";
136
136
  import type { ArtifactRecallOptions } from "./orchestration/recall-search-prefilter.js";
137
137
  import type { CorpusReadOptions } from "./corpus-read-cancellation.js";
138
138
  import { TurnIngestionCoordinator, type TurnIngestionOptions } from "./orchestration/turn-ingestion.js";
@@ -716,8 +716,6 @@ export class Orchestrator {
716
716
  statuses: Map<string, "active" | "superseded" | "archived" | "missing">;
717
717
  }
718
718
  >();
719
- /** Read by NamespaceReadFanoutCoordinator (seam 26), hence not `private`. */
720
- static readonly ARTIFACT_STATUS_CACHE_TTL_MS = 60_000;
721
719
 
722
720
  // Batched access-tracking counts and timestamps (Phase 1A).
723
721
  private accessTrackingBuffer: Map<