Current retrieval candidates

Lexical, semantic and hybrid search use the current_records_v1 candidate selection plan in QilbeeDB 0.10.0. This plan prevents deleted memories from consuming the candidate budget and selects exact tag and episode-type partitions before reading memory content or vectors. Tenant, project, mission, agent and private subject authorization still determine the namespace before candidate selection. Embeddings remain external.

What changes for a client#

Continue to use the existing endpoints and server-owned ranking versions. cosine_exact_v1 retains exact float64 cosine accumulation over float32 vectors; BM25 and both weighted RRF profiles retain their formulas and tie breaking. This change does not introduce approximate neighbors or a new relevance claim.

Successful responses include these headers in all three search modes:

Field Meaning
X-Qilbee-Candidate-Selection-Version current_records_v1; record this with server and ranking versions in comparisons
X-Qilbee-Scanned-Records Current candidates admitted from the authorized tag/type partition
X-Qilbee-Candidate-Index-Bytes Logical candidate key/value bytes admitted, separate from source bytes
X-Qilbee-Scanned-Bytes Serialized current records and selected-space bindings admitted; now also available for semantic search
JSON page.next_after Exclusive UUID of the last examined current candidate if more candidates remain
JSON page.exhaustive True only when a cursorless request covers the complete current-candidate partition

scan_limit limits the scanned-record counter, including semantic candidates that have no binding in the requested model space. scanned_embeddings counts only bindings actually decoded for eligible current candidates. A stale binding can be decoded but cannot contribute a score. Missing bindings never acquire an inferred model identity. Hybrid embedded_records and embedding_coverage retain their meaning.

The JSON shape is unchanged, including for clients that forbid unknown response fields. Lexical/hybrid pages retain scanned_records and scanned_bytes; semantic pages retain scanned_embeddings and expose their new work counters through headers. The Rust library also exposes these counters on its native page types. Scores retain their previous units. When comparing versions, keep the candidate selection version in the report: the examined population and work counters differ from the legacy all-record/all-binding scan.

Maintenance and upgrades#

Creation, update, tag/type changes, deletion and review maintain the candidate projection in the same synchronous WAL batch as the canonical memory, integrity index, receipt and change event. A deleted or directly rejected record has no candidate entry. Historical receipts, tombstones and vectors remain durable; search does not enumerate them as candidates. Updating a memory invalidates the old revision's vector for scoring until a new binding is attached.

The server checks a per-namespace journal fingerprint at startup. An absent or stale fingerprint triggers reconstruction from canonical records before serving requests, including after the journal-aware 0.9.0 version wrote to the database. Downgrading to a binary that changes canonical memories without updating the journal is not a supported write path. Legacy namespaces without a journal are rebuilt at every open. Reconstruction uses batches of at most 256 source records, holds no corpus-sized collection and publishes its completion marker last. An interrupted reconstruction restarts safely. Errors abort startup; an incomplete projection is never advertised ready. Unchanged namespaces are skipped by seeking over their key ranges.

Allow time and disk headroom for this migration. A namespace that needs rebuilding requires a scan of its canonical records, including tombstones. The 256-record batch limit bounds individual writes; it does not bound the total startup time. The projection adds storage and write work proportional to the number of tags. It is a candidate filter, not a token inverted index or an ANN structure.

Coverage and operational limits#

Expiry and transitive source eligibility are evaluated in the request snapshot. A record that expires after indexing, or becomes ineligible because a source changes, can still consume the candidate budget. This release does not implement background expiry reclamation or recursive removal from this projection. Such records contribute neither hits nor BM25 statistics. Check exhaustive and dependency_work; do not assume that live-record count alone guarantees complete coverage under every policy and history.

The byte counters are logical serialized work. They exclude integrity-index reads, RocksDB amplification, allocations and one lookahead entry; dependency reads are reported separately. They are not network traffic, RAM or physical disk I/O. Lexical/hybrid byte limits still apply, and semantic work remains bounded by candidate count and embedding dimensions. Record latency, CPU and memory under the actual workload before increasing production limits.

A cursor traverses current candidates, not ranked hits or a retained snapshot. Each continuation takes a new snapshot. An unchanged corpus advances without duplicate UUIDs, but concurrent changes can alter subsequent pages. Continued pages remain non-exhaustive. Do not combine BM25 or hybrid page scores into a global ranking. Prefer a complete filtered corpus within the agreed budgets.

Use scripts/benchmark_retrieval_history.py only against a dedicated disposable scope. Its synthetic 1,536-dimensional vectors measure coverage and read work; they do not measure relevance or agent-task improvement.

The benchmark refuses a scope containing records or tombstones and never overwrites an output directory. It saves exact write intents before requests, without bearer credentials. A failed or uncertain write aborts the run; reconcile the saved idempotency keys before attempting further mutations. Do not label an interrupted run a completed coverage measurement. Optional --resource-container sampling requires an isolated qilbeedb-history-* container with the server as PID 1.

The history qualification report includes the three-cycle coverage results, clean-corpus size curve, upgrade comparison and real-vector eight-document regression.