@mmnto/mcp 1.13.0 → 1.14.0

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.
@@ -4,9 +4,79 @@ import { ContentTypeSchema } from '@mmnto/totem';
4
4
  import { getContext, reconnectStore } from '../context.js';
5
5
  import { logSearch, setLogDir } from '../search-log.js';
6
6
  import { formatSystemWarning, formatXmlResponse } from '../xml-format.js';
7
+ function makeFailureLog() {
8
+ return { primary: null, linked: new Map() };
9
+ }
10
+ function failureLogIsEmpty(log) {
11
+ return log.primary === null && log.linked.size === 0;
12
+ }
7
13
  const MAX_SEARCH_RESULTS = 100;
8
14
  /** Session-level flag — healthCheck runs only on the first search call. */
9
15
  let firstHealthCheckDone = false;
16
+ /** Session-level flag — linkedStoreInitErrors surface only on the first search call. */
17
+ let firstLinkedStoresCheckDone = false;
18
+ /**
19
+ * Reset both session flags. Test-only export — production code should never
20
+ * call this. Allows test suites to exercise the first-query behaviors
21
+ * repeatedly across individual test cases.
22
+ */
23
+ export function _resetSessionFlags() {
24
+ firstHealthCheckDone = false;
25
+ firstLinkedStoresCheckDone = false;
26
+ }
27
+ /**
28
+ * Run a one-time check on linked-store initialization errors (mmnto/totem#1294
29
+ * Phase 2). Returns a formatted system warning listing every linked index
30
+ * that failed to initialize, or null when none failed / after the first call.
31
+ *
32
+ * This is INTENTIONALLY non-blocking — unlike `runFirstQueryHealthCheck`,
33
+ * which treats a dimension mismatch as fatal, linked-store failures are
34
+ * always recoverable by degrading to primary-only search. The warning is
35
+ * surfaced so the agent sees it in-context, but the server continues to
36
+ * serve every subsequent search from whatever stores did initialize.
37
+ */
38
+ async function runFirstLinkedStoresCheck() {
39
+ if (firstLinkedStoresCheckDone)
40
+ return null;
41
+ try {
42
+ const { linkedStoreInitErrors } = await getContext();
43
+ // mmnto/totem#1295 CR minor: only consume the one-shot flag AFTER
44
+ // getContext resolves successfully. Setting it before the await meant
45
+ // a transient init failure on the first call would permanently
46
+ // suppress the startup warning for the rest of the session.
47
+ firstLinkedStoresCheckDone = true;
48
+ if (linkedStoreInitErrors.size === 0)
49
+ return null;
50
+ // mmnto/totem#1295 CR minor: `linkedStoreInitErrors` now holds BOTH
51
+ // fatal init failures AND non-fatal startup warnings (e.g., empty
52
+ // linked stores, name collisions where the first link still loaded).
53
+ // Use neutral wording so the summary line accurately covers both.
54
+ const lines = [
55
+ `Cross-Repo Context Mesh: ${linkedStoreInitErrors.size} linked index startup issue(s).`,
56
+ '',
57
+ 'Federated search will proceed using only the stores that initialized successfully. Review the issues below so cross-repo queries return complete context. (mmnto/totem#1294)',
58
+ '',
59
+ ];
60
+ for (const [name, err] of linkedStoreInitErrors.entries()) {
61
+ lines.push(` - ${name}: ${err}`);
62
+ }
63
+ return formatSystemWarning(lines.join('\n'));
64
+ }
65
+ catch (err) {
66
+ // Meta-failure: getContext() itself threw. Log and return null — the
67
+ // outer runFirstQueryHealthCheck will surface that failure via its own
68
+ // path, so there's no value in double-reporting here.
69
+ logSearch({
70
+ timestamp: new Date().toISOString(),
71
+ query: 'internal:linked-stores-check',
72
+ resultCount: 0,
73
+ durationMs: 0,
74
+ topScore: null,
75
+ error: `Linked stores check failed: ${err instanceof Error ? err.message : String(err)}`,
76
+ });
77
+ return null;
78
+ }
79
+ }
10
80
  /**
11
81
  * Run a one-time health check on the LanceDB index and return any warnings.
12
82
  * Returns null when healthy or after the first call (cached).
@@ -14,13 +84,24 @@ let firstHealthCheckDone = false;
14
84
  async function runFirstQueryHealthCheck() {
15
85
  if (firstHealthCheckDone)
16
86
  return null;
17
- firstHealthCheckDone = true;
18
87
  try {
19
88
  const { store } = await getContext();
20
89
  const result = await store.healthCheck();
21
- if (result.healthy)
90
+ // Healthy — consume the one-shot flag and skip the warning for this
91
+ // session. This is the common case.
92
+ if (result.healthy) {
93
+ firstHealthCheckDone = true;
22
94
  return null;
23
- // Dimension mismatch is a blocking error — search will fail with a cryptic LanceDB error
95
+ }
96
+ // mmnto/totem#1295 CR MAJOR: dimension mismatch must KEEP firing on
97
+ // every query until the user actually fixes the index. Consuming the
98
+ // flag here would let query 2 onwards skip the gate and fall back to
99
+ // the cryptic LanceDB "vector dimension mismatch" error — exactly
100
+ // what the friendly diagnostic exists to prevent. The outer
101
+ // `registerSearchKnowledge` blocks the search with isError: true
102
+ // whenever this branch returns a warning, so a persistent mismatch
103
+ // produces a persistent actionable message rather than a one-shot
104
+ // reminder followed by silent cryptic failures.
24
105
  if (!result.dimensionMatch && result.storedDimensions !== null) {
25
106
  const lines = [
26
107
  `DIMENSION MISMATCH: Index has ${result.storedDimensions}-dim vectors but the configured embedder produces ${result.expectedDimensions}-dim vectors.`,
@@ -32,7 +113,10 @@ async function runFirstQueryHealthCheck() {
32
113
  ];
33
114
  return formatSystemWarning(lines.join('\n'));
34
115
  }
35
- // Build actionable warning lines for other issues
116
+ // Non-fatal health warnings (stale rows, missing partitions, etc.):
117
+ // search still returns results — the warning is informational, not
118
+ // blocking — so one-shot consumption is appropriate here.
119
+ firstHealthCheckDone = true;
36
120
  const lines = ['Index health issues detected:'];
37
121
  for (const issue of result.issues) {
38
122
  lines.push(`- ${issue}`);
@@ -54,31 +138,360 @@ async function runFirstQueryHealthCheck() {
54
138
  return null;
55
139
  }
56
140
  }
141
+ /**
142
+ * Format a single search result for display. Linked-store results (sourceRepo
143
+ * set) get a `[<sourceRepo>]` prefix on the label and the absolute path as
144
+ * the File field, so the agent can route file-reading tools without having
145
+ * to reason about which repo owns the result. Primary results (sourceRepo
146
+ * undefined) use the compact relative-path form for readability.
147
+ *
148
+ * mmnto/totem#1294 Phase 2.
149
+ */
150
+ function formatResult(r, index) {
151
+ // Build the header line in two halves so the `[tag] label` segment is
152
+ // joined with explicit `+` rather than two adjacent template placeholders
153
+ // (which the concat-without-delimiter lint rule flags).
154
+ const labelWithTag = r.sourceRepo ? `[${r.sourceRepo}] ` + r.label : r.label;
155
+ // mmnto/totem#1295 CR MAJOR: ALWAYS display the absolute path. The whole
156
+ // point of `absoluteFilePath` on `SearchResult` is to give agents an
157
+ // unambiguous Read/Edit target. Falling back to the relative `filePath`
158
+ // for primary hits reintroduced repo-root ambiguity in the common case —
159
+ // exactly the bug that field was added to fix.
160
+ return (`### ${index + 1}. ${labelWithTag} (${r.type})\n` +
161
+ `**File:** ${r.absoluteFilePath} | **Score:** ${r.score.toFixed(3)}\n\n` +
162
+ r.content);
163
+ }
164
+ /**
165
+ * Run federated search across primary + all linked stores in parallel.
166
+ * Each store fetches up to `perStoreLimit` results; the combined pool is
167
+ * then re-sorted by score and truncated to `finalLimit`.
168
+ *
169
+ * Mirrors the semantic-merge pattern established in
170
+ * `packages/cli/src/commands/spec.ts:retrieveContext` — fetch per-store
171
+ * budgets, concat, re-rank by score, truncate.
172
+ *
173
+ * **Runtime failure handling (mmnto/totem#1295 rewrite):** On a linked-
174
+ * store search error, attempt a targeted `reconnect()` + retry. If the
175
+ * retry succeeds, return the fresh results. If it fails, record the
176
+ * failure into the caller-provided `failures` log and return empty for
177
+ * that store on THIS query only. Primary failures go in `failures.primary`
178
+ * (a dedicated slot — `'primary'` would collide with a legal link name);
179
+ * linked failures go in `failures.linked` keyed by link name.
180
+ *
181
+ * This function DOES NOT mutate the global `linkedStores` or
182
+ * `linkedStoreInitErrors` maps — an earlier revision evicted failing
183
+ * stores to avoid log spam, but GCA + CR both flagged that as a Tenet 4
184
+ * violation: transient errors (file locks during parallel sync, network
185
+ * blips) caused permanent context loss until server restart. The correct
186
+ * tradeoff is to accept some log spam for resilience, and surface
187
+ * runtime failures via the per-request warning path (see `performSearch`).
188
+ *
189
+ * mmnto/totem#1294 Phase 2 + mmnto/totem#1295 fix.
190
+ */
191
+ async function federatedSearch(query, typeFilter, perStoreLimit, finalLimit, failures) {
192
+ const { store: primaryStore, linkedStores } = await getContext();
193
+ // mmnto/totem#1295 GCA HIGH: catch primary failures inside federatedSearch
194
+ // ONLY when linked stores exist, so a transient primary failure doesn't
195
+ // kill linked-store results. For non-mesh users (no linked stores), let
196
+ // primary failures bubble to the outer reconnect+retry in
197
+ // `registerSearchKnowledge` — that path produces a hard error which is
198
+ // strictly more useful than "empty results + warning" when primary is
199
+ // the only target. The outer path also still handles raw-prefix cases
200
+ // (Cases 1, 4) where primary is the only target regardless of mesh state.
201
+ //
202
+ // When the inner catch fires, primary uses the SAME targeted reconnect+
203
+ // retry pattern as linked stores below: catch → reconnect → retry → on
204
+ // second failure, log and record into `failures.primary`. Promise.all
205
+ // never rejects from the primary slot.
206
+ const hasLinkedStores = linkedStores.size > 0;
207
+ const primaryPromise = hasLinkedStores
208
+ ? primaryStore
209
+ .search({ query, typeFilter, maxResults: perStoreLimit })
210
+ .catch(async (err) => {
211
+ const firstMsg = err instanceof Error ? err.message : String(err);
212
+ try {
213
+ await primaryStore.reconnect();
214
+ return await primaryStore.search({ query, typeFilter, maxResults: perStoreLimit });
215
+ }
216
+ catch (retryErr) {
217
+ const retryMsg = retryErr instanceof Error ? retryErr.message : String(retryErr);
218
+ const combinedMsg = `search failed (initial: ${firstMsg}; reconnect+retry: ${retryMsg})`;
219
+ logSearch({
220
+ timestamp: new Date().toISOString(),
221
+ query: 'internal:primary-store-search',
222
+ resultCount: 0,
223
+ durationMs: 0,
224
+ topScore: null,
225
+ error: `Primary store ${combinedMsg}`,
226
+ });
227
+ failures.primary = combinedMsg;
228
+ return [];
229
+ }
230
+ })
231
+ : primaryStore.search({ query, typeFilter, maxResults: perStoreLimit });
232
+ // Linked stores: catch per-store failures so one broken linked index
233
+ // doesn't break the overall query. On failure, attempt targeted
234
+ // reconnect + retry, then return empty for this query (populating
235
+ // `failures.linked` for the caller to surface). Global state is NEVER
236
+ // mutated here — the store stays in `linkedStores` so the next query
237
+ // can try again (the transient issue may have cleared).
238
+ const linkedPromises = Array.from(linkedStores.entries()).map(([name, ls]) => ls.search({ query, typeFilter, maxResults: perStoreLimit }).catch(async (err) => {
239
+ const firstMsg = err instanceof Error ? err.message : String(err);
240
+ try {
241
+ await ls.reconnect();
242
+ return await ls.search({ query, typeFilter, maxResults: perStoreLimit });
243
+ }
244
+ catch (retryErr) {
245
+ const retryMsg = retryErr instanceof Error ? retryErr.message : String(retryErr);
246
+ const combinedMsg = `search failed (initial: ${firstMsg}; reconnect+retry: ${retryMsg})`;
247
+ logSearch({
248
+ timestamp: new Date().toISOString(),
249
+ query: `internal:linked-store-search:${name}`,
250
+ resultCount: 0,
251
+ durationMs: 0,
252
+ topScore: null,
253
+ error: `Linked store "${name}" ${combinedMsg}`,
254
+ });
255
+ failures.linked.set(name, combinedMsg);
256
+ return [];
257
+ }
258
+ }));
259
+ const [primaryResults, ...linkedResults] = await Promise.all([primaryPromise, ...linkedPromises]);
260
+ const buckets = [primaryResults, ...linkedResults];
261
+ // Single-bucket fast path (no linked stores configured): scores are
262
+ // already comparable since they all come from one store. Skip RRF
263
+ // normalization to keep the original scores visible to the agent.
264
+ if (buckets.length === 1) {
265
+ return primaryResults.slice(0, finalLimit);
266
+ }
267
+ // mmnto/totem#1295 GCA CRITICAL: re-rank via Reciprocal Rank Fusion
268
+ // across stores. `LanceStore.search` returns scores in incompatible
269
+ // scales depending on the search method:
270
+ //
271
+ // - Hybrid (default): RRF scores ~0.01–0.04
272
+ // - Vector-only (no FTS): 1/(1+distance) ~0.5–0.95
273
+ // - FTS-only: raw _score, often > 1
274
+ //
275
+ // Sorting by raw scores would bias the merge toward whichever store
276
+ // happens to use the larger-scale scoring method. RRF fixes this: each
277
+ // store's results are treated as a ranked list and a new score is
278
+ // assigned based on rank-within-store. The visible `score` field is
279
+ // OVERWRITTEN with the RRF score so the displayed order matches the
280
+ // displayed score (avoids the "ranked first but lower number" UX
281
+ // confusion). Within-store relative ordering is preserved.
282
+ //
283
+ // RRF k=60 matches the constant used inside `LanceStore.rrfMerge` for
284
+ // intra-store hybrid fusion, for consistency.
285
+ const RRF_K_FEDERATION = 60;
286
+ const reranked = [];
287
+ for (const bucket of buckets) {
288
+ bucket.forEach((r, rank) => {
289
+ reranked.push({ ...r, score: 1 / (RRF_K_FEDERATION + rank + 1) });
290
+ });
291
+ }
292
+ reranked.sort((a, b) => (b.score ?? 0) - (a.score ?? 0));
293
+ return reranked.slice(0, finalLimit);
294
+ }
57
295
  async function performSearch(query, typeFilter, maxResults, boundary) {
58
- const { store, config } = await getContext();
59
- // Resolve partition alias to path prefixes, or fall back to raw prefix
60
- const resolvedBoundary = boundary
61
- ? (config.partitions?.[boundary] ?? boundary)
62
- : undefined;
63
- const results = await store.search({
64
- query,
65
- typeFilter,
66
- maxResults: maxResults ?? 5,
67
- boundary: resolvedBoundary,
68
- });
69
- if (results.length === 0) {
296
+ const { config, linkedStores, linkedStoreInitErrors } = await getContext();
297
+ const finalLimit = maxResults ?? 5;
298
+ // Per-query runtime failure log (mmnto/totem#1295). Populated by
299
+ // `federatedSearch` when primary or any linked store errors during this
300
+ // specific query. Surfaced as a compact system warning on the response
301
+ // so the agent sees the failure in-context — NOT gated by any session-
302
+ // level "already warned" flag. Every query where a store fails produces
303
+ // its own warning; this is the correct Tenet 4 tradeoff versus the
304
+ // earlier one-shot snapshot approach.
305
+ //
306
+ // Primary lives in `failures.primary` (a dedicated slot, NOT keyed under
307
+ // `'primary'` in a map) because `'primary'` is a legal link name —
308
+ // `deriveLinkName` strips leading dots so a `.primary/` linked repo would
309
+ // collide with a reserved key. CR MAJOR catch on round 7.
310
+ const failures = makeFailureLog();
311
+ // ─── Boundary resolution (mmnto/totem#1294 Phase 2) ──
312
+ //
313
+ // Order of precedence:
314
+ // 1. Local partition name (config.partitions[boundary]) → primary only, prefix filter
315
+ // 2. Linked store name (linkedStores has key === boundary) → route ONLY to that linked store
316
+ // 3. Broken linked store name (linkedStoreInitErrors has key === boundary) → explicit error
317
+ // 4. Raw prefix string → primary only, prefix filter (today's fallback)
318
+ // 5. Undefined → federated across primary + ALL linked stores
319
+ //
320
+ // Partition names win over linked-store names on collision. Users who
321
+ // want to query a linked store whose name collides with a local
322
+ // partition can rename the linked directory.
323
+ //
324
+ // Case 3 exists to prevent a silent-fallback drift bug (Tenet 4): if a
325
+ // linked store previously existed but failed to reconnect, falling
326
+ // through to the raw-prefix branch would query the primary store using
327
+ // the broken link's name as a path prefix and return unrelated primary
328
+ // hits. The agent would think it's querying the linked repo but get
329
+ // local results — exactly the "silent drift" pattern Tenet 4 forbids.
330
+ // Shield AI catch on mmnto/totem#1294 Phase 2 review.
331
+ let results;
332
+ if (boundary !== undefined && config.partitions?.[boundary]) {
333
+ // Case 1: local partition — primary only, prefix filter
334
+ const { store: primaryStore } = await getContext();
335
+ results = await primaryStore.search({
336
+ query,
337
+ typeFilter,
338
+ maxResults: finalLimit,
339
+ boundary: config.partitions[boundary],
340
+ });
341
+ }
342
+ else if (boundary !== undefined && linkedStores.has(boundary)) {
343
+ // Case 2: linked store name — route ONLY to that linked store.
344
+ //
345
+ // Complete failure of an explicitly-targeted linked store (initial
346
+ // search throws AND reconnect+retry also throws) returns isError: true
347
+ // for symmetry with Case 3 (mmnto/totem#1295 GCA HIGH). When the
348
+ // user explicitly names a boundary, "no results" and "the boundary
349
+ // is broken" are very different signals — falling through to a
350
+ // generic "no results" response would let the agent misinterpret a
351
+ // real outage as an absence of relevant knowledge.
352
+ const linked = linkedStores.get(boundary);
353
+ try {
354
+ results = await linked.search({ query, typeFilter, maxResults: finalLimit });
355
+ }
356
+ catch (err) {
357
+ const firstMsg = err instanceof Error ? err.message : String(err);
358
+ try {
359
+ await linked.reconnect();
360
+ results = await linked.search({ query, typeFilter, maxResults: finalLimit });
361
+ }
362
+ catch (retryErr) {
363
+ const retryMsg = retryErr instanceof Error ? retryErr.message : String(retryErr);
364
+ const errorText = formatSystemWarning([
365
+ `Linked-store search: targeted index "${boundary}" failed.`,
366
+ '',
367
+ ` Initial error: ${firstMsg}`,
368
+ ` Reconnect+retry error: ${retryMsg}`,
369
+ '',
370
+ `Cross-repo search for this boundary cannot proceed on this query. The store may recover on a subsequent call if the failure was transient (stale handle, file lock). mmnto/totem#1294.`,
371
+ ].join('\n'));
372
+ return {
373
+ content: [{ type: 'text', text: errorText }], // totem-ignore #1294 — system-generated + XML-wrapped
374
+ isError: true,
375
+ };
376
+ }
377
+ }
378
+ }
379
+ else if (boundary !== undefined && linkedStoreInitErrors.has(boundary)) {
380
+ // Case 3: explicitly-named linked store is in the failure map. Surface
381
+ // the specific error rather than silently degrading to raw-prefix
382
+ // search on the primary (which would return bogus hits from the
383
+ // primary repo under the link's name as a prefix).
384
+ const errMsg = linkedStoreInitErrors.get(boundary);
385
+ const warning = formatSystemWarning([
386
+ `Linked index "${boundary}" is not available: ${errMsg ?? 'unknown error'}`,
387
+ '',
388
+ `Cross-repo search for this boundary cannot proceed. Fix the linked index and restart the MCP server (mmnto/totem#1294).`,
389
+ ].join('\n'));
70
390
  return {
71
- content: [
72
- { type: 'text', text: formatXmlResponse('knowledge', 'No results found.') },
73
- ],
391
+ content: [{ type: 'text', text: warning }], // totem-ignore #1294 — system-generated + XML-wrapped
392
+ isError: true,
74
393
  };
75
394
  }
76
- const formatted = results
77
- .map((r, i) => `### ${i + 1}. ${r.label} (${r.type})\n` +
78
- `**File:** ${r.filePath} | **Score:** ${r.score.toFixed(3)}\n\n` +
79
- `${r.content}`)
80
- .join('\n\n---\n\n');
395
+ else if (boundary !== undefined) {
396
+ // Case 4: raw prefix primary only, prefix filter (today's behavior)
397
+ const { store: primaryStore } = await getContext();
398
+ results = await primaryStore.search({
399
+ query,
400
+ typeFilter,
401
+ maxResults: finalLimit,
402
+ boundary,
403
+ });
404
+ }
405
+ else {
406
+ // Case 5: no boundary → federated search across primary + all linked.
407
+ // Pass the `failures` log so the federation path can populate it on
408
+ // store errors without mutating global state. Primary lives in a
409
+ // dedicated slot to avoid colliding with linked-store names.
410
+ results = await federatedSearch(query, typeFilter, finalLimit, finalLimit, failures);
411
+ }
412
+ // Build the runtime-failures warning (if any) once so we can decide
413
+ // whether to skip the "no results" early return for warn-only cases.
414
+ //
415
+ // Only Case 5 (federated) reaches this with `failures` populated:
416
+ // Cases 1/4 bubble primary failures up, Case 2 returns isError early
417
+ // on full linked failure (mmnto/totem#1295 GCA HIGH), Case 3 returns
418
+ // isError immediately. So the IIFE only ever runs in the federated case.
419
+ //
420
+ // Copy branches three ways based on which store(s) failed (mmnto/totem
421
+ // #1295 CR fixes — accurate reporting + no `'primary'` map-key collision).
422
+ const runtimeWarning = (() => {
423
+ if (failureLogIsEmpty(failures))
424
+ return null;
425
+ const detailLines = [];
426
+ if (failures.primary !== null) {
427
+ detailLines.push(` - primary: ${failures.primary}`);
428
+ }
429
+ for (const [name, err] of failures.linked.entries()) {
430
+ detailLines.push(` - ${name}: ${err}`);
431
+ }
432
+ const recoveryNote = 'The store(s) above may recover on a subsequent call if the failure was transient (stale handle, file lock). mmnto/totem#1294.';
433
+ const primaryFailed = failures.primary !== null;
434
+ const linkedFailureCount = failures.linked.size;
435
+ let summary;
436
+ if (primaryFailed && linkedFailureCount > 0) {
437
+ summary = `Federated search: primary store and ${linkedFailureCount} linked index(es) failed on this query.`;
438
+ }
439
+ else if (primaryFailed) {
440
+ summary = `Federated search: primary store failed on this query. Linked stores returned their results normally.`;
441
+ }
442
+ else {
443
+ summary = `Federated search: ${linkedFailureCount} linked index(es) failed on this query. Other stores returned their results normally.`;
444
+ }
445
+ return formatSystemWarning([summary, '', ...detailLines, '', recoveryNote].join('\n'));
446
+ })();
447
+ // mmnto/totem#1295 CR MAJOR: detect the "entire federation is down" case
448
+ // and return isError instead of a success-shaped "No results found" body.
449
+ //
450
+ // When `boundary === undefined` (federated Case 5), every store we TRIED
451
+ // to query failed, and results came back empty, the agent must see this
452
+ // as an outage — not as "no relevant knowledge found." Otherwise it
453
+ // concludes there's nothing in the index when the entire search plane
454
+ // is actually broken.
455
+ //
456
+ // The condition is narrow on purpose:
457
+ // - `boundary === undefined`: only the federated case (targeted Cases
458
+ // 2 & 3 have their own isError paths; Cases 1 & 4 bubble primary
459
+ // failures to the outer reconnect+retry)
460
+ // - `failures.primary !== null`: primary actually failed (if primary
461
+ // succeeded with 0 rows, that's a legitimate "no results")
462
+ // - `failures.linked.size === linkedStores.size`: every linked store
463
+ // also failed (if ANY linked store succeeded with 0 rows, that
464
+ // answer is authoritative)
465
+ //
466
+ // Primary failures with at least one healthy linked store still return
467
+ // a success-shaped response with the runtime warning prepended — the
468
+ // linked stores' zero-results answer is authoritative for the query.
469
+ const allFederatedStoresFailed = boundary === undefined &&
470
+ failures.primary !== null &&
471
+ failures.linked.size === linkedStores.size;
472
+ if (results.length === 0) {
473
+ if (allFederatedStoresFailed) {
474
+ return {
475
+ content: [
476
+ {
477
+ type: 'text',
478
+ text: runtimeWarning ??
479
+ '[Totem Error] Federated search failed: every queried store errored.', // totem-ignore #1294 — system-generated + XML-wrapped
480
+ },
481
+ ],
482
+ isError: true,
483
+ };
484
+ }
485
+ const body = formatXmlResponse('knowledge', 'No results found.');
486
+ const text = runtimeWarning ? runtimeWarning + '\n\n' + body : body; // totem-ignore #1294 — system-generated + XML-wrapped
487
+ return { content: [{ type: 'text', text }] };
488
+ }
489
+ const formatted = results.map((r, i) => formatResult(r, i)).join('\n\n---\n\n');
81
490
  let text = formatXmlResponse('knowledge', formatted);
491
+ // Prepend the per-query runtime warning if federatedSearch populated it
492
+ if (runtimeWarning) {
493
+ text = runtimeWarning + '\n\n' + text; // totem-ignore #1294 — system-generated + XML-wrapped
494
+ }
82
495
  // Append a system warning when the payload is large enough to risk context pressure
83
496
  if (text.length > config.contextWarningThreshold) {
84
497
  text +=
@@ -104,10 +517,18 @@ export function registerSearchKnowledge(server) {
104
517
  .max(MAX_SEARCH_RESULTS)
105
518
  .optional()
106
519
  .describe(`Maximum number of results to return (default: 5, max: ${MAX_SEARCH_RESULTS})`),
520
+ // Normalize blank/whitespace boundaries to undefined so they take
521
+ // the federated default path. Without this, "" and " " fall into
522
+ // the raw-prefix branch and silently drop linked-repo federation.
523
+ // mmnto/totem#1295 CR fix — input sanitization at the MCP boundary.
107
524
  boundary: z
108
- .string()
109
- .optional()
110
- .describe('Partition name or file path prefix to restrict results to an architectural boundary. Use configured partition names (e.g., "core", "cli", "mcp") or raw path prefixes (e.g., "src/components/"). Enables context isolation per layer.'),
525
+ .preprocess((value) => {
526
+ if (typeof value !== 'string')
527
+ return value;
528
+ const trimmed = value.trim();
529
+ return trimmed === '' ? undefined : trimmed;
530
+ }, z.string().optional())
531
+ .describe('Partition name, linked-index name, or file path prefix to scope results. Resolution order: (1) configured partition names (e.g., "core", "cli", "mcp") → primary index, prefix-filtered; (2) linked-index names from linkedIndexes config (e.g., "strategy") → routes only to that cross-repo index; (3) raw path prefixes (e.g., "src/components/") → primary, prefix-filtered. When omitted, search federates across primary + all linked indexes, merging by semantic score. Blank or whitespace-only values are normalized to "omitted" (federated default).'),
111
532
  },
112
533
  annotations: {
113
534
  readOnlyHint: true,
@@ -136,10 +557,16 @@ export function registerSearchKnowledge(server) {
136
557
  // Dimension mismatch is fatal — search will crash with a cryptic LanceDB error
137
558
  if (healthWarning && healthWarning.includes('DIMENSION MISMATCH')) {
138
559
  return {
139
- content: [{ type: 'text', text: healthWarning }], // totem-ignore — healthWarning is from formatSystemWarning (already XML-wrapped)
560
+ content: [{ type: 'text', text: healthWarning }], // totem-ignore #1294 — healthWarning is from formatSystemWarning (already XML-wrapped)
140
561
  isError: true,
141
562
  };
142
563
  }
564
+ // First-query linked-stores gate — non-blocking (mmnto/totem#1294 Phase 2).
565
+ // Surfaces init failures so the agent sees them in-context on the first
566
+ // search_knowledge call. Unlike dimension mismatch, linked-store failures
567
+ // are always recoverable (degrade to primary-only), so we don't set
568
+ // isError — we just prepend the warning to the result content below.
569
+ const linkedStoresWarning = await runFirstLinkedStoresCheck();
143
570
  let result;
144
571
  try {
145
572
  result = await performSearch(query, type_filter, max_results, boundary);
@@ -177,20 +604,46 @@ export function registerSearchKnowledge(server) {
177
604
  const resultText = result.content[0]?.text ?? '';
178
605
  const scoreMatches = [...resultText.matchAll(/\*\*Score:\*\* ([\d.]+)/g)];
179
606
  const topScore = scoreMatches.length > 0 ? parseFloat(scoreMatches[0][1]) : null;
180
- logSearch({
181
- timestamp: new Date().toISOString(),
182
- query,
183
- typeFilter: type_filter,
184
- boundary,
185
- resultCount: scoreMatches.length,
186
- durationMs: Date.now() - start,
187
- topScore,
188
- });
189
- // Prepend health warning to the first search result if issues were found
190
- if (healthWarning && result.content.length > 0) {
607
+ // Log error responses (e.g., the broken-linked-boundary path at
608
+ // performSearch Case 3) as errors instead of zero-result successes,
609
+ // so routing failures are visible in search-log.jsonl. Without this
610
+ // branch, isError responses would be indistinguishable from "no
611
+ // matches found." mmnto/totem#1295 CR fix.
612
+ if (result.isError) {
613
+ logSearch({
614
+ timestamp: new Date().toISOString(),
615
+ query,
616
+ typeFilter: type_filter,
617
+ boundary,
618
+ resultCount: 0,
619
+ durationMs: Date.now() - start,
620
+ topScore: null,
621
+ error: resultText,
622
+ });
623
+ }
624
+ else {
625
+ logSearch({
626
+ timestamp: new Date().toISOString(),
627
+ query,
628
+ typeFilter: type_filter,
629
+ boundary,
630
+ resultCount: scoreMatches.length,
631
+ durationMs: Date.now() - start,
632
+ topScore,
633
+ });
634
+ }
635
+ // Prepend health warning and linked-stores warning to the first search
636
+ // result if issues were found. Order is deliberate: health first
637
+ // (local index issues are higher priority), then linked-stores second.
638
+ const warnings = [];
639
+ if (healthWarning)
640
+ warnings.push(healthWarning);
641
+ if (linkedStoresWarning)
642
+ warnings.push(linkedStoresWarning); // totem-ignore #1294 — system-generated
643
+ if (warnings.length > 0 && result.content.length > 0) {
191
644
  result.content[0] = {
192
645
  type: 'text',
193
- text: healthWarning + '\n\n' + result.content[0].text, // totem-ignore — healthWarning is system-generated, text is already XML-wrapped
646
+ text: warnings.join('\n\n') + '\n\n' + result.content[0].text, // totem-ignore #1294 all system-generated + XML-wrapped
194
647
  };
195
648
  }
196
649
  return result;
@@ -1 +1 @@
1
- {"version":3,"file":"search-knowledge.js","sourceRoot":"","sources":["../../src/tools/search-knowledge.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"search-knowledge.js","sourceRoot":"","sources":["../../src/tools/search-knowledge.ts"],"names":[],"mappings":"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"}