From 4aa3c5a1ca2db9fdc8d83b0213c7a4f9715042e9 Mon Sep 17 00:00:00 2001 From: osobh Date: Sat, 19 Sep 2026 13:32:47 -0700 Subject: [PATCH] chore(release): v2.4.0 Bump all workspace crates, the node package and pyproject to 2.4.0, finalize the changelog and add upgrade notes for the search behaviour changes. Co-Authored-By: Claude Fable 5.1 --- CHANGELOG.md | 20 +++++++++++++++++++- Cargo.toml | 2 +- crates/clawhdf5-accel/Cargo.toml | 2 +- crates/clawhdf5-agent/Cargo.toml | 14 +++++++------- crates/clawhdf5-android/Cargo.toml | 2 +- crates/clawhdf5-ann/Cargo.toml | 8 ++++---- crates/clawhdf5-bench/Cargo.toml | 2 +- crates/clawhdf5-cli/Cargo.toml | 4 ++-- crates/clawhdf5-derive/Cargo.toml | 2 +- crates/clawhdf5-filters/Cargo.toml | 2 +- crates/clawhdf5-format/Cargo.toml | 4 ++-- crates/clawhdf5-gpu/Cargo.toml | 2 +- crates/clawhdf5-io/Cargo.toml | 4 ++-- crates/clawhdf5-migrate/Cargo.toml | 8 ++++---- crates/clawhdf5-napi/Cargo.toml | 4 ++-- crates/clawhdf5-netcdf4/Cargo.toml | 6 +++--- crates/clawhdf5-py/Cargo.toml | 6 +++--- crates/clawhdf5-py/pyproject.toml | 2 +- crates/clawhdf5/Cargo.toml | 12 ++++++------ packages/clawhdf5-node/package.json | 2 +- 20 files changed, 63 insertions(+), 45 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7cb31dd..0f54dbf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,24 @@ # Changelog -## Unreleased +## v2.4.0 (2026-09-19) + +### Upgrade Notes +- **Search results improve on upgrade.** The HNSW index now reaches true + neighbours it previously could not (recall@10 0.31 -> 0.98 at 100K records on + clustered data), so `hybrid_search` rankings change for the better. The agent + rebuilds its index from the store automatically; a standalone `HnswIndex` + persisted with `to_hdf5_bytes` keeps its old graph until rebuilt. +- **`hybrid_search` no longer writes the store.** Hebbian activation boosts are + persisted by the next checkpoint (any flushing write, `flush_wal`, or when + the `HDF5Memory` is dropped) instead of inside every query; a crash before + then forgets only the boosts since the last checkpoint. Activation weights + are now capped at 16. +- A new sidecar file, `.h5.ann`, holds the vector index graph. It is + derived data: safe to delete (the index is rebuilt), copied by `snapshot()`, + and worth including when copying a store by hand to avoid a rebuild. +- `BM25Index` no longer caches IDF and gained `add_document`, + `remove_document`, `pad_to`, `scores`, `len` and `is_empty`; results are now + deterministic (ties break by record id). ### Search - `clawhdf5-ann`: **HNSW recall fix.** Neighbours were chosen as the plain diff --git a/Cargo.toml b/Cargo.toml index 8b42a0a..a70132d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,7 @@ members = [ resolver = "2" [workspace.package] -version = "2.3.0" +version = "2.4.0" edition = "2024" license = "MIT" repository = "https://git.redclaw.dev/quantumclaw/clawhdf5" diff --git a/crates/clawhdf5-accel/Cargo.toml b/crates/clawhdf5-accel/Cargo.toml index f7b0d28..d4a10da 100644 --- a/crates/clawhdf5-accel/Cargo.toml +++ b/crates/clawhdf5-accel/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clawhdf5-accel" -version = "2.3.0" +version = "2.4.0" edition = "2024" description = "SIMD-accelerated operations for rustyhdf5" license = "MIT" diff --git a/crates/clawhdf5-agent/Cargo.toml b/crates/clawhdf5-agent/Cargo.toml index 871c62b..4f2dbb4 100644 --- a/crates/clawhdf5-agent/Cargo.toml +++ b/crates/clawhdf5-agent/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clawhdf5-agent" -version = "2.3.0" +version = "2.4.0" edition = "2024" description = "HDF5-backed persistent memory store for on-device AI agents" license = "MIT" @@ -10,12 +10,12 @@ keywords = ["agent", "memory", "hdf5", "vector-search", "embedding"] categories = ["database", "science", "algorithms"] [dependencies] -clawhdf5-format = { path = "../clawhdf5-format", version = "2.3.0", features = ["parallel", "fast-checksum"] } -clawhdf5 = { path = "../clawhdf5", version = "2.3.0" } -clawhdf5-io = { path = "../clawhdf5-io", version = "2.3.0", features = ["mmap"] } -clawhdf5-accel = { path = "../clawhdf5-accel", version = "2.3.0" } -clawhdf5-ann = { path = "../clawhdf5-ann", version = "2.3.0", optional = true } -clawhdf5-gpu = { path = "../clawhdf5-gpu", version = "2.3.0", optional = true, default-features = false } +clawhdf5-format = { path = "../clawhdf5-format", version = "2.4.0", features = ["parallel", "fast-checksum"] } +clawhdf5 = { path = "../clawhdf5", version = "2.4.0" } +clawhdf5-io = { path = "../clawhdf5-io", version = "2.4.0", features = ["mmap"] } +clawhdf5-accel = { path = "../clawhdf5-accel", version = "2.4.0" } +clawhdf5-ann = { path = "../clawhdf5-ann", version = "2.4.0", optional = true } +clawhdf5-gpu = { path = "../clawhdf5-gpu", version = "2.4.0", optional = true, default-features = false } serde = { workspace = true } byteorder = "1" half = { workspace = true, optional = true } diff --git a/crates/clawhdf5-android/Cargo.toml b/crates/clawhdf5-android/Cargo.toml index 522b374..b62cfd2 100644 --- a/crates/clawhdf5-android/Cargo.toml +++ b/crates/clawhdf5-android/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clawhdf5-android" -version = "2.3.0" +version = "2.4.0" edition = "2024" description = "Android JNI bridge for edgehdf5-memory HDF5 backend" license = "MIT" diff --git a/crates/clawhdf5-ann/Cargo.toml b/crates/clawhdf5-ann/Cargo.toml index dd2b79a..07eb5f8 100644 --- a/crates/clawhdf5-ann/Cargo.toml +++ b/crates/clawhdf5-ann/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clawhdf5-ann" -version = "2.3.0" +version = "2.4.0" edition = "2024" description = "HNSW approximate nearest neighbor index stored as HDF5" license = "MIT" @@ -10,9 +10,9 @@ keywords = ["hdf5", "ann", "hnsw", "nearest-neighbor"] categories = ["algorithms", "science"] [dependencies] -clawhdf5-format = { path = "../clawhdf5-format", version = "2.3.0" } -clawhdf5-io = { path = "../clawhdf5-io", version = "2.3.0" } -clawhdf5-accel = { path = "../clawhdf5-accel", version = "2.3.0" } +clawhdf5-format = { path = "../clawhdf5-format", version = "2.4.0" } +clawhdf5-io = { path = "../clawhdf5-io", version = "2.4.0" } +clawhdf5-accel = { path = "../clawhdf5-accel", version = "2.4.0" } rayon = { version = "1", optional = true } [features] diff --git a/crates/clawhdf5-bench/Cargo.toml b/crates/clawhdf5-bench/Cargo.toml index 7f8ffbf..f6f737d 100644 --- a/crates/clawhdf5-bench/Cargo.toml +++ b/crates/clawhdf5-bench/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clawhdf5-bench" -version = "2.3.0" +version = "2.4.0" edition = "2024" description = "Benchmark harnesses for clawhdf5-agent (Track 8)" license = "MIT" diff --git a/crates/clawhdf5-cli/Cargo.toml b/crates/clawhdf5-cli/Cargo.toml index 6e5a61d..45900d7 100644 --- a/crates/clawhdf5-cli/Cargo.toml +++ b/crates/clawhdf5-cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clawhdf5-cli" -version = "2.3.0" +version = "2.4.0" edition = "2024" license = "MIT" description = "CLI for clawhdf5 agent memory — create, save, search, recall, stats" @@ -14,7 +14,7 @@ name = "clawhdf5" path = "src/main.rs" [dependencies] -clawhdf5-agent = { path = "../clawhdf5-agent", version = "2.3.0" } +clawhdf5-agent = { path = "../clawhdf5-agent", version = "2.4.0" } clap = { version = "4", features = ["derive", "env"] } serde_json = "1" serde = { workspace = true } diff --git a/crates/clawhdf5-derive/Cargo.toml b/crates/clawhdf5-derive/Cargo.toml index d5aba1e..a70370c 100644 --- a/crates/clawhdf5-derive/Cargo.toml +++ b/crates/clawhdf5-derive/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clawhdf5-derive" -version = "2.3.0" +version = "2.4.0" edition = "2024" description = "Derive macros for rustyhdf5 HDF5 traits" license = "MIT" diff --git a/crates/clawhdf5-filters/Cargo.toml b/crates/clawhdf5-filters/Cargo.toml index b8ffb9b..1c33439 100644 --- a/crates/clawhdf5-filters/Cargo.toml +++ b/crates/clawhdf5-filters/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clawhdf5-filters" -version = "2.3.0" +version = "2.4.0" edition = "2024" description = "Filter and compression pipeline for clawhdf5" license = "MIT" diff --git a/crates/clawhdf5-format/Cargo.toml b/crates/clawhdf5-format/Cargo.toml index 50b0cad..7393ee4 100644 --- a/crates/clawhdf5-format/Cargo.toml +++ b/crates/clawhdf5-format/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clawhdf5-format" -version = "2.3.0" +version = "2.4.0" edition = "2024" description = "Pure-Rust HDF5 binary format parsing and writing — no C dependencies" license = "MIT" @@ -25,7 +25,7 @@ pco = { version = "1.0", optional = true } [dev-dependencies] serde_json = "1" criterion = { workspace = true } -clawhdf5-derive = { path = "../clawhdf5-derive", version = "2.3.0" } +clawhdf5-derive = { path = "../clawhdf5-derive", version = "2.4.0" } [[bench]] name = "bench" diff --git a/crates/clawhdf5-gpu/Cargo.toml b/crates/clawhdf5-gpu/Cargo.toml index f046f94..3c71b2a 100644 --- a/crates/clawhdf5-gpu/Cargo.toml +++ b/crates/clawhdf5-gpu/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clawhdf5-gpu" -version = "2.3.0" +version = "2.4.0" edition = "2024" description = "GPU-accelerated vector operations for rustyhdf5 using wgpu compute shaders" license = "MIT" diff --git a/crates/clawhdf5-io/Cargo.toml b/crates/clawhdf5-io/Cargo.toml index 92d8004..475e1ff 100644 --- a/crates/clawhdf5-io/Cargo.toml +++ b/crates/clawhdf5-io/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clawhdf5-io" -version = "2.3.0" +version = "2.4.0" edition = "2024" description = "I/O abstraction layer for rustyhdf5" license = "MIT" @@ -10,7 +10,7 @@ keywords = ["hdf5", "io", "science", "data"] categories = ["filesystem", "science"] [dependencies] -clawhdf5-format = { path = "../clawhdf5-format", version = "2.3.0" } +clawhdf5-format = { path = "../clawhdf5-format", version = "2.4.0" } memmap2 = { version = "0.9", optional = true } libc = { version = "0.2", optional = true } tokio = { version = "1", features = ["fs", "io-util"], optional = true } diff --git a/crates/clawhdf5-migrate/Cargo.toml b/crates/clawhdf5-migrate/Cargo.toml index 9eef58a..0195dc1 100644 --- a/crates/clawhdf5-migrate/Cargo.toml +++ b/crates/clawhdf5-migrate/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clawhdf5-migrate" -version = "2.3.0" +version = "2.4.0" edition = "2024" description = "CLI to migrate SQLite agent memory databases to HDF5 format" license = "MIT" @@ -14,9 +14,9 @@ name = "clawhdf5-migrate" path = "src/main.rs" [dependencies] -clawhdf5-agent = { path = "../clawhdf5-agent", version = "2.3.0" } -clawhdf5-format = { path = "../clawhdf5-format", version = "2.3.0" } -clawhdf5 = { path = "../clawhdf5", version = "2.3.0" } +clawhdf5-agent = { path = "../clawhdf5-agent", version = "2.4.0" } +clawhdf5-format = { path = "../clawhdf5-format", version = "2.4.0" } +clawhdf5 = { path = "../clawhdf5", version = "2.4.0" } rusqlite = { version = "0.31", features = ["bundled"] } clap = { version = "4", features = ["derive"] } half = { workspace = true } diff --git a/crates/clawhdf5-napi/Cargo.toml b/crates/clawhdf5-napi/Cargo.toml index cf5f6a6..f350149 100644 --- a/crates/clawhdf5-napi/Cargo.toml +++ b/crates/clawhdf5-napi/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clawhdf5-napi" -version = "2.3.0" +version = "2.4.0" edition = "2024" description = "Node.js native addon (napi-rs) exposing clawhdf5-agent to TypeScript/JavaScript" license = "MIT" @@ -10,7 +10,7 @@ repository = "https://git.redclaw.dev/quantumclaw/clawhdf5" crate-type = ["cdylib"] [dependencies] -clawhdf5-agent = { path = "../clawhdf5-agent", version = "2.3.0" } +clawhdf5-agent = { path = "../clawhdf5-agent", version = "2.4.0" } napi = { version = "2", default-features = false, features = ["napi9"] } napi-derive = "2" diff --git a/crates/clawhdf5-netcdf4/Cargo.toml b/crates/clawhdf5-netcdf4/Cargo.toml index c8021dc..ab3c389 100644 --- a/crates/clawhdf5-netcdf4/Cargo.toml +++ b/crates/clawhdf5-netcdf4/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clawhdf5-netcdf4" -version = "2.3.0" +version = "2.4.0" edition = "2024" description = "NetCDF-4 read support built on rustyhdf5 — pure Rust, no C dependencies" license = "MIT" @@ -10,8 +10,8 @@ keywords = ["netcdf", "netcdf4", "hdf5", "science", "climate"] categories = ["parser-implementations", "science"] [dependencies] -clawhdf5 = { path = "../clawhdf5", version = "2.3.0" } -clawhdf5-format = { path = "../clawhdf5-format", version = "2.3.0" } +clawhdf5 = { path = "../clawhdf5", version = "2.4.0" } +clawhdf5-format = { path = "../clawhdf5-format", version = "2.4.0" } [dev-dependencies] tempfile = { workspace = true } diff --git a/crates/clawhdf5-py/Cargo.toml b/crates/clawhdf5-py/Cargo.toml index b048543..c3dfcea 100644 --- a/crates/clawhdf5-py/Cargo.toml +++ b/crates/clawhdf5-py/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clawhdf5-py" -version = "2.3.0" +version = "2.4.0" edition = "2024" description = "Python bindings for rustyhdf5 — a pure-Rust HDF5 library" license = "MIT" @@ -14,8 +14,8 @@ name = "clawhdf5" crate-type = ["cdylib", "rlib"] [dependencies] -clawhdf5_rs = { path = "../clawhdf5", version = "2.3.0", package = "clawhdf5" } -clawhdf5-format = { path = "../clawhdf5-format", version = "2.3.0" } +clawhdf5_rs = { path = "../clawhdf5", version = "2.4.0", package = "clawhdf5" } +clawhdf5-format = { path = "../clawhdf5-format", version = "2.4.0" } pyo3 = "0.29" numpy = "0.29" diff --git a/crates/clawhdf5-py/pyproject.toml b/crates/clawhdf5-py/pyproject.toml index 44c8f0a..c9c9bba 100644 --- a/crates/clawhdf5-py/pyproject.toml +++ b/crates/clawhdf5-py/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "maturin" [project] name = "rustyhdf5" -version = "2.3.0" +version = "2.4.0" description = "Python bindings for rustyhdf5 — a pure-Rust HDF5 library" requires-python = ">=3.8" license = { text = "MIT" } diff --git a/crates/clawhdf5/Cargo.toml b/crates/clawhdf5/Cargo.toml index 3e437bf..59c8b07 100644 --- a/crates/clawhdf5/Cargo.toml +++ b/crates/clawhdf5/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clawhdf5" -version = "2.3.0" +version = "2.4.0" edition = "2024" description = "Pure-Rust HDF5 reader/writer — no C dependencies" license = "MIT" @@ -10,16 +10,16 @@ keywords = ["hdf5", "science", "data", "binary"] categories = ["parser-implementations", "science", "encoding"] [dependencies] -clawhdf5-format = { path = "../clawhdf5-format", version = "2.3.0" } -clawhdf5-io = { path = "../clawhdf5-io", version = "2.3.0" } +clawhdf5-format = { path = "../clawhdf5-format", version = "2.4.0" } +clawhdf5-io = { path = "../clawhdf5-io", version = "2.4.0" } rayon = { version = "1", optional = true } [dev-dependencies] tempfile = { workspace = true } criterion = { workspace = true } -clawhdf5-io = { path = "../clawhdf5-io", version = "2.3.0", features = ["mmap"] } -clawhdf5-format = { path = "../clawhdf5-format", version = "2.3.0", features = ["parallel", "fast-checksum"] } -clawhdf5-filters = { path = "../clawhdf5-filters", version = "2.3.0" } +clawhdf5-io = { path = "../clawhdf5-io", version = "2.4.0", features = ["mmap"] } +clawhdf5-format = { path = "../clawhdf5-format", version = "2.4.0", features = ["parallel", "fast-checksum"] } +clawhdf5-filters = { path = "../clawhdf5-filters", version = "2.4.0" } [[bench]] name = "mmap_bench" diff --git a/packages/clawhdf5-node/package.json b/packages/clawhdf5-node/package.json index 389444d..3d452ea 100644 --- a/packages/clawhdf5-node/package.json +++ b/packages/clawhdf5-node/package.json @@ -1,6 +1,6 @@ { "name": "@redclaw/clawhdf5", - "version": "2.3.0", + "version": "2.4.0", "description": "Node.js bindings for clawhdf5 — HDF5-backed agent memory with hippocampal consolidation", "main": "index.js", "types": "index.d.ts",