Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .config/nextest.toml
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ retries = 1
[[profile.default.overrides]]
# Trybuild compile checks build fixture crates in isolated target directories
# and can exceed the generic 60s timeout on shared developer machines.
filter = "test(/portable_simd_gating_compile_checks|session_api_compiles_when_cpu_feature_is_enabled|dataset_recipe_phase_order|arrow_parquet_types_share_one_family/)"
filter = "test(/portable_simd_without_feature_is_rejected|portable_simd_with_feature_compiles|session_api_compiles_when_cpu_feature_is_enabled|dataset_recipe_phase_order|arrow_parquet_types_share_one_family/)"
threads-required = 4
slow-timeout = { period = "300s", terminate-after = 1, grace-period = "5s" }

Expand Down Expand Up @@ -171,7 +171,7 @@ retries = 1
[[profile.ci.overrides]]
# Trybuild compile checks build fixture crates in isolated target directories
# and can exceed the generic 60s timeout on shared runners.
filter = "test(/portable_simd_gating_compile_checks|session_api_compiles_when_cpu_feature_is_enabled|dataset_recipe_phase_order|arrow_parquet_types_share_one_family/)"
filter = "test(/portable_simd_without_feature_is_rejected|portable_simd_with_feature_compiles|session_api_compiles_when_cpu_feature_is_enabled|dataset_recipe_phase_order|arrow_parquet_types_share_one_family/)"
threads-required = 4
slow-timeout = { period = "300s", terminate-after = 1, grace-period = "5s" }

Expand Down
10 changes: 10 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,13 @@ updates:
cooldown:
default-days: 7
semver-major-days: 14

