fix(metadata): the indexable-array bound is 256 — a keyword list is not a vector

64 cleared tags, authors and labels, but not the shape that actually turns up
in production metadata: a long keyword or participant list. 256 clears those
and still refuses every embedding this engine will ever meet — the narrowest
model it ships is 384-dimensional, so the two populations still do not overlap
and nobody has to tune anything. A vector parked in metadata throws by name;
a 200-keyword list writes and indexes.

The number lives in ONE place, `MAX_INDEXED_ARRAY_LENGTH`, and every message,
warning and pin derives it from there. Two pins still carried a literal:
metadata-vector-exclusion refused an array of exactly 100 — which sits UNDER
the new bound, so the case would have asserted a refusal that no longer
happens — and the array-bound suite named "all 64 elements" in a title and
picked its middle element as a hardcoded 't31'. Both derive from the constant
now, so the pins follow it wherever it goes rather than silently inverting the
next time it moves.
This commit is contained in:
David Snelling 2026-09-02 15:41:11 -07:00
parent a2820e81af
commit e435da787d
3 changed files with 19 additions and 11 deletions

View file

@ -412,18 +412,23 @@ export class MigrationInProgressError extends BrainyError {
* embedding parked in the metadata bag would mint 384 postings for one row.
* The bound exists to keep that out of the index.
*
* 64 is hardcoded on purpose (the zero-config law: no knob). It sits far above
* 256 is hardcoded on purpose (the zero-config law: no knob). It sits far above
* every legitimate multi-value field the engine has seen tags, authors,
* categories, labels, participant lists and far below any real embedding
* width, so the two populations do not overlap and no caller has to tune it.
* categories, labels, keyword lists, participant lists and still below the
* narrowest embedding this engine will ever meet (384 dimensions, the smallest
* model it ships), so the two populations do not overlap and no caller has to
* tune it. A vector parked in metadata is refused; a long keyword list is not.
*
* It replaces a limit of 10 that was applied SILENTLY: a row whose `tags` array
* held eleven entries had that field skipped entirely and dropped out of every
* filtered search on it, with no error, no warning and no way to tell the
* difference from "no row matches". A rule this consequential is a law with a
* name and a refusal, not a `continue`.
*
* This is the ONE place the number lives. Every message, warning, doc line and
* pin derives it from here never a literal.
*/
export const MAX_INDEXED_ARRAY_LENGTH = 64
export const MAX_INDEXED_ARRAY_LENGTH = 256
/**
* A metadata field carries an array longer than {@link MAX_INDEXED_ARRAY_LENGTH}.