Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Gates and checks

Four checks gate the workspace:

cargo fmt --all -- --check                                        # formatting
cargo clippy --all-targets --all-features --locked -- -D warnings # lints, warnings denied
cargo test --all --all-features --locked                          # tests
cargo deny check bans licenses sources                            # dependency policy

No single hook or workflow runs all four. Enforcement is split, and running those four commands yourself is the only place they are checked together. Do it before finishing a unit of work.

What runs where

Checkpre-commitCI
cargo fmtyesyes
cargo clippyyesyes
cargo testnoyes
cargo deny (bans/licenses/sources)yes
cargo deny check advisoriesneverscheduled only

The tests never run on commit because they take too long. The cost is that you have to run them yourself. Do it before you finish a unit of work, not before every commit.

Each pre-commit hook is a whole-workspace check (pass_filenames: false) gated by a files matcher, so the matcher only decides whether it runs this commit, never what it checks. Staging a .rs file runs fmt and clippy over everything; staging only a Markdown file runs neither.

The advisories rule

Never run cargo deny check advisories as a local gate, and never bare cargo deny check, which includes it.

Advisories query the live RustSec database, so a new advisory can fail your build without a single change on your side.

Advisories belong to the scheduled audit.yml workflow, which runs them daily, on pushes touching dependency manifests, and on manual dispatch. If one does appear, do not let it block or derail what you are doing, just flag it and carry on. The fix is a routine cargo update -p <crate> handled separately.

Lint posture

Strict by default, declared in Cargo.toml under [workspace.lints]: clippy pedantic and nursery enabled, unsafe_code forbidden.

Those groups are set to warn in the manifest, but both the pre-commit hook and CI run -D warnings. A warning is a hard failure at the gate. The manifest level only controls what you see mid-edit.

Any unsafe requires a // SAFETY: justification plus an explicit lint allow. Every crate carries #![forbid(unsafe_code)] except vidi-py, whose PyO3 macros expand to unsafe and so cannot inherit the forbid, as it writes none of its own.

CI

Two workflows in .github/workflows/:

lint.yml — every push to main and every pull request. Format check and clippy, then a build-and-test matrix across Linux, macOS and Windows.

It also checks that docs/src/reference/cli.md is current. That page is generated from the binary’s own --help, so a renamed flag silently invalidates it. If the check fails, run python docs/generate-cli-reference.py and commit the result.

audit.yml — the live advisory scan, on a schedule.

Hooks that block skipping

Agent hooks under .claude/hooks/ refuse git commit, push and merge invocations that bypass verification — --no-verify, the -n shorthand, and core.hooksPath overrides.

The point is not that skipping a hook is forbidden. However, skipping one should be a decision you make out loud rather than a flag that becomes a habit.

Next

Commit conventions