# Keep the pinned Rust toolchain current alongside Cargo dependencies.
- package-ecosystem: "rust-toolchain"
directory: "/"
open-pull-requests-limit: 5
labels:
- "dependencies"
- "rust-toolchain"
schedule:
interval: "weekly"
5 changes: 5 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,11 @@ jobs:
# out is what makes the local backend's indifference to those
# variables count.
use-sccache: 'false'
# `make lint` selects the dated Cranelift maintenance toolchain and
# checksum-verified mold binary. The direct stable SIMD and coverage
# commands below continue to use the repository toolchain.
- name: Install development build prerequisites
run: make install-dev-fast
# Pinned, checksum-verified release archive; nothing is built from
# source in CI.
- name: Install sccache
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/coverage-main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ jobs:
# the rest of the job. Keeping the step out avoids that. See
# ci.yml.
use-sccache: 'false'
# Keep the lint build shape identical to ci.yml's cache reader. Coverage
# itself invokes Cargo directly and remains on the repository toolchain.
- name: Install development build prerequisites
run: make install-dev-fast
# Pinned, checksum-verified release archive; nothing is built from
# source in CI.
- name: Install sccache
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/nightly-portable-simd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ jobs:
run: |
cargo +nightly test -p chutoro-providers-dense \
--features nightly_portable_simd \
-- --skip portable_simd_gating_compile_checks
-- --skip portable_simd_without_feature_is_rejected
- name: Lint dense portable SIMD backend
if: ${{ steps.gate.outputs.should_run == 'true' }}
run: cargo +nightly clippy -p chutoro-providers-dense --all-targets --features nightly_portable_simd -- -D warnings
2 changes: 2 additions & 0 deletions .markdownlint-cli2.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
},
"ignores": [
"**/.venv/**",
// Generated third-party Verus installation Markdown is outside repository ownership and must not be formatted or linted.
"**/.verus/**",
".node_modules/**",
"**/node_modules/**",
"**/target/**",
Expand Down
72 changes: 49 additions & 23 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,42 +133,66 @@ This repository is written in Rust and uses Cargo for building and dependency
management. Contributors should follow these best practices when working on the
project:

- Run `make check-fmt`, `make lint`, and `make test` before committing. These
targets wrap the following commands, so contributors understand the exact
behaviour and policy enforced:
- Run `make check-fmt`, `make lint`, and `make test` before committing. Their
routing is part of the repository build policy:
- `make check-fmt` executes:

```sh
cargo fmt --workspace -- --check
```

validating formatting across the entire workspace without modifying files.
- `make lint` executes rustdoc and Clippy followed by the Whitaker Dylint
suite:
- `make lint` runs `lint-clippy` and then `lint-whitaker`. The first target
runs rustdoc with `RUSTDOCFLAGS="--cfg docsrs -D warnings"` and Clippy
with all targets and features plus `-D warnings`, using the toolchain and
fragment recorded by `tools/dev-fast/TOOLCHAIN` and
`tools/dev-fast/config.toml`. That fragment selects Cranelift and uses GCC
with `mold` on Linux. Install its toolchain components and `mold` with
`make install-dev-fast`; provide GCC on Linux. The installer verifies the
pinned `mold` archive. See the [toolchain and build routing
guide](docs/developers-guide.md#rust-toolchain-and-build-routing). Linux CI
provisions the prerequisites and runs `lint-clippy` through the fragment;
`lint-whitaker` invokes the wrapper
with `RUSTFLAGS="-D warnings"` and uses its own pinned toolchain without
the development fragment.

```sh
cargo doc --workspace --no-deps
cargo clippy --all-targets --all-features -- -D warnings
RUSTFLAGS="-D warnings" whitaker --all -- --all-targets --all-features
```

linting every target with all features enabled and denying all warnings.
The `whitaker` wrapper must already be on `PATH`; never install,
upgrade, or downgrade it from this repository — repository tooling and
agents must not modify the user's Whitaker installation. If the wrapper
is missing, ask the user to install it. Per-lint configuration (including
`no_std_fs_operations` exclusions, each with a rationale comment) lives
in the root `dylint.toml`. Use `make lint-clippy` for a Clippy-only pass
where Whitaker is unavailable.
- `make test` executes:

```sh
cargo test --workspace
```

running the full workspace test suite. Use `make fmt`
(`cargo fmt --workspace`) to apply formatting fixes reported by the
formatter check.
- `make test` runs `cargo-nextest` with the selected development toolchain
and configuration for ordinary tests. Nextest starts a separate Cargo
invocation to compile tests and does not inherit the outer Cargo
configuration, so the Makefile passes the fragment before `nextest` and
again with `nextest run` for that inner invocation. On Linux, ordinary
tests use nightly Cranelift with GCC and `mold`. The Makefile sets
`RUSTFLAGS` explicitly because environment `RUSTFLAGS` replaces configured
target rustflags; it repeats the documentation-denial flags and, on Linux,
the `mold` linker flag.
The byte-exact core diagnostic suites (`result_api_surface` and
`session_api_surface`) and the dense negative `portable_simd` check are
excluded from nextest and run in separate Cargo commands under the
repository-pinned stable toolchain. Those commands retain warning and
documentation denials. The positive dense portable-SIMD coverage remains
on the accelerated nextest path.
The HNSW regression test
`graph_helpers_report_poisoning_without_reconfiguring` is a fourth binding
stable test leaf: it deliberately panics while holding the graph's
`RwLock` to verify poisoned-lock handling, and the selected nightly
Cranelift backend aborts on that path instead of unwinding. Make excludes
only this exact case from nextest and runs it separately with stable LLVM
and the warning and documentation denials.
`make build`, `make typecheck`, and the explicit `make dev-build` and
`make dev-test` targets also select this configuration. `make release`,
formatting, coverage, Kani, Verus, benchmarks, and Whitaker do not. Direct
Cargo invocations use stable Rust 1.93.1 and `.cargo/config.toml`, above the
workspace MSRV of 1.89. Non-Linux Make backend support is not established by
CI; the direct stable Cargo path remains available there. Use `make fmt`
(`cargo fmt --all` plus Markdown formatting) to apply formatting fixes
reported by the formatter checks.
- Clippy warnings MUST be disallowed.
- Fix any warnings emitted during tests in the code itself rather than
silencing them.
Expand Down Expand Up @@ -286,8 +310,10 @@ project:
- Use `anyhow`/`eyre` with `.context(...)` to **preserve backtraces** and
provide clear, typed failure paths.
- Update helpers (e.g., `set_dir`) to **return errors** rather than panicking.
- Consume fallible fixtures in `rstest` by **making the test return `Result`**
and applying `?` to the fixture.
- Consume fallible fixtures with a reasoned `.expect(...)` in recognized
`#[test]` and `#[rstest]` bodies when `Result` would only carry setup errors
or make assertions trip `panic_in_result_fn`. Tests with genuinely fallible
work may return `Result` and use `?` when the lint permits it.

### Observability

Expand Down
53 changes: 43 additions & 10 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,9 +1,24 @@
.PHONY: help all clean test build release typecheck lint lint-clippy lint-whitaker fmt check-fmt markdownlint nixie spelling kani kani-full verus bench test-workflow-contracts
.PHONY: help all clean test build release dev-build dev-test install-dev-fast typecheck lint lint-clippy lint-whitaker fmt check-fmt markdownlint nixie spelling kani kani-full verus bench test-workflow-contracts
.NOTPARALLEL: lint

export PATH := $(HOME)/.cargo/bin:$(HOME)/.bun/bin:$(PATH)
export PATH := $(HOME)/.cargo/bin:$(HOME)/.local/bin:$(HOME)/.bun/bin:$(PATH)

APP ?= chutoro-cli
CARGO ?= cargo
DEV_FAST_TOOLCHAIN := $(strip $(file <tools/dev-fast/TOOLCHAIN))
DEV_FAST_CONFIG := tools/dev-fast/config.toml
DEV_CARGO = $(CARGO) +$(DEV_FAST_TOOLCHAIN) --config $(DEV_FAST_CONFIG)
# RUSTFLAGS overrides Cargo configuration rather than extending it. Preserve
# the Linux linker selection when the test gate adds its warning policy.
DEV_FAST_HOST_OS ?= $(shell uname -s)
DEV_TEST_RUSTFLAGS = $(strip -D warnings -Dmissing_docs \
-Dmissing_crate_level_docs \
$(if $(filter Linux,$(DEV_FAST_HOST_OS)),-Clink-arg=-fuse-ld=mold))
# Exact compiler diagnostics belong to the repository's stable toolchain.
STABLE_VERIFY_RUSTFLAGS = -D warnings -Dmissing_docs -Dmissing_crate_level_docs
NEXTEST_ARGS ?=
STABLE_POISONED_LOCK_TEST = hnsw::cpu::test_helpers::tests::graph_helpers_report_poisoning_without_reconfiguring
NEXTEST_FILTER = not kind(bench) & not (package(chutoro-core) & binary(result_api_surface)) & not (package(chutoro-core) & binary(session_api_surface)) & not (package(chutoro-providers-dense) & test(portable_simd_without_feature_is_rejected)) & not (package(chutoro-core) & test(=$(STABLE_POISONED_LOCK_TEST)))
WHITAKER ?= whitaker
BUILD_JOBS ?=
CLIPPY_FLAGS ?= --all-targets --all-features -- -D warnings
Expand Down Expand Up @@ -47,15 +62,16 @@ KANI_VERSION_REMAINDER := $(subst 8,,$(KANI_VERSION_REMAINDER))
KANI_VERSION_REMAINDER := $(subst 9,,$(KANI_VERSION_REMAINDER))
KANI_VERSION_REMAINDER := $(subst .,,$(KANI_VERSION_REMAINDER))
ifneq ($(words $(KANI_VERSION_PARTS)),3)
$(error KANI_VERSION must be MAJOR.MINOR.PATCH)
_KANI_VERSION_CHECK := $(error KANI_VERSION must be MAJOR.MINOR.PATCH)
endif
ifneq ($(strip $(KANI_VERSION_REMAINDER)),)
$(error KANI_VERSION must be MAJOR.MINOR.PATCH)
_KANI_VERSION_CHECK := $(error KANI_VERSION must be MAJOR.MINOR.PATCH)
endif
KANI_LIB_PATH ?= $(KANI_HOME)/kani-$(KANI_VERSION)/toolchain/lib
KANI_ENV ?= LD_LIBRARY_PATH="$(KANI_LIB_PATH):$(LD_LIBRARY_PATH)"

build: target/debug/$(APP) ## Build debug binary
build: ## Build debug binary
$(DEV_CARGO) build $(BUILD_JOBS) --bin $(APP)
release: target/release/$(APP) ## Build release binary

all: release spelling ## Default target builds release binary and checks spelling
Expand All @@ -64,22 +80,39 @@ clean: ## Remove build artefacts
$(CARGO) clean

test: ## Run tests with warnings treated as errors
RUSTFLAGS="-D warnings" $(CARGO) nextest run --profile $(NEXTEST_PROFILE) --all-targets --all-features $(BUILD_JOBS) -E 'not kind(bench)'
RUSTFLAGS="$(DEV_TEST_RUSTFLAGS)" $(DEV_CARGO) nextest run --config $(DEV_FAST_CONFIG) --profile $(NEXTEST_PROFILE) --all-targets --all-features $(NEXTEST_ARGS) $(BUILD_JOBS) -E '$(NEXTEST_FILTER)'
RUSTFLAGS="$(STABLE_VERIFY_RUSTFLAGS)" env -u RUSTUP_TOOLCHAIN $(CARGO) test -p chutoro-core --all-features --test result_api_surface --test session_api_surface $(BUILD_JOBS)
RUSTFLAGS="$(STABLE_VERIFY_RUSTFLAGS)" env -u RUSTUP_TOOLCHAIN $(CARGO) test -p chutoro-providers-dense --all-features --test portable_simd_gating $(BUILD_JOBS) -- --exact portable_simd_without_feature_is_rejected
# Cranelift aborts on this lock-poison panic; verify under pinned stable LLVM.
RUSTFLAGS="$(STABLE_VERIFY_RUSTFLAGS)" env -u RUSTUP_TOOLCHAIN $(CARGO) test -p chutoro-core --all-features --lib $(BUILD_JOBS) -- --exact $(STABLE_POISONED_LOCK_TEST)

target/%/$(APP): ## Build binary in debug or release mode
$(CARGO) build $(BUILD_JOBS) $(if $(findstring release,$(@)),--release) --bin $(APP)
$(if $(findstring release,$(@)),$(CARGO),$(DEV_CARGO)) build $(BUILD_JOBS) $(if $(findstring release,$(@)),--release) --bin $(APP)

# The explicit names use the same selected route as the standard debug gates.
dev-build: build ## Build the debug binary with the selected development backend

dev-test: test ## Run the tests with the selected development backend

install-dev-fast: ## Install pinned nightly components and the verified mold binary
rustup toolchain install $(DEV_FAST_TOOLCHAIN) --profile minimal --component rustfmt --component clippy --component rust-analyzer --component rustc-codegen-cranelift-preview
ifeq ($(DEV_FAST_HOST_OS),Linux)
scripts/install-mold.sh
else
@echo 'mold is Linux-only; the platform linker remains selected'
endif

lint: lint-clippy lint-whitaker ## Run Clippy and the Whitaker Dylint suite with warnings denied

lint-clippy: ## Run rustdoc and Clippy with warnings denied
RUSTDOCFLAGS="$(RUSTDOC_FLAGS)" $(CARGO) doc --workspace --no-deps
$(CARGO) clippy $(CLIPPY_FLAGS)
RUSTDOCFLAGS="$(RUSTDOC_FLAGS)" $(DEV_CARGO) doc --workspace --no-deps
$(DEV_CARGO) clippy $(CLIPPY_FLAGS)

lint-whitaker: ## Run the Whitaker Dylint suite with warnings denied
RUSTFLAGS="-D warnings" $(WHITAKER) --all -- --all-targets --all-features

typecheck: ## Type-check all workspace targets and features
$(CARGO) check --workspace --all-targets --all-features $(BUILD_JOBS)
$(DEV_CARGO) check --workspace --all-targets --all-features $(BUILD_JOBS)

fmt: ## Format Rust and Markdown sources
$(CARGO) fmt --all
Expand Down
4 changes: 2 additions & 2 deletions chutoro-benches/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,11 @@ harness = false

[[test]]
name = "hnsw_environment"
path = "benches/hnsw.rs"
path = "tests/hnsw_environment.rs"

[[test]]
name = "hnsw_ef_sweep_environment"
path = "benches/hnsw_ef_sweep.rs"
path = "tests/hnsw_ef_sweep_environment.rs"

[[bench]]
name = "edge_harvest"
Expand Down
Loading
Loading