Skip to content

[codex] Document backend determinism contract#155

Merged
Navi Bot (project-navi-bot) merged 4 commits into
mainfrom
codex/backend-determinism-contract
Jun 3, 2026
Merged

[codex] Document backend determinism contract#155
Navi Bot (project-navi-bot) merged 4 commits into
mainfrom
codex/backend-determinism-contract

Conversation

@Fieldnote-Echo

Copy link
Copy Markdown
Member

Summary

Closes #127.

  • Add docs/determinism.md covering score ordering, tie keys, backend scope, scalar/SIMD tolerance language, batched/single-query parity, FastScan's approximate status, and compatibility-note requirements.
  • Change RankQuant::search_asymmetric_subset equal-score ties from local candidate position to global row ID, matching full search, candidate prefilters, Python, and C ABI ordering.
  • Add golden deterministic fixtures for full search ties, RankQuant scalar/production ordered ties, subset global-row ties, candidate prefilter batched parity, and empty/zero-k shapes.
  • Update stale docs/comments that still described bitmap candidate tie-breaking as unresolved or allowed tied-score permutation without referencing the golden contract.
  • Add Python binding coverage for subset global-row tie ordering and full sign-bitmap batched-vs-single ordered parity.

Compatibility Note

This PR intentionally changes RankQuant::search_asymmetric_subset behavior for unsorted equal-score candidate lists: ties now resolve by global row ID ascending, not candidate-list position. Duplicate candidate IDs are still accepted, scored separately, and may produce duplicate hits.

Scope Notes

This stays on origin/main and does not stack on PR #153 or PR #154. It does not change manifest verification, persisted format bytes, release policy, or storage semantics. RankQuantFastscan remains explicitly separate as an approximate hidden pre-ranker rather than an exact RankQuant parity surface.

Validation

  • cargo fmt --check
  • cargo test --test determinism_contract
  • cargo test --test index
  • cargo test --test redteam_beta
  • cargo test --test redteam_delta
  • cargo test -p ordvec-ffi
  • VIRTUAL_ENV=/home/ndspence/GitHub/ordvec/ordvec-python/.venv PATH=/home/ndspence/GitHub/ordvec/ordvec-python/.venv/bin:$PATH maturin develop -m ordvec-python/Cargo.toml
  • ordvec-python/.venv/bin/python -m pytest ordvec-python/tests/test_rank_quant.py::test_search_asymmetric_subset_matches_full_when_candidates_eq_all ordvec-python/tests/test_rank_quant.py::test_search_asymmetric_subset_ties_use_global_row_ids ordvec-python/tests/test_sign_bitmap.py::test_batched_matches_scalar_for_each_row
  • cargo test -p ordvec --all-features
  • cargo test --workspace --exclude ordvec-python --all-features
  • cargo check -p ordvec-python --all-features
  • cargo clippy --workspace --all-targets --all-features -- -D warnings
  • cargo deny check
  • git diff --check

Adversarial Review

A read-only adversarial review found two documentation blockers: the current subset tie-key behavior change needed an explicit compatibility note, and docs/RANK_MODES.md overpromised exact SIMD/scalar top-k equivalence. Both were fixed before publishing this PR.

@codecov

codecov Bot commented Jun 2, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request establishes a formal Search Determinism Contract and updates the codebase to guarantee deterministic search results across different backends and query paths. Notably, it modifies the TopK collector to break score ties using global row IDs instead of local candidate-list positions during subset scans, and updates candidate prefilters to use composite-key sorting. Feedback on this PR highlights a potential edge case in TopK::finalize_into where duplicate candidate IDs with identical scores and tie keys could still be ordered nondeterministically due to the unstable sort; adding the local index as a final tie-breaker is recommended to ensure absolute determinism.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread src/util.rs
@qodo-code-review

Copy link
Copy Markdown

Review Summary by Qodo

Document backend determinism contract and fix subset tie-breaking

📝 Documentation ✨ Enhancement

