fix: honest index readiness — no silently-empty queries on a cold index
Closes the "dishonest readiness proxy" anti-pattern (Pattern A): size()>0 /
isInitialized were treated as "this index serves queries", but a cold native
index can load its COUNT before its SERVING structure, so a query returned a
silent [] indistinguishable from "no such data". A shared assessIndexReadiness()
now reads only the provider's honest isReady() signal (never size()), applied at
every site:
- Vector: a one-shot verifyVectorLive() guard on the semantic/proximity search
path (a pure semantic find({query}) has no filter, so nothing guarded it). It
prefers isReady(), else a known-vector self-match probe; self-heals via rebuild
or throws the new VectorIndexNotReadyError instead of a silent [].
- Graph: getVerbsBySource/ByTarget skip the fast path when the provider reports
not-ready (falling to the canonical shard scan), plus a one-shot probe that
self-heals a no-isReady provider whose adjacency did not cold-load.
- getIndexStatus(): folds in per-index honest `ready` (making `populated`
honest) + rebuildFailed/rebuildError/degradedIds, so a readiness probe never
200s a brain that is still warming up or degraded.
Unblocked by the native providers now reporting serving-truth (graph via
SSTable-residency readiness, vector via durableBaseLoadFailed). New export:
VectorIndexNotReadyError. getIndexStatus gains additive fields. No breaking API.
13 new tests; existing readiness guards green.
This commit is contained in:
parent
36d4e80ba2
commit
d0f69c731f
9 changed files with 654 additions and 9 deletions
|
|
@ -14,6 +14,7 @@ export type BrainyErrorType =
|
|||
| 'FIELD_NOT_INDEXED'
|
||||
| 'GRAPH_INDEX_NOT_READY'
|
||||
| 'METADATA_INDEX_NOT_READY'
|
||||
| 'VECTOR_INDEX_NOT_READY'
|
||||
| 'MIGRATION_IN_PROGRESS'
|
||||
|
||||
/**
|
||||
|
|
@ -280,6 +281,32 @@ export class MetadataIndexNotReadyError extends BrainyError {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Thrown when the vector index reports vectors (`size() > 0` or, on a native
|
||||
* provider, `isReady() === false`) but cannot return a KNOWN persisted vector
|
||||
* even after a rebuild — i.e. the semantic serving structure did not load on a
|
||||
* cold open and could not be restored. The vector-search counterpart of
|
||||
* {@link GraphIndexNotReadyError} / {@link MetadataIndexNotReadyError}: it
|
||||
* replaces the silent-empty failure mode (a cold `find({ query })` returning
|
||||
* `[]` indistinguishable from "no similar data") with a loud, catchable error,
|
||||
* so a consumer never renders "nothing found" over data that is simply
|
||||
* not-yet-warm.
|
||||
*
|
||||
* Detected once per brain by a known-vector serving probe on the first
|
||||
* semantic / proximity `find()`; brainy self-heals (rebuilds the index from the
|
||||
* canonical records) first and only raises this if the rebuild still cannot
|
||||
* serve the known vector.
|
||||
*/
|
||||
export class VectorIndexNotReadyError extends BrainyError {
|
||||
constructor(message: string, originalError?: Error) {
|
||||
super(message, 'VECTOR_INDEX_NOT_READY', false, originalError)
|
||||
this.name = 'VectorIndexNotReadyError'
|
||||
if (Error.captureStackTrace) {
|
||||
Error.captureStackTrace(this, VectorIndexNotReadyError)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Thrown when a data-plane read or write is issued against a brain that is
|
||||
* running its one-time, automatic 7.x → 8.0 on-disk upgrade — the coordinated
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue