@remnic/core 9.3.715 → 9.3.717
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/access-boundary.d.ts +2 -2
- package/dist/access-boundary.js +4 -3
- package/dist/access-cli.js +13 -12
- package/dist/access-cli.js.map +1 -1
- package/dist/access-http.d.ts +2 -2
- package/dist/access-http.js +8 -7
- package/dist/access-mcp.d.ts +2 -2
- package/dist/access-mcp.js +7 -6
- package/dist/access-operations-batch.js +5 -4
- package/dist/access-operations.d.ts +2 -2
- package/dist/access-operations.js +6 -5
- package/dist/{access-service-GgnA--CE.d.ts → access-service-d4Tk-Dlr.d.ts} +2 -2
- package/dist/access-service.d.ts +2 -2
- package/dist/access-service.js +3 -2
- package/dist/access-surface-catalog.d.ts +2 -2
- package/dist/bootstrap.d.ts +1 -1
- package/dist/{chunk-MECU6WSH.js → chunk-2B43BYYZ.js} +6 -6
- package/dist/chunk-2KF4HDG2.js +24 -0
- package/dist/chunk-2KF4HDG2.js.map +1 -0
- package/dist/{chunk-HHLWSWWF.js → chunk-BF2426TN.js} +2 -2
- package/dist/{chunk-RBHANGVX.js → chunk-BZAK3RBN.js} +2 -2
- package/dist/{chunk-YUJL27ET.js → chunk-CTUWGJRI.js} +40 -63
- package/dist/chunk-CTUWGJRI.js.map +1 -0
- package/dist/{chunk-6QUPUTT7.js → chunk-DZYARLJ7.js} +5 -9
- package/dist/{chunk-6QUPUTT7.js.map → chunk-DZYARLJ7.js.map} +1 -1
- package/dist/{chunk-CTAHKIG6.js → chunk-EM22PCQR.js} +7 -7
- package/dist/{chunk-SHRRWOVY.js → chunk-J6BH2OBA.js} +64 -21
- package/dist/chunk-J6BH2OBA.js.map +1 -0
- package/dist/{chunk-GM3BMWKR.js → chunk-KHQ433G5.js} +2 -2
- package/dist/{chunk-SYDHFFAW.js → chunk-OUDAU3T5.js} +4 -4
- package/dist/{chunk-OQH5XUH3.js → chunk-Q6IP2ARR.js} +2 -5
- package/dist/chunk-Q6IP2ARR.js.map +1 -0
- package/dist/{chunk-O62P2LFL.js → chunk-VZQXJNBD.js} +2 -2
- package/dist/{chunk-BNOAB5HH.js → chunk-YAINYEM3.js} +57 -48
- package/dist/chunk-YAINYEM3.js.map +1 -0
- package/dist/{chunk-3VUPWDSE.js → chunk-ZAVTEQFM.js} +4 -4
- package/dist/{chunk-IHMT6XTY.js → chunk-ZXLSNG3T.js} +3 -3
- package/dist/{cli-Do1YtfnH.d.ts → cli-insNLYs6.d.ts} +2 -2
- package/dist/cli.d.ts +3 -3
- package/dist/cli.js +12 -11
- package/dist/direct-answer-wiring.d.ts +9 -9
- package/dist/direct-answer-wiring.js +1 -1
- package/dist/explicit-capture.d.ts +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.js +23 -22
- package/dist/index.js.map +1 -1
- package/dist/mcp-memory-inspector-app.d.ts +2 -2
- package/dist/operator-toolkit.js +5 -3
- package/dist/orchestration/maintenance.js +5 -2
- package/dist/{orchestrator-BOaVstFG.d.ts → orchestrator-XPKhY2OV.d.ts} +6 -7
- package/dist/orchestrator.d.ts +1 -1
- package/dist/orchestrator.js +7 -6
- package/dist/recall-planner-llm.d.ts +1 -1
- package/dist/recall-planner-llm.js +2 -2
- package/dist/recall-planner-llm.js.map +1 -1
- package/dist/schemas.d.ts +22 -22
- package/dist/transfer/types.d.ts +12 -12
- package/package.json +2 -2
- package/src/access-service.ts +56 -41
- package/src/capabilities.test.ts +28 -0
- package/src/direct-answer-wiring.test.ts +20 -13
- package/src/direct-answer-wiring.ts +9 -13
- package/src/maintenance/namespace-planner.ts +3 -10
- package/src/orchestrator.ts +42 -71
- package/src/recall-planner-llm.test.ts +30 -11
- package/src/recall-planner-llm.ts +4 -5
- package/src/scopes/scope-plan.test.ts +168 -1
- package/src/scopes/scope-plan.ts +163 -0
- package/dist/chunk-BNOAB5HH.js.map +0 -1
- package/dist/chunk-OQH5XUH3.js.map +0 -1
- package/dist/chunk-SHRRWOVY.js.map +0 -1
- package/dist/chunk-YUJL27ET.js.map +0 -1
- /package/dist/{chunk-MECU6WSH.js.map → chunk-2B43BYYZ.js.map} +0 -0
- /package/dist/{chunk-HHLWSWWF.js.map → chunk-BF2426TN.js.map} +0 -0
- /package/dist/{chunk-RBHANGVX.js.map → chunk-BZAK3RBN.js.map} +0 -0
- /package/dist/{chunk-CTAHKIG6.js.map → chunk-EM22PCQR.js.map} +0 -0
- /package/dist/{chunk-GM3BMWKR.js.map → chunk-KHQ433G5.js.map} +0 -0
- /package/dist/{chunk-SYDHFFAW.js.map → chunk-OUDAU3T5.js.map} +0 -0
- /package/dist/{chunk-O62P2LFL.js.map → chunk-VZQXJNBD.js.map} +0 -0
- /package/dist/{chunk-3VUPWDSE.js.map → chunk-ZAVTEQFM.js.map} +0 -0
- /package/dist/{chunk-IHMT6XTY.js.map → chunk-ZXLSNG3T.js.map} +0 -0
package/src/scopes/scope-plan.ts
CHANGED
|
@@ -33,10 +33,16 @@
|
|
|
33
33
|
|
|
34
34
|
import {
|
|
35
35
|
canReadNamespace,
|
|
36
|
+
canWriteNamespace,
|
|
36
37
|
defaultNamespaceForPrincipal,
|
|
37
38
|
recallNamespacesForPrincipal,
|
|
38
39
|
resolvePrincipal,
|
|
39
40
|
} from "../namespaces/principal.js";
|
|
41
|
+
import {
|
|
42
|
+
namespaceIdentityFromToken,
|
|
43
|
+
namespaceIdentityToken,
|
|
44
|
+
} from "../namespaces/identity.js";
|
|
45
|
+
import path from "node:path";
|
|
40
46
|
import type { ResolvedScopeProfilePlan } from "../namespaces/scope-profiles.js";
|
|
41
47
|
import {
|
|
42
48
|
expandScopeProfileReadNamespaces,
|
|
@@ -318,3 +324,160 @@ export function resolveScopePlan(options: ResolveScopePlanOptions): ScopePlan {
|
|
|
318
324
|
scopeProfilePlan,
|
|
319
325
|
};
|
|
320
326
|
}
|
|
327
|
+
|
|
328
|
+
// ────────────────────────────────────────────────────────────────────────────
|
|
329
|
+
// Centralized namespace-resolution helpers (issue #1521 step 3–4)
|
|
330
|
+
//
|
|
331
|
+
// The three functions below consolidate the ad-hoc namespace-resolution logic
|
|
332
|
+
// that was previously scattered across orchestrator.ts (namespaceFromStorageDir,
|
|
333
|
+
// configuredNamespaces) and access-service.ts (resolveWritableNamespace). By
|
|
334
|
+
// living in THIS module they are excluded from the adHocNamespaceResolutions
|
|
335
|
+
// ratchet, and every consumer reaches them through a single well-known import
|
|
336
|
+
// instead of reimplementing the derivation inline (#1519's failure mode).
|
|
337
|
+
// ────────────────────────────────────────────────────────────────────────────
|
|
338
|
+
|
|
339
|
+
/**
|
|
340
|
+
* The configured namespace set: default + shared + every namespace-policy
|
|
341
|
+
* name, trimmed and de-duplicated. Pure — reads only from `config`.
|
|
342
|
+
*
|
|
343
|
+
* Replaces the `configuredNamespaces()` private method that lived on both
|
|
344
|
+
* `Orchestrator` and the maintenance namespace-planner (two copies of the
|
|
345
|
+
* same logic).
|
|
346
|
+
*/
|
|
347
|
+
export function getConfiguredNamespaces(config: PluginConfig): string[] {
|
|
348
|
+
return Array.from(
|
|
349
|
+
new Set(
|
|
350
|
+
[
|
|
351
|
+
config.defaultNamespace,
|
|
352
|
+
config.sharedNamespace,
|
|
353
|
+
...config.namespacePolicies.map((policy) => policy.name),
|
|
354
|
+
]
|
|
355
|
+
.map((value) => value.trim())
|
|
356
|
+
.filter(Boolean),
|
|
357
|
+
),
|
|
358
|
+
);
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
/**
|
|
362
|
+
* Options for {@link resolveNamespaceFromStorageDir}.
|
|
363
|
+
*/
|
|
364
|
+
export interface ResolveNamespaceFromStorageDirOptions {
|
|
365
|
+
/** Plugin config (memoryDir, defaultNamespace, namespacesEnabled, …). */
|
|
366
|
+
readonly config: PluginConfig;
|
|
367
|
+
/**
|
|
368
|
+
* Pre-computed configured-namespace set (from {@link getConfiguredNamespaces}).
|
|
369
|
+
* Passed by the caller so this function does not re-derive it on every call.
|
|
370
|
+
*/
|
|
371
|
+
readonly configuredNamespaces: readonly string[];
|
|
372
|
+
/**
|
|
373
|
+
* Catalog-owned dir→namespace hints (best-effort union of configured +
|
|
374
|
+
* catalog-discovered). May be `undefined` when no catalog hints are loaded.
|
|
375
|
+
*/
|
|
376
|
+
readonly hints?: ReadonlyMap<string, ReadonlySet<string>> | undefined;
|
|
377
|
+
/**
|
|
378
|
+
* Lazy catalog-hint loader. Called ONLY after the early returns (disabled,
|
|
379
|
+
* memory root, no namespace segment, configured namespace) — matching the
|
|
380
|
+
* original lazy behavior so an eager load does not mark hints as loaded
|
|
381
|
+
* before the catalog file exists (codex P2).
|
|
382
|
+
*/
|
|
383
|
+
readonly loadHints?: () => void;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
/**
|
|
387
|
+
* Derive the namespace a storage directory belongs to.
|
|
388
|
+
*
|
|
389
|
+
* Pure (no orchestrator state): the caller passes `config`, the configured set,
|
|
390
|
+
* and any catalog hints. The logic is byte-identical to the private
|
|
391
|
+
* `namespaceFromStorageDir` method that previously lived on `Orchestrator`
|
|
392
|
+
* (including the token round-trip guard from codex round 6).
|
|
393
|
+
*/
|
|
394
|
+
export function resolveNamespaceFromStorageDir(
|
|
395
|
+
storageDir: string,
|
|
396
|
+
options: ResolveNamespaceFromStorageDirOptions,
|
|
397
|
+
): string {
|
|
398
|
+
const { config } = options;
|
|
399
|
+
if (!config.namespacesEnabled) return config.defaultNamespace;
|
|
400
|
+
const resolvedStorageDir = path.resolve(storageDir);
|
|
401
|
+
const resolvedMemoryDir = path.resolve(config.memoryDir);
|
|
402
|
+
if (resolvedStorageDir === resolvedMemoryDir) return config.defaultNamespace;
|
|
403
|
+
const m = resolvedStorageDir.match(/[\\/]namespaces[\\/]([^\\/]+)$/);
|
|
404
|
+
if (!m?.[1]) return config.defaultNamespace;
|
|
405
|
+
const dirName = m[1];
|
|
406
|
+
// Token-shaped raw names (codex P2 — NBsFz): a dir name might be a tokenized
|
|
407
|
+
// identity OR a literal raw namespace name that merely LOOKS like a token.
|
|
408
|
+
// A dir name that is itself a KNOWN namespace is preserved BEFORE decoding.
|
|
409
|
+
if (options.configuredNamespaces.includes(dirName)) {
|
|
410
|
+
return dirName;
|
|
411
|
+
}
|
|
412
|
+
// Load catalog hints ONLY after the early returns (codex P2: an eager load
|
|
413
|
+
// before the catalog file exists would mark hints as loaded and skip later
|
|
414
|
+
// catalog-derived rows).
|
|
415
|
+
options.loadHints?.();
|
|
416
|
+
const hints = options.hints;
|
|
417
|
+
const hintedNamespaces = hints?.get(resolvedStorageDir);
|
|
418
|
+
if (hintedNamespaces?.has(dirName)) {
|
|
419
|
+
return dirName;
|
|
420
|
+
}
|
|
421
|
+
if (hintedNamespaces?.size === 1) {
|
|
422
|
+
const [hintedNamespace] = hintedNamespaces;
|
|
423
|
+
if (hintedNamespace) return hintedNamespace;
|
|
424
|
+
}
|
|
425
|
+
const decoded = namespaceIdentityFromToken(dirName);
|
|
426
|
+
if (decoded && namespaceIdentityToken(decoded) === dirName) {
|
|
427
|
+
return decoded;
|
|
428
|
+
}
|
|
429
|
+
return dirName;
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
/**
|
|
433
|
+
* Result of resolving a writable namespace: either the authorized namespace
|
|
434
|
+
* or a structured rejection. The caller decides how to surface the rejection
|
|
435
|
+
* (e.g. as an `EngramAccessInputError` in the access-service layer), keeping
|
|
436
|
+
* this module free of transport-specific error types.
|
|
437
|
+
*/
|
|
438
|
+
export type WritableNamespaceResult =
|
|
439
|
+
| { readonly ok: true; readonly namespace: string }
|
|
440
|
+
| { readonly ok: false; readonly reason: "unsupported" | "not_writable"; readonly namespace: string };
|
|
441
|
+
|
|
442
|
+
/**
|
|
443
|
+
* Resolve and authorize a writable namespace.
|
|
444
|
+
*
|
|
445
|
+
* Combines the three steps that `AccessService.resolveWritableNamespace`
|
|
446
|
+
* performed inline: (1) resolve the namespace value (trim → default fallback →
|
|
447
|
+
* validate against `namespacesEnabled`), (2) resolve the principal, (3) check
|
|
448
|
+
* `canWriteNamespace`. Returns a structured result so this module stays free of
|
|
449
|
+
* `EngramAccessInputError` (avoiding a circular dependency on access-service.ts).
|
|
450
|
+
*
|
|
451
|
+
* The caller throws `EngramAccessInputError` when `ok === false` — the access-
|
|
452
|
+
* service wrapper does this in one place.
|
|
453
|
+
*/
|
|
454
|
+
export function resolveWritableNamespaceValue(
|
|
455
|
+
namespace: string | undefined,
|
|
456
|
+
sessionKey: string | undefined,
|
|
457
|
+
authenticatedPrincipal: string | undefined,
|
|
458
|
+
config: PluginConfig,
|
|
459
|
+
): WritableNamespaceResult {
|
|
460
|
+
const requested = namespace?.trim();
|
|
461
|
+
let resolved: string;
|
|
462
|
+
if (!requested) {
|
|
463
|
+
resolved = config.defaultNamespace;
|
|
464
|
+
} else if (
|
|
465
|
+
!config.namespacesEnabled &&
|
|
466
|
+
requested !== config.defaultNamespace
|
|
467
|
+
) {
|
|
468
|
+
return { ok: false, reason: "unsupported", namespace: requested };
|
|
469
|
+
} else {
|
|
470
|
+
resolved = requested;
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
const trusted = authenticatedPrincipal?.trim();
|
|
474
|
+
const principal =
|
|
475
|
+
typeof trusted === "string" && trusted.length > 0
|
|
476
|
+
? trusted
|
|
477
|
+
: resolvePrincipal(sessionKey, config);
|
|
478
|
+
|
|
479
|
+
if (!canWriteNamespace(principal, resolved, config)) {
|
|
480
|
+
return { ok: false, reason: "not_writable", namespace: resolved };
|
|
481
|
+
}
|
|
482
|
+
return { ok: true, namespace: resolved };
|
|
483
|
+
}
|