|
| 1 | +# AGENTS.md |
| 2 | + |
| 3 | +This file provides guidance to coding agents collaborating on this repository. |
| 4 | + |
| 5 | +## Mission |
| 6 | + |
| 7 | +Vq is a vector quantization library for Rust. |
| 8 | +It provides implementations of binary quantization (BQ), scalar quantization (SQ), product quantization (PQ), and tree-structured vector quantization (TSVQ). |
| 9 | +The project also ships Python bindings through the `pyvq` package. |
| 10 | + |
| 11 | +Priorities, in order: |
| 12 | + |
| 13 | +1. Correctness of quantization, dequantization, distance calculations, and reconstruction behavior. |
| 14 | +2. A stable, simple Rust API centered on the `Quantizer` trait and public quantizer types. |
| 15 | +3. Reliable Python bindings that match the Rust behavior where exposed. |
| 16 | +4. Performance for training, quantization, and evaluation without sacrificing correctness. |
| 17 | +5. Memory safety across Rust code, C SIMD FFI, and Python bindings. |
| 18 | + |
| 19 | +## Core Rules |
| 20 | + |
| 21 | +- Use English for code, comments, docs, and tests. |
| 22 | +- Prefer small, focused changes over large refactoring. |
| 23 | +- Add comments only when they clarify non-obvious behavior. |
| 24 | +- Do not add features, error handling, dependencies, or abstractions beyond what is needed for the current task. |
| 25 | +- Keep public behavior deterministic where seeds are accepted or required. |
| 26 | +- Preserve compatibility with Rust 1.85 or later unless a task explicitly changes the MSRV. |
| 27 | + |
| 28 | +## Writing Style |
| 29 | + |
| 30 | +- Use Oxford commas in inline lists: "a, b, and c" not "a, b, c". |
| 31 | +- Do not use em dashes. Restructure the sentence, or use a colon or semicolon instead. |
| 32 | +- Avoid colorful adjectives and adverbs. Write "vector quantization library" not "powerful vector quantization library". |
| 33 | +- Use noun phrases for checklist items, not imperative verbs. Write "distance metric coverage" not "cover distance metrics". |
| 34 | +- Headings in Markdown files must be in title case: "Build from Source" not "Build from source". Minor words (a, an, the, and, but, or, for, in, on, at, to, by, of, is, are, was, were, be) stay lowercase unless they are the first word. |
| 35 | + |
| 36 | +## Repository Layout |
| 37 | + |
| 38 | +- `src/lib.rs`: Rust crate root. Re-exports public quantizers, distance types, error types, and core traits. |
| 39 | +- `src/bq.rs`: Binary quantization implementation. |
| 40 | +- `src/sq.rs`: Scalar quantization implementation. |
| 41 | +- `src/pq.rs`: Product quantization implementation. |
| 42 | +- `src/tsvq.rs`: Tree-structured vector quantization implementation. |
| 43 | +- `src/core/`: Shared distance, error, quantizer trait, vector, and optional SIMD FFI modules. |
| 44 | +- `src/bin/`: Evaluation binaries used by `make eval` and `make eval-all`. |
| 45 | +- `tests/`: Rust integration tests and test data helpers. |
| 46 | +- `external/hsdlib/`: C SIMD acceleration library used by the `simd` feature through `build.rs`. |
| 47 | +- `pyvq/`: Python package and bindings built with Maturin. |
| 48 | +- `docs/`: Main project documentation and assets. |
| 49 | +- `.github/workflows/`: CI workflows for tests, linting, documentation, and packaging. |
| 50 | +- `Cargo.toml`: Rust package metadata, feature flags, dependencies, and profile settings. |
| 51 | +- `pyproject.toml`: Python development environment, test, coverage, mypy, and Ruff configuration. |
| 52 | +- `Makefile`: Main automation entry point for formatting, tests, linting, builds, docs, evaluation, and Python workflows. |
| 53 | + |
| 54 | +## Architecture |
| 55 | + |
| 56 | +### Rust Crate |
| 57 | + |
| 58 | +The Rust crate targets edition 2024 and Rust 1.85 or later. |
| 59 | +Public consumers primarily use the quantizer types (`BinaryQuantizer`, `ScalarQuantizer`, `ProductQuantizer`, and `TSVQ`), the `Quantizer` trait, `Distance`, and the `VqResult` / `VqError` error types. |
| 60 | +Keep public API changes deliberate because they affect both Rust users and Python bindings. |
| 61 | + |
| 62 | +### Quantizer API |
| 63 | + |
| 64 | +Quantizers expose training or construction, quantization, and dequantization paths through concrete types and the shared `Quantizer` trait. |
| 65 | +New or changed quantizer behavior should include tests for: |
| 66 | + |
| 67 | +- Valid inputs and expected output shapes. |
| 68 | +- Invalid dimensions, invalid parameters, and empty data when applicable. |
| 69 | +- Distance metric behavior where the quantizer supports distances. |
| 70 | +- Deterministic output when a seed is part of the API. |
| 71 | + |
| 72 | +### Feature Flags |
| 73 | + |
| 74 | +- `default`: No optional features. |
| 75 | +- `binaries`: Evaluation binaries. |
| 76 | +- `parallel`: Enables Rayon-backed parallel training paths. |
| 77 | +- `simd`: Enables C SIMD acceleration through `external/hsdlib` and `build.rs`. |
| 78 | +- `all`: Enables `binaries`, `parallel`, and `simd`. |
| 79 | + |
| 80 | +When changing feature-gated code, verify that the relevant feature combinations still compile. |
| 81 | +At minimum, test the feature set touched by the change and the `all` feature set when practical. |
| 82 | + |
| 83 | +### SIMD and FFI |
| 84 | + |
| 85 | +The `simd` feature uses `external/hsdlib` through C FFI. |
| 86 | +Treat changes in `build.rs`, `external/hsdlib/`, and FFI modules as memory-safety-sensitive. |
| 87 | +Validate pointer lifetimes, slice lengths, alignment assumptions, CPU feature detection, and fallback behavior. |
| 88 | +Run sanitizer or careful checks when changing unsafe Rust or C integration paths. |
| 89 | + |
| 90 | +### Python Bindings |
| 91 | + |
| 92 | +The Python package lives under `pyvq/` and is built with Maturin. |
| 93 | +Python tests are configured through `pyproject.toml` and run with `make test-py`. |
| 94 | +When Rust API changes affect exported Python behavior, update Python bindings, type stubs, docs, and tests together. |
| 95 | + |
| 96 | +## Rust Conventions |
| 97 | + |
| 98 | +- Rust edition: 2024. |
| 99 | +- MSRV: Rust 1.85. |
| 100 | +- Formatting: `cargo fmt` through `make format`. |
| 101 | +- Linting: `cargo clippy` through `make lint`, with warnings denied and `unwrap` / `expect` disallowed. |
| 102 | +- Naming: follow standard Rust naming conventions (`snake_case` functions and variables, `CamelCase` types, `SCREAMING_SNAKE_CASE` constants). |
| 103 | +- Error handling: prefer `VqResult` and `VqError` for library errors. Do not introduce panics for recoverable invalid input. |
| 104 | +- Randomness: expose or use deterministic seeds for tests and reproducible algorithms. |
| 105 | +- Dependencies: avoid new dependencies unless they are necessary and justified. |
| 106 | + |
| 107 | +## Python Conventions |
| 108 | + |
| 109 | +- Python version: `>=3.10,<4.0`. |
| 110 | +- Package tooling: `uv`, Maturin, Pytest, MyPy, and Ruff. |
| 111 | +- Formatting and lint settings are in `pyproject.toml`. |
| 112 | +- Use type annotations for new Python code. |
| 113 | +- Keep Python behavior aligned with the Rust implementation. |
| 114 | + |
| 115 | +## Required Validation |
| 116 | + |
| 117 | +Run the relevant targets for any change: |
| 118 | + |
| 119 | +| Target | Command | What It Runs | |
| 120 | +|--------------------|---------------------|---------------------------------------------------| |
| 121 | +| Rust format | `make format` | `cargo fmt` | |
| 122 | +| Rust tests | `make test` | Format, doctests, and `cargo test --features all` | |
| 123 | +| Rust doctests | `make doctest` | Rust documentation tests with all features | |
| 124 | +| Rust lint | `make lint` | `cargo clippy` with warnings denied | |
| 125 | +| Rust build | `make build` | Release build | |
| 126 | +| Rust benchmarks | `make bench` | `cargo bench --features all` | |
| 127 | +| Coverage | `make coverage` | Tarpaulin XML and HTML coverage reports | |
| 128 | +| Security audit | `make audit` | `cargo audit` | |
| 129 | +| Careful checks | `make careful` | `cargo careful run` | |
| 130 | +| Rust docs | `make docs` | Rust documentation generation | |
| 131 | +| Evaluation | `make eval-all` | Evaluation binaries for BQ, SQ, PQ, and TSVQ | |
| 132 | +| Python develop | `make develop-py` | Maturin development install | |
| 133 | +| Python tests | `make test-py` | Pytest for `pyvq` | |
| 134 | +| Python docs | `make docs-py` | PyVq MkDocs build | |
| 135 | +| Project docs | `make docs-build` | Main MkDocs build | |
| 136 | +| Git hooks | `make test-hooks` | Pre-commit hooks on all files | |
| 137 | + |
| 138 | +For documentation-only changes, tests may be skipped after reviewing the changed Markdown. |
| 139 | +For public Rust API changes, run `make test`, `make lint`, and relevant documentation checks. |
| 140 | +For Python binding changes, run `make test-py` and update type stubs when needed. |
| 141 | +For unsafe Rust, FFI, SIMD, or memory-sensitive changes, run `make careful` or another appropriate sanitizer-style check. |
| 142 | + |
| 143 | +## First Contribution Flow |
| 144 | + |
| 145 | +1. Read the relevant module under `src/` and any matching tests under `tests/`. |
| 146 | +2. Identify whether the change affects the Rust API, Python bindings, feature flags, or SIMD FFI. |
| 147 | +3. Implement the smallest change that covers the requirement. |
| 148 | +4. Add or update tests for new behavior, bug fixes, and edge cases. |
| 149 | +5. Run `make format` and the relevant validation targets. |
| 150 | +6. Update docs, examples, or type stubs when public behavior changes. |
| 151 | + |
| 152 | +Good first tasks: |
| 153 | + |
| 154 | +- A regression test for a quantizer edge case. |
| 155 | +- A small documentation correction in `README.md`, `docs/`, or `pyvq/docs/`. |
| 156 | +- A targeted fix for invalid input handling. |
| 157 | +- A benchmark or evaluation cleanup that does not change public API behavior. |
| 158 | + |
| 159 | +## Testing Expectations |
| 160 | + |
| 161 | +- Prefer deterministic tests with fixed seeds for randomized training or sampling. |
| 162 | +- Cover BQ, SQ, PQ, and TSVQ behavior when shared logic changes. |
| 163 | +- Include shape and dimensionality checks for vector inputs and outputs. |
| 164 | +- Include negative tests for invalid parameters and incompatible vector dimensions. |
| 165 | +- Compare floating-point results with tolerances instead of exact equality when appropriate. |
| 166 | +- Keep long-running benchmark or evaluation workloads out of regular unit tests. |
| 167 | +- Test Python binding behavior when exposed Python APIs change. |
| 168 | + |
| 169 | +## Change Design Checklist |
| 170 | + |
| 171 | +Before coding: |
| 172 | + |
| 173 | +1. Public API surface: Rust exports, Python bindings, docs, and type stubs. |
| 174 | +2. Feature flags: default, `parallel`, `simd`, `binaries`, and `all`. |
| 175 | +3. Algorithm behavior: output shape, reconstruction error expectations, and distance semantics. |
| 176 | +4. Error behavior: invalid inputs, empty data, and dimension mismatches. |
| 177 | +5. Memory safety: unsafe Rust, FFI pointers, C buffers, and ownership across Python bindings. |
| 178 | +6. Performance impact: avoid unnecessary allocations and preserve existing parallel or SIMD paths. |
| 179 | + |
| 180 | +Before submitting: |
| 181 | + |
| 182 | +1. `make format` has been run or the change is Markdown-only. |
| 183 | +2. Relevant Rust tests pass for the affected feature set. |
| 184 | +3. `make lint` passes when Rust code changes. |
| 185 | +4. Python tests pass when `pyvq/` changes. |
| 186 | +5. Docs or examples are updated when public behavior changes. |
| 187 | +6. Unsafe, FFI, or memory-sensitive changes have an additional safety validation. |
| 188 | + |
| 189 | +## Commit and PR Hygiene |
| 190 | + |
| 191 | +- Keep commits scoped to one logical change. |
| 192 | +- Do not commit generated artifacts such as coverage reports, built wheels, `target/`, or `site/` unless explicitly requested. |
| 193 | +- PR descriptions should include: |
| 194 | + 1. Behavioral change summary. |
| 195 | + 2. Tests added or updated. |
| 196 | + 3. Validation commands run locally, such as `make test`, `make lint`, or `make test-py`. |
0 commit comments