# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
## [1.3.0] - 2026-06-12
### Fixed
- **Site**: restore docs site build — Starlight 0.39 removed labeled
`autogenerate` sidebar groups; the "Workflow Reference" group now nests
the autogenerate config in `items` (broken since the auto-merged
Starlight 0.40 bump, which no CI gate builds the site to catch)
- **Tests**: embedding tests skip gracefully when the BGE-M3 model cannot
be downloaded (network-dependent Hugging Face fetch) instead of failing
the suite — this intermittently broke CI on main
### Added
- **CI**: `site` job builds the docs site on every push/PR and gates
`All Checks Pass` — site-dependency bumps can no longer automerge with
a broken build
- **Release**: Attested delivery — releases now publish platform binaries
(`rlm-cli-{version}-{platform}` for linux-amd64, linux-arm64, macos-arm64,
windows-amd64.exe), each carrying SLSA build provenance via
`actions/attest-build-provenance`
- macos-amd64 is not published: ort (onnxruntime, via the default
fastembed feature) provides no prebuilt binaries for
`x86_64-apple-darwin`
- Release publication is gated on fail-closed attestation verification —
a tag publishes nothing unattested
- `workflow_dispatch` dry-run exercises the build → attest → verify chain
without cutting a release
- **Security**: `SECURITY.md` with vulnerability reporting policy and
release-artifact verification instructions (`gh attestation verify`)
- **Release**: CycloneDX SBOM per release (Syft), attested to every binary
via `actions/attest-sbom` and verified fail-closed alongside provenance
- **Release**: `cargo audit` gate — a release publishes nothing if any
dependency carries a known vulnerability
- **Release**: test gate — tags are not guaranteed to point at CI-green
commits, so the release workflow runs the full test suite and publishes
nothing untested
- **Release**: `rlm-cli-{version}-checksums.txt` asset with SHA-256 digests
of all release artifacts
- **Release**: crates.io publishing now uses Trusted Publishing (OIDC) via
`rust-lang/crates-io-auth-action` instead of a long-lived registry token
(requires one-time Trusted Publishing setup on crates.io before the next
release)
### Security
- **Dependencies**: update npm `uuid` to 14.0.0 in the docs site lockfile
(CVE-2026-41907 / GHSA-w5hq-g745-h8pq, fixed ≥ 11.1.1)
- **Dependencies**: update quinn-proto 0.11.13 → 0.11.14 in the lockfile
(RUSTSEC-2026-0037); the entry was an unreachable phantom resolution — no
shipped binary included the vulnerable code — but the audit gate flags it
- **Supply chain**: align `deny.toml` `[graph] targets` with the release
matrix (adds `aarch64-unknown-linux-gnu`, `x86_64-pc-windows-msvc`) so
cargo-deny analyzes every shipped platform's dependency graph
- **CI**: `pin-check` job (central `zircote/.github` reusable workflow)
asserts every GitHub Actions `uses:` reference is pinned to a full
40-character commit SHA
- **CI**: pinned the remaining mutable workflow ref
(`reusable-dependabot-automerge.yml@main`) to a commit SHA
### Changed
- **Build**: Bump MSRV to 1.95 — libsqlite3-sys 0.38.1 (via the rusqlite
0.40.1 bump) uses `cfg_select!`, stabilized in Rust 1.95; the MSRV CI job
now also passes `--locked` so it checks the dependency versions that
actually ship
- **Documentation**: Enhanced troubleshooting guide with usearch version pinning details
- Documented the `<2.25` version constraint; usearch v2.24.x is supported since rlm-cli v1.2.4
- Added troubleshooting section for usearch version issues
- Updated features guide to reference usearch v2.23.x requirement
### Performance
- **Search**: Batch chunk lookup in `populate_previews()` using `get_chunks_by_ids()`
- Replaces N individual `get_chunk()` calls with a single `WHERE id IN (…)` query
- Reduces database round-trips from O(n) to O(1) when rendering content previews
- **Search**: Parallelize cosine similarity scan in `semantic_search()` using `rayon::par_iter()`
- Linear scan over stored embeddings now distributes across all available CPU cores
- Near-linear speedup for large embedding collections (>1 000 chunks)
- **Storage**: Pre-size embedding byte buffers in `store_embedding()` and `store_embeddings_batch()`
- `Vec::with_capacity(embedding.len() * 4)` avoids repeated heap reallocations per embedding
- Reduces heap churn when indexing large batches of chunks
- **Storage**: Replace O(n) per-chunk embedding checks with a single `NOT EXISTS` query
- `SqliteStorage::all_chunks_have_embeddings()` and `buffer_fully_embedded()` now issue one SQL
query regardless of how many chunks a buffer contains
- Eliminates the previous pattern of issuing one `has_embedding()` call per chunk when checking
whether a buffer is fully embedded
## [1.2.4] - 2026-02-08
### Added
- **Chunking**: Code-aware chunker for language-specific boundaries
- Supports Rust, Python, JavaScript, TypeScript, Go, Java, C/C++, Ruby, PHP
- Splits at function, class, and method boundaries
- Available via `--chunker code` or `--chunker ast`
- **Search**: HNSW vector index for scalable approximate nearest neighbor search
- O(log n) search performance
- Optional feature: enable with `usearch-hnsw` feature flag
- **Search**: Content preview in search results with `--preview` flag
- Configurable length with `--preview-len` (default: 150 chars)
- **CLI**: `update-buffer` command to update buffer content with re-chunking
- Supports `--embed` flag for automatic re-embedding
- Incremental embedding (only new/changed chunks)
- **CLI**: `dispatch` command for parallel subagent processing
- Split chunks into batches by size or worker count
- Filter chunks by search query
- **CLI**: `aggregate` command to combine analyst findings
- Filter by relevance level
- Group and sort findings
- Store results in output buffer
- **Embedding**: Incremental embedding support
- Only embeds new or changed chunks
- Model version tracking for migration detection
- **Embedding**: Model name tracking in `Embedder` trait
- **Output**: NDJSON format support (`--format ndjson`)
- **CI**: Crates.io publish workflow with pre-publish validation
- **CI**: Dependabot auto-merge workflow
- **Documentation**: ADRs for error handling, concurrency model, and feature flags
- **Documentation**: MCP agentic workflow prompts (analyst, orchestrator, synthesizer)
### Changed
- **Core**: Consolidated UTF-8 and timestamp utilities in io module
- `find_char_boundary` and `current_timestamp` now shared across modules
- **Core**: Improved token estimation with `estimate_tokens_accurate()` method
- **Error**: Dedicated `Embedding` error variant in `StorageError`
- **Embedding**: Removed unnecessary unsafe `Send`/`Sync` impls from `FallbackEmbedder`
### Fixed
- **Search**: Resolve usearch segfault via move semantics fix
- **Documentation**: Fix unresolved intra-doc links in Chunk methods
### Security
- Update `bytes` to 1.11.1 to resolve RUSTSEC-2026-0007
### Dependencies
- Bump `bytes` from 1.10.1 to 1.11.1
- Bump `clap` from 4.5.54 to 4.5.56 ([#11])
- Bump the github-actions group with 2 updates ([#12])
- Bump `actions/github-script` from 7 to 8 ([#7])
- Bump `criterion` from 0.5.1 to 0.8.1 ([#9])
- Bump `rusqlite` from 0.33.0 to 0.38.0 ([#8])
- Bump `actions/checkout` from 4 to 6 ([#6])
- Bump `taiki-e/install-action` in the github-actions group ([#5])
## [1.2.3] - 2026-01-20
### Fixed
- **CI**: Allow `multiple_crate_versions` lint (fastembed transitive deps)
- **CI**: Add ISC, BSD, MPL-2.0, CDLA-Permissive-2.0 to allowed licenses
- **CI**: Ignore unmaintained `paste` advisory (fastembed transitive dep)
- **CI**: Skip openssl ban check for fastembed transitive deps
## [1.2.2] - 2026-01-20
### Fixed
- **CLI**: Handle broken pipe gracefully when output is piped to commands like `jq` or `head`
## [1.2.1] - 2026-01-20
### Fixed
- **Build**: Enable `fastembed-embeddings` feature by default (BGE-M3 now works out of the box)
## [1.2.0] - 2026-01-20
### Added
- **Search**: Search results now include `index` (document position) and `buffer_id` fields for temporal ordering
- **Documentation**: Architecture Decision Records (ADRs) documenting 10 key architectural decisions from project history
### Changed
- **Embedding**: Switch from all-MiniLM-L6-v2 to BGE-M3 embedding model
- Dimensions increased from 384 to 1024 for richer semantic representation
- Token context increased from ~512 to 8192 for full chunk coverage
- **Breaking**: Existing embeddings must be regenerated (schema migration v3 clears old embeddings)
- **Build**: Bump MSRV to 1.88
### Fixed
- **Search**: Escape FTS5 special characters in search queries to prevent syntax errors
- **Chunking**: Validate UTF-8 boundaries in semantic chunker search window to prevent panics on multi-byte characters
## [1.1.2] - 2026-01-19
### Changed
- **Chunking**: Reduced default chunk size from 240,000 to 3,000 characters for better semantic search granularity
- **Chunking**: Reduced max chunk size from 250,000 to 50,000 characters
## [1.1.1] - 2026-01-19
### Fixed
- **Search**: BM25 scores now display in scientific notation for small values (e.g., `1.60e-6` instead of `0.0000`)
- **Search**: FTS queries use OR semantics for multi-word searches (more forgiving matching)
- **Embedding**: Auto-embedding during load now outputs proper JSON when `--format json` is used
## [1.1.0] - 2026-01-19
### Added
- **Search**: Hybrid semantic + BM25 search with Reciprocal Rank Fusion (RRF)
- **Search**: `search` command with `--mode` option (`hybrid`, `semantic`, `bm25`)
- **Embedding**: Auto-embedding during `load` command (embeddings generated automatically)
- **Chunks**: `chunk get` command for pass-by-reference retrieval
- **Chunks**: `chunk list` command to list chunks for a buffer
- **Chunks**: `chunk embed` command to generate/regenerate embeddings
- **Chunks**: `chunk status` command to show embedding status
### Changed
- **Load**: Embeddings are now generated automatically during load (no separate embed step needed)
## [1.0.0] - 2026-01-19
### Added
- **Core**: Initial release with semantic search and pass-by-reference architecture
- **Chunking**: Fixed, semantic, and parallel chunking strategies
- **Storage**: SQLite persistence for buffers, chunks, and variables
- **Search**: Regex search with `grep` command
- **I/O**: Memory-mapped file handling for large documents
- **CLI**: JSON output format support for all commands
## [0.2.0] - 2026-01-19
### Added
- **CI/CD**: Release workflow to auto-update Homebrew tap
## [0.1.0] - 2026-01-19
### Added
- Initial implementation of RLM-RS CLI
- Buffer management (load, list, show, delete, peek)
- Chunking with configurable strategies
- Variable storage (context and global)
- Export functionality
[Unreleased]: https://github.com/zircote/rlm-rs/compare/v1.3.0...HEAD
[1.3.0]: https://github.com/zircote/rlm-rs/compare/v1.2.4...v1.3.0
[1.2.4]: https://github.com/zircote/rlm-rs/compare/v1.2.3...v1.2.4
[1.2.3]: https://github.com/zircote/rlm-rs/compare/v1.2.2...v1.2.3
[1.2.2]: https://github.com/zircote/rlm-rs/compare/v1.2.1...v1.2.2
[1.2.1]: https://github.com/zircote/rlm-rs/compare/v1.2.0...v1.2.1
[1.2.0]: https://github.com/zircote/rlm-rs/compare/v1.1.2...v1.2.0
[1.1.2]: https://github.com/zircote/rlm-rs/compare/v1.1.1...v1.1.2
[1.1.1]: https://github.com/zircote/rlm-rs/compare/v1.1.0...v1.1.1
[1.1.0]: https://github.com/zircote/rlm-rs/compare/v1.0.0...v1.1.0
[1.0.0]: https://github.com/zircote/rlm-rs/compare/v0.2.0...v1.0.0
[0.2.0]: https://github.com/zircote/rlm-rs/compare/v0.1.0...v0.2.0
[0.1.0]: https://github.com/zircote/rlm-rs/releases/tag/v0.1.0