Skip to content

chore(ci): production release gate (CI matrix, SDE AVX-512, deny, MSRV)#3

Merged
Fieldnote-Echo merged 6 commits into
mainfrom
prod/ci
May 23, 2026
Merged

chore(ci): production release gate (CI matrix, SDE AVX-512, deny, MSRV)#3
Fieldnote-Echo merged 6 commits into
mainfrom
prod/ci

Conversation

@Fieldnote-Echo
Copy link
Copy Markdown
Owner

Production release gate — CI, deny, Cargo metadata

Stacked on #1 (hygiene) — merge #1 first.

CI (.github/workflows/ci.yml)

  • lintcargo fmt --check + clippy --all-targets --all-features -D warnings.
  • test — ubuntu/macos/windows matrix; default, --features experimental, --no-default-features, + release build of bench_rank.
  • msrvdtolnay/rust-toolchain@1.89.0 build + test. No rust-toolchain.toml by design — the action does not override one, so a committed file would take rustup precedence and silently change the floor.
  • deps — fails if any blas|openblas|faer|ndarray|statrs enters the tree (--all-features --edges normal,build,dev), then cargo publish --dry-run.
  • avx512 — runs the suite under Intel SDE (Sapphire Rapids) so the AVX-512 kernels are actually exercised on hosted runners. A CPUID probe fails the job if SDE doesn't expose AVX-512 (no silent no-op coverage), and a moved Intel URL fails loudly rather than skipping.
  • Workflow RUSTFLAGS: -D warnings, concurrency cancel-in-progress, least-privilege permissions, pinned actions.

Project hygiene

  • deny.toml (cargo-deny: license allow-list, advisories, bans, crates.io-only sources) — passes clean.
  • CHANGELOG.md (Keep a Changelog) + .github/PULL_REQUEST_TEMPLATE.md.
  • Cargo.toml: license = "MIT OR Apache-2.0" + [package.metadata.docs.rs].

Cross-PR note: the LICENSE-MIT / LICENSE-APACHE files + README dual-license land in #2 (de-fiction). Both are needed for a coherent dual-license.

Note

The lint / SDE jobs can only be fully validated on GitHub's runners; locally I verified the deps-gate regex (catches a planted ndarray, passes clean on ordvec), cargo deny check, cargo publish --dry-run packaging, and the SDE heredoc/probe generation.

All 26 clippy errors fixed across src/, tests/, and examples/:
- manual_is_multiple_of (13×): x % n == 0 → x.is_multiple_of(n),
  stable since 1.87, safe on MSRV 1.89
- manual_range_contains (2×): negated range comparisons →
  !(a..=b).contains(&x)
- manual_repeat_n (1×): repeat(v).take(n) → repeat_n(v, n),
  stable 1.82
- too_many_arguments (7×): #[allow] with justifying comment on
  scan_b2_fastscan_avx512, scan_b2_fastscan_scalar,
  scan_via_lut_scalar (src), finalise_row, bench_two_stage,
  bench_two_stage_batched, bench_sign_two_stage_batched (examples)
- needless_range_loop (9×): #[allow] on all SIMD kernel loops
  (bitmap.rs AVX-512 kernels, sign_bitmap.rs AVX-512 kernel,
  fastscan.rs scalar finalize) plus two clear mechanical rewrites
  in tests/rank_index/quant.rs and two #[allow] in
  tests/rank_index/index.rs (raw index used in assertion message)

cargo fmt --all run; reformatted bitmap.rs, fastscan.rs and
several test/example files. No behavior change.
Old lockfile was version 3 and still listed serde as a transitive
dependency that no longer exists in the dependency tree. Regenerated
with `cargo generate-lockfile`; new lockfile is version 4, contains
no serde entries, and passes `cargo build --locked` and
`cargo test --locked`.
@qodo-code-review
Copy link
Copy Markdown

Review Summary by Qodo

Production release gate: CI workflow, MSRV, AVX-512 SDE, deny, and code hygiene

✨ Enhancement 🧪 Tests

Grey Divider

Walkthroughs

Description
• Implement production release gate CI workflow with multi-OS testing matrix
• Add AVX-512 coverage via Intel SDE emulation on Sapphire Rapids
• Enforce MSRV 1.89, dependency hygiene, and packaging validation
• Apply cargo fmt and clippy fixes across codebase (13× manual_is_multiple_of, 9×
  needless_range_loop, 7× too_many_arguments)
