@remnic/core 9.3.676 → 9.3.678

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 (92) hide show
  1. package/dist/access-cli.js +21 -21
  2. package/dist/access-http.js +16 -16
  3. package/dist/access-mcp.js +15 -15
  4. package/dist/access-schema.js +3 -3
  5. package/dist/access-service.js +13 -13
  6. package/dist/capabilities.d.ts +29 -1
  7. package/dist/capabilities.js +5 -3
  8. package/dist/causal-behavior.js +2 -2
  9. package/dist/causal-chain.js +2 -2
  10. package/dist/causal-consolidation.js +2 -2
  11. package/dist/causal-retrieval.js +2 -2
  12. package/dist/causal-trajectory-graph.js +1 -1
  13. package/dist/causal-trajectory.js +1 -1
  14. package/dist/{chunk-SDLJ2W7S.js → chunk-2AP4QJX5.js} +4 -4
  15. package/dist/{chunk-Y56J7CXW.js → chunk-2LDBXPLB.js} +10 -5
  16. package/dist/chunk-2LDBXPLB.js.map +1 -0
  17. package/dist/{chunk-ZLINDOBG.js → chunk-4PPMUNV5.js} +5 -5
  18. package/dist/{chunk-Q5ZU3RNY.js → chunk-57ME5VSI.js} +4 -4
  19. package/dist/{chunk-R37A3BEW.js → chunk-7AAKSHDG.js} +147 -122
  20. package/dist/chunk-7AAKSHDG.js.map +1 -0
  21. package/dist/{chunk-T2AOOHDA.js → chunk-ACYX37IM.js} +2 -2
  22. package/dist/{chunk-DOCTITOP.js → chunk-DGEZKYVI.js} +4 -4
  23. package/dist/{chunk-Q6MIDQEL.js → chunk-EQYP3HA6.js} +2 -2
  24. package/dist/{chunk-52LZ42LI.js → chunk-ERA5RSMZ.js} +1 -1
  25. package/dist/{chunk-SF45RQDX.js → chunk-K2JYO6QV.js} +4 -4
  26. package/dist/{chunk-IPLYGWQF.js → chunk-KQAFEZQX.js} +5 -5
  27. package/dist/{chunk-RI5XBIZ6.js → chunk-PBH4JUAB.js} +14 -2
  28. package/dist/{chunk-RI5XBIZ6.js.map → chunk-PBH4JUAB.js.map} +1 -1
  29. package/dist/{chunk-XVVEKF5I.js → chunk-PCGCQTU6.js} +22 -22
  30. package/dist/{chunk-B6IUW76R.js → chunk-Q2H5U37U.js} +1 -1
  31. package/dist/{chunk-WXGTC424.js → chunk-RC3AFF6Z.js} +1 -1
  32. package/dist/{chunk-HQCGRSRU.js → chunk-SECQS4G4.js} +2 -2
  33. package/dist/{chunk-QLRYXOAD.js → chunk-UDJLF3BO.js} +2 -2
  34. package/dist/{chunk-OG7A6AZX.js → chunk-UNZLU2MX.js} +4 -4
  35. package/dist/{chunk-B55KFEGS.js → chunk-YJ4J2JJ2.js} +10 -10
  36. package/dist/{chunk-NE566K4E.js → chunk-YXWAILM4.js} +2 -2
  37. package/dist/{chunk-OUWAQVDJ.js → chunk-Z6SEG36L.js} +4 -4
  38. package/dist/cli.js +25 -25
  39. package/dist/{coding-graph-types-Dd2tGrnm.d.ts → coding/coding-graph-types.d.ts} +1 -1
  40. package/dist/coding/coding-graph-types.js +10 -0
  41. package/dist/coding/coding-graph-types.js.map +1 -0
  42. package/dist/coding/optional-coding-graph.d.ts +2 -2
  43. package/dist/coding/optional-coding-graph.js +1 -1
  44. package/dist/compounding/engine.js +1 -1
  45. package/dist/contradiction/index.js +4 -4
  46. package/dist/{graph-edge-decay-PUFNHOBS.js → graph-edge-decay-KSVJGCZW.js} +2 -2
  47. package/dist/graph-snapshot.js +2 -2
  48. package/dist/graph.d.ts +11 -0
  49. package/dist/graph.js +1 -1
  50. package/dist/index.d.ts +1 -1
  51. package/dist/index.js +38 -38
  52. package/dist/lcm/index.js +3 -3
  53. package/dist/namespaces/migrate.js +8 -8
  54. package/dist/namespaces/search.js +7 -7
  55. package/dist/operator-toolkit.js +10 -10
  56. package/dist/orchestrator.js +17 -17
  57. package/dist/search/factory.js +6 -6
  58. package/dist/search/index.js +11 -11
  59. package/dist/search/lancedb-backend.js +2 -2
  60. package/dist/search/meilisearch-backend.js +2 -2
  61. package/dist/search/orama-backend.js +2 -2
  62. package/dist/transfer/autodetect.js +1 -1
  63. package/dist/transfer/backup.js +1 -1
  64. package/dist/transfer/capsule-export.js +2 -2
  65. package/package.json +7 -2
  66. package/src/capabilities.test.ts +173 -0
  67. package/src/capabilities.ts +61 -0
  68. package/src/graph.ts +20 -4
  69. package/src/orchestrator.ts +85 -208
  70. package/src/scopes/scope-plan.test.ts +360 -0
  71. package/src/scopes/scope-plan.ts +320 -0
  72. package/dist/chunk-R37A3BEW.js.map +0 -1
  73. package/dist/chunk-Y56J7CXW.js.map +0 -1
  74. /package/dist/{chunk-SDLJ2W7S.js.map → chunk-2AP4QJX5.js.map} +0 -0
  75. /package/dist/{chunk-ZLINDOBG.js.map → chunk-4PPMUNV5.js.map} +0 -0
  76. /package/dist/{chunk-Q5ZU3RNY.js.map → chunk-57ME5VSI.js.map} +0 -0
  77. /package/dist/{chunk-T2AOOHDA.js.map → chunk-ACYX37IM.js.map} +0 -0
  78. /package/dist/{chunk-DOCTITOP.js.map → chunk-DGEZKYVI.js.map} +0 -0
  79. /package/dist/{chunk-Q6MIDQEL.js.map → chunk-EQYP3HA6.js.map} +0 -0
  80. /package/dist/{chunk-52LZ42LI.js.map → chunk-ERA5RSMZ.js.map} +0 -0
  81. /package/dist/{chunk-SF45RQDX.js.map → chunk-K2JYO6QV.js.map} +0 -0
  82. /package/dist/{chunk-IPLYGWQF.js.map → chunk-KQAFEZQX.js.map} +0 -0
  83. /package/dist/{chunk-XVVEKF5I.js.map → chunk-PCGCQTU6.js.map} +0 -0
  84. /package/dist/{chunk-B6IUW76R.js.map → chunk-Q2H5U37U.js.map} +0 -0
  85. /package/dist/{chunk-WXGTC424.js.map → chunk-RC3AFF6Z.js.map} +0 -0
  86. /package/dist/{chunk-HQCGRSRU.js.map → chunk-SECQS4G4.js.map} +0 -0
  87. /package/dist/{chunk-QLRYXOAD.js.map → chunk-UDJLF3BO.js.map} +0 -0
  88. /package/dist/{chunk-OG7A6AZX.js.map → chunk-UNZLU2MX.js.map} +0 -0
  89. /package/dist/{chunk-B55KFEGS.js.map → chunk-YJ4J2JJ2.js.map} +0 -0
  90. /package/dist/{chunk-NE566K4E.js.map → chunk-YXWAILM4.js.map} +0 -0
  91. /package/dist/{chunk-OUWAQVDJ.js.map → chunk-Z6SEG36L.js.map} +0 -0
  92. /package/dist/{graph-edge-decay-PUFNHOBS.js.map → graph-edge-decay-KSVJGCZW.js.map} +0 -0
