Skip to content

Quality Gates & Verification

Before any code is merged, it MUST pass the following automated and manual quality gates.

1. Mandatory Pre-Commit Checks

Run these commands locally to ensure your code is ready for CI:

# 1. Rust Formatting & Linting
cargo clippy --workspace --all-targets --all-features -- -D warnings
cargo fmt --all

# 2. Python Formatting & Linting
uv run ruff check . --fix
uv run ruff format .

# 3. Static Type Checking (Python)
uv run --group types --group bench --group etl basedpyright

# 4. Unit Testing
# We use cargo-nextest for fast, concurrent test execution.
# By default, heavy regression tests are excluded (see .config/nextest.toml).
# Always use --release for Rust tests as debug performance is non-representative.
cargo nextest run --release --all-features

# 4b. The dataset-backed suites, in one command (~25 s warm, 50 tests).
# This is the inverse of the default filter: exactly what step 4 holds back. It needs no
# environment — `common::datasets` defaults to the in-tree caches `tests/data/hub_cache`
# and `tests/data/icra2020` — and it must run in release, because unoptimised these are
# ~19x slower (10.12 s against 0.52 s for one render-tag case) and the suites refuse a
# debug build rather than let that cost pass unnoticed.
#
# These suites FAIL when their dataset is absent. That is deliberate: until 2026-10-06 they
# returned early and reported "8 passed; finished in 0.00s", and PR #449 moved render-tag
# corner RMSE 25-40 % under that cover with every gate green. If you genuinely have no
# datasets, say so with LOCUS_ALLOW_MISSING_DATASETS=1 and accept that they verify nothing.
cargo nextest run --profile datasets --release --features bench-internals

# Build the Python extension in release mode before running Python tests.
uv run maturin develop --release --manifest-path crates/locus-py/Cargo.toml
uv run pytest

# 5. Cross-Compilation Check (aarch64)
# Ensure NEON/SIMD paths compile correctly for ARM targets.
rustup target add aarch64-unknown-linux-gnu
cargo check --target aarch64-unknown-linux-gnu --all-features

2. Performance & Regression Gates

Changes to the detection pipeline, math kernels, or SIMD dispatch must empirically validate that latency and recall remain within acceptable bounds.

Micro-Optimization Protocol

Before performing any micro-performance optimization (e.g., SIMD kernels, hot-loop refactoring): 1. Setup Benchmark: Create or update a realistic, isolated benchmark in crates/locus-core/benches/ using the divan framework. 2. Establish Baseline: Run the benchmark on the main branch or current stable state to establish a statistically significant baseline. 3. Verify Gain: Demonstrate a measurable improvement in the targeted metric without regressing other pipeline stages.

# Example: Running a specific micro-benchmark
cargo bench --bench comprehensive -- "bench_thresholding"

System-Level Verification

Datasets are pinned in xtask/datasets.toml and fetched into tests/data/ (where the tests and loaders look by default):

cargo xtask data fetch icra2020-forward icra2020-circle icra2020-random euroc
cargo xtask data fetch hub --subsets all
# 1. Forward Evaluation — ICRA 2020 (Accuracy & Yield)
uv run --group bench tools/cli.py bench real --compare

# 2. Hub Dataset Evaluation — Python CLI (Recall + Pose RMSE)
PYTHONPATH=. uv run --group bench tools/cli.py bench real --hub-config locus_v1_tag36h11_1920x1080
PYTHONPATH=. uv run --group bench tools/cli.py bench real --hub-config aprilgrid_golden_v1_1920x1080
PYTHONPATH=. uv run --group bench tools/cli.py bench real --hub-config charuco_golden_v1_1920x1080

# 3. Rust Regression Testing (Sequential for accurate latency)
# Reads tests/data/icra2020 by default; LOCUS_ICRA_DATASET_DIR relocates it.
TRACY_NO_INVARIANT_CHECK=1 cargo test --release --test regression_icra2020 --features bench-internals -- --test-threads=1

# Environment, for reference:
#   LOCUS_HUB_DATASET_DIR / LOCUS_ICRA_DATASET_DIR  relocate a dataset; unset uses the
#       in-tree default, and a value that is not a directory is an error rather than a
#       silent fallback.
#   LOCUS_ALLOW_MISSING_DATASETS=1  let the dataset suites report success without data.
#       Only for environments that have none (CI sets it on the snapshot-parity step).
#   LOCUS_ALLOW_DEBUG_DATASET_TESTS=1  permit an unoptimised run, e.g. under a debugger.
#
# 4. Snapshot Verification & Update
# Runs all regression suites (ICRA, Hub tag-level, Hub board-level, distortion)
# and dictionary parity tests. LOCUS_HUB_DATASET_DIR is required by
# regression_render_tag and regression_distortion_hub; regression_board_hub
# resolves tests/data/hub_cache/ automatically from the workspace root.
#
# The distortion suite (regression_distortion_hub) additionally requires
# syncing the `aprilgrid_distortion_brown_conrady_v1_1920x1080` and
# `aprilgrid_distortion_kannala_brandt_v1_1920x1080` configs — see
# `.agent/skills/testing/SKILL.md` for the one-time setup.
TRACY_NO_INVARIANT_CHECK=1 \
LOCUS_ICRA_DATASET_DIR=tests/data/icra2020 \
LOCUS_HUB_DATASET_DIR=tests/data/hub_cache \
cargo insta test --release --all-features --features bench-internals --review

# 5. EuRoC MAV Real-Data Regression (Optional)
# Reads tests/data/euroc (cargo xtask data fetch euroc)
TRACY_NO_INVARIANT_CHECK=1 \
cargo test --release --features bench-internals,non_rectified \
  --test regression_euroc -- --test-threads=1

Comparative Verification (cargo xtask sota)

The regression suites guard against Locus getting worse than itself. Claims about Locus relative to other detectors — and any change expected to move the scoreboard — are checked with cargo xtask sota against the pinned references (OpenCV 4.10.0, aruco_nano 961b18b); see xtask/README.md.

cargo xtask sota setup                                # once
cargo xtask sota run euroc --jobs 4 --stride 2        # quick accuracy-only pass
cargo xtask sota all liu4k                            # fetch, run, score, report
cargo xtask sota scoreboard                           # win table over every scored benchmark

Accuracy runs may use --jobs > 1; latency is publishable only from --jobs 1 runs on an idle machine, reported with lscpu metadata, build profile and thread count (Constraints §6).

3. Documentation Quality

# 1. Sync dependencies for documentation
uv sync --group docs

# 2. Build the MkDocs static site
uv run --group docs mkdocs build