• Add project hygiene: deny.toml (licenses/advisories/bans), CHANGELOG.md, dual MIT/Apache-2.0
  license, PR template
Diagram
flowchart LR
  A["Code Formatting<br/>cargo fmt + clippy"] --> B["CI Workflow<br/>lint/test/msrv/deps/avx512"]
  C["Cargo.toml<br/>dual license + docs.rs"] --> B
  D["deny.toml<br/>licenses/advisories/bans"] --> B
  E["CHANGELOG.md<br/>Keep a Changelog"] --> B
  F["PR Template<br/>checklist"] --> B
  B --> G["Release Gate<br/>Production Ready"]

Loading

File Changes

1. .github/workflows/ci.yml ⚙️ Configuration changes +194/-0

Production CI workflow with multi-OS matrix and AVX-512 SDE

.github/workflows/ci.yml


2. deny.toml ⚙️ Configuration changes +76/-0

License allow-list, advisories, bans, crates.io-only sources

deny.toml


3. CHANGELOG.md 📝 Documentation +53/-0

Initial release notes following Keep a Changelog format

CHANGELOG.md


View more (22)
4. .github/PULL_REQUEST_TEMPLATE.md 📝 Documentation +20/-0

PR checklist for formatting, testing, SIMD, and hygiene

.github/PULL_REQUEST_TEMPLATE.md


5. Cargo.toml ⚙️ Configuration changes +10/-1

Dual MIT/Apache-2.0 license and docs.rs metadata

Cargo.toml


6. examples/bench_rank.rs Formatting +141/-63

Formatting and clippy fixes for too_many_arguments

examples/bench_rank.rs


7. tests/rank_index/bitmap.rs Formatting +40/-23

Import reordering and line-wrapping for readability

tests/rank_index/bitmap.rs


8. src/rank_index/bitmap.rs ✨ Enhancement +19/-29

Replace modulo checks with is_multiple_of, add needless_range_loop allows

src/rank_index/bitmap.rs


9. src/rank_index/quant.rs ✨ Enhancement +30/-15

Replace modulo checks with is_multiple_of, format function signatures

src/rank_index/quant.rs


10. tests/redteam_alpha.rs Formatting +21/-6

Line-wrapping and formatting for readability

tests/redteam_alpha.rs


11. src/sign_bitmap.rs ✨ Enhancement +10/-11

Replace modulo checks with is_multiple_of, add needless_range_loop allows

src/sign_bitmap.rs


12. tests/redteam_beta.rs Formatting +11/-29

Simplify filter chains and improve line wrapping

tests/redteam_beta.rs


13. src/rank_io.rs ✨ Enhancement +11/-21

Replace modulo checks with is_multiple_of and range contains

src/rank_io.rs


14. src/rank_index/fastscan.rs ✨ Enhancement +10/-19

Add too_many_arguments allow and format macro invocations

src/rank_index/fastscan.rs


15. tests/rank_index/fastscan.rs Formatting +15/-7

Import reordering and line-wrapping for readability

tests/rank_index/fastscan.rs


16. tests/rank_index/main.rs Formatting +14/-11

Import reordering and use repeat_n instead of repeat().take()

tests/rank_index/main.rs


17. tests/rank_index/quant.rs Formatting +17/-14

Import reordering and iterator chain simplification

tests/rank_index/quant.rs


18. src/rank_index/quant_kernels.rs ✨ Enhancement +13/-8

Add too_many_arguments allow and format assert statements

src/rank_index/quant_kernels.rs


19. src/rank.rs ✨ Enhancement +15/-8

Add needless_range_loop allow and format assertions

src/rank.rs


20. tests/rank_index/index.rs ✨ Enhancement +3/-1

Add needless_range_loop allows for assertion clarity

tests/rank_index/index.rs


21. src/rank_index/util.rs Formatting +2/-7

Simplify boolean logic and format function signature

src/rank_index/util.rs


22. src/rank_index/multi_bucket.rs Formatting +3/-6

Simplify iterator chain formatting

src/rank_index/multi_bucket.rs


23. tests/redteam_delta.rs Formatting +7/-5

