@remnic/core 9.3.732 → 9.3.734
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 +10 -10
- package/dist/access-boundary.js +9 -9
- package/dist/access-cli.js +25 -23
- package/dist/access-cli.js.map +1 -1
- package/dist/access-http.d.ts +10 -10
- package/dist/access-http.js +14 -14
- package/dist/access-mcp.d.ts +10 -10
- package/dist/access-mcp.js +13 -13
- package/dist/access-operations-batch.js +11 -11
- package/dist/access-operations.d.ts +10 -10
- package/dist/access-operations.js +12 -12
- package/dist/{access-service-Byoe3HsT.d.ts → access-service-rjFfmfKB.d.ts} +4 -4
- package/dist/access-service.d.ts +10 -10
- package/dist/access-service.js +8 -8
- package/dist/access-surface-catalog.d.ts +10 -10
- package/dist/action-confidence.d.ts +1 -1
- package/dist/active-memory-bridge.d.ts +1 -1
- package/dist/active-memory-bridge.js +3 -2
- package/dist/active-recall.d.ts +1 -1
- package/dist/behavior-learner.d.ts +1 -1
- package/dist/behavior-signals.d.ts +1 -1
- package/dist/bootstrap.d.ts +9 -9
- package/dist/briefing.d.ts +1 -1
- package/dist/buffer-surprise-report.d.ts +1 -1
- package/dist/buffer.d.ts +1 -1
- package/dist/calibration.d.ts +1 -1
- package/dist/capabilities.d.ts +97 -2
- package/dist/capabilities.js +11 -3
- package/dist/{catalog-DM1nk7cM.d.ts → catalog-DHYXzM4-.d.ts} +2 -2
- package/dist/causal-behavior.d.ts +1 -1
- package/dist/causal-consolidation.d.ts +1 -1
- package/dist/causal-trajectory-graph.d.ts +1 -1
- package/dist/{chunk-24D66MMN.js → chunk-2L5RTVMO.js} +7 -4
- package/dist/chunk-2L5RTVMO.js.map +1 -0
- package/dist/{chunk-KQYGNGON.js → chunk-3QETM5NG.js} +6 -3
- package/dist/chunk-3QETM5NG.js.map +1 -0
- package/dist/{chunk-ZQUAVZNG.js → chunk-54RCE5Z3.js} +7 -4
- package/dist/chunk-54RCE5Z3.js.map +1 -0
- package/dist/{chunk-NOU77OHX.js → chunk-5DIKZKOD.js} +2 -2
- package/dist/{chunk-CGPHMNL4.js → chunk-5OYHJIJN.js} +10 -6
- package/dist/chunk-5OYHJIJN.js.map +1 -0
- package/dist/{chunk-LUCARK4W.js → chunk-6U7TES2M.js} +29 -28
- package/dist/chunk-6U7TES2M.js.map +1 -0
- package/dist/{chunk-FFUCCKPN.js → chunk-7FPJFCXL.js} +10 -7
- package/dist/chunk-7FPJFCXL.js.map +1 -0
- package/dist/{chunk-PMAQRUN4.js → chunk-CILX2XW7.js} +5 -2
- package/dist/chunk-CILX2XW7.js.map +1 -0
- package/dist/{chunk-ZVHRSR2R.js → chunk-ET5HXSQL.js} +6 -3
- package/dist/chunk-ET5HXSQL.js.map +1 -0
- package/dist/{chunk-KSJCXXOU.js → chunk-FAGERSH2.js} +6 -3
- package/dist/chunk-FAGERSH2.js.map +1 -0
- package/dist/{chunk-FYWUNVFZ.js → chunk-IDIXGGDN.js} +6 -6
- package/dist/{chunk-CX77GNMB.js → chunk-IWMGBNXY.js} +6 -3
- package/dist/chunk-IWMGBNXY.js.map +1 -0
- package/dist/{chunk-GGL34GCW.js → chunk-IZLTOS5L.js} +7 -4
- package/dist/chunk-IZLTOS5L.js.map +1 -0
- package/dist/{chunk-HHNSLPX7.js → chunk-K7PAILHO.js} +10 -9
- package/dist/chunk-K7PAILHO.js.map +1 -0
- package/dist/{chunk-UZYLX7M6.js → chunk-LV32K4OP.js} +9 -6
- package/dist/chunk-LV32K4OP.js.map +1 -0
- package/dist/{chunk-HJWQJUKQ.js → chunk-NDYQIN6C.js} +3 -3
- package/dist/{chunk-DKT3X5C3.js → chunk-PEF2XOIV.js} +7 -4
- package/dist/chunk-PEF2XOIV.js.map +1 -0
- package/dist/{chunk-646B5ERJ.js → chunk-PKO5NJ65.js} +51 -48
- package/dist/chunk-PKO5NJ65.js.map +1 -0
- package/dist/{chunk-QZHF4BWN.js → chunk-Q5LGXWNG.js} +6 -6
- package/dist/{chunk-ESF7TRYJ.js → chunk-SHJGBAIW.js} +37 -2
- package/dist/{chunk-ESF7TRYJ.js.map → chunk-SHJGBAIW.js.map} +1 -1
- package/dist/{chunk-O4ZIBPIW.js → chunk-T7CGPTFU.js} +3 -3
- package/dist/{chunk-PLBIPT6I.js → chunk-TJSQHO4Q.js} +7 -4
- package/dist/chunk-TJSQHO4Q.js.map +1 -0
- package/dist/{chunk-6TUWSUUD.js → chunk-UF3N7IRP.js} +26 -24
- package/dist/chunk-UF3N7IRP.js.map +1 -0
- package/dist/{chunk-P3VJCTVE.js → chunk-UH3NYOHN.js} +4 -3
- package/dist/chunk-UH3NYOHN.js.map +1 -0
- package/dist/{chunk-J6BH2OBA.js → chunk-UK6U5C3N.js} +8 -5
- package/dist/chunk-UK6U5C3N.js.map +1 -0
- package/dist/{chunk-OTQE66IX.js → chunk-V5OVSGB6.js} +6 -3
- package/dist/chunk-V5OVSGB6.js.map +1 -0
- package/dist/{chunk-H3MB3F62.js → chunk-WHQ2JB35.js} +4 -3
- package/dist/chunk-WHQ2JB35.js.map +1 -0
- package/dist/{chunk-NIZQH6AU.js → chunk-WTTVFSCO.js} +8 -7
- package/dist/chunk-WTTVFSCO.js.map +1 -0
- package/dist/{chunk-OUITHS6V.js → chunk-Z7J3OAPR.js} +357 -325
- package/dist/chunk-Z7J3OAPR.js.map +1 -0
- package/dist/{cli-Dt-tuiYH.d.ts → cli-XVpmSoQs.d.ts} +3 -3
- package/dist/cli.d.ts +11 -11
- package/dist/cli.js +20 -20
- package/dist/compounding/engine.d.ts +3 -2
- package/dist/compounding/engine.js +2 -1
- package/dist/compounding/preference-consolidator.d.ts +1 -1
- package/dist/compression-optimizer.d.ts +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/connectors/codex-materialize-runner.d.ts +1 -1
- package/dist/connectors/codex-materialize.d.ts +1 -1
- package/dist/connectors/index.d.ts +1 -1
- package/dist/consolidation-provenance-check.d.ts +1 -1
- package/dist/consolidation-undo.d.ts +1 -1
- package/dist/contradiction/index.d.ts +2 -2
- package/dist/contradiction/index.js +2 -1
- package/dist/{contradiction-scan-HWGEOUDS.js → contradiction-scan-OUHMCUBT.js} +3 -2
- package/dist/conversation-index/backend.d.ts +1 -1
- package/dist/conversation-index/chunker.d.ts +1 -1
- package/dist/conversation-index/faiss-adapter.d.ts +1 -1
- package/dist/conversation-index/indexer.d.ts +1 -1
- package/dist/conversation-index/search.d.ts +1 -1
- package/dist/day-summary.d.ts +1 -1
- package/dist/delinearize.d.ts +1 -1
- package/dist/direct-answer-wiring.d.ts +1 -1
- package/dist/direct-answer.d.ts +1 -1
- package/dist/embedding-fallback.d.ts +1 -1
- package/dist/embedding-fallback.js +2 -2
- package/dist/enrichment/index.d.ts +1 -1
- package/dist/entity-retrieval.d.ts +1 -1
- package/dist/entity-retrieval.js +2 -1
- package/dist/entity-schema.d.ts +1 -1
- package/dist/explicit-capture.d.ts +9 -9
- package/dist/explicit-capture.js +2 -1
- package/dist/extraction-faithfulness.d.ts +1 -1
- package/dist/extraction-judge-telemetry.d.ts +1 -1
- package/dist/extraction-judge-training.d.ts +1 -1
- package/dist/extraction-judge.d.ts +1 -1
- package/dist/extraction.d.ts +1 -1
- package/dist/extraction.js +3 -3
- package/dist/fallback-llm.d.ts +1 -1
- package/dist/{first-start-migration-OOR57AYR.js → first-start-migration-W4U6XDKI.js} +7 -6
- package/dist/first-start-migration-W4U6XDKI.js.map +1 -0
- package/dist/graph-dashboard-diff.d.ts +1 -1
- package/dist/graph-dashboard-key.d.ts +1 -1
- package/dist/graph-dashboard-parser.d.ts +1 -1
- package/dist/graph-edge-reinforcement.d.ts +1 -1
- package/dist/graph-snapshot.d.ts +1 -1
- package/dist/graph.d.ts +1 -1
- package/dist/identity-continuity.d.ts +1 -1
- package/dist/importance.d.ts +1 -1
- package/dist/index.d.ts +12 -12
- package/dist/index.js +43 -43
- package/dist/intent.d.ts +1 -1
- package/dist/lcm/engine.d.ts +1 -1
- package/dist/lcm/index.d.ts +1 -1
- package/dist/lcm/tools.d.ts +1 -1
- package/dist/lifecycle.d.ts +1 -1
- package/dist/live-connectors-runner.d.ts +1 -1
- package/dist/local-llm.d.ts +1 -1
- package/dist/local-llm.js +2 -1
- package/dist/local-model-endpoint.d.ts +1 -1
- package/dist/maintenance/memory-governance.d.ts +1 -1
- package/dist/mcp-memory-inspector-app.d.ts +10 -10
- package/dist/memory-action-policy.d.ts +1 -1
- package/dist/memory-cache.d.ts +1 -1
- package/dist/memory-lifecycle-ledger-utils.d.ts +1 -1
- package/dist/memory-projection-store.d.ts +1 -1
- package/dist/memory-provenance.d.ts +1 -1
- package/dist/memory-worth-outcomes.d.ts +1 -1
- package/dist/models-json.d.ts +1 -1
- package/dist/namespaces/migrate.d.ts +2 -2
- package/dist/namespaces/migrate.js +6 -6
- package/dist/namespaces/principal.d.ts +1 -1
- package/dist/namespaces/principal.js +2 -1
- package/dist/namespaces/search.d.ts +1 -1
- package/dist/namespaces/search.js +4 -4
- package/dist/namespaces/storage.d.ts +2 -2
- package/dist/namespaces/storage.js +2 -1
- package/dist/native-knowledge.d.ts +1 -1
- package/dist/operator-toolkit.d.ts +1 -1
- package/dist/operator-toolkit.js +11 -11
- package/dist/orchestration/compression-guideline-coordinator.d.ts +1 -1
- package/dist/orchestration/maintenance.d.ts +2 -2
- package/dist/orchestration/maintenance.js +6 -5
- package/dist/{orchestrator-B4KjaOtY.d.ts → orchestrator-BXi-gadS.d.ts} +66 -5
- package/dist/orchestrator.d.ts +5 -5
- package/dist/orchestrator.js +20 -18
- package/dist/patterns-cli.d.ts +1 -1
- package/dist/policy-runtime.d.ts +1 -1
- package/dist/provenance.d.ts +1 -1
- package/dist/qmd-recall-cache.d.ts +1 -1
- package/dist/qmd.d.ts +1 -1
- package/dist/recall-disclosure-escalation.d.ts +1 -1
- package/dist/recall-explain-renderer.d.ts +1 -1
- package/dist/recall-planner-llm.d.ts +1 -1
- package/dist/recall-state.d.ts +1 -1
- package/dist/recall-tag-filter.d.ts +1 -1
- package/dist/recall-xray-cli.d.ts +1 -1
- package/dist/recall-xray-renderer.d.ts +1 -1
- package/dist/recall-xray.d.ts +1 -1
- package/dist/resolve-auth-token.d.ts +1 -1
- package/dist/retrieval-agents.d.ts +1 -1
- package/dist/retrieval-tiers.d.ts +1 -1
- package/dist/routing/engine.d.ts +1 -1
- package/dist/routing/store.d.ts +1 -1
- package/dist/schemas.d.ts +22 -22
- package/dist/search/embed-helper.d.ts +1 -1
- package/dist/search/embed-helper.js +2 -2
- package/dist/search/factory.d.ts +1 -1
- package/dist/search/factory.js +3 -3
- package/dist/search/index.d.ts +1 -1
- package/dist/search/index.js +3 -3
- package/dist/search/lancedb-backend.d.ts +1 -1
- package/dist/search/meilisearch-backend.d.ts +1 -1
- package/dist/search/noop-backend.d.ts +1 -1
- package/dist/search/orama-backend.d.ts +1 -1
- package/dist/search/port.d.ts +1 -1
- package/dist/search/remote-backend.d.ts +1 -1
- package/dist/{semantic-SLAa_prH.d.ts → semantic-DJR8_DMQ.d.ts} +1 -1
- package/dist/{semantic-consolidation-CstTvHPo.d.ts → semantic-consolidation-DeL5grLx.d.ts} +1 -1
- package/dist/semantic-consolidation.d.ts +2 -2
- package/dist/semantic-rule-verifier.d.ts +1 -1
- package/dist/session-observer-bands.d.ts +1 -1
- package/dist/session-observer-state.d.ts +1 -1
- package/dist/shared-context/manager.d.ts +1 -1
- package/dist/signal.d.ts +1 -1
- package/dist/storage.d.ts +1 -1
- package/dist/summarizer.d.ts +1 -1
- package/dist/summarizer.js +3 -2
- package/dist/summary-snapshot.d.ts +1 -1
- package/dist/temporal-supersession.d.ts +1 -1
- package/dist/temporal-validity.d.ts +1 -1
- package/dist/threading.d.ts +1 -1
- package/dist/tier-migration.d.ts +1 -1
- package/dist/tier-routing.d.ts +1 -1
- package/dist/{tier-stats-3LYQ3VV5.js → tier-stats-LSM35HZY.js} +5 -2
- package/dist/tier-stats-LSM35HZY.js.map +1 -0
- package/dist/topics.d.ts +1 -1
- package/dist/transcript.d.ts +1 -1
- package/dist/transfer/types.d.ts +12 -12
- package/dist/trust-score-stage.d.ts +1 -1
- package/dist/trust-score.d.ts +1 -1
- package/dist/{types-VkxElCHR.d.ts → types-CpFz51Pv.d.ts} +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/utility-runtime.d.ts +1 -1
- package/package.json +2 -2
- package/src/access-service.ts +42 -37
- package/src/active-memory-bridge.ts +2 -1
- package/src/admin/admin-surfaces.ts +2 -1
- package/src/capabilities.test.ts +178 -0
- package/src/capabilities.ts +197 -0
- package/src/cli.ts +13 -9
- package/src/compounding/engine.ts +4 -3
- package/src/contradiction/contradiction-scan.ts +4 -3
- package/src/embedding-fallback.ts +5 -2
- package/src/entity-retrieval.ts +3 -2
- package/src/explicit-capture.ts +2 -1
- package/src/extraction.ts +6 -3
- package/src/local-llm.ts +4 -3
- package/src/maintenance/first-start-migration.ts +6 -3
- package/src/maintenance/namespace-maintenance-fanout.ts +2 -1
- package/src/maintenance/namespace-planner.ts +4 -3
- package/src/maintenance/tier-stats.ts +2 -1
- package/src/namespaces/catalog.ts +2 -1
- package/src/namespaces/migrate.ts +2 -1
- package/src/namespaces/principal.ts +6 -5
- package/src/namespaces/scope-profiles.ts +2 -1
- package/src/namespaces/search.ts +2 -1
- package/src/namespaces/storage.ts +4 -3
- package/src/operator-toolkit.ts +19 -18
- package/src/orchestration/maintenance.ts +8 -4
- package/src/orchestration/semantic-consolidation-coordinator.ts +454 -0
- package/src/orchestration/tier-migration-coordinator.ts +5 -4
- package/src/orchestrator.ts +78 -417
- package/src/scopes/scope-plan.ts +3 -2
- package/src/search/embed-helper.ts +5 -2
- package/src/search/factory.ts +9 -6
- package/src/summarizer.ts +3 -2
- package/dist/chunk-24D66MMN.js.map +0 -1
- package/dist/chunk-646B5ERJ.js.map +0 -1
- package/dist/chunk-6TUWSUUD.js.map +0 -1
- package/dist/chunk-CGPHMNL4.js.map +0 -1
- package/dist/chunk-CX77GNMB.js.map +0 -1
- package/dist/chunk-DKT3X5C3.js.map +0 -1
- package/dist/chunk-FFUCCKPN.js.map +0 -1
- package/dist/chunk-GGL34GCW.js.map +0 -1
- package/dist/chunk-H3MB3F62.js.map +0 -1
- package/dist/chunk-HHNSLPX7.js.map +0 -1
- package/dist/chunk-J6BH2OBA.js.map +0 -1
- package/dist/chunk-KQYGNGON.js.map +0 -1
- package/dist/chunk-KSJCXXOU.js.map +0 -1
- package/dist/chunk-LUCARK4W.js.map +0 -1
- package/dist/chunk-NIZQH6AU.js.map +0 -1
- package/dist/chunk-OTQE66IX.js.map +0 -1
- package/dist/chunk-OUITHS6V.js.map +0 -1
- package/dist/chunk-P3VJCTVE.js.map +0 -1
- package/dist/chunk-PLBIPT6I.js.map +0 -1
- package/dist/chunk-PMAQRUN4.js.map +0 -1
- package/dist/chunk-UZYLX7M6.js.map +0 -1
- package/dist/chunk-ZQUAVZNG.js.map +0 -1
- package/dist/chunk-ZVHRSR2R.js.map +0 -1
- package/dist/first-start-migration-OOR57AYR.js.map +0 -1
- package/dist/tier-stats-3LYQ3VV5.js.map +0 -1
- /package/dist/{chunk-NOU77OHX.js.map → chunk-5DIKZKOD.js.map} +0 -0
- /package/dist/{chunk-FYWUNVFZ.js.map → chunk-IDIXGGDN.js.map} +0 -0
- /package/dist/{chunk-HJWQJUKQ.js.map → chunk-NDYQIN6C.js.map} +0 -0
- /package/dist/{chunk-QZHF4BWN.js.map → chunk-Q5LGXWNG.js.map} +0 -0
- /package/dist/{chunk-O4ZIBPIW.js.map → chunk-T7CGPTFU.js.map} +0 -0
- /package/dist/{contradiction-scan-HWGEOUDS.js.map → contradiction-scan-OUHMCUBT.js.map} +0 -0
package/src/access-service.ts
CHANGED
|
@@ -5,7 +5,12 @@ import { readdirSync, unlinkSync } from "node:fs";
|
|
|
5
5
|
import { createHash } from "node:crypto";
|
|
6
6
|
import { ZodError } from "zod";
|
|
7
7
|
import { AccessIdempotencyStore, hashAccessIdempotencyPayload } from "./access-idempotency.js";
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
resolveNamespaceCapabilities,
|
|
10
|
+
resolveMemoryLifecycleCapabilities,
|
|
11
|
+
resolveQmdCapabilities,
|
|
12
|
+
resolveIdentityContinuityCapabilities,
|
|
13
|
+
} from "./capabilities.js";
|
|
9
14
|
import { AccessAuditAdapter, type AccessAuditConfig, type AccessAuditResult } from "./access-audit.js";
|
|
10
15
|
import type { AnomalyDetectorResult } from "./recall-audit-anomaly.js";
|
|
11
16
|
import { resolveGitContext } from "./coding/git-context.js";
|
|
@@ -1339,7 +1344,7 @@ export class EngramAccessService {
|
|
|
1339
1344
|
private resolveNamespace(namespace?: string): string {
|
|
1340
1345
|
const requested = namespace?.trim();
|
|
1341
1346
|
if (!requested) return this.orchestrator.config.defaultNamespace;
|
|
1342
|
-
if (!this.orchestrator.config.
|
|
1347
|
+
if (!resolveNamespaceCapabilities(this.orchestrator.config).namespaces && requested !== this.orchestrator.config.defaultNamespace) {
|
|
1343
1348
|
throw new EngramAccessInputError(`unsupported namespace: ${requested}`);
|
|
1344
1349
|
}
|
|
1345
1350
|
return requested;
|
|
@@ -1458,14 +1463,14 @@ export class EngramAccessService {
|
|
|
1458
1463
|
typeof request.sessionKey === "string" && request.sessionKey.length > 0;
|
|
1459
1464
|
const codingContext =
|
|
1460
1465
|
hasSession &&
|
|
1461
|
-
this.orchestrator.config.
|
|
1466
|
+
resolveNamespaceCapabilities(this.orchestrator.config).namespaces &&
|
|
1462
1467
|
this.orchestrator.config.codingMode?.projectScope
|
|
1463
1468
|
? this.orchestrator.getCodingContextForSession(request.sessionKey) ??
|
|
1464
1469
|
(await this.resolveCodingContextFromOptions(request))
|
|
1465
1470
|
: null;
|
|
1466
1471
|
const overlay =
|
|
1467
1472
|
hasSession &&
|
|
1468
|
-
this.orchestrator.config.
|
|
1473
|
+
resolveNamespaceCapabilities(this.orchestrator.config).namespaces &&
|
|
1469
1474
|
this.orchestrator.config.codingMode?.projectScope
|
|
1470
1475
|
? resolveCodingNamespaceOverlay(
|
|
1471
1476
|
codingContext,
|
|
@@ -1686,7 +1691,7 @@ export class EngramAccessService {
|
|
|
1686
1691
|
typeof request.sessionKey === "string" && request.sessionKey.length > 0;
|
|
1687
1692
|
const overlayEligible =
|
|
1688
1693
|
hasSession &&
|
|
1689
|
-
this.orchestrator.config.
|
|
1694
|
+
resolveNamespaceCapabilities(this.orchestrator.config).namespaces === true &&
|
|
1690
1695
|
this.orchestrator.config.codingMode?.projectScope === true;
|
|
1691
1696
|
|
|
1692
1697
|
// Resolve the coding context the overlay must use: the session's ATTACHED
|
|
@@ -1822,7 +1827,7 @@ export class EngramAccessService {
|
|
|
1822
1827
|
this.orchestrator.config.objectiveStateSnapshotWritesEnabled === true;
|
|
1823
1828
|
if (
|
|
1824
1829
|
willWriteObjectiveState &&
|
|
1825
|
-
this.orchestrator.config.
|
|
1830
|
+
resolveNamespaceCapabilities(this.orchestrator.config).namespaces === true &&
|
|
1826
1831
|
!canWriteNamespace(principal, baseNamespace, this.orchestrator.config)
|
|
1827
1832
|
) {
|
|
1828
1833
|
clearSeededContext();
|
|
@@ -1897,7 +1902,7 @@ export class EngramAccessService {
|
|
|
1897
1902
|
memoryDir: string;
|
|
1898
1903
|
objectiveStateStoreDir?: string;
|
|
1899
1904
|
}> {
|
|
1900
|
-
if (!this.orchestrator.config.
|
|
1905
|
+
if (!resolveNamespaceCapabilities(this.orchestrator.config).namespaces) {
|
|
1901
1906
|
return {
|
|
1902
1907
|
memoryDir: this.orchestrator.config.memoryDir,
|
|
1903
1908
|
objectiveStateStoreDir: this.orchestrator.config.objectiveStateStoreDir,
|
|
@@ -1909,7 +1914,7 @@ export class EngramAccessService {
|
|
|
1909
1914
|
objectiveStateStoreDir: objectiveStateStoreOverrideForNamespace({
|
|
1910
1915
|
memoryDir: this.orchestrator.config.memoryDir,
|
|
1911
1916
|
configuredStoreDir: this.orchestrator.config.objectiveStateStoreDir,
|
|
1912
|
-
namespacesEnabled: this.orchestrator.config.
|
|
1917
|
+
namespacesEnabled: resolveNamespaceCapabilities(this.orchestrator.config).namespaces,
|
|
1913
1918
|
namespace,
|
|
1914
1919
|
}),
|
|
1915
1920
|
};
|
|
@@ -1917,7 +1922,7 @@ export class EngramAccessService {
|
|
|
1917
1922
|
|
|
1918
1923
|
private resolveReadableNamespace(namespace: string | undefined, principal?: string): string {
|
|
1919
1924
|
const resolved = this.resolveNamespace(namespace);
|
|
1920
|
-
const namespacesEnabled = this.orchestrator.config.
|
|
1925
|
+
const namespacesEnabled = resolveNamespaceCapabilities(this.orchestrator.config).namespaces;
|
|
1921
1926
|
|
|
1922
1927
|
if (!namespacesEnabled) {
|
|
1923
1928
|
// Namespaces are disabled globally — no ACL needed for any caller.
|
|
@@ -1946,7 +1951,7 @@ export class EngramAccessService {
|
|
|
1946
1951
|
return [this.resolveReadableNamespace(requested, principal)];
|
|
1947
1952
|
}
|
|
1948
1953
|
|
|
1949
|
-
if (!this.orchestrator.config.
|
|
1954
|
+
if (!resolveNamespaceCapabilities(this.orchestrator.config).namespaces) {
|
|
1950
1955
|
return [this.resolveNamespace(undefined)];
|
|
1951
1956
|
}
|
|
1952
1957
|
|
|
@@ -1998,7 +2003,7 @@ export class EngramAccessService {
|
|
|
1998
2003
|
namespaces: string[],
|
|
1999
2004
|
collectionPrincipal?: string,
|
|
2000
2005
|
): string[] {
|
|
2001
|
-
if (!this.orchestrator.config.
|
|
2006
|
+
if (!resolveNamespaceCapabilities(this.orchestrator.config).namespaces) {
|
|
2002
2007
|
return namespaces;
|
|
2003
2008
|
}
|
|
2004
2009
|
|
|
@@ -2702,7 +2707,7 @@ export class EngramAccessService {
|
|
|
2702
2707
|
const resolvedNamespace = this.resolveNamespace(namespace);
|
|
2703
2708
|
const storage = await this.orchestrator.getStorage(resolvedNamespace);
|
|
2704
2709
|
const searchBackend = this.orchestrator.config.searchBackend ?? "qmd";
|
|
2705
|
-
const qmdEnabled = this.orchestrator.config.
|
|
2710
|
+
const qmdEnabled = resolveQmdCapabilities(this.orchestrator.config).qmd === true;
|
|
2706
2711
|
let projectionAvailable = false;
|
|
2707
2712
|
try {
|
|
2708
2713
|
await stat(getMemoryProjectionPath(storage.dir));
|
|
@@ -2714,7 +2719,7 @@ export class EngramAccessService {
|
|
|
2714
2719
|
return {
|
|
2715
2720
|
ok: true,
|
|
2716
2721
|
memoryDir: storage.dir,
|
|
2717
|
-
namespacesEnabled: this.orchestrator.config.
|
|
2722
|
+
namespacesEnabled: resolveNamespaceCapabilities(this.orchestrator.config).namespaces === true,
|
|
2718
2723
|
defaultNamespace: this.orchestrator.config.defaultNamespace,
|
|
2719
2724
|
searchBackend,
|
|
2720
2725
|
qmdEnabled,
|
|
@@ -2730,7 +2735,7 @@ export class EngramAccessService {
|
|
|
2730
2735
|
}
|
|
2731
2736
|
|
|
2732
2737
|
private qmdCollectionForHealth(namespace: string, storageDir: string): string {
|
|
2733
|
-
if (this.orchestrator.config.
|
|
2738
|
+
if (resolveNamespaceCapabilities(this.orchestrator.config).namespaces !== true) {
|
|
2734
2739
|
return this.orchestrator.config.qmdCollection;
|
|
2735
2740
|
}
|
|
2736
2741
|
|
|
@@ -2766,7 +2771,7 @@ export class EngramAccessService {
|
|
|
2766
2771
|
};
|
|
2767
2772
|
}
|
|
2768
2773
|
|
|
2769
|
-
if (this.orchestrator.config.
|
|
2774
|
+
if (resolveNamespaceCapabilities(this.orchestrator.config).namespaces === true) {
|
|
2770
2775
|
const namespaceHealth = await this.namespaceQmdHealth(searchBackend, qmdEnabled, namespace, collection);
|
|
2771
2776
|
if (namespaceHealth) return namespaceHealth;
|
|
2772
2777
|
}
|
|
@@ -3224,7 +3229,7 @@ export class EngramAccessService {
|
|
|
3224
3229
|
const normalizedRequest = { ...request, query };
|
|
3225
3230
|
const authenticatedPrincipal = request.authenticatedPrincipal?.trim();
|
|
3226
3231
|
const principal = this.resolveRequestPrincipal(request.sessionKey, authenticatedPrincipal);
|
|
3227
|
-
if (this.orchestrator.config.
|
|
3232
|
+
if (resolveNamespaceCapabilities(this.orchestrator.config).namespaces && !principal) {
|
|
3228
3233
|
throw new EngramAccessInputError(
|
|
3229
3234
|
"authentication required: namespaces are enabled and no principal was supplied",
|
|
3230
3235
|
);
|
|
@@ -3307,7 +3312,7 @@ export class EngramAccessService {
|
|
|
3307
3312
|
// accounting (Codex P1: budget recorded before mode validation).
|
|
3308
3313
|
const mode = this.normalizeRecallMode(request.mode);
|
|
3309
3314
|
const maybePrincipal = this.resolveRequestPrincipal(request.sessionKey, authenticatedPrincipal);
|
|
3310
|
-
if (this.orchestrator.config.
|
|
3315
|
+
if (resolveNamespaceCapabilities(this.orchestrator.config).namespaces && !maybePrincipal) {
|
|
3311
3316
|
throw new EngramAccessInputError(
|
|
3312
3317
|
"authentication required: namespaces are enabled and no principal was supplied",
|
|
3313
3318
|
);
|
|
@@ -3321,7 +3326,7 @@ export class EngramAccessService {
|
|
|
3321
3326
|
const profileCodingOverlay =
|
|
3322
3327
|
!namespaceOverride &&
|
|
3323
3328
|
profileCodingContext &&
|
|
3324
|
-
this.orchestrator.config.
|
|
3329
|
+
resolveNamespaceCapabilities(this.orchestrator.config).namespaces &&
|
|
3325
3330
|
this.orchestrator.config.codingMode?.projectScope
|
|
3326
3331
|
? resolveCodingNamespaceOverlay(
|
|
3327
3332
|
profileCodingContext,
|
|
@@ -3725,7 +3730,7 @@ export class EngramAccessService {
|
|
|
3725
3730
|
return { found: false };
|
|
3726
3731
|
}
|
|
3727
3732
|
} else if (
|
|
3728
|
-
this.orchestrator.config.
|
|
3733
|
+
resolveNamespaceCapabilities(this.orchestrator.config).namespaces
|
|
3729
3734
|
&& !principal
|
|
3730
3735
|
) {
|
|
3731
3736
|
return { found: false };
|
|
@@ -3744,7 +3749,7 @@ export class EngramAccessService {
|
|
|
3744
3749
|
return candidate.namespace === requestedNamespace ? candidate : null;
|
|
3745
3750
|
})();
|
|
3746
3751
|
const readableSnapshot = (() => {
|
|
3747
|
-
if (!snapshot || !this.orchestrator.config.
|
|
3752
|
+
if (!snapshot || !resolveNamespaceCapabilities(this.orchestrator.config).namespaces) return snapshot;
|
|
3748
3753
|
const snapshotNamespace = snapshot.namespace ?? this.orchestrator.config.defaultNamespace;
|
|
3749
3754
|
return canReadNamespace(principal, snapshotNamespace, this.orchestrator.config)
|
|
3750
3755
|
? snapshot
|
|
@@ -3754,7 +3759,7 @@ export class EngramAccessService {
|
|
|
3754
3759
|
if (requestedNamespace) return requestedNamespace;
|
|
3755
3760
|
if (readableSnapshot?.namespace) return readableSnapshot.namespace;
|
|
3756
3761
|
const fallbackNamespace = this.orchestrator.config.defaultNamespace;
|
|
3757
|
-
if (!this.orchestrator.config.
|
|
3762
|
+
if (!resolveNamespaceCapabilities(this.orchestrator.config).namespaces) return fallbackNamespace;
|
|
3758
3763
|
return canReadNamespace(principal, fallbackNamespace, this.orchestrator.config)
|
|
3759
3764
|
? fallbackNamespace
|
|
3760
3765
|
: null;
|
|
@@ -3773,7 +3778,7 @@ export class EngramAccessService {
|
|
|
3773
3778
|
namespace?: string,
|
|
3774
3779
|
authenticatedPrincipal?: string,
|
|
3775
3780
|
) {
|
|
3776
|
-
const namespacesEnabled = this.orchestrator.config.
|
|
3781
|
+
const namespacesEnabled = resolveNamespaceCapabilities(this.orchestrator.config).namespaces;
|
|
3777
3782
|
const requestedNamespace = namespace?.trim()
|
|
3778
3783
|
? this.resolveNamespace(namespace)
|
|
3779
3784
|
: undefined;
|
|
@@ -3882,7 +3887,7 @@ export class EngramAccessService {
|
|
|
3882
3887
|
);
|
|
3883
3888
|
}
|
|
3884
3889
|
|
|
3885
|
-
const namespacesEnabled = this.orchestrator.config.
|
|
3890
|
+
const namespacesEnabled = resolveNamespaceCapabilities(this.orchestrator.config).namespaces;
|
|
3886
3891
|
const requestedNamespace = request.namespace?.trim()
|
|
3887
3892
|
? this.resolveNamespace(request.namespace)
|
|
3888
3893
|
: undefined;
|
|
@@ -5983,7 +5988,7 @@ export class EngramAccessService {
|
|
|
5983
5988
|
// namespace to one store, so leaving the override undefined preserves the
|
|
5984
5989
|
// existing single-store routing byte-for-byte.
|
|
5985
5990
|
const writeNamespaceOverride =
|
|
5986
|
-
this.orchestrator.config.
|
|
5991
|
+
resolveNamespaceCapabilities(this.orchestrator.config).namespaces === true
|
|
5987
5992
|
? writeNamespace
|
|
5988
5993
|
: undefined;
|
|
5989
5994
|
// Pin provenance PRINCIPAL to the scope plan's resolved principal (#1505
|
|
@@ -6188,7 +6193,7 @@ export class EngramAccessService {
|
|
|
6188
6193
|
(typeof request.sessionKey === "string" &&
|
|
6189
6194
|
request.sessionKey.length > 0) ||
|
|
6190
6195
|
lcmSessionPrefixes.some((prefix) => typeof prefix === "string" && prefix.length > 0);
|
|
6191
|
-
if (!hasScopedSession && this.orchestrator.config.
|
|
6196
|
+
if (!hasScopedSession && resolveNamespaceCapabilities(this.orchestrator.config).namespaces === true) {
|
|
6192
6197
|
return {
|
|
6193
6198
|
query: request.query,
|
|
6194
6199
|
namespace,
|
|
@@ -6483,7 +6488,7 @@ export class EngramAccessService {
|
|
|
6483
6488
|
principal: string | undefined,
|
|
6484
6489
|
): string | undefined {
|
|
6485
6490
|
const config = this.orchestrator.config;
|
|
6486
|
-
if (!config.
|
|
6491
|
+
if (!resolveNamespaceCapabilities(config).namespaces) return config.defaultNamespace;
|
|
6487
6492
|
// PROCEED when `default` is readable (single-store / readable-default flows)
|
|
6488
6493
|
// — the LCM prefix resolves to the overlay when self-authorized, else the
|
|
6489
6494
|
// default raw key.
|
|
@@ -6824,7 +6829,7 @@ export class EngramAccessService {
|
|
|
6824
6829
|
period?: "weekly" | "monthly";
|
|
6825
6830
|
key?: string;
|
|
6826
6831
|
}): Promise<{ enabled: boolean; reason?: string; period?: string; key?: string; reportPath?: string }> {
|
|
6827
|
-
if (!this.orchestrator.config.
|
|
6832
|
+
if (!resolveIdentityContinuityCapabilities(this.orchestrator.config).identityContinuity) {
|
|
6828
6833
|
return { enabled: false, reason: "Identity continuity is disabled. Enable `identityContinuityEnabled: true`." };
|
|
6829
6834
|
}
|
|
6830
6835
|
if (!this.orchestrator.config.continuityAuditEnabled) {
|
|
@@ -6846,7 +6851,7 @@ export class EngramAccessService {
|
|
|
6846
6851
|
triggerWindow?: string;
|
|
6847
6852
|
suspectedCause?: string;
|
|
6848
6853
|
}): Promise<unknown> {
|
|
6849
|
-
if (!this.orchestrator.config.
|
|
6854
|
+
if (!resolveIdentityContinuityCapabilities(this.orchestrator.config).identityContinuity) {
|
|
6850
6855
|
return { enabled: false, reason: "Identity continuity is disabled. Enable `identityContinuityEnabled: true`." };
|
|
6851
6856
|
}
|
|
6852
6857
|
if (!this.orchestrator.config.continuityIncidentLoggingEnabled) {
|
|
@@ -6872,7 +6877,7 @@ export class EngramAccessService {
|
|
|
6872
6877
|
verificationResult: string;
|
|
6873
6878
|
preventiveRule?: string;
|
|
6874
6879
|
}): Promise<unknown> {
|
|
6875
|
-
if (!this.orchestrator.config.
|
|
6880
|
+
if (!resolveIdentityContinuityCapabilities(this.orchestrator.config).identityContinuity) {
|
|
6876
6881
|
return { enabled: false, reason: "Identity continuity is disabled." };
|
|
6877
6882
|
}
|
|
6878
6883
|
if (!this.orchestrator.config.continuityIncidentLoggingEnabled) {
|
|
@@ -6901,7 +6906,7 @@ export class EngramAccessService {
|
|
|
6901
6906
|
principal?: string;
|
|
6902
6907
|
limit?: number;
|
|
6903
6908
|
}): Promise<unknown> {
|
|
6904
|
-
if (!this.orchestrator.config.
|
|
6909
|
+
if (!resolveIdentityContinuityCapabilities(this.orchestrator.config).identityContinuity) {
|
|
6905
6910
|
return { enabled: false, reason: "Identity continuity is disabled." };
|
|
6906
6911
|
}
|
|
6907
6912
|
const state = request.state === "closed" || request.state === "all" ? request.state : "open";
|
|
@@ -6923,7 +6928,7 @@ export class EngramAccessService {
|
|
|
6923
6928
|
lastReviewed?: string;
|
|
6924
6929
|
notes?: string;
|
|
6925
6930
|
}): Promise<unknown> {
|
|
6926
|
-
if (!this.orchestrator.config.
|
|
6931
|
+
if (!resolveIdentityContinuityCapabilities(this.orchestrator.config).identityContinuity) {
|
|
6927
6932
|
return { enabled: false, reason: "Identity continuity is disabled." };
|
|
6928
6933
|
}
|
|
6929
6934
|
const resolvedNs = this.writableNamespaceFor(request.namespace, undefined, request.principal);
|
|
@@ -6948,7 +6953,7 @@ export class EngramAccessService {
|
|
|
6948
6953
|
notes?: string;
|
|
6949
6954
|
reviewedAt?: string;
|
|
6950
6955
|
}): Promise<unknown> {
|
|
6951
|
-
if (!this.orchestrator.config.
|
|
6956
|
+
if (!resolveIdentityContinuityCapabilities(this.orchestrator.config).identityContinuity) {
|
|
6952
6957
|
return { enabled: false, reason: "Identity continuity is disabled." };
|
|
6953
6958
|
}
|
|
6954
6959
|
const id = request.id?.trim();
|
|
@@ -6968,7 +6973,7 @@ export class EngramAccessService {
|
|
|
6968
6973
|
namespace?: string;
|
|
6969
6974
|
principal?: string;
|
|
6970
6975
|
}): Promise<unknown> {
|
|
6971
|
-
if (!this.orchestrator.config.
|
|
6976
|
+
if (!resolveIdentityContinuityCapabilities(this.orchestrator.config).identityContinuity) {
|
|
6972
6977
|
return { enabled: false, reason: "Identity continuity is disabled." };
|
|
6973
6978
|
}
|
|
6974
6979
|
const resolvedNs = this.resolveReadableNamespace(request.namespace, request.principal);
|
|
@@ -6994,7 +6999,7 @@ export class EngramAccessService {
|
|
|
6994
6999
|
operatingPrinciples?: string;
|
|
6995
7000
|
continuityNotes?: string;
|
|
6996
7001
|
}): Promise<unknown> {
|
|
6997
|
-
if (!this.orchestrator.config.
|
|
7002
|
+
if (!resolveIdentityContinuityCapabilities(this.orchestrator.config).identityContinuity) {
|
|
6998
7003
|
return { enabled: false, reason: "Identity continuity is disabled." };
|
|
6999
7004
|
}
|
|
7000
7005
|
|
|
@@ -7419,7 +7424,7 @@ export class EngramAccessService {
|
|
|
7419
7424
|
}
|
|
7420
7425
|
|
|
7421
7426
|
let results: Array<{ path: string; score: number; snippet?: string }>;
|
|
7422
|
-
if (!this.orchestrator.config.
|
|
7427
|
+
if (!resolveNamespaceCapabilities(this.orchestrator.config).namespaces) {
|
|
7423
7428
|
this.resolveReadableNamespace(namespace, principal);
|
|
7424
7429
|
results = collection === "global"
|
|
7425
7430
|
? await this.orchestrator.qmd.searchGlobal(query, maxResults)
|
|
@@ -8162,7 +8167,7 @@ export class EngramAccessService {
|
|
|
8162
8167
|
namespace: string;
|
|
8163
8168
|
storage: StorageManager;
|
|
8164
8169
|
}> {
|
|
8165
|
-
if (this.orchestrator.config.
|
|
8170
|
+
if (resolveNamespaceCapabilities(this.orchestrator.config).namespaces && !principal?.trim()) {
|
|
8166
8171
|
throw new EngramAccessInputError(
|
|
8167
8172
|
"authentication required: namespaces are enabled and no principal was supplied",
|
|
8168
8173
|
);
|
|
@@ -8902,7 +8907,7 @@ export class EngramAccessService {
|
|
|
8902
8907
|
actor?: never; // ignored — actor is derived from the authenticated principal
|
|
8903
8908
|
}) {
|
|
8904
8909
|
const config = this.orchestrator.config;
|
|
8905
|
-
const namespacesEnabled = config.
|
|
8910
|
+
const namespacesEnabled = resolveNamespaceCapabilities(config).namespaces === true;
|
|
8906
8911
|
// Fix OdCl3: when no namespace is supplied, resolve the source via the
|
|
8907
8912
|
// scope plan (principal self / scope-profile write layer / coding overlay)
|
|
8908
8913
|
// instead of falling through to config.defaultNamespace. This matches the
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { resolveNamespaceCapabilities } from "./capabilities.js";
|
|
1
2
|
import { canReadNamespace, defaultNamespaceForPrincipal, resolvePrincipal } from "./namespaces/principal.js";
|
|
2
3
|
import type { MemoryFile, PluginConfig } from "./types.js";
|
|
3
4
|
import { collapseWhitespace, truncateCodePointSafe } from "./whitespace.js";
|
|
@@ -106,7 +107,7 @@ function resolveActiveMemoryNamespace(
|
|
|
106
107
|
typeof orchestrator.resolvePrincipal === "function"
|
|
107
108
|
? orchestrator.resolvePrincipal(sessionKey)
|
|
108
109
|
: resolvePrincipal(sessionKey, config);
|
|
109
|
-
if (config.
|
|
110
|
+
if (resolveNamespaceCapabilities(config).namespaces && !principal) {
|
|
110
111
|
throw new Error("authentication required: namespaces are enabled and no principal was supplied");
|
|
111
112
|
}
|
|
112
113
|
if (explicitNamespace) {
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
* NamespaceSearchRouter health. No new scope-resolution or namespace-listing
|
|
24
24
|
* logic is introduced.
|
|
25
25
|
*/
|
|
26
|
+
import { resolveNamespaceCapabilities } from "../capabilities.js";
|
|
26
27
|
import path from "node:path";
|
|
27
28
|
import type { NamespaceCatalog, NamespaceRecord } from "../namespaces/catalog.js";
|
|
28
29
|
import { canReadNamespace, canWriteNamespace } from "../namespaces/principal.js";
|
|
@@ -190,7 +191,7 @@ export function inspectScope(options: InspectScopeOptions): ScopeInspection {
|
|
|
190
191
|
const { config } = options;
|
|
191
192
|
// Honour the pre-read flag when the caller supplied one (avoids a scattered
|
|
192
193
|
// read here); fall back to the config flag for direct callers (tests/CLI).
|
|
193
|
-
const namespacesEnabled = options.namespacesEnabled ?? config.
|
|
194
|
+
const namespacesEnabled = options.namespacesEnabled ?? resolveNamespaceCapabilities(config).namespaces === true;
|
|
194
195
|
|
|
195
196
|
const plan = resolveScopePlan({
|
|
196
197
|
config,
|
package/src/capabilities.test.ts
CHANGED
|
@@ -5,8 +5,16 @@ import { parseConfig } from "./config.js";
|
|
|
5
5
|
import {
|
|
6
6
|
resolveCapabilities,
|
|
7
7
|
resolveAccessSetupCapabilities,
|
|
8
|
+
resolveNamespaceCapabilities,
|
|
9
|
+
resolveQmdCapabilities,
|
|
10
|
+
resolveIdentityContinuityCapabilities,
|
|
11
|
+
resolveLocalLlmCapabilities,
|
|
8
12
|
type CapabilitySet,
|
|
9
13
|
type AccessSetupCapabilitySet,
|
|
14
|
+
type NamespaceCapabilitySet,
|
|
15
|
+
type QmdCapabilitySet,
|
|
16
|
+
type IdentityContinuityCapabilitySet,
|
|
17
|
+
type LocalLlmCapabilitySet,
|
|
10
18
|
} from "./capabilities.js";
|
|
11
19
|
|
|
12
20
|
/**
|
|
@@ -646,3 +654,173 @@ test("resolveCreationMemoryCapabilities matches pre-migration config reads (pari
|
|
|
646
654
|
}
|
|
647
655
|
}
|
|
648
656
|
});
|
|
657
|
+
|
|
658
|
+
// ---------------------------------------------------------------------------
|
|
659
|
+
// Namespace capability set parity tests (issue #1523 batch 5).
|
|
660
|
+
//
|
|
661
|
+
// Guard: resolveNamespaceCapabilities(config).namespaces must always equal
|
|
662
|
+
// config.namespacesEnabled. The flag is a non-optional boolean so no default
|
|
663
|
+
// coercion is needed.
|
|
664
|
+
// ---------------------------------------------------------------------------
|
|
665
|
+
|
|
666
|
+
test("resolveNamespaceCapabilities: namespaces === config.namespacesEnabled (parity)", () => {
|
|
667
|
+
const cases = [
|
|
668
|
+
{ label: "on", overrides: { namespacesEnabled: true } },
|
|
669
|
+
{ label: "off", overrides: { namespacesEnabled: false } },
|
|
670
|
+
];
|
|
671
|
+
|
|
672
|
+
for (const { label, overrides } of cases) {
|
|
673
|
+
const config = parseConfig(overrides);
|
|
674
|
+
const caps = resolveNamespaceCapabilities(config);
|
|
675
|
+
assert.equal(
|
|
676
|
+
caps.namespaces,
|
|
677
|
+
config.namespacesEnabled,
|
|
678
|
+
`[${label}] caps.namespaces must equal config.namespacesEnabled`,
|
|
679
|
+
);
|
|
680
|
+
}
|
|
681
|
+
});
|
|
682
|
+
|
|
683
|
+
test("resolveNamespaceCapabilities: result is frozen", () => {
|
|
684
|
+
const config = parseConfig({ namespacesEnabled: true });
|
|
685
|
+
const caps = resolveNamespaceCapabilities(config);
|
|
686
|
+
assert.ok(Object.isFrozen(caps), "NamespaceCapabilitySet must be frozen");
|
|
687
|
+
});
|
|
688
|
+
|
|
689
|
+
// ---------------------------------------------------------------------------
|
|
690
|
+
// QmdCapabilitySet — gate-parity tests (issue #1523 batch 6).
|
|
691
|
+
//
|
|
692
|
+
// Same invariant: every caps field must project from its `<field>Enabled`
|
|
693
|
+
// config flag. All twelve flags are required booleans on PluginConfig (defaults
|
|
694
|
+
// resolved at the parse boundary), so the projection is pure passthrough.
|
|
695
|
+
// ---------------------------------------------------------------------------
|
|
696
|
+
|
|
697
|
+
const QMD_FIELD_TO_FLAG: Record<keyof QmdCapabilitySet, string> = {
|
|
698
|
+
qmd: "qmdEnabled",
|
|
699
|
+
qmdTierMigration: "qmdTierMigrationEnabled",
|
|
700
|
+
qmdTierAutoBackfill: "qmdTierAutoBackfillEnabled",
|
|
701
|
+
qmdAutoEmbed: "qmdAutoEmbedEnabled",
|
|
702
|
+
qmdMaintenance: "qmdMaintenanceEnabled",
|
|
703
|
+
qmdColdTier: "qmdColdTierEnabled",
|
|
704
|
+
qmdDaemon: "qmdDaemonEnabled",
|
|
705
|
+
qmdTierParityGraph: "qmdTierParityGraphEnabled",
|
|
706
|
+
qmdQueryRerank: "qmdQueryRerankEnabled",
|
|
707
|
+
qmdIntentHints: "qmdIntentHintsEnabled",
|
|
708
|
+
qmdExplain: "qmdExplainEnabled",
|
|
709
|
+
qmdAutoUpgrade: "qmdAutoUpgradeEnabled",
|
|
710
|
+
};
|
|
711
|
+
|
|
712
|
+
const QMD_FIELDS = Object.keys(QMD_FIELD_TO_FLAG) as Array<keyof QmdCapabilitySet>;
|
|
713
|
+
|
|
714
|
+
test("resolveQmdCapabilities projects every field from its flag (true variant)", () => {
|
|
715
|
+
const overrides: Record<string, boolean> = {};
|
|
716
|
+
for (const flag of Object.values(QMD_FIELD_TO_FLAG)) overrides[flag] = true;
|
|
717
|
+
const config = parseConfig(overrides);
|
|
718
|
+
const caps = resolveQmdCapabilities(config);
|
|
719
|
+
|
|
720
|
+
for (const field of QMD_FIELDS) {
|
|
721
|
+
const flag = QMD_FIELD_TO_FLAG[field];
|
|
722
|
+
assert.equal(caps[field], true, `caps.${field} must be true when ${flag}=true`);
|
|
723
|
+
}
|
|
724
|
+
});
|
|
725
|
+
|
|
726
|
+
test("resolveQmdCapabilities projects every field from its flag (false variant)", () => {
|
|
727
|
+
const overrides: Record<string, boolean> = {};
|
|
728
|
+
for (const flag of Object.values(QMD_FIELD_TO_FLAG)) overrides[flag] = false;
|
|
729
|
+
const config = parseConfig(overrides);
|
|
730
|
+
const caps = resolveQmdCapabilities(config);
|
|
731
|
+
|
|
732
|
+
for (const field of QMD_FIELDS) {
|
|
733
|
+
const flag = QMD_FIELD_TO_FLAG[field];
|
|
734
|
+
assert.equal(caps[field], false, `caps.${field} must be false when ${flag}=false`);
|
|
735
|
+
}
|
|
736
|
+
});
|
|
737
|
+
|
|
738
|
+
test("resolveQmdCapabilities returns a frozen object", () => {
|
|
739
|
+
const config = parseConfig({});
|
|
740
|
+
const caps = resolveQmdCapabilities(config);
|
|
741
|
+
assert.equal(Object.isFrozen(caps), true);
|
|
742
|
+
});
|
|
743
|
+
|
|
744
|
+
test("resolveQmdCapabilities matches pre-migration config reads (parity contract)", () => {
|
|
745
|
+
const cases: Record<string, Record<string, boolean>> = {
|
|
746
|
+
"all-off": Object.fromEntries(Object.values(QMD_FIELD_TO_FLAG).map((f) => [f, false])),
|
|
747
|
+
"all-on": Object.fromEntries(Object.values(QMD_FIELD_TO_FLAG).map((f) => [f, true])),
|
|
748
|
+
"qmd-on-rest-off": {
|
|
749
|
+
...Object.fromEntries(Object.values(QMD_FIELD_TO_FLAG).map((f) => [f, false])),
|
|
750
|
+
qmdEnabled: true,
|
|
751
|
+
},
|
|
752
|
+
"tiers-on-qmd-off": {
|
|
753
|
+
...Object.fromEntries(Object.values(QMD_FIELD_TO_FLAG).map((f) => [f, false])),
|
|
754
|
+
qmdTierMigrationEnabled: true,
|
|
755
|
+
qmdColdTierEnabled: true,
|
|
756
|
+
},
|
|
757
|
+
};
|
|
758
|
+
|
|
759
|
+
for (const [label, overrides] of Object.entries(cases)) {
|
|
760
|
+
const config = parseConfig(overrides);
|
|
761
|
+
const caps = resolveQmdCapabilities(config);
|
|
762
|
+
|
|
763
|
+
for (const field of QMD_FIELDS) {
|
|
764
|
+
const flag = QMD_FIELD_TO_FLAG[field];
|
|
765
|
+
assert.equal(
|
|
766
|
+
caps[field],
|
|
767
|
+
(config as unknown as Record<string, boolean>)[flag],
|
|
768
|
+
`[${label}] caps.${field} must equal config.${flag}`,
|
|
769
|
+
);
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
});
|
|
773
|
+
|
|
774
|
+
// ---------------------------------------------------------------------------
|
|
775
|
+
// IdentityContinuityCapabilitySet — gate-parity tests (issue #1523 batch 6).
|
|
776
|
+
// ---------------------------------------------------------------------------
|
|
777
|
+
|
|
778
|
+
test("resolveIdentityContinuityCapabilities: identityContinuity === config.identityContinuityEnabled (parity)", () => {
|
|
779
|
+
const cases = [
|
|
780
|
+
{ label: "on", overrides: { identityContinuityEnabled: true } },
|
|
781
|
+
{ label: "off", overrides: { identityContinuityEnabled: false } },
|
|
782
|
+
];
|
|
783
|
+
|
|
784
|
+
for (const { label, overrides } of cases) {
|
|
785
|
+
const config = parseConfig(overrides);
|
|
786
|
+
const caps = resolveIdentityContinuityCapabilities(config);
|
|
787
|
+
assert.equal(
|
|
788
|
+
caps.identityContinuity,
|
|
789
|
+
config.identityContinuityEnabled,
|
|
790
|
+
`[${label}] caps.identityContinuity must equal config.identityContinuityEnabled`,
|
|
791
|
+
);
|
|
792
|
+
}
|
|
793
|
+
});
|
|
794
|
+
|
|
795
|
+
test("resolveIdentityContinuityCapabilities: result is frozen", () => {
|
|
796
|
+
const config = parseConfig({ identityContinuityEnabled: true });
|
|
797
|
+
const caps = resolveIdentityContinuityCapabilities(config);
|
|
798
|
+
assert.ok(Object.isFrozen(caps), "IdentityContinuityCapabilitySet must be frozen");
|
|
799
|
+
});
|
|
800
|
+
|
|
801
|
+
// ---------------------------------------------------------------------------
|
|
802
|
+
// LocalLlmCapabilitySet — gate-parity tests (issue #1523 batch 6).
|
|
803
|
+
// ---------------------------------------------------------------------------
|
|
804
|
+
|
|
805
|
+
test("resolveLocalLlmCapabilities: localLlm === config.localLlmEnabled (parity)", () => {
|
|
806
|
+
const cases = [
|
|
807
|
+
{ label: "on", overrides: { localLlmEnabled: true } },
|
|
808
|
+
{ label: "off", overrides: { localLlmEnabled: false } },
|
|
809
|
+
];
|
|
810
|
+
|
|
811
|
+
for (const { label, overrides } of cases) {
|
|
812
|
+
const config = parseConfig(overrides);
|
|
813
|
+
const caps = resolveLocalLlmCapabilities(config);
|
|
814
|
+
assert.equal(
|
|
815
|
+
caps.localLlm,
|
|
816
|
+
config.localLlmEnabled,
|
|
817
|
+
`[${label}] caps.localLlm must equal config.localLlmEnabled`,
|
|
818
|
+
);
|
|
819
|
+
}
|
|
820
|
+
});
|
|
821
|
+
|
|
822
|
+
test("resolveLocalLlmCapabilities: result is frozen", () => {
|
|
823
|
+
const config = parseConfig({ localLlmEnabled: true });
|
|
824
|
+
const caps = resolveLocalLlmCapabilities(config);
|
|
825
|
+
assert.ok(Object.isFrozen(caps), "LocalLlmCapabilitySet must be frozen");
|
|
826
|
+
});
|