Skip to content

chore(release): merge v0.15.0 to main - #551

Merged
ajianaz merged 5 commits into
mainfrom
release/v0.15.0
Aug 31, 2026
Merged

chore(release): merge v0.15.0 to main#551
ajianaz merged 5 commits into
mainfrom
release/v0.15.0

Conversation

@ajianaz

@ajianaz ajianaz commented Aug 31, 2026

Copy link
Copy Markdown
Collaborator

What

GitFlow release merge: develop → main for v0.15.0. Tag v0.15.0 will be pushed on main after this merges, triggering release.yml.

Why

Ship 0.15.0: opt-in vecq vector store with keyed persistence, residual default width, and the brain.vector_bits knob (#543, #548, #547); fresh-process vector signal fix (#546, #545); cross-project fingerprint heal; cora upgrade docs (#549, #541).

Testing

Full suite green on develop (947 tests); CI validates this PR.

ajianaz and others added 5 commits August 29, 2026 19:28
* feat(brain): opt-in vecq vector store backend

Add `brain.vector_store: usearch|vecq` (default usearch). vecq-core 0.2.0
replaces the HNSW store with a 4-bit quantized brute-force scan: pure Rust
(no C++ FFI), bit-identical deterministic results, ~6x smaller index,
14x faster builds — query latency stays sub-ms at cora's typical index
sizes and the recall trade is absorbed by Brain's RRF fusion (#542).

- CodeVectorIndex gains an enum backend (Usearch | Vecq); every backend
  owns its file extension (.usearch / .vecq) so switching stores never
  misreads the other's format
- config applied at every Brain entry point (index, watch, brain cmd,
  MCP brain_search) so CLI and MCP cannot silently diverge
- vecq insert/remove map symbol ids to native u64 keys (tombstones);
  search converts similarity to the cosine-distance contract

Known limitation (documented + tested): vecq-core 0.2.0 from_bytes does
not serialize the keyed map (vecq#32), so reload rebuilds fresh instead
of serving a silently-empty index; `cora index` re-embeds. Persistence
lands when vecq ships key serialization.

Regression tests: backend roundtrip (insert/replace/remove/search +
distance conversion), per-backend persistence extensions, lenient
store-kind parsing.

Signed-off-by: ajianaz <ajianaz@users.noreply.github.com>

* fix(brain): wire brain section config, self-heal vecq reload, dedupe config load

Three fixes from PR #543 review:

1. Config wiring: .cora.yaml 'brain:' section was never parsed —
   CoraFile had no brain field, so vector_store: vecq silently
   fell back to usearch and embedding mode was ignored. Add
   BrainSection + field-wise merge_into (matches other sections).

2. Vecq reload self-heal: a reloaded vecq index is rebuilt empty
   (upstream vecq#32 lacks key serialization) and arrived with
   dirty=false, so a no-change 'cora index' run saved an empty
   index over the stored one — permanently losing vector signal.
   Now reload marks the index dirty, embed_project clears stale
   embed fingerprints when it sees dirty+empty, and cora index
   forces re-embed when the on-disk vecq file needs a rebuild.

3. Brain command: load_config was called twice; fold into one
   load shared by resolve_backend and apply_config_store.

Verified: 937/937 tests pass; e2e with CODECORA_HOME sandbox —
vector_store: vecq now creates cora_index.vecq config now works,
and a no-change re-run logs 'cleared=2, re-embedding all symbols'
instead of silently persisting an empty index.

---------

Signed-off-by: ajianaz <ajianaz@users.noreply.github.com>
Co-authored-by: ajianaz <ajianaz@users.noreply.github.com>
VECTOR_CACHE was only populated by embed_project (i.e. 'cora index'),
so a fresh search process — 'cora brain' CLI or MCP brain_search —
always saw an empty cache and the vector signal never fired; results
silently degraded to FTS + graph only. Verified on develop and on the
vecq PR branch with the same sandboxed e2e run.

vector_search now lazy-loads the on-disk index once per process via
ensure_vector_cache (double-checked read/write locking; a concurrent
double load is idempotent). Load failures degrade gracefully with a
warn log. Also guard dimension mismatch (embedding provider switched
since the index was built) — previously a panic inside the backend.

Note: the vecq backend still degrades to FTS-only in fresh search
processes — that is the documented upstream limitation (vecq#32, no
key serialization), tracked separately.

Regression tests (tests/brain_search_process.rs): fresh-process brain
search must emit the vector signal (default usearch backend), and
brain.vector_store: vecq must produce a .vecq file — both run with
isolated CODECORA_HOME sandboxes.

Co-authored-by: ajianaz <ajianaz@users.noreply.github.com>
…rain.vector_bits knob (#548)

Upgrade the opt-in vecq store to vecq-core 0.3.0 and close #547.

- Keyed persistence (upstream vecq#32 closed, format v1.3+): symbol-id
  keys survive reload. load_or_create_vecq now deserializes for real and
  keeps a healthy keyed index; legacy keyless files, corrupt files, and
  dim mismatches rebuild dirty so the next  re-embeds. A dim
  guard is mandatory: add_keyed panics on wrong-dim vectors.
- brain.vector_bits config (residual|4|5|6, lenient, default residual):
  residual is best recall@10 at 4-bit scan speed in a recall study on
  cora's own embeddings (ahead of plain 5-bit at 1k/5k/13k scales).
  A width change rebuilds the index once so the config takes effect;
  vecq_file_needs_rebuild is width-aware.
- BrainConfig gets a manual Default (derived Default produced empty
  strings, inconsistent with the serde defaults).
- Cross-project heal: the vector index is one shared file; a rebuild
  (width/dims/legacy/corrupt) now clears embed fingerprints for ALL
  projects, not just the active one, and the usearch dims-mismatch
  deletion path joins the same heal (pre-existing fingerprint leak).

Tests: keyed roundtrip, legacy keyless rebuild, corrupt rebuild,
dim-mismatch rebuild, width-switch rebuild, roundtrip across all four
widths, lenient parsing, config merge. 947 pass incl. the fresh-process
integration tests from #546.

Closes #547

Co-authored-by: ajianaz <ajianaz@users.noreply.github.com>
Add a Self-Upgrade section to docs/cli-reference.md (--check, default
flow with SHA-256 checksum verification, -y for CI), a README install/
upgrade note and a command-table row, per #541.

Correction vs the issue body: the background update check is disabled
via the CORA_NO_UPDATE_CHECK=1 environment variable — no
--no-update-check flag exists.

Closes #541

Co-authored-by: ajianaz <ajianaz@users.noreply.github.com>
Co-authored-by: ajianaz <ajianaz@users.noreply.github.com>
@ajianaz
ajianaz merged commit 283eb45 into main Aug 31, 2026
15 checks passed
@ajianaz
ajianaz deleted the release/v0.15.0 branch August 31, 2026 06:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant