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:
parent
a2820e81af
commit
e435da787d
3 changed files with 19 additions and 11 deletions
|
|
@ -15,9 +15,10 @@
|
|||
* and the caller had no way to tell that from "no row matches". Eleven tags is
|
||||
* not an exotic shape; the eleventh tag made the row invisible.
|
||||
*
|
||||
* THE LAW. Arrays of scalars index up to {@link MAX_INDEXED_ARRAY_LENGTH} = 64,
|
||||
* THE LAW. Arrays of scalars index up to {@link MAX_INDEXED_ARRAY_LENGTH},
|
||||
* hardcoded (the zero-config law: no knob), which clears every legitimate
|
||||
* multi-value field and stays far below any embedding width. Above it the WRITE
|
||||
* multi-value field — tags, authors, keyword lists — and stays below the
|
||||
* narrowest embedding this engine meets (384 dimensions). Above it the WRITE
|
||||
* IS REFUSED by name — `MetadataArrayTooLargeError`, carrying the field, the
|
||||
* length and the bound — at `add`, `update`, `relate` and `updateRelation`
|
||||
* alike. Nothing is skipped in silence.
|
||||
|
|
@ -65,7 +66,7 @@ describe('the indexable-array bound', () => {
|
|||
}
|
||||
})
|
||||
|
||||
it('indexes right up to the bound — all 64 elements', async () => {
|
||||
it('indexes right up to the bound — every element of it', async () => {
|
||||
await brain.add({
|
||||
id: 'at-bound',
|
||||
data: 'a row at the bound',
|
||||
|
|
@ -74,8 +75,9 @@ describe('the indexable-array bound', () => {
|
|||
vector: []
|
||||
})
|
||||
|
||||
// The first, the last, and one in the middle.
|
||||
for (const tag of ['t0', `t${MAX_INDEXED_ARRAY_LENGTH - 1}`, 't31']) {
|
||||
// The first, the last, and one in the middle — all derived from the
|
||||
// bound, so the case follows the constant wherever it moves.
|
||||
for (const tag of ['t0', `t${MAX_INDEXED_ARRAY_LENGTH - 1}`, `t${Math.floor(MAX_INDEXED_ARRAY_LENGTH / 2)}`]) {
|
||||
const hits = await brain.find({ where: { tags: tag }, limit: 10 } as any)
|
||||
expect(hits.map((r: any) => r.id)).toContain(resolveEntityId('at-bound'))
|
||||
}
|
||||
|
|
|
|||
Reference in a new issue