agentleFS
korniakornia/kornia-rs/AGENTS.md

kornia-rs

AGENTS.md748 starsChanged 7 days agoApache-2.0View on GitHub

Guidance for AI AGENTS and human contributors working in this repository. kornia-rs is a low-level 3D computer vision library written in Rust, with Python bindings (PyO3/Maturin) and C++ bindings. Part of the Kornia ecosystem. Skills live in .claude/skills/ (also exposed at .agents/skills/). Read the relevant skill before starting a task; this is mandatory for contributors and agents. pixi run skills-check (CI: skills_check.yml) validates their structure and the facts they restate (MSRV, pixi tasks, crates, publish set, cited paths); it cannot…

  • Commits and pushes

We split this AGENTS.md into the rules it gives an agent

18 rules. About 0 are common, 5 are distinctive, and 13 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈5

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 13

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Naming convention: use <output>_from_<input> — gray_from_rgb, rgb_from_gray, bgr_from_rgb.

    line 113
  2. Very specific:

    Dtype dispatch: use a sealed trait (e.g. GrayFromRgb) to route a single fn gray_from_rgb<T: GrayFromRgb> entry point to the right kernel at …

    line 115
  3. Very specific:

    Run rustfmt and clippy before every commit — warnings are denied

    line 124
  4. Distinctive:

    Prefer borrowing over cloning, especially for images and tensors

    line 125
  5. Very specific:

    Use Conventional Commits: feat:, fix:, docs:, refactor:, test:, chore:

    line 128
  6. Distinctive:

    Every public item must have a doc comment.

    line 132
  7. Very specific:

    Document all pub functions, structs, enums, and traits — no exceptions

    line 170
  8. Distinctive:

    Keep examples compilable (they run as doctests)

    line 173
  9. Very specific:

    Avoid unsafe unless strictly necessary

    line 177
  10. Very specific:

    Every unsafe block must be preceded by a // SAFETY: comment explaining exactly why it is sound:

    line 178
  11. Very specific:

    Never cast away const or use transmute without an explicit soundness proof in the comment

    line 187
  12. Very specific:

    Prefer safe abstractions (e.g., bytemuck, zerocopy) over raw pointer arithmetic where possible

    line 188
  13. Very specific:

    Use thiserror for all library error types — no anyhow in library crates

    line 192
  14. Very specific:

    Never use .unwrap(), .expect(), or panic!() in library code

    line 193
  15. Very specific:

    Avoid allocations in hot paths — use pre-allocated &mut output buffers (established pattern)

    line 212
  16. Distinctive:

    Prefer iterators over index-based loops for cache-friendly access

    line 213
  17. Distinctive:

    Do not clone images or tensors unnecessarily — pass references

    line 214
  18. Very specific:

    Verify doctests compile and pass: cargo test --doc -p <crate>

    line 251

≈ “Common” is an estimate: at least 1 in 5 of the 36,368 AGENTS.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
AGENTS.md

AGENTS.md

Guidance for AI AGENTS and human contributors working in this repository.

Project Overview

kornia-rs is a low-level 3D computer vision library written in Rust, with Python bindings (PyO3/Maturin) and C++ bindings. Part of the Kornia ecosystem.


Required Skills

Skills live in .claude/skills/ (also exposed at .agents/skills/). Read the relevant skill before starting a task; this is mandatory for contributors and agents. pixi run skills-check (CI: skills_check.yml) validates their structure and the facts they restate (MSRV, pixi tasks, crates, publish set, cited paths); it cannot check that a skill was applied — review does that. pixi run pr-check is the pre-PR gate.

SkillRead when
kornia-archnavigating crates, features, core types
kornia-workflowbefore committing/PR; build, lint, test, PR rules
kornia-coding-styleany Rust edit
kornia-api-flavordesigning new public API
kornia-code-reviewmandatory self-review before every PR; reviewing a PR: scope, copies, latency, benchmarks
kornia-curationchanging a fact the guidance describes; editing skills
kornia-simdSIMD / performance work in kornia-imgproc
kornia-bindingsPython / C++ binding changes
releasecutting a release

Build & Development Commands

The project uses pixi for environment management.

Rust

pixi run rust-test                    # Run all Rust tests (with CI features)
pixi run rust-test-package <package>  # Test a specific crate
pixi run rust-lint                    # Format + clippy + check (run before PRs)
pixi run rust-clippy                  # Clippy with -D warnings, all targets, CI features
pixi run rust-fmt                     # Format with rustfmt
pixi run rust-check                   # Check compilation