@@ -95,3 +95,176 @@ test("resolveCapabilities returns a frozen object", () => {
95
95
  const caps = resolveCapabilities(parseConfig({}));
96
96
  assert.equal(Object.isFrozen(caps), true, "CapabilitySet must be frozen");
97
97
  });
98
+
99
+ // ---------------------------------------------------------------------------
100
+ // GraphConstructionCapabilitySet — gate-parity tests (issue #1566 Cluster A).
101
+ //
102
+ // Same invariant as the recall CapabilitySet tests above: every caps field
103
+ // must project from its `<field>Enabled` config flag, so a future edit to
104
+ // `resolveGraphConstructionCapabilities` that maps a field to the wrong flag
105
+ // (or drops the `!== false` default for the optional session-adjacency flag)
106
+ // fails loudly here.
107
+ //
108
+ // Parity contract: a caps-resolved run and a config-derived run MUST produce
109
+ // identical boolean values for every gate — on AND off. These tests are the
110
+ // executable proof of that contract.
111
+ // ---------------------------------------------------------------------------
112
+
113
+ import {
114
+ resolveGraphConstructionCapabilities,
115
+ type GraphConstructionCapabilitySet,
116
+ } from "./capabilities.js";
117
+
118
+ const GRAPH_FIELD_TO_FLAG: Record<keyof GraphConstructionCapabilitySet, string> = {
119
+ entityGraph: "entityGraphEnabled",
120
+ timeGraph: "timeGraphEnabled",
121
+ causalGraph: "causalGraphEnabled",
122
+ multiGraphMemory: "multiGraphMemoryEnabled",
123
+ graphWriteSessionAdjacency: "graphWriteSessionAdjacencyEnabled",
124
+ };
125
+
126
+ const GRAPH_FIELDS = Object.keys(GRAPH_FIELD_TO_FLAG) as Array<
127
+ keyof GraphConstructionCapabilitySet
128
+ >;
129
+
130
+ test("resolveGraphConstructionCapabilities projects every field from its flag (true variant)", () => {
131
+ const overrides: Record<string, boolean> = {};
132
+ for (const flag of Object.values(GRAPH_FIELD_TO_FLAG)) overrides[flag] = true;
133
+ const config = parseConfig(overrides);
134
+ const graphCaps = resolveGraphConstructionCapabilities(config);
135
+
136
+ for (const field of GRAPH_FIELDS) {
137
+ const flag = GRAPH_FIELD_TO_FLAG[field];
138
+ assert.equal(
139
+ graphCaps[field],
140
+ (config as unknown as Record<string, boolean>)[flag],
141
+ `graphCaps.${field} must equal config.${flag} (true variant)`,
142
+ );
143
+ assert.equal(graphCaps[field], true, `graphCaps.${field} should be true here`);
144
+ }
145
+ });
146
+
147
+ test("resolveGraphConstructionCapabilities projects every field from its flag (false variant)", () => {
148
+ const overrides: Record<string, boolean> = {};
149
+ for (const flag of Object.values(GRAPH_FIELD_TO_FLAG)) overrides[flag] = false;
150
+ const config = parseConfig(overrides);
151
+ const graphCaps = resolveGraphConstructionCapabilities(config);
152
+
153
+ for (const field of GRAPH_FIELDS) {
154
+ const flag = GRAPH_FIELD_TO_FLAG[field];
155
+ assert.equal(
156
+ graphCaps[field],
157
+ (config as unknown as Record<string, boolean>)[flag],
158
+ `graphCaps.${field} must equal config.${flag} (false variant)`,
159
+ );
160
+ assert.equal(graphCaps[field], false, `graphCaps.${field} should be false here`);
161
+ }
162
+ });
163
+
164
+ test("resolveGraphConstructionCapabilities preserves graphWriteSessionAdjacency default-on when undefined", () => {
165
+ // graphWriteSessionAdjacencyEnabled is optional — `!== false` means
166
+ // default-ON. This is the exact semantics the migrated call site used
167
+ // (orchestrator.ts buildGraphEdge), and the parity test below verifies
168
+ // the caps resolver does not drift from it.
169
+ const config = parseConfig({});
170
+ const graphCaps = resolveGraphConstructionCapabilities(config);
171
+
172
+ assert.equal(
173
+ graphCaps.graphWriteSessionAdjacency,
174
+ config.graphWriteSessionAdjacencyEnabled !== false,
175
+ "graphWriteSessionAdjacency must be default-on unless explicitly false",
176
+ );
177
+ assert.equal(
178
+ graphCaps.graphWriteSessionAdjacency,
179
+ true,
180
+ "with no explicit override, graphWriteSessionAdjacency should be true",
181
+ );
182
+
183
+ // Explicit-false must propagate (not get swallowed by the default).
184
+ const disabled = parseConfig({ graphWriteSessionAdjacencyEnabled: false });
185
+ assert.equal(
186
+ resolveGraphConstructionCapabilities(disabled).graphWriteSessionAdjacency,
187
+ false,
188
+ "explicit false must disable graphWriteSessionAdjacency",
189
+ );
190
+ });
191
+
192
+ test("resolveGraphConstructionCapabilities returns a frozen object", () => {
193
+ const graphCaps = resolveGraphConstructionCapabilities(parseConfig({}));
194
+ assert.equal(Object.isFrozen(graphCaps), true, "GraphConstructionCapabilitySet must be frozen");
195
+ });
196
+
197
+ test("resolveGraphConstructionCapabilities matches pre-migration config reads (parity contract)", () => {
198
+ // This is the core parity test: for EVERY combination of the 5 cluster-A
199
+ // flags, the caps-resolved values MUST be identical to what the old
200
+ // scattered `this.config.<flag>Enabled` reads would have produced.
201
+ //
202
+ // We exercise representative combinations rather than the full 2^5 space
203
+ // (32 cases) to keep the test cheap, but we cover:
204
+ // - all-off (the "no graphs" baseline)
205
+ // - all-on (the "full graph" mode)
206
+ // - only entity graph
207
+ // - multiGraph off but others on (the recall-without-write split)
208
+ // - session-adjacency undefined vs explicit-false
209
+ const cases: Record<string, Record<string, boolean | undefined>> = {
210
+ "all-off": {
211
+ entityGraphEnabled: false,
212
+ timeGraphEnabled: false,
213
+ causalGraphEnabled: false,
214
+ multiGraphMemoryEnabled: false,
215
+ graphWriteSessionAdjacencyEnabled: false,
216
+ },
217
+ "all-on": {
218
+ entityGraphEnabled: true,
219
+ timeGraphEnabled: true,
220
+ causalGraphEnabled: true,
221
+ multiGraphMemoryEnabled: true,
222
+ graphWriteSessionAdjacencyEnabled: true,
223
+ },
224
+ "entity-only": {
225
+ entityGraphEnabled: true,
226
+ timeGraphEnabled: false,
227
+ causalGraphEnabled: false,
228
+ multiGraphMemoryEnabled: true,
229
+ graphWriteSessionAdjacencyEnabled: true,
230
+ },
231
+ "multigraph-off": {
232
+ entityGraphEnabled: true,
233
+ timeGraphEnabled: true,
234
+ causalGraphEnabled: true,
235
+ multiGraphMemoryEnabled: false,
236
+ graphWriteSessionAdjacencyEnabled: true,
237
+ },
238
+ "session-adj-undefined": {
239
+ entityGraphEnabled: true,
240
+ timeGraphEnabled: true,
241
+ causalGraphEnabled: true,
242
+ multiGraphMemoryEnabled: true,
243
+ // graphWriteSessionAdjacencyEnabled deliberately omitted
244
+ },
245
+ };
246
+
247
+ for (const [label, overrides] of Object.entries(cases)) {
248
+ const config = parseConfig(overrides);
249
+ const graphCaps = resolveGraphConstructionCapabilities(config);
250
+
251
+ // Parity: each caps field must equal the pre-migration config read.
252
+ // entityGraph/timeGraph/causalGraph/multiGraphMemory used bare reads:
253
+ // config.entityGraphEnabled → graphCaps.entityGraph
254
+ // graphWriteSessionAdjacency used `!== false`:
255
+ // config.graphWriteSessionAdjacencyEnabled !== false → graphCaps.graphWriteSessionAdjacency
256
+ assert.equal(graphCaps.entityGraph, config.entityGraphEnabled, `[${label}] entityGraph parity`);
257
+ assert.equal(graphCaps.timeGraph, config.timeGraphEnabled, `[${label}] timeGraph parity`);
258
+ assert.equal(graphCaps.causalGraph, config.causalGraphEnabled, `[${label}] causalGraph parity`);
259
+ assert.equal(
260
+ graphCaps.multiGraphMemory,
261
+ config.multiGraphMemoryEnabled,
262
+ `[${label}] multiGraphMemory parity`,
263
+ );
264
+ assert.equal(
265
+ graphCaps.graphWriteSessionAdjacency,
266
+ config.graphWriteSessionAdjacencyEnabled !== false,
267
+ `[${label}] graphWriteSessionAdjacency parity (must match !== false)`,
268
+ );
269
+ }
270
+ });
@@ -84,3 +84,64 @@ export function resolveCapabilities(config: PluginConfig): CapabilitySet {
84
84
  graphExpandedIntent: config.graphExpandedIntentEnabled === true,
85
85
  });
