feat(health): the gate reads the named report — reads refuse loudly, never rebuild; open serves before it returns; the ceremony door
The read gate stops consulting the unnamed isReady() boolean: every provider
may expose healthReport() (sync, O(1), composed from exact ledgers —
HealthReport with a monotonic generation, per-invariant source
ledger|deep|unledgered, missing {count, sample}), and one readiness
authority (assessProviderHealth) derives the verdict. Unledgered families
are UNKNOWN — never healthy, never broken; a report that throws is a loud
not-ready, never a shrug. Reads at the four index choke points refuse with
the typed NotReady errors, narrated once per (provider, generation) — a
read NEVER starts a store walk:
- the first-read lazy build retires (open builds instead, regardless of
size — the ≥10k deferral and the "lazy loading on first query" branch go;
disableAutoRebuild is re-meant honestly in its docs);
- the verify*Live read-path rebuild triggers retire (refuse-or-serve);
- the read-time consistency probe that could launch a dark rebuild from an
ordinary find() retires;
- repairIndex({ rebuild: ['metadata'|'graph'|'vector'] | 'all' }) is the
one explicit door: rebuilds the named leg unconditionally and reports
rebuilt per family; bare repairIndex() stays report-driven.
test(lifecycle): the biography lane — a store's whole life, refereed
tests/lifecycle/: an independent shadow model referees every read after
every chapter (founding, a working day, clean restart, crash, repair,
second life). Chapters 1-3 green. Chapters 4-6 assert the true contract and
are marked .fails as a release-blocking finding (the kill-matrix
convention): after a crash + adopt reopen the metadata index computes its
'catchup' watermark verdict and nothing consumes it — find() serves the
pre-crash index while canonical and counts recover. The catchup wiring is
the cure; a passing .fails will force the marker's removal. The lane runs
in the integration gate (config + coverage guard).
This commit is contained in:
parent
a8b5ca0c8f
commit
f8f64780b1
19 changed files with 2160 additions and 652 deletions
|
|
@ -1816,10 +1816,16 @@ export interface BrainyConfig {
|
|||
| StorageAdapter
|
||||
|
||||
/**
|
||||
* Disable the automatic index rebuild check during `init()`. By default
|
||||
* Brainy auto-decides from dataset size: small datasets rebuild missing
|
||||
* indexes inline, large datasets rebuild lazily on first query. Set `true`
|
||||
* only when an operator wants full manual control via `repairIndex()`.
|
||||
* RE-MEANT (the health-gate contract): `init()` (open) always verifies the
|
||||
* durable generation of every derived index, and a needed rebuild ALWAYS
|
||||
* runs at open — it is never deferred to the first read, regardless of
|
||||
* dataset size or this flag. There is no first-query lazy-build path
|
||||
* anymore: a read that finds a provider not serving throws a typed
|
||||
* `*NotReadyError` rather than building anything (see
|
||||
* `assessProviderHealth` / the read gate in `brainy.ts`). Setting this
|
||||
* `true` no longer defers index construction to the first query — it has
|
||||
* no effect on WHEN a needed rebuild runs. Full manual control over
|
||||
* rebuilds remains available via `repairIndex({ rebuild: [...] })`.
|
||||
*/
|
||||
disableAutoRebuild?: boolean
|
||||
|
||||
|
|
|
|||
Reference in a new issue