docs(util): state that TurboQuant's packed codec has no storage path - #802
Merged
sroussey merged 1 commit intoAug 15, 2026
Conversation
The module ships two independent encoders and nothing said so. `turboQuantizeToTypedArray` returns a plain Int8Array/Int16Array and drops into any IVectorStorage backend; the four packed-codec functions return a `TurboQuantizeResult` that no backend in this repo can accept, and none could without a new column type. Verified: `git grep` for the six packed-codec names and `TurboQuantizeResult` across the branch, excluding the module and its own test, returns zero hits. And the storage layer cannot take the shape even if a caller wanted to — `assertVectorShape` (called by every backend on write and query) requires an array-like whose length equals the declared dimensionality with every entry a finite number, which a record fails outright and whose packed `codes` buffer fails too (at 4 bits it holds two coordinates per byte). The backends that score in-process all call `cosineSimilarity` on raw numbers with no hook for `turboQuantizedCosineSimilarity`, and the pgvector-backed ones compute the distance server-side where no client-side scorer can be injected at all. Nothing is un-exported and no storage is wired. Un-exporting was considered and rejected: the ~1200-line test suite imports those names from `@workglow/util/schema`, so it would force a cross-package deep import into `packages/util/src` (which nothing in `packages/test` does) or the deletion of verified-correct code and its tests. Wiring storage needs a new column type, a client-side scoring path, and per-backend fallbacks for the server-side-distance engines — a multi-package feature, not a review fix. So the fix is documentation: a module-header section naming which encoder has a storage path, why the other cannot have one, what the packed record IS good for (in-process comparison — a candidate cache, a client-side rerank over a shortlist), and an explicit "do not persist it expecting a retrieval path to exist". The real integration is tracked in #798, linked from the section. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UW1Qr5mxetAQr61YKEY9nz
sroussey
merged commit Aug 15, 2026
42c97c9
into
claude/integrate-arxiv-paper-VF55c
10 of 11 checks passed
sroussey
added a commit
that referenced
this pull request
Aug 16, 2026
…802) The module ships two independent encoders and nothing said so. `turboQuantizeToTypedArray` returns a plain Int8Array/Int16Array and drops into any IVectorStorage backend; the four packed-codec functions return a `TurboQuantizeResult` that no backend in this repo can accept, and none could without a new column type. Verified: `git grep` for the six packed-codec names and `TurboQuantizeResult` across the branch, excluding the module and its own test, returns zero hits. And the storage layer cannot take the shape even if a caller wanted to — `assertVectorShape` (called by every backend on write and query) requires an array-like whose length equals the declared dimensionality with every entry a finite number, which a record fails outright and whose packed `codes` buffer fails too (at 4 bits it holds two coordinates per byte). The backends that score in-process all call `cosineSimilarity` on raw numbers with no hook for `turboQuantizedCosineSimilarity`, and the pgvector-backed ones compute the distance server-side where no client-side scorer can be injected at all. Nothing is un-exported and no storage is wired. Un-exporting was considered and rejected: the ~1200-line test suite imports those names from `@workglow/util/schema`, so it would force a cross-package deep import into `packages/util/src` (which nothing in `packages/test` does) or the deletion of verified-correct code and its tests. Wiring storage needs a new column type, a client-side scoring path, and per-backend fallbacks for the server-side-distance engines — a multi-package feature, not a review fix. So the fix is documentation: a module-header section naming which encoder has a storage path, why the other cannot have one, what the packed record IS good for (in-process comparison — a candidate cache, a client-side rerank over a shortlist), and an explicit "do not persist it expecting a retrieval path to exist". The real integration is tracked in #798, linked from the section. Claude-Session: https://claude.ai/code/session_01UW1Qr5mxetAQr61YKEY9nz Co-authored-by: Claude <noreply@anthropic.com>
sroussey
deleted the
claude/optimistic-goldberg-onotd9-turboquant-codec-scope
branch
August 24, 2026 18:48
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Small; land with or right after #801. Documentation only — one module-header section, no code changed, nothing un-exported, no storage wired.
The gap
TurboQuantize.tsships two independent encoders and nothing said so:turboQuantizeToTypedArrayInt8Array/Int16ArrayIVectorStoragefixed-width columnturboQuantize/turboDequantize/turboQuantizedInnerProduct/turboQuantizedCosineSimilarity(+ the two sizing helpers)TurboQuantizeResultThe packed codec is the interesting half — sub-byte widths (1–8 bits/dim), the exact 1-bit angle correction, pairwise comparability enforcement — and it is currently unreachable from any persistence path.
Verified:
git grepfor the six packed-codec names andTurboQuantizeResultacross the branch, excluding the module and its own test, returns zero hits.And the storage layer cannot accept the shape even if a caller wanted to:
assertVectorShape(packages/storage/src/vector/assertVectorShape.ts:22-52), called by every backend on write and on query, requires an array-like whoselengthequals the declared dimensionality with every entry a finite number. ATurboQuantizeResultis a record and fails on the first check; its packedcodesbuffer fails on the second, since at 4 bits it holds two coordinates per byte and its length isceil(paddedDimensions * bits / 8), notdimensions.InMemoryVectorStorage(:161),SqliteVectorStorage(:151),SqliteAiVectorStorage(:660) — all callcosineSimilarity(query, vector)on raw numbers, with no hook to substituteturboQuantizedCosineSimilarity, the only function that can read these codes.PostgresVectorStorage(operators<=>/<->/<#>) andSupabaseVectorStorage(amatch_<table>RPC) — compute the distance server-side, where no client-side scorer can be injected at all.Two rejected alternatives, and why documentation is the fix
Un-exporting was evaluated and rejected: the ~1200-line test suite imports those six names from
@workglow/util/schema, so hiding them forces a cross-package deep import intopackages/util/src(which nothing inpackages/testdoes) or deleting ~700 lines of verified-correct code plus its tests.Wiring storage needs a new column type, a client-side scoring path, and per-backend fallbacks for the server-side-distance engines — a multi-package feature, not a review fix.
So the fix is to state the split at the point of use: which encoder has a storage path, why the other cannot have one, what the packed record IS good for (in-process comparison — an in-memory candidate cache, a client-side rerank over a shortlist retrieved by other means), and an explicit "do not persist it expecting a retrieval path to exist."
Real
IVectorStorageintegration is tracked in #798, linked from the new section.Note on the review's backend list
The review named "pgvector/sqlite-vec/DuckDB" as three server-side-distance engines. Re-checked against the tree: there are two pgvector-backed ones (
PostgresVectorStorage,SupabaseVectorStorage);SqliteVectorStorageandSqliteAiVectorStoragein fact score client-side withcosineSimilarity, and this repo has no DuckDB vector storage at all (onlyDuckDbTabularStorage). The doc section is written to the verified picture. The conclusion is unchanged — and the client-side ones are blocked too, just by a different constraint (no scorer hook rather than server-side evaluation).Verification
bunx vitest run --project test packages/test/src/test/util/TurboQuantize.test.ts→ 72 passedbunx eslint packages/util/src/vector/TurboQuantize.ts→ exit 0bunx prettier --check packages/util/src/vector/TurboQuantize.ts→All matched files use Prettier code style!Generated by Claude Code