* Release: turbovec 0.8.0 (Python) + 0.9.0 (Rust crate)
Security-audit release (#108): untrusted-load hardening, binding panic
fixes, integration data-integrity fixes, and the x86 scalar-fallback
correctness fix. Resolves #104, #105, #106. Minor bump on both surfaces
because a few inputs that previously panicked or were silently accepted now
return typed errors. See CHANGELOG.md.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* docs: correct stale benchmark figures in README
Fact-checked the README prose against benchmarks/results/. Several figures
had drifted (mostly from before TQ+ landed):
- ARM speed 12-20% -> 10-19% (actual range 10.3-19.4%)
- OpenAI R@1 +0.4-3.4 pts -> +0.2-1.9 pts (no config reaches 3.4)
- GloVe R@1 +0.3/-1.2 -> +0.9/tied (TQ+ closed the 2-bit gap)
- x86 2-bit 'within ~1% ST, 2-4% MT' -> trails 3-8% on both ST and MT
- softened 'matches the Shannon lower bound' -> 'near-optimal' (the
how-it-works section already states within 2.7x of the bound)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* docs: fix benchmark + baseline-note drift in README
- intro: 'matches the Shannon lower bound' -> 'near-optimal distortion';
trim to 'no separate training phase'
- speed bullet/x86 prose: characterize x86 2-bit honestly (behind, most
visibly d=1536 ST ~8%) instead of 'match-or-beat'/'3-8%'
- recall: OpenAI converge to 1.0 by k=8 (>=0.997 at k=4)
- baselines note: drop stale 'visible gap on GloVe' (TQ+ closed it; GloVe is
now level at 2-bit, ahead at 4-bit)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* docs: fix drift vs the security release (#108)
Audited docs/ against the merged behavior changes:
- api.md: document that search() raises ValueError on non-finite/oversized
query coords; dim must be a positive multiple of 8 and <= 65536 (MAX_DIM);
zero-width add raises; load now validates the header before allocating.
- agno.md: duplicate derived doc_id is now keep-all (both kept and
deletable, matching LanceDb) — previous text implied last-write-wins;
clarify delete_by_name/_content_id/_metadata target only matching docs.
- agno/langchain/haystack/llama_index: loading a side-car out of sync with
its .tvim now raises ValueError at load instead of a later KeyError.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* Mark AddError/ConstructError #[non_exhaustive]
Adding the DimTooLarge variant this release is already breaking for
downstream exhaustive matches. Mark both public error enums
#[non_exhaustive] now so future variant additions stop being breaking
changes — this release is the one-time free moment to do it. The Python
binding only uses Display (e.to_string()), so it is unaffected.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* Require a 64-bit target via compile_error guard
turbovec's usize size/offset arithmetic in encode/pack/search assumes a
64-bit pointer width; on 32-bit/wasm those products can overflow and index
out of bounds. The untrusted-load path is already gated by checked_mul in
io.rs, so this is not a vulnerability via file input — but a developer
adding very large data on a 32-bit target could still overflow. Refuse to
compile on non-64-bit targets rather than ship a silently-unsafe build.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* Add SECURITY.md (private vulnerability disclosure policy)
Route security reports through GitHub private vulnerability reporting /
Security Advisories instead of public issues, with reporting steps, what to
include, expectations, supported-version policy, and scope. #105 came in as
a public issue; this gives finders a private channel.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* SECURITY.md: drop the direct-contact fallback
Private vulnerability reporting is the single channel; no alternate contact.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>