brainy/docs/architecture/zero-config.md
David Snelling 606445cd61 feat(8.0): API simplification — remove neural()/Db.search, one storage path key, integration→0
8.0 RC cleanup toward "one place per thing, zero-config, no deprecation":

- Remove the `brain.neural()` clustering namespace (ImprovedNeuralAPI + the dead
  legacy NeuralAPI + the neural CLI + neural-only types). Similarity is `find({vector})`
  / `similar({to})`; attribute grouping is the aggregation `GROUP BY` engine. The separate
  entity-extraction / smart-import feature (NeuralImport, NeuralEntityExtractor, SmartExtractor,
  NaturalLanguageProcessor, `brain.extract()`/`brain.nlp()`) is kept.
- Remove `Db.search()`; `find()` is the one query verb (accepts a bare string or FindParams).
  Fix the bundled MCP client, which called a non-existent `brain.search(query, limit)` →
  now `find({ query, limit })`.
- Storage config: collapse to one canonical top-level `path` key. The pre-8.0 aliases
  (`rootDirectory`, `options.*`, `fileSystemStorage.*`) are removed and now THROW with the
  exact rename instead of silently defaulting to `./brainy-data` on upgrade. A single resolver
  feeds createStorage, the 7.x→8.0 migration probe, and the plugin-factory handoff, so a native
  storage provider resolves the identical root (no split-brain).
- Fix `similar({ threshold })`: the min-similarity filter was silently dropped; it is now
  applied as a post-filter on `result.score` (the documented way to bound semantic results).
- Fix `vfs.rename()` on a directory: child path updates spread the entity vector into `update()`
  and failed dimension validation; they are metadata-only updates now.
- Fix `vfs.move()`: copy+delete orphaned the content-addressed content blob (the destination
  shared the source hash, then unlink removed it). `move()` now delegates to `rename()` — an
  in-place path change that preserves the blob and the entity id, for files and directories.
- Fix streaming import: the bulk fast path never flushed mid-import nor signalled queryability.
  Entity writes are now chunked by a progressive flush interval (100 → 1000 → 5000); each chunk
  flushes and emits `progress.queryable`, so imported data is queryable during the import.
- Sweep all docs, comments, and JSDoc for the removed/changed APIs.

Integration suite: 49 files / 588 passed / 0 failed. Unit: 80 files / 1456 passed, no type errors.
2026-06-20 13:31:11 -07:00

5.1 KiB

title slug public category template order description next
Zero Configuration concepts/zero-config false concepts concept 3 Brainy auto-detects storage, initializes embeddings, and builds indexes — no configuration required. Works in Node.js and Bun (server-only since 8.0).
getting-started/installation
guides/storage-adapters

Zero Configuration & Auto-Adaptation

"Zero config by default, fully tunable when you need it." Construct a Brainy() with no options and it picks sensible, environment-aware defaults. Every default below is overridable through the constructor — see the API Reference.

Overview

Brainy 8.0 is server-only (Node.js 22+ / Bun). With no configuration it:

  • selects a storage adapter from the runtime,
  • initializes the embedding model (all-MiniLM-L6-v2, 384 dimensions),
  • builds and maintains the metadata, graph, and vector indexes,
  • sizes its caches and write buffers to the detected memory budget,
  • chooses a persistence mode that matches the storage backend, and
  • quiets its own logging when it detects a production environment.

There is no public config-generation function — adaptation happens inside the constructor and init().

Instant Start

import { Brainy } from '@soulcraft/brainy'

// That's it. No config needed.
const brain = new Brainy()
await brain.init()

await brain.add({ data: 'First entity', type: 'concept' })
const results = await brain.find('first')

What Auto-Adaptation Covers

1. Storage auto-detection

With no storage option, Brainy uses type: 'auto':

  • Filesystem when running on a runtime with a writable Node filesystem and a resolvable root directory. This is the default for typical Node/Bun servers and persists across restarts.
  • In-memory otherwise (no filesystem access, or an explicit memory request). Fast, zero I/O, discarded on process exit — ideal for tests and ephemeral caches.

8.0 ships exactly two storage adapters — memory and filesystem — plus the auto selector that resolves to one of them. See Storage Adapters for the full contract.

// Explicit override when you want a specific root
const brain = new Brainy({
  storage: { type: 'filesystem', path: './brainy-data' }
})

2. HNSW quality from the recall preset

Vector-index quality comes from a single preset rather than hand-tuned graph parameters. config.vector.recall accepts 'fast', 'balanced', or 'accurate' and defaults to 'balanced'. The preset maps internally to the HNSW construction and search parameters (M / efConstruction / efSearch), so you trade recall against latency with one knob instead of three.

const brain = new Brainy({
  vector: { recall: 'fast' } // favor latency over recall
})

The default JS index is JsHnswVectorIndex. An optional native acceleration provider (the @soulcraft/cortex package) can replace it with a higher-performing implementation; the public knobs stay the same. Quantization and other index-internal acceleration are the native provider's concern, not a Brainy configuration option.

3. Persistence mode follows the backend

config.vector.persistMode accepts 'immediate' or 'deferred'. Left unset, Brainy chooses for you:

  • Immediate on filesystem storage, so the index file stays in lock-step with the data and survives a crash.
  • Deferred on in-memory storage, where there is nothing durable to sync to, so writes are batched for throughput.
const brain = new Brainy({
  vector: { persistMode: 'deferred' } // batch persistence for write-heavy loads
})

4. Memory-aware cache and buffer sizing

Brainy reads the container's memory budget — CLOUD_RUN_MEMORY, MEMORY_LIMIT, or the cgroup memory limit when running in a container — and sizes its read caches and write buffers to fit. On a small instance it stays conservative; on a large one it uses more of the available headroom. Query-result limits are capped against the same budget (roughly 25 KB per result) to keep a single oversized query from exhausting memory.

You can pin the cache explicitly:

const brain = new Brainy({
  cache: { maxSize: 10000, ttl: 3_600_000 }
})

5. Logging quiets in production

Brainy detects production-style environments (for example NODE_ENV set to a non-development value) and reduces its own log verbosity automatically. This is logging-only behavior — it does not change indexing, storage, or query results.

Configuration Override

Zero-config is the default, not a ceiling. Every adaptive decision above has an explicit constructor option:

const brain = new Brainy({
  storage: { type: 'filesystem', path: '/var/lib/brainy' },
  vector: {
    recall: 'accurate',
    persistMode: 'immediate'
  },
  cache: { maxSize: 50000, ttl: 600_000 }
})

await brain.init()

See the API Reference for the complete option list.

See Also