refactor(8.0): API-surface + quality polish from the readiness audit

- find() search-mode: collapsed the two overlapping options to one canonical
  `searchMode: SearchMode` (the redundant `mode` alias was silently ignored on
  the primary find() path while honored on the historical path — a footgun) and
  removed the unwired `explain?` FindParams field (never read by find()).
- Documentation accuracy on the public type surface: entity ids documented as
  UUID v7 (auto) / v5 (natural key), not v4; dropped the stale "Brainy 3.0"
  banners and "backward compatibility" hedging on the fresh-8.0 Result type;
  documented the via/type alias; removed the dead GraphConstraints.bidirectional;
  fixed the no-op `EmbeddedGraphVerb = Omit<GraphVerb,'source'>` to omit the real
  sourceId; corrected the GraphIndexProvider.isInitialized JSDoc; documented
  removeMany's per-chunk generation granularity; JSDoc'd the public VFS surface.
- Honest perf comments in source: removed unmeasured billion-scale figures from
  the LSMTree / graphAdjacencyIndex headers (the JS fallback is in-memory after
  open; native is the scale path).
- Robustness: getVerbMetadata propagates read errors symmetrically with
  getNounMetadata; the find() egress integrity-guard keeps a row when the JS
  matcher doesn't implement an operator the provider already matched on; hardened
  the boundary-no-native CI guard to catch side-effect imports + re-exports.
- Tests: de-theatricalized a relateMany test to assert the real contract; fixed
  a stale Model-B header.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
David Snelling 2026-06-29 10:04:19 -07:00
parent 47e8031124
commit a52dba2168
10 changed files with 346 additions and 45 deletions

View file

@ -1,6 +1,10 @@
/**
* 🧠 Brainy 3.0 Type Definitions
*
* @module types/brainy.types
* @description Public type definitions for the Brainy API the entity/relation
* shapes, the `find()`/`add()`/`relate()` parameter and result types, and the
* configuration surface. (Version-agnostic header: these track the package
* version, not a fixed number.)
*
* Beautiful, consistent, type-safe interfaces for the future of neural databases
*/
@ -27,7 +31,7 @@ import type {
* alongside user metadata but extracted to top-level Entity fields on read.
*/
export interface Entity<T = any> {
/** Unique identifier (UUID v4) */
/** Unique identifier — a UUID (auto-generated as a time-ordered v7; a supplied natural key is normalized to a stable v5). */
id: string
/** Embedding vector (384-dim by default). Empty array when loaded without includeVectors. */
vector: Vector
@ -140,8 +144,8 @@ export interface RelationEvidence {
/**
* Search result with similarity score
*
* Flattens commonly-used entity fields to top level for convenience,
* while preserving full entity in 'entity' field for backward compatibility.
* Flattens commonly-used entity fields to the top level for convenience, while
* keeping the complete record under `entity` for callers that need the full shape.
*/
export interface Result<T = any> {
// Search metadata
@ -158,7 +162,7 @@ export interface Result<T = any> {
weight?: number // Entity importance (from entity.weight)
_rev?: number // Monotonic revision counter (from entity._rev) — pass back as update({ ifRev }) for CAS
// Full entity (preserved for backward compatibility)
// Full entity record (the flattened fields above are projections of this)
entity: Entity<T>
// Score transparency
@ -173,8 +177,8 @@ export interface Result<T = any> {
// Aggregation: present only on rows returned by find({ aggregate }). These mirror the
// documented AggregateResult shape so callers can read group/metric data at the top level
// instead of digging into `metadata`. (The same values are also flattened into `metadata`
// for backward compatibility.)
// instead of digging into `metadata`. (The same values are also mirrored into `metadata`
// so aggregate-unaware callers still see them.)
groupKey?: Record<string, string | number> // Group-by key values for this aggregate row
metrics?: Record<string, number> // Computed metric values (sum/avg/min/max/count)
count?: number // Total entity count in this group
@ -327,7 +331,7 @@ export interface AddParams<T = any> {
* a one-shot warning.
*/
metadata?: EntityMetadataInput<T>
/** Custom entity ID (auto-generated UUID v4 if not provided) */
/** Custom entity ID. When omitted, a time-ordered UUID v7 is generated; a supplied natural-key string is normalized to a stable UUID v5. */
id?: string
/** Pre-computed embedding vector (skips auto-embedding when provided) */
vector?: Vector
@ -551,8 +555,6 @@ export interface FindParams<T = any> {
order?: 'asc' | 'desc' // Sort direction: 'asc' (default) or 'desc'
// Advanced options
mode?: SearchMode // Search strategy
explain?: boolean // Return scoring explanation
includeRelations?: boolean // Include entity relationships
excludeVFS?: boolean // Exclude VFS entities from results (default: false - VFS included)
service?: string // Multi-tenancy filter
@ -566,7 +568,12 @@ export interface FindParams<T = any> {
includeVectors?: boolean
// Hybrid search options
searchMode?: 'auto' | 'text' | 'semantic' | 'vector' | 'hybrid' // Search strategy: auto (default), text-only, semantic/vector-only, or explicit hybrid
/**
* Search strategy the single canonical search-mode knob (the redundant `mode`
* alias was removed in 8.0). `'auto'` (default) blends text + semantic; the
* other members force a single intelligence. See {@link SearchMode}.
*/
searchMode?: SearchMode
hybridAlpha?: number // Weight between text (0.0) and semantic (1.0) search, default: auto-detected by query length
// Triple Intelligence Fusion
@ -593,8 +600,8 @@ export interface FindParams<T = any> {
export interface GraphConstraints {
to?: string // Connected to this entity
from?: string // Connected from this entity
via?: VerbType | VerbType[] // Via these relationship types
type?: VerbType | VerbType[] // Alias for via
via?: VerbType | VerbType[] // Traverse via these relationship types (the canonical key)
type?: VerbType | VerbType[] // Accepted alias for `via` (resolved identically: `via ?? type`)
/**
* Filter traversal edges by VerbType subtype. Single string for equality,
* array for set membership. Composes with `via` `{ via: 'manages', subtype:
@ -604,7 +611,6 @@ export interface GraphConstraints {
subtype?: string | string[]
depth?: number // Max traversal depth (default: 1)
direction?: 'in' | 'out' | 'both' // Direction of traversal (default: 'both')
bidirectional?: boolean // Consider both directions
}
/**

View file

@ -399,10 +399,12 @@ export interface GraphVerb {
}
/**
* Version of GraphVerb for embedded relationships
* Used when the source is implicit from the parent document
* A {@link GraphVerb} for relationships embedded under a parent noun, where the
* source is implicit (the parent), so `sourceId` is dropped. (`GraphVerb` has no
* `source` field the prior `Omit<GraphVerb, 'source'>` was a no-op that left the
* shape identical to `GraphVerb`; this omits the real `sourceId`.)
*/
export type EmbeddedGraphVerb = Omit<GraphVerb, 'source'>
export type EmbeddedGraphVerb = Omit<GraphVerb, 'sourceId'>
// Proper Noun interfaces - extend GraphNoun with specific noun types