Format string and file creation for readability

tests/redteam_delta.rs


24. src/rank_index/index.rs Formatting +5/-1

Format struct initialization for readability

src/rank_index/index.rs


25. tests/rank_index/multi_bucket.rs Formatting +2/-2

Import reordering for consistency

tests/rank_index/multi_bucket.rs


Grey Divider

Qodo Logo

@qodo-code-review
Copy link
Copy Markdown

qodo-code-review Bot commented May 22, 2026

Code Review by Qodo

🐞 Bugs (2) 📘 Rule violations (0)

Grey Divider


Action required

1. Deps gate regex bypass 🐞 Bug ≡ Correctness
Description
In the deps job, the grep pattern treats - and _ as word characters, so forbidden crates with
common suffixes (e.g., openblas-src, blas-src, faer-core, ndarray-rand) will not match and
can slip into the dependency tree. This breaks the intended “no BLAS/faer/ndarray/statrs” release
gate.
Code

.github/workflows/ci.yml[R117-122]

Evidence
The workflow captures cargo tree output and checks it with a regex whose boundary classes
explicitly treat - and _ as non-boundaries, so strings like openblas-src won’t satisfy the
required right boundary after openblas.

.github/workflows/ci.yml[113-123]

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 deps-gate grep uses boundary classes that include `-` and `_`, which prevents matches when a forbidden crate name is followed or preceded by those characters. This allows common suffixed/prefixed crate names (like `openblas-src`) to bypass the gate.

## Issue Context
The workflow is intended to enforce a “no system/numerical deps” guarantee, but the current regex only detects exact tokens separated by characters *other than* alnum/`_`/`-`.

## Fix Focus Areas
- .github/workflows/ci.yml[113-123]

### Suggested direction
Update the check to parse crate names more robustly (e.g., `cargo tree --prefix none` and match whole crate names), or adjust the regex so `-`/`_` act as boundaries (or explicitly match known suffix patterns such as `(-src)?`).

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



Remediation recommended

2. Unverified SDE tarball execution 🐞 Bug ⛨ Security
Description
The avx512 job downloads an Intel SDE tarball, extracts it, and executes the included sde64
binary without any checksum/signature verification. This makes CI execution dependent on the
integrity of an unauthenticated artifact and weakens the “production release gate” trust model.
Code

.github/workflows/ci.yml[R149-156]

Evidence
The workflow uses wget to fetch the tarball, immediately extracts it with tar, and then runs the
extracted sde64 binary; there is no checksum/signature verification step in between.

.github/workflows/ci.yml[149-156]
.github/workflows/ci.yml[185-191]

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 workflow downloads an external tarball and executes its binary (`sde64`) without verifying integrity (e.g., SHA256). This is a supply-chain risk for a release gate.

## Issue Context
Even with a pinned URL/version, without an integrity check the workflow cannot detect tampering or unexpected content.

## Fix Focus Areas
- .github/workflows/ci.yml[149-156]
- .github/workflows/ci.yml[185-191]

### Suggested direction
Add a pinned checksum (e.g., `SDE_SHA256`) and verify it before extraction/execution, or vendor/cache the artifact in a trusted location and validate it prior to running.

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


Grey Divider

Qodo Logo

Comment thread .github/workflows/ci.yml
Copy link
Copy Markdown

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

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 prepares the ordvec crate for its initial release (v0.1.0) by adding a PR template, a detailed changelog, and a cargo-deny configuration for license and advisory checks. The codebase has been extensively refactored for better idiomaticity and formatting, including the use of is_multiple_of for alignment checks and the addition of clippy allow attributes for specialized SIMD kernels. Additionally, the serde dependency was removed, the license was updated to MIT OR Apache-2.0, and various tests were updated for clarity. I have no feedback to provide.

The x86 SIMD dispatch (select_simd_tier + the SimdTier match arms, the AVX
kernels, BATCHED_AVX512_CHUNK) is cfg(target_arch=x86_64)-gated, but the glue
it references — the SimdTier::Avx2/Avx512 variants, the batched-chunk consts,
and the simd_tier / centre_drop_used bindings — was defined unconditionally.
On non-x86 (aarch64 / macos-latest CI) those are dead/unused and, under
RUSTFLAGS=-D warnings, fail the build with 7 dead_code/unused errors.

