Here's the patch-level breakdown for each minor version, with the retrieval-quality principle applied throughout: **every patch that touches retrieval must pass the golden-set regression gate at equal-or-better recall/precision than the previous tag, or it doesn't ship** — that's what "best in what we're doing" actually enforces, not just adding more models.

## v0.2.x — Cross-encoder reranking

| Version | Adds |
|---|---|
| v0.2.0 | `Reranker` protocol (same abstraction pattern as `Embedder`) + one default cross-encoder model, ONNX-exported, wired as an optional second pass after RRF fusion |
| v0.2.1 | Golden-set before/after comparison — prove the reranker actually improves precision@k over fusion alone; if it doesn't, this is where you'd cut it, not ship it anyway |
| v0.2.2 | Multiple reranker options, config-selectable (fast/small vs. higher-quality/slower) — same registry pattern as embedding providers |
| v0.2.3 | GPU-optional acceleration via ONNX Runtime execution providers (CUDA/DirectML) with automatic CPU fallback — still fully offline, no cloud, just using local GPU if present |
| v0.2.4 | Latency benchmarking + hardening/docs — stable close of the 0.2 line |

## v0.3.x — Query rewriting/expansion

| Version | Adds |
|---|---|
| v0.3.0 | Rule-based expansion only (synonym/term substitution) — deterministic, zero-model, matches the "no LLM in core retrieval" v0.1 discipline |
| v0.3.1 | First local quantized LLM expansion path (small 1-3B model, ONNX-runnable), behind `--deep --llm-expand` |
| v0.3.2 | Multiple query-rewriting model options, config-selectable (rule-based / small local model A / small local model B) — same registry pattern as embedding/reranker |
| v0.3.3 | Multi-query RRF fusion tuned and golden-set validated — must show measurable recall improvement over single-query baseline, or the "deep" mode isn't earning its added latency |
| v0.3.4 | GPU-optional acceleration for the expansion model, CPU fallback default, hardening/docs |

## v0.4.x — Multi-language support

| Version | Adds |
|---|---|
| v0.4.0 | JS/TS tree-sitter grammar, chunking parity tests against the same golden-set methodology used for Python |
| v0.4.1 | Go grammar |
| v0.4.2 | Rust grammar |
| v0.4.3 | Per-language call/import graph correctness pass — each language's graph stays scoped to itself; cross-language linking (e.g. a Python backend calling a JS frontend) explicitly out of scope here, worth deciding deliberately rather than assuming |
| v0.4.4 | Golden-set expanded to include real non-Python repos per language, hardening/docs |

## v0.5.x — Embedding model flexibility (this is where "best in retrieval" concentrates)

| Version | Adds |
|---|---|
| v0.5.0 | Opens the `Embedder` registry to any local HF model path via config, not just the shipped default — still ONNX-runnable, still offline |
| v0.5.1 | Ships 2-3 curated default model options (fast/small vs. higher-quality/code-specialized), each benchmarked against the golden set so users pick based on measured recall/precision tradeoff, not guesswork |
| v0.5.2 | GPU-optional acceleration for embedding generation (CUDA/DirectML execution providers), automatic CPU fallback — same pattern as v0.2.3/v0.3.4, applied to the last remaining CPU-bound model in the pipeline |
| v0.5.3 | `rylox bench --embedding-model X` — lets a user run the golden-set comparison against their own repo locally, so model choice isn't just your benchmark, it's verifiable on their code too |
| v0.5.4 | Hardening, docs, stable close of the 0.5 line |

**The consistent pattern across all four minors:** first patch adds the capability, middle patches add model choice + measured proof it helps, later patches add GPU-optional acceleration (never GPU-required — CPU stays the default, GPU is opportunistic), and the last patch in each line is hardening/docs before moving to the next minor. That's how "offline, ONNX, CPU or GPU, no cloud" stays true at every single patch, not just as a v0.1 promise that erodes as features get added.