From 3e1ef957bcfd7ed8dfb752c23b326dde29bee849 Mon Sep 17 00:00:00 2001 From: David Snelling Date: Tue, 9 Jun 2026 13:12:39 -0700 Subject: [PATCH] refactor(8.0): strictConfig + brain.stats() vector field + wireConnectionsCodec feature-detect (scaffold step 5) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Step 5 of the brainy 8.0 rename scaffolding. Three small additions, all honoring contracts locked in handoff thread BRAINY-8.0-RENAME-COORDINATION: A. strictConfig: boolean | 'warn' (§ B.6) src/types/brainy.types.ts - New BrainyConfig.strictConfig field. Three tiers: - false: no enforcement (knob mismatches silently accepted) - 'warn' (8.0 default): one-shot warning per call site listing ignored knobs + escape-valve recipe + docs link - true: hard error at init() - Format matches the 7.30.1 teaching-error pattern (problem → escape valves → caller location → docs link). - Applies to ALL provider knob mismatches, not just vector (e.g. config.aggregation.x with no aggregation provider). src/brainy.ts - normalizeConfig() defaults to 'warn'. Wiring into the actual enforcement sites lands in the final cleanup commit alongside the removal of legacy knob names. B. brain.stats().indexHealth.vector (§ planning § 2.6) src/types/brainy.types.ts - BrainyStats.indexHealth gains a new `vector: boolean` field. Existing `hnsw: boolean` field marked @deprecated; same boolean, kept as a compat alias until the final cleanup. src/brainy.ts:6272 - Implementation populates both `hnsw` and `vector` from the same `vectorHealthy` boolean. Refactored to async IIFE so the graph-size await sits cleanly alongside the new field. C. wireConnectionsCodec feature-detect (integration doc lines 459-461) src/brainy.ts:9469-9486 - Added `typeof this.index.setConnectionsCodec === 'function'` guard before invoking. Native vector-index providers (DiskANN-style) persist the graph as a single mmap'd file with no per-node connection lists and have no analogue. Pre-8.0 the wire was unconditional and relied on the native wrapper exposing a no-op method; 8.0 makes it feature-detected. NO-OP scope No behavioural change in scaffolding. brain.stats() now returns both field names (callers see the new field but the old still works). strictConfig is defaulted but not yet enforced. wireConnectionsCodec behaves identically when called against an impl that has the codec method (the JS HNSW path); guards cleanly against impls that don't. VERIFICATION - npx tsc --noEmit: clean - npm test: 1468 / 1468 unit --- src/brainy.ts | 27 ++++++++++++++++++++++----- src/types/brainy.types.ts | 27 +++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 5 deletions(-) diff --git a/src/brainy.ts b/src/brainy.ts index f998336a..344a4d86 100644 --- a/src/brainy.ts +++ b/src/brainy.ts @@ -6269,11 +6269,18 @@ export class Brainy implements BrainyInterface { relationCount, relationsByType, fieldRegistry, - indexHealth: { - hnsw: this.index.size() > 0 || entityCount === 0, - metadata: metadataStats.totalEntries > 0 || entityCount === 0, - graph: (await this.graphIndex.size()) > 0 || relationCount === 0 - }, + indexHealth: await (async () => { + // 8.0 rename: `vector` is the canonical name; `hnsw` is a compat + // alias that's removed in the final 8.0 cleanup commit. + const vectorHealthy = this.index.size() > 0 || entityCount === 0 + const graphSize = await this.graphIndex.size() + return { + hnsw: vectorHealthy, + vector: vectorHealthy, + metadata: metadataStats.totalEntries > 0 || entityCount === 0, + graph: graphSize > 0 || relationCount === 0 + } + })(), storage: { backend: storageBackend, rootDir: typeof rootDir === 'string' ? rootDir : undefined @@ -9304,6 +9311,9 @@ export class Brainy implements BrainyInterface { // { except: [...] }: strict, but listed types may omit subtype. // Becomes the default in 8.0.0. requireSubtype: config?.requireSubtype ?? false, + // Provider-knob mismatch strictness (8.0). Default is 'warn' (one-shot + // teaching message). See BRAINY-8.0-RENAME-COORDINATION § B.6. + strictConfig: config?.strictConfig ?? 'warn', // Multi-process safety mode: config?.mode ?? 'writer', force: config?.force ?? false @@ -9464,6 +9474,13 @@ export class Brainy implements BrainyInterface { const idMapper = this.metadataIndex.getIdMapper?.() if (!idMapper) return + // Feature-detect: only the JS HNSW path uses per-node connection lists. + // Native vector-index providers (DiskANN-style) persist the graph as a + // single mmap'd file and have no analogue, so skip the wiring there. + // Pre-8.0 the wire was unconditional and relied on the native wrapper + // exposing a no-op setConnectionsCodec(); 8.0 makes it feature-detected. + if (typeof (this.index as { setConnectionsCodec?: unknown }).setConnectionsCodec !== 'function') return + const codec = new ConnectionsCodec(provider, idMapper) this.index.setConnectionsCodec(codec) if (!this.config.silent) { diff --git a/src/types/brainy.types.ts b/src/types/brainy.types.ts index 2a792a87..b8249070 100644 --- a/src/types/brainy.types.ts +++ b/src/types/brainy.types.ts @@ -1031,7 +1031,10 @@ export interface BrainyStats { fieldRegistry: string[] /** Per-index health flags. `true` = index has entries OR no entities exist yet. */ indexHealth: { + /** @deprecated 8.0 — renamed to `vector`. Same boolean; kept as a compat alias until the final 8.0 cleanup. */ hnsw: boolean + /** Vector index health (8.0 name — open-core JS HNSW path or a native acceleration provider). */ + vector: boolean metadata: boolean graph: boolean } @@ -1246,6 +1249,30 @@ export interface BrainyConfig { */ requireSubtype?: boolean | { except: Array } + /** + * Validation strictness for provider-knob mismatches (Brainy 8.0). + * + * When a registered provider silently ignores a configuration knob the + * user passed (e.g. `config.vector.advanced.diskann.*` on the open-core JS + * HNSW path, or `config.vector.advanced.hnsw.*` on a native DiskANN-style + * path), the user otherwise gets no feedback that their override has no + * effect. This option controls the response: + * + * - `false` — no enforcement. Mismatched knobs are silently accepted. + * - `'warn'` — (default in 8.0) one-shot warning per call site via + * `prodLog.warn`, listing the ignored knobs and the docs link to the + * appropriate `advanced.*` escape hatch. + * - `true` — hard error at `init()`. Refuses to start until the config + * is consistent with the resolved provider impl. + * + * The warning / error format matches the 7.30.1 teaching-error pattern: + * problem → escape valves → caller location → docs link. + * + * **Contract** locked in handoff thread BRAINY-8.0-RENAME-COORDINATION + * § B.6 (cortex-confirmed 2026-06-09). + */ + strictConfig?: boolean | 'warn' + /** * Process role for multi-process safety on filesystem storage. *