Add cfg_attr(not(target_arch=x86_64), allow(...)) to each so the crate builds
clean on aarch64 (scalar path) while x86 is untouched. Verified: aarch64 lib +
tests + examples compile clean under -D warnings; x86 fmt/clippy/test 80/86.
…al license)

CI workflow (.github/workflows/ci.yml) — Grumpy's release gate:
- lint:    fmt --check + clippy --all-targets --all-features -D warnings
- test:    ubuntu/macos/windows matrix; default, experimental,
           no-default-features; release build of bench_rank example
- msrv:    rust 1.89.0 build + test (proves the declared AVX-512 floor)
- deps:    cargo tree gate failing on blas|openblas|faer|ndarray|statrs
           + cargo publish --dry-run
- avx512:  runs the suite under Intel SDE (-spr / Sapphire Rapids) so the
           runtime-dispatched AVX-512 kernels are actually covered on
           GitHub-hosted runners that lack AVX-512. Includes an inline
           is_x86_feature_detected! probe asserting SDE exposes avx512f +
           avx512vpopcntdq. Pattern adapted from microsoft/DiskANN.
Actions pinned: dtolnay/rust-toolchain, Swatinem/rust-cache@v2,
actions/checkout@v4.

Cargo.toml:
- license = "MIT OR Apache-2.0" (was "MIT")
- [package.metadata.docs.rs]: all-features = false,
  rustdoc-args = ["--cfg", "docsrs"] (keeps experimental + doc-hidden
  items off the published docs page)

Hygiene:
- deny.toml (cargo-deny 0.19 schema): license allow-list
  MIT/Apache-2.0/Unicode-3.0/BSD-2-Clause/Apache-2.0-WITH-LLVM-exception;
  advisories + bans (multiple-versions warn, wildcards deny); sources
  locked to crates.io. `cargo deny check` passes clean.
- CHANGELOG.md (Keep a Changelog) with Unreleased + 0.1.0 extraction notes
- .github/PULL_REQUEST_TEMPLATE.md

rust-toolchain.toml intentionally omitted: a committed toolchain file
takes rustup precedence over dtolnay/rust-toolchain@1.89.0 and would
silently defeat the MSRV job (verified empirically).
The previous comment claimed CI overrides a contributor rust-toolchain.toml.
In fact dtolnay/rust-toolchain neither removes nor overrides one — a committed
toolchain file takes rustup directory-override precedence and would silently
change the MSRV floor. The repo intentionally has no such file; say so, and
pin the floor in the workflow as the source of truth.
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a “production release gate” for the ordvec Rust crate by introducing a comprehensive CI workflow (lint/test/MSRV/deps/AVX-512-under-SDE), plus release hygiene artifacts (cargo-deny config, changelog, PR template) and some accompanying formatting/lint-driven refactors across core code, examples, and tests.

Changes:

  • Add GitHub Actions CI with OS matrix testing, MSRV enforcement, dependency-tree gate + publish dry-run, and AVX-512 coverage via Intel SDE.
  • Add release hygiene files (deny.toml, CHANGELOG.md, PR template) and update crate metadata (dual license expression, docs.rs config, refreshed lockfile).
  • Apply clippy-/rustfmt-driven refactors and targeted #[allow]s to keep -D warnings clean across platforms/SIMD cfgs.

Reviewed changes

