release: 1.0.0 (#537)

* release: 1.0.0

Cuts the Unreleased section and takes both packages to 1.0.0. The crate
and the Python package had drifted to 0.9.0 and 0.8.0; they are one
version from here.

What 1.0 commits to is the on-disk format. v7 is what turbovec reads and
writes, and a file written by this release will be readable by later
ones — which is a claim worth making now that there is one format
instead of two, and a converter for anything older.

The release is breaking: a .tv or .tvim from any earlier release no
longer loads, and is refused by version rather than misread. The
changelog leads with that and with how to migrate.

Versions moved in step across turbovec/Cargo.toml,
turbovec-python/Cargo.toml, turbovec-python/pyproject.toml and
Cargo.lock — the two release workflows check the tag against those
manifests before building anything (#343), so a mismatch fails fast.

Rust suite and 482 Python tests green at these versions.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* release: keep [Unreleased], and update the example's lockfile

Two things the release cut got wrong, both caught by CI and review.

The downstream-smoke example carries its own Cargo.lock pinning the
crate version, and ci.yml runs it with --locked. Bumping to 1.0.0
without it left the lock at 0.9.0, so the job failed with "cannot update
the lock file because --locked was passed". Updated; the exact CI
command now runs clean.

And the release section replaced `## [Unreleased]` rather than sitting
below it. Every previous cut kept the heading, and for a reason beyond
tidiness: changelog_gate.py looks for it and, finding none, returns a
pass — so deleting it would have silently disabled the changelog gate
for every later PR. Restored above the 1.0.0 section.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* release: re-base the compare links for the 1.0.0 cut

[Unreleased] still resolved to v0.9.0...HEAD, so once v1.0.0 is tagged
that span covers everything this PR just documented as released —
clicking through would show the whole 1.0.0 release as unreleased. It
now starts at v1.0.0, with compare links added for both new tags.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Ryan Codrai
2026-08-18 13:23:21 +01:00
committed by GitHub
parent 9f2c990be1
commit ccab9f325e
6 changed files with 44 additions and 9 deletions
+38 -3
View File
@@ -11,7 +11,40 @@ appears under each surface it touches.
## [Unreleased]
### turbovec — Rust crate
## turbovec 1.0.0 (Python package) + turbovec 1.0.0 (Rust crate) — 2026-08-18
First stable release, and the two packages are now on one version — the
crate and the Python package had drifted to 0.9.0 and 0.8.0 and both go
to 1.0.0 here. What 1.0 commits to is the on-disk format: v7 is what
turbovec reads and writes, and a file written by this release will be
readable by later ones.
**Breaking: v7 is the only format turbovec reads or writes.** A `.tv` or
`.tvim` file written by any earlier release no longer loads — it is
refused with an error naming its version rather than misread. Use
[`turbovec::convert`], added in this release, to bring a v5 or v6 file
forward (or take a v7 file back); `cargo run --example convert -- <in>
<out> v7` does it from a shell. Files older than v5 predate the rotation
change that altered every encoded byte and can only be rebuilt from the
source vectors.
What v7 buys is `sync()`: saving an index that has changed writes the
rows that changed rather than the whole file, and `write()` / `to_bytes()`
now produce the same container so there is one format to reason about
instead of two.
The rest of the release is bug fixes, several of them long-lived. A
delete could stall for seconds behind concurrent searches; the first
small add after a load permanently doubled the codes buffer; a load
allocated from a file's apparent length rather than its declared
contents; a built index carried two copies of its codes for its lifetime;
the stale-temp sweep never fired for long filenames; an aarch64 search
got slower the moment an index crossed 32768 vectors; and Agno's async
writes paid for embeddings before discovering the store was not created.
[`turbovec::convert`]: https://docs.rs/turbovec/1.0.0/turbovec/convert/
### turbovec — Rust crate (current: 0.9.0 → next: 1.0.0)
#### Added
@@ -1612,7 +1645,7 @@ appears under each surface it touches.
result count) and the `scores_for_query` / `indices_for_query`
accessors. (#162)
### turbovec — Python package
### turbovec — Python package (current: 0.8.0 → next: 1.0.0)
#### Added
@@ -3663,6 +3696,8 @@ turbovec 0.4.4 or later.
`schema_version` field; loaders reject unknown versions instead of
silently misinterpreting bytes.
[Unreleased]: https://github.com/RyanCodrai/turbovec/compare/v0.9.0...HEAD
[Unreleased]: https://github.com/RyanCodrai/turbovec/compare/v1.0.0...HEAD
[v1.0.0]: https://github.com/RyanCodrai/turbovec/compare/v0.9.0...v1.0.0
[py-v1.0.0]: https://github.com/RyanCodrai/turbovec/compare/py-v0.8.0...py-v1.0.0
[py-v0.4.2]: https://github.com/RyanCodrai/turbovec/compare/py-v0.4.1...py-v0.4.2
[py-v0.4.1]: https://github.com/RyanCodrai/turbovec/compare/py-v0.4.0...py-v0.4.1
Generated
+2 -2
View File
@@ -442,7 +442,7 @@ checksum = "adb6935a6f5c20170eeceb1a3835a49e12e19d792f6dd344ccc76a985ca5a6ca"
[[package]]
name = "turbovec"
version = "0.9.0"
version = "1.0.0"
dependencies = [
"ordered-float",
"rand",
@@ -454,7 +454,7 @@ dependencies = [
[[package]]
name = "turbovec-python"
version = "0.8.0"
version = "1.0.0"
dependencies = [
"libc",
"numpy",
+1 -1
View File
@@ -322,7 +322,7 @@ dependencies = [
[[package]]
name = "turbovec"
version = "0.9.0"
version = "1.0.0"
dependencies = [
"ordered-float",
"rand",
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "turbovec-python"
version = "0.8.0"
version = "1.0.0"
edition = "2021"
# Kept in lockstep with turbovec's `rust-version` — the `msrv` leg in ci.yml
# fails if the two manifests disagree. The rationale for the number, and why
+1 -1
View File
@@ -4,7 +4,7 @@ build-backend = "maturin"
[project]
name = "turbovec"
version = "0.8.0"
version = "1.0.0"
description = "Fast vector quantization with 2-4 bit compression and SIMD search"
readme = "README.md"
requires-python = ">=3.9"
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "turbovec"
version = "0.9.0"
version = "1.0.0"
edition = "2021"
# 1.89 is a floor the code actually needs, not a rounded-up default, and it has
# now been reported as over-declared twice (#351). The AVX-512 search kernel is