Grey Divider

Walkthroughs

Description
• Document backend determinism contract with golden fixtures
• Fix RankQuant::search_asymmetric_subset tie-breaking to use global row IDs
• Update TopK to support caller-supplied tie keys for subset scans
• Add comprehensive determinism tests covering full search, subset, and batched paths
Diagram
flowchart LR
  A["TopK struct"] -->|"add tie_keys field"| B["Support configurable tie keys"]
  B -->|"used by"| C["search_asymmetric_subset"]
  C -->|"now breaks ties by"| D["Global row ID ascending"]
  D -->|"matches"| E["Full search policy"]
  E -->|"documented in"| F["determinism.md"]
  F -->|"verified by"| G["Golden fixtures"]

Loading

Grey Divider

File Changes

1. docs/determinism.md 📝 Documentation +82/-0

New determinism contract documentation

docs/determinism.md


2. src/util.rs ✨ Enhancement +64/-39

Refactor TopK to support configurable tie keys

src/util.rs


3. src/quant.rs ✨ Enhancement +4/-2

Update subset search to use global row ID tie-breaking

src/quant.rs


View more (9)
4. ordvec-ffi/src/lib.rs 📝 Documentation +3/-5

Update FFI comments for subset tie-breaking policy

ordvec-ffi/src/lib.rs


5. tests/determinism_contract.rs 🧪 Tests +142/-0

Add golden determinism contract test fixtures

tests/determinism_contract.rs


6. tests/index/quant.rs 📝 Documentation +3/-2

Update test comments for determinism contract

tests/index/quant.rs


7. tests/redteam_beta.rs 📝 Documentation +3/-1

Clarify tolerance vs exact tie-ordering expectations

tests/redteam_beta.rs


8. ordvec-python/tests/test_rank_quant.py 🧪 Tests +16/-3

Add Python binding subset tie-ordering test

ordvec-python/tests/test_rank_quant.py


9. ordvec-python/tests/test_sign_bitmap.py 🧪 Tests +3/-9

Strengthen batched vs scalar parity test

ordvec-python/tests/test_sign_bitmap.py


10. docs/FOLLOWUP_BODY_KERNEL_TIE_BREAK.md 📝 Documentation +9/-18

Mark body kernel tie-break as resolved

docs/FOLLOWUP_BODY_KERNEL_TIE_BREAK.md


11. docs/RANK_MODES.md 📝 Documentation +7/-4

Reference determinism contract for backend guarantees

docs/RANK_MODES.md


12. README.md 📝 Documentation +1/-0

Add determinism.md to documentation index

README.md


Grey Divider

Qodo Logo

@qodo-code-review

qodo-code-review Bot commented Jun 3, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (1) 🔗 Cross-repo conflicts (0)

Context used

Grey Divider


Action required

1. Tolerance value missing in docs 📎 Requirement gap ≡ Correctness
Description
docs/determinism.md references a “documented test tolerance” / “tolerance stated below” for
floating-point primitives but never states the actual numeric tolerance or whether each primitive is
bit-exact vs tolerance-based. This leaves cross-backend/architecture compatibility expectations
ambiguous.
Code

docs/determinism.md[R24-46]

Evidence
PR Compliance ID 3 requires each public primitive to state bit-exact vs tolerance-based expectations
and define any tolerance. The new determinism doc mentions a tolerance but does not provide a
numeric value, while existing tests demonstrate a concrete tolerance (1e-4) that should be
reflected in the contract.

Specify bit-exact vs tolerance-based expectations per primitive
docs/determinism.md[24-36]
docs/determinism.md[40-46]
tests/index/quant.rs[155-165]
tests/index/rank.rs[39-46]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The determinism contract references a tolerance for floating-point primitives (e.g., Rank/RankQuant) but does not specify the numeric tolerance value(s) or clearly label which primitives are bit-exact vs tolerance-based per backend/architecture.