86
86
  }
87
+
88
+ // ---------------------------------------------------------------------------
89
+ // Graph-construction capability set (issue #1566 Cluster A).
90
+ //
91
+ // The recall CapabilitySet above covers flags whose EVERY read site lives on
92
+ // the recall call chain. The five flags below are read on graph-construction,
93
+ // write/extraction, AND recall paths — so they cannot join the recall set
94
+ // without leaving some sites on `caps.` and others on `config.` (the exact
95
+ // divergence #1523 forbade). They get their own projection, resolved at graph
96
+ // build/write entry (and alongside `caps` when recall reads them).
97
+ // ---------------------------------------------------------------------------
98
+
99
+ /**
100
+ * Frozen projection of graph-construction feature gates.
101
+ *
102
+ * Every field is `readonly boolean`. Composition (including default-when-
103
+ * undefined semantics for the optional `graphWriteSessionAdjacencyEnabled`)
104
+ * lives ONLY in {@link resolveGraphConstructionCapabilities}.
105
+ */
106
+ export interface GraphConstructionCapabilitySet {
107
+ /** `entityGraphEnabled` — maintain entity co-reference graph edges. */
108
+ readonly entityGraph: boolean;
109
+ /** `timeGraphEnabled` — maintain thread-adjacency graph edges. */
110
+ readonly timeGraph: boolean;
111
+ /** `causalGraphEnabled` — maintain causal-language graph edges. */
112
+ readonly causalGraph: boolean;
113
+ /** `multiGraphMemoryEnabled` — master switch for multi-graph writes/traversal. */
114
+ readonly multiGraphMemory: boolean;
115
+ /** `graphWriteSessionAdjacencyEnabled` — session-adjacency fallback for time edges (default-on). */
116
+ readonly graphWriteSessionAdjacency: boolean;
117
+ }
118
+
119
+ /**
120
+ * Resolve the {@link GraphConstructionCapabilitySet} from parsed config.
121
+ *
122
+ * Call this ONCE at graph build/write entry (extraction, recall graph
123
+ * expansion, graph-health/repair) and thread the result down — exactly the
124
+ * pattern {@link resolveCapabilities} established for recall.
125
+ */
126
+ export type GraphConstructionConfigProjection = Pick<
127
+ PluginConfig,
128
+ | "entityGraphEnabled"
129
+ | "timeGraphEnabled"
130
+ | "causalGraphEnabled"
131
+ | "multiGraphMemoryEnabled"
132
+ | "graphWriteSessionAdjacencyEnabled"
133
+ >;
134
+
135
+ export function resolveGraphConstructionCapabilities(
136
+ config: GraphConstructionConfigProjection,
137
+ ): GraphConstructionCapabilitySet {
138
+ return Object.freeze({
139
+ entityGraph: config.entityGraphEnabled,
140
+ timeGraph: config.timeGraphEnabled,
141
+ causalGraph: config.causalGraphEnabled,
142
+ multiGraphMemory: config.multiGraphMemoryEnabled,
143
+ // Optional flag: preserve the exact default-when-undefined semantics the
144
+ // migrated call site used (`!== false` = default-on).
145
+ graphWriteSessionAdjacency: config.graphWriteSessionAdjacencyEnabled !== false,
146
+ });
147
+ }
package/src/graph.ts CHANGED
@@ -424,13 +424,29 @@ export class GraphIndex {
424
424
  recentInThread?: string[];
425
425
  entitySiblings?: string[];
426
426
  causalPredecessor?: string;
427
+ /**
428
+ * Optional frozen gate overrides (from GraphConstructionCapabilitySet).
429
+ * When provided, these take precedence over `this.cfg` so the caller's
430
+ * operation-scoped snapshot is the single source of truth (#1566).
431
+ */
432
+ graphCapsOverride?: {
433
+ entityGraph: boolean;
434
+ timeGraph: boolean;
435
+ causalGraph: boolean;
436
+ multiGraphMemory: boolean;
437
+ };
427
438
  }): Promise<void> {
428
- if (!this.cfg.multiGraphMemoryEnabled) return;
439
+ const g = opts.graphCapsOverride;
440
+ const multiGraphOn = g ? g.multiGraphMemory : this.cfg.multiGraphMemoryEnabled;
441
+ if (!multiGraphOn) return;
442
+ const entityOn = g ? g.entityGraph : this.cfg.entityGraphEnabled;
443
+ const timeOn = g ? g.timeGraph : this.cfg.timeGraphEnabled;
444
+ const causalOn = g ? g.causalGraph : this.cfg.causalGraphEnabled;
429
445
  const ts = new Date().toISOString();
430
446
 
431
447
  try {
432
448
  // Entity graph
433
- if (this.cfg.entityGraphEnabled && opts.entityRef && opts.entitySiblings?.length) {
449
+ if (entityOn && opts.entityRef && opts.entitySiblings?.length) {
434
450
  const siblings = opts.entitySiblings.slice(0, this.cfg.maxEntityGraphEdgesPerMemory);
435
451
  for (const sibling of siblings) {
436
452
  await appendEdge(this.memoryDir, {
@@ -445,7 +461,7 @@ export class GraphIndex {
445
461
  }
446
462
 
447
463
  // Time graph — link to most recent memory in same thread
448
- if (this.cfg.timeGraphEnabled && opts.threadId && opts.recentInThread?.length) {
464
+ if (timeOn && opts.threadId && opts.recentInThread?.length) {
449
465
  const predecessor = opts.recentInThread[opts.recentInThread.length - 1];
450
466
  if (predecessor && predecessor !== opts.memoryPath) {
451
467
  await appendEdge(this.memoryDir, {
@@ -460,7 +476,7 @@ export class GraphIndex {
460
476
  }
461
477
 
462
478
  // Causal graph
463
- if (this.cfg.causalGraphEnabled && opts.causalPredecessor) {
479
+ if (causalOn && opts.causalPredecessor) {
464
480
  const phrase = detectCausalPhrase(opts.content);
465
481
  if (phrase) {
466
482
  await appendEdge(this.memoryDir, {