Copilot reviewed 25 out of 26 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
.github/workflows/ci.yml New CI workflow covering lint, OS matrix tests, MSRV, deps/publish gate, and AVX-512 coverage under Intel SDE.
.github/PULL_REQUEST_TEMPLATE.md Adds a PR checklist aligned with the new CI/release gates.
deny.toml Introduces cargo-deny policy for licenses/advisories/bans/sources.
CHANGELOG.md Adds Keep-a-Changelog formatted changelog with initial 0.1.0 entry.
Cargo.toml Updates license expression and configures docs.rs build options.
Cargo.lock Regenerated lockfile (v4), removing stale transitive entries.
src/rank_io.rs Refactors validation checks (range/is_multiple_of) and minor signature formatting.
src/rank.rs Adds a targeted clippy allow for indexed loop; minor formatting in tests.
src/sign_bitmap.rs Uses is_multiple_of, adds clippy allows for kernel-style loops, minor formatting.
src/rank_index/index.rs Formatting-only struct construction change.
src/rank_index/util.rs Formatting-only changes in TopK utilities.
src/rank_index/multi_bucket.rs Minor formatting of parallel scoring loop.
src/rank_index/bitmap.rs Uses is_multiple_of, adds clippy allows for kernel loops, minor formatting.
src/rank_index/fastscan.rs Adds clippy allow for argument-heavy kernels; minor formatting.
src/rank_index/quant.rs Non-x86 warning hygiene via cfg_attr allows; is_multiple_of and formatting tweaks.
src/rank_index/quant_kernels.rs Adds clippy allow for argument-heavy scalar kernel; formatting in asserts.
examples/bench_rank.rs Formatting and clippy allows for argument-heavy bench helpers.
tests/redteam_alpha.rs Formatting-only refactors in tests.
tests/redteam_beta.rs Formatting-only refactors in tests.
tests/redteam_delta.rs Formatting-only refactor of temp-file forge helper.
tests/rank_index/main.rs Formatting refactors; uses repeat_n; minor assertion formatting.
tests/rank_index/index.rs Import ordering + targeted clippy allow for indexed loop in tests.
tests/rank_index/quant.rs Import ordering + small iterator refactors and formatting.
tests/rank_index/bitmap.rs Formatting-only refactors in tests.
tests/rank_index/fastscan.rs Import ordering + formatting-only refactors.
tests/rank_index/multi_bucket.rs Import ordering changes.

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

Comment thread .github/workflows/ci.yml Outdated
Comment thread .github/workflows/ci.yml
Comment thread tests/rank_index/main.rs
Comment thread Cargo.toml
Address bot review on PR #3:
- deps gate: the word-boundary class [^[:alnum:]_-] treated '-'/'_' as part of
  the crate name, so blas-src / openblas-src / ndarray-linalg / faer-core /
  blas_sys slipped through the no-system-deps check. Drop '_' and '-' from the
  boundaries so those variants are caught (verified: still clean on ordvec, no
  false positive on names like 'myblaster').
- avx512 (SDE): pin and verify the Intel SDE tarball SHA256 before unpacking and
  executing it — the job previously ran remote network content unverified.
@Fieldnote-Echo Fieldnote-Echo merged commit 579626b into main May 23, 2026
7 checks passed
@Fieldnote-Echo Fieldnote-Echo deleted the prod/ci branch May 23, 2026 00:02
Fieldnote-Echo added a commit that referenced this pull request May 23, 2026
… review)

Address the bot review wave (gemini/Codex/qodo) — all "convert core panics to
clean Python errors", completing the binding's boundary-guard design:

- Width validation (check_width): every f32 input now checks ncols == dim (2-D)
  / len == dim (1-D). The core derives n = len/dim and only asserts divisibility,
  so a wrong-but-divisible shape (e.g. (1,128) into a dim-64 index) was silently
  reinterpreted as a different vector count, or panicked on the result reshape.
  Now a clean ValueError. (gemini x3 critical, Codex x2 P1, qodo #3)
- Constructor validation: Rank/RankQuant/Bitmap/SignBitmap `new` return PyResult
  and validate against the EXACT core asserts (dim in [2, u16::MAX]; bits in
  {1,2,4} + dim multiple of 8/bits and 2^bits; dim % 64 + 0 < n_top < dim;
  dim % 64 + <= MAX_SIGN_BITMAP_DIM) -> ValueError instead of panic. (gemini x4)
- swap_remove (Rank, RankQuant): bounds-check -> IndexError, not panic.
  (gemini high, qodo #4)
- README provenance tightened to the canonical "developed within turbovec,
  factored out" phrasing. (qodo #2)

Tests: +9 (width-mismatch x6, swap_remove OOB x3); constructor-rejection tests
tightened from BaseException to ValueError. Suite now 117 passed + 1 xfail.
clippy -D warnings + fmt clean; MSRV 1.89 builds core + binding.

Not changed: qodo #1 (ndarray via numpy) is a deliberate, documented core-vs-
binding split (deps grep + publish scoped to -p ordvec; the core's published lock
is clean; the binding is publish = false, PyPI-only) -- explained on-thread.
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.

2 participants