## Issue Context
Compliance requires explicitly stating, per public primitive, whether results are bit-exact across backends/architectures or allowed to differ within a defined tolerance, and to define that tolerance.

The test suite appears to enforce an absolute score tolerance of `1e-4` in multiple places, but the contract only says “within the tolerance used by the test suite” and “tolerance stated below” without actually stating it.

## Fix Focus Areas
- docs/determinism.md[24-46]
- docs/determinism.md[38-52]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR documents and enforces a cross-backend determinism/ordering contract for ordvec search APIs, and aligns RankQuant::search_asymmetric_subset tie-breaking with the same global row-id ordering used by full-index search, the C ABI, and Python bindings.

Changes:

  • Added docs/determinism.md describing score/order/tie-key guarantees, backend tolerance scope, batched-vs-single parity, and compatibility-note requirements.
  • Changed RankQuant::search_asymmetric_subset to break equal-score ties by global row ID ascending (not candidate-list position) by introducing tie-key support in the shared TopK collector.
  • Added deterministic golden tests/fixtures (Rust + Python) covering ties, subset ordering, batched parity, and empty/zero-k shapes; updated older docs/comments to point at the new contract.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated no comments.

Show a summary per file
File Description
tests/redteam_beta.rs Clarifies why set-equality is used for random/tolerance-boundary checks and points to determinism fixtures for ordering.
tests/index/quant.rs Same clarification for quant reference tests; avoids asserting strict order where tolerance can affect near-ties.
tests/determinism_contract.rs New golden tests pinning deterministic ordering/tie behavior across primitives and edge-case shapes.
src/util.rs Extends TopK to support caller-supplied tie keys, enabling subset scans to order by global row IDs while returning local indices for mapping.
src/quant.rs Updates search_asymmetric_subset to use TopK::new_with_tie_keys(...) and documents the global-row tie policy.
README.md Adds link to the determinism contract doc.
ordvec-python/tests/test_sign_bitmap.py Strengthens parity assertion: batched candidate selection must match single-query results including ties.
ordvec-python/tests/test_rank_quant.py Requires subset search ordering to match full search (and adds explicit subset tie-order test).
ordvec-ffi/src/lib.rs Updates C ABI commentary to reflect new core subset tie behavior and normalization expectations.
docs/RANK_MODES.md Removes over-strong claims about exact scalar/SIMD equivalence; points readers to determinism contract.
docs/FOLLOWUP_BODY_KERNEL_TIE_BREAK.md Marks prior tie-break follow-up as resolved and references the new determinism contract as the source of truth.
docs/determinism.md New compatibility contract document for ordering, ties, tolerance scope, and compatibility-note triggers.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread docs/determinism.md Outdated
Signed-off-by: Nelson Spence <nelson@projectnavi.ai>
@Fieldnote-Echo Nelson Spence (Fieldnote-Echo) force-pushed the codex/backend-determinism-contract branch from 225a8c1 to 5504784 Compare June 3, 2026 14:23
Signed-off-by: Nelson Spence <nelson@projectnavi.ai>
Signed-off-by: Nelson Spence <nelson@projectnavi.ai>

Copy link
Copy Markdown
Member Author

Addressed Qodo's determinism tolerance-doc finding in d7fba4ab9fd2be7194eb9d4348c935d11b6b69d0.

docs/determinism.md now states the public floating-score tolerance as absolute 1e-4 with rtol = 0, distinguishes that from tighter helper-test tolerances, and labels each primitive row as tolerance-based or integer-exact.

Local validation:

  • cargo fmt --all --check
  • cargo test --test determinism_contract
  • git diff --check

The inline Qodo thread has also been replied to and resolved.

@project-navi-bot Navi Bot (project-navi-bot) merged commit 7efe9cd into main Jun 3, 2026
36 checks passed
@project-navi-bot Navi Bot (project-navi-bot) deleted the codex/backend-determinism-contract branch June 3, 2026 16:20
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.

compat: cross-backend determinism and score-equivalence contract

3 participants