# Without pixi (direct cargo)
cargo test --features ci
cargo test -p kornia-imgproc
cargo clippy --workspace --no-deps --all-targets --features ci -- -D warnings

Python Bindings

pixi run py-build   # Build kornia-py (dev mode via maturin)
pixi run py-test    # Run pytest (auto-builds first)

C++ Bindings

pixi run cpp-test   # Build and run C++ tests

Architecture

Workspace Structure

Cargo.toml          ← workspace root
crates/*            ← core library crates (default members)
examples/*          ← standalone example binaries
kornia-py/          ← Python bindings (PyO3/Maturin)
kornia-cpp/         ← C++ bindings

Core Crates

CrateRe-exported asPurpose
kornia-tensorkornia::tensorN-dimensional tensor type
kornia-tensor-opskornia::tensor_opsTensor operations
kornia-imagekornia::imageImage type built on tensors (Image<T, C, _>)
kornia-imgprockornia::imgprocImage processing (resize, color, filters)
kornia-iokornia::ioImage/video I/O (turbojpeg, gstreamer, v4l)
kornia-3dkornia::k3d3D vision (ICP, point clouds)
kornia-algebrakornia::linalgLinear algebra
kornia-vlm(direct)Visual language model integration (candle)
kornia-apriltag(standalone)AprilTag detection
kornia-calib(standalone)Multi-camera extrinsic calibration (AprilTag BA)
kornia-bow(standalone)Bag of words

Feature Flags

FlagDescriptionNotes
turbojpeglibjpeg-turbo I/ORequires nasm
gstreamerGStreamer video—
v4lVideo4Linux cameraRequires clang
cudaCUDA for VLM + kornia-3d (stereo rectifier, via imgproc remap)—
ciAll CI-compatible featuresExcludes cuda
serde, bincode, arrowSerialization formats—

Key Patterns

  • Image type: Image<T, C, Alloc> — T is pixel type (u8, f32), C is channel count (1, 3)
  • Operations: Many imgproc functions take &source and &mut destination (pre-allocated output)
  • I/O: kornia::io::functional provides top-level read/write functions
  • Naming convention: use <output>_from_<input> — gray_from_rgb, rgb_from_gray, bgr_from_rgb. Never rgb_to_gray or gray_to_rgb. The output type comes first.
  • Module layout for SIMD ops: when an op has multiple SIMD kernels (e.g. different per dtype), use a subdir with mod.rs (public Image API + sealed-trait dispatch) and kernels.rs (slice-level dispatch, NEON/AVX2/scalar). See src/color/gray/ as the canonical example. Single-dtype ops can stay in a flat .rs file.
  • Dtype dispatch: use a sealed trait (e.g. GrayFromRgb) to route a single fn gray_from_rgb<T: GrayFromRgb> entry point to the right kernel at compile time. Explicit impls for each concrete type (u8, f32, f64); no blanket impl<T: Float> (conflicts without stable specialization). See SIMD.md for the full pattern.

Code Conventions

General

  • Rust edition 2021, MSRV 1.89
  • Run rustfmt and clippy before every commit — warnings are denied
  • Prefer borrowing over cloning, especially for images and tensors
  • No unwrap() or expect() in library code — always propagate errors with ?
  • Tests live in #[cfg(test)] modules; run per-crate with cargo test -p <crate>
  • Use Conventional Commits: feat:, fix:, docs:, refactor:, test:, chore:

Documentation

Every public item must have a doc comment. Follow this structure:

/// One-line summary of what this does.
///
/// Longer explanation if needed — describe the algorithm, coordinate system,
/// units, or any non-obvious behavior. Keep it factual, not conversational.
///
/// # Arguments
///
/// * `src` - Input image. Must be RGB with `u8` pixels.
/// * `dst` - Pre-allocated output image. Must match `src` dimensions.
///
/// # Returns
///
/// `Ok(())` on success, or a [`KorniaError`] if dimensions mismatch.
///
/// # Errors
///
/// Returns [`KorniaError::InvalidChannels`] if `src` does not have 3 channels.
/// Returns [`KorniaError::SizeMismatch`] if `src` and `dst` dimensions differ.
///
/// # Example
///
/// ```rust
/// use kornia::image::Image;
/// use kornia::imgproc;
///
/// let src = Image::<u8, 3>::new(...)?;
/// let mut dst = Image::<u8, 1>::new(...)?;
/// imgproc::color::rgb_to_grayscale(&src, &mut dst)?;
/// ```
pub fn rgb_to_grayscale(src: &Image<u8, 3>, dst: &mut Image<u8, 1>) -> Result<(), KorniaError> {
    // ...
}

Rules:

  • Document all pub functions, structs, enums, and traits — no exceptions
  • # Arguments, # Returns, and # Errors sections are required on all public functions
  • Include at least one # Example for non-trivial public APIs
  • Keep examples compilable (they run as doctests)

Safety

  • Avoid unsafe unless strictly necessary
  • Every unsafe block must be preceded by a // SAFETY: comment explaining exactly why it is sound:
// SAFETY: `ptr` is non-null and aligned, and `len` bytes have been
// initialised by the preceding call to `init_buffer`. No other references
// to this memory exist at this point.
let slice = unsafe { std::slice::from_raw_parts(ptr, len) };
  • Never cast away const or use transmute without an explicit soundness proof in the comment
  • Prefer safe abstractions (e.g., bytemuck, zerocopy) over raw pointer arithmetic where possible

Error Handling

  • Use thiserror for all library error types — no anyhow in library crates
  • Never use .unwrap(), .expect(), or panic!() in library code
  • In test code, .unwrap() is acceptable but prefer ? with #[test] -> Result<(), Box<dyn Error>>
  • Error variants should be descriptive and carry context:
// Bad
Err(KorniaError::Generic("failed".into()))

// Good
Err(KorniaError::SizeMismatch {
    expected: src.size(),
    got: dst.size(),
})
  • Keep public error enums exhaustively matchable — do not mark them #[non_exhaustive]. When a new failure mode appears, add a variant to the existing error enum and document the (pre-1.0) breaking change in the CHANGELOG. Reserve #[non_exhaustive] for public data structs where future field additions are expected.

Performance

  • Avoid allocations in hot paths — use pre-allocated &mut output buffers (established pattern)
  • Prefer iterators over index-based loops for cache-friendly access
  • Do not clone images or tensors unnecessarily — pass references
  • Benchmark before and after any change to a core algorithm using cargo bench
  • SIMD / cross-arch work in kornia-imgproc: see crates/kornia-imgproc/SIMD.md for the dispatch pattern, cross-arch testing setup (qemu + tonistiigi/binfmt on aarch64 hosts), correctness-vs-scalar harness, benchmark methodology (best-of-N rounds), and common gotchas (qemu overhead, is_x86_feature_detected! compile-time behavior, rayon row-chunking).

Contributing

Pull Requests

  1. Keep PRs small and in scope — one concern per PR, only what the linked issue asks. Out-of-scope hunks are a blocking review finding (kornia-code-review).
  2. Test locally first — pixi run pr-check must pass, plus:

    pixi run py-test     # Python binding tests (if py code changed)
    pixi run cpp-test    # C++ binding tests (if C++ code changed)

    Agents posting comments or reviews for someone end them with Posted on behalf of @<handle> by <Agent> (<actual model>).

    Then self-review with kornia-code-review and paste its output in the PR's Self-review section (required; the PR check fails without it).

  3. Update documentation — any new or changed public API must have updated doc comments. New features need an entry in the relevant crate's README.md or module-level doc.
  4. Write tests — new functionality requires unit tests. Bug fixes require a regression test that would have caught the bug.
  5. PR description — fill in .github/pull_request_template.md (gh pr create --body-file <filled copy>; --body skips the template). It covers:
    • What changed and why
    • Any breaking changes
    • Benchmarks or profiling data for performance-sensitive changes (before/after, see kornia-code-review)
    • AI disclosure: agent + version, model, effort level, skills applied, human vs AI part
    • A changelog.d/<PR>.<type>.md fragment for user-visible changes (see changelog.d/README.md); never edit CHANGELOG.md outside a release PR
    • What use case does this pr address which you use yourself

Contributing to Documentation

  • Doc comments live alongside the code — edit the .rs source file directly
  • Verify doctests compile and pass: cargo test --doc -p <crate>
  • For larger documentation (guides, architecture docs), add or update Markdown files under docs/

Commit Style

Follow Conventional Commits


Quick Reference Checklist (before every PR)

  • pixi run rust-lint passes with zero warnings
  • pixi run rust-test passes
  • All new/changed pub items have complete doc comments (args, errors, panics, example)
  • Every unsafe block has a // SAFETY: comment
  • No unwrap()/expect() added to library code
  • New functionality has unit tests; bug fixes have regression tests
  • Commit messages follow Conventional Commits

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.