feat(open-path): init never gates on the embedding model; open goes concurrent; slow opens narrate

A production restart storm measured 90,017ms for a single brain init vs
1,117ms quiet (~80x contention multiplier), traced to performInit() eagerly
awaiting the process-global WASM embedding engine before the VFS root even
existed. Every writer's open() queued on the one throttled model compile
(90-140s on throttled CPUs).

- VirtualFileSystem.doInitializeRoot() no longer embeds '/'. The root is
  system-tier plumbing nothing ever searches; when the default WASM engine
  is active it now gets an explicit all-zero placeholder vector
  (cosineDistance returns max distance for a zero vector, so it never ranks
  ahead of real content). deferEmbedding was considered and rejected: its
  landing path kicks the embed worker synchronously right after commit,
  which would still force the cold compile within milliseconds — just off
  the awaited path, not avoided. A registered native 'embeddings' provider
  (no cold-start cost, possibly a different dimension) still embeds the
  root for real, via the new Brainy.usesDefaultWasmEmbedder() seam.

- performInit()'s eager-embedding step now only STARTS the WASM engine warm
  in the background instead of awaiting it inline. embed()/embeddingManager
  already serialize concurrent callers on one shared init promise, so the
  first real embed() converges correctly either way; a failed warm narrates
  loudly instead of surfacing as a silent latency spike or an unhandled
  rejection. eagerEmbeddings: false still means no warm at all.

- FileSystemStorage.init() batches its ~8 independent bootstrap mkdirs
  (each creates its own full subtree via recursive:true, so none depend on
  the others existing) into one Promise.all. The restore-completion step
  and initializeCounts() stay strictly sequential — they have real order
  dependencies on rootDir and systemDir respectively.

- performInit() now times five phases (storage init / generation-store
  open+fold / index init+gate / VFS bootstrap / embedding-warm-started) and
  logs one warning with the per-phase breakdown when total open exceeds
  2000ms; silent otherwise.
This commit is contained in:
David Snelling 2026-08-25 10:09:45 -07:00
parent f8f64780b1
commit 96624f408c
5 changed files with 446 additions and 53 deletions

View file

@ -1983,25 +1983,32 @@ export interface BrainyConfig {
reservedQueryMemory?: number // Memory reserved for queries in bytes (e.g., 1073741824 = 1GB)
/**
* Controls when the WASM embedding engine is initialized.
* Controls whether `init()` starts a BACKGROUND warm of the WASM embedding
* engine.
*
* **Adaptive default (8.0):** when omitted, the engine eagerly initializes
* during `init()` whenever the WASM embedder is the *active* one i.e. no
* native `'embeddings'` provider is registered and this instance is a
* writer (not `mode: 'reader'`) running outside unit tests. The WASM module
* (93MB with the embedded model) takes 90-140s to compile on throttled
* CPUs, so paying that during boot rather than on the first `embed()`-driven
* call is the right default for a single-process server.
* **Adaptive default (8.0, background since the open-path fix):** when
* omitted, `init()` STARTS a background warm of the engine whenever the
* WASM embedder is the *active* one i.e. no native `'embeddings'`
* provider is registered and this instance is a writer (not
* `mode: 'reader'`) running outside unit tests. The WASM module (93MB with
* the embedded model) takes 90-140s to compile on throttled CPUs but
* `init()` never awaits that compile. It only starts it, so N concurrent
* opens no longer serialize on the one process-global engine singleton.
* The first `embed()` call then waits for whichever finishes first: the
* background warm (if still running) or its own fresh init (if the warm
* never started, e.g. `eagerEmbeddings: false`) both paths converge on
* the SAME shared promise inside the engine singleton, so the vector is
* always correct; only the timing of who pays the wait differs.
*
* The adaptive path skips itself automatically when a native embeddings
* provider owns embeddings, in reader-mode (readers query existing vectors
* and never embed), and in unit-test mode (kept fast via the mock embedder).
*
* - `true` force eager init during `init()` (the adaptive default already
* does this for the active-embedder writer case; set it explicitly to be
* unambiguous).
* - `false` explicit override to force lazy init (first `embed()` call)
* even when this instance is the active embedder.
* - `true` force the background warm to start during `init()` (the
* adaptive default already does this for the active-embedder writer
* case; set it explicitly to be unambiguous).
* - `false` no warm at all. Fully lazy: the first `embed()` call pays the
* full cold-compile cost inline, on whichever request triggers it.
*/
eagerEmbeddings?: boolean