Skip to content
CAI
Software that uses CAICheck a score

astral-sh/ruff

66.3

Adequate · 29 July 2026

632k

lines of production code

Rust

primary language

2

measurements over time

CAI band scale
CAI trend line
CAI lens gauges

How this codebase got here

Score

  • CAI 60 → 66 (+6.6)
  • Rubric changed (rubric-2026.08.17 → rubric-2026.08.18) — scores are not directly comparable.

Lenses

  • Code Health 78 → 78 (-0.2)
  • Architecture 90 → 90 (+0.1)
  • Maturity 85 → 79 (-6.8)
  • Readiness 49 → 55 (+6.6)
  • Security 58 → 77 (+18.8)
  • Domain Modelling 100 → 100 (+0.0)
  • Event Sourcing 100 → 100 (+0.0)
  • Accessibility 70 → 70 (+0.0)

Resolved (167)

  • BoundTypeVarInstance.apply_type_mapping_impl (cyclomatic 16) (crates/ty_python_semantic/src/types/typevar.rs)
  • Boundary-crossing change coupling: db.rs ↔ ty_check_invalid_syntax.rs (crates/ruff_graph/src/db.rs)
  • CallArguments.expand (cyclomatic 16) (crates/ty_python_semantic/src/types/call/arguments.rs)
  • CallableDescription.new (cyclomatic 16) (crates/ty_python_semantic/src/types/call/bind.rs)
  • Change coupling: codes.rs ↔ mod.rs (crates/ruff_linter/src/codes.rs)
  • Change coupling: codes.rs ↔ mod.rs (crates/ruff_linter/src/codes.rs)
  • Change coupling: codes.rs ↔ mod.rs (crates/ruff_linter/src/codes.rs)
  • Change coupling: codes.rs ↔ mod.rs (crates/ruff_linter/src/codes.rs)
  • Change coupling: format.rs ↔ format_range.rs (crates/ruff_server/src/server/api/requests/format.rs)
  • ClassDecoratorUnknownResultPolicy.known_from_decorator (cyclomatic 16) (crates/ty_python_semantic/src/types/infer/builder/class.rs)
  • ClassType.into_callable (cognitive 22) (crates/ty_python_semantic/src/types/class.rs)
  • ClassType.into_callable (cyclomatic 16) (crates/ty_python_semantic/src/types/class.rs)
  • CodeActions.run_with_snapshot (cyclomatic 16) (crates/ruff_server/src/server/api/requests/code_action.rs)
  • ConfigArgumentParser.parse_ref (cyclomatic 16) (crates/ruff/src/args.rs)
  • Consequences/trade-offs are cut by the scanner clip marker and not flagged as missing; only context and decision are visible (crates/ty_python_semantic/resources/mdtest/regression/3208_recursive_protocol_signature.md)
  • Decision and consequences are absent; only a test is shown (crates/ty_python_semantic/resources/mdtest/regression/3020_callable_type_of.md)
  • Decision is a code-assertion test with no context or consequences; the body is boilerplate stubs of static_assert calls (crates/ty_python_semantic/resources/mdtest/regression/2236_tuple_is_disjoint.md)
  • Definitions.resolve (cyclomatic 16) (crates/ruff_python_semantic/src/definition.rs)
  • Dependency hygiene not measured — no supported dependency manifest was read
  • DisplayParameters.fmt_detailed (cognitive 32) (crates/ty_python_semantic/src/types/display.rs)
  • …and 147 more

New (201)

  • ArgumentTypeChecker::check_argument_type (cognitive 17) (crates/ty_python_semantic/src/types/call/bind.rs)
  • ArgumentTypeChecker::evaluate_paramspec_sub_call (cognitive 17) (crates/ty_python_semantic/src/types/call/bind.rs)
  • AssignmentAttributeWriteEvaluator::evaluate_class (cognitive 27) (crates/ty_python_semantic/src/types/infer/builder/attribute_assignment.rs)
  • Change coupling: capabilities.rs ↔ requests.rs (crates/ty_server/src/capabilities.rs)
  • Change coupling: dunder_all.rs ↔ class.rs (crates/ty_python_semantic/src/dunder_all.rs)
  • Change coupling: expression.rs ↔ codes.rs (crates/ruff_linter/src/checkers/ast/analyze/expression.rs)
  • Change coupling: fix.rs ↔ lint.rs (crates/ruff_server/src/fix.rs)
  • Change coupling: goto_type_definition.rs ↔ hover.rs (crates/ty_server/src/server/api/requests/goto_type_definition.rs)
  • Change coupling: lib.rs ↔ requests.rs (crates/ty_ide/src/lib.rs)
  • Change coupling: mod.rs ↔ check_docstring.rs (crates/ruff_linter/src/rules/pydoclint/mod.rs)
  • Change coupling: server.rs ↔ requests.rs (crates/ty_server/src/server.rs)
  • Change coupling: symbol.rs ↔ infer.rs (crates/ty_python_core/src/symbol.rs)
  • Change coupling: testing.rs ↔ program.rs (crates/ty_module_resolver/src/testing.rs)
  • ClassType::into_callable_with_receiver (cognitive 26) (crates/ty_python_semantic/src/types/class.rs)
  • ClassType::into_callable_with_receiver (cyclomatic 16) (crates/ty_python_semantic/src/types/class.rs)
  • Critical CVE: [GHSA redacted] (playground/package-lock.json)
  • Dependency hygiene not measured — dependency manifest found but not parsed for hygiene
  • DisplayParameters::fmt_detailed::display_parameters (cognitive 20) (crates/ty_python_semantic/src/types/display.rs)
  • Document::propagate_expand::propagate_expands (cognitive 21) (crates/ruff_formatter/src/format_element/document.rs)
  • Document::propagate_expand::propagate_expands (cyclomatic 21) (crates/ruff_formatter/src/format_element/document.rs)
  • …and 181 more

Changes since last survey

  • 211 commits — 190 feature/other, 21 fixes

By area

  • crates/ty_python_semantic — 69 commits
  • (root) — 39 commits
  • crates/ruff_linter — 39 commits
  • .github/workflows — 16 commits
  • crates/ruff — 8 commits
  • crates/ty_ide — 8 commits
  • crates/ty — 4 commits
  • python/ruff-ecosystem — 4 commits
  • crates/ruff_db — 3 commits
  • docs/requirements.txt — 3 commits
  • crates/ruff_python_parser — 2 commits
  • crates/ty_project — 2 commits
  • crates/ty_python_core — 2 commits
  • crates/ty_server — 2 commits
  • playground/api — 2 commits
  • (repo) — 1 commit
  • crates/ruff_benchmark — 1 commit
  • crates/ruff_dev — 1 commit
  • crates/ruff_server — 1 commit
  • crates/ty_site_packages — 1 commit

Notable commits

  • fix: Fix format --check spans for syntax errors (#27045)
  • fix: Fix indexing of excluded nested Ruff workspaces (#27303)
  • fix: Stabilize fix diffs in full check output (#26958)
  • fix: [flake8-comprehensions] NFKC-normalize keyword names in C408 fix (#26813)
  • fix: [flake8-pytest-style] Make fixes safe by default and unsafe only when comments are present (PT018) (#27201)
  • fix: [pydocstyle] Document fix safety (D400) (#26971)
  • fix: [pylint] Add missing fix safety gotchas for non-augmented-assignment (PLR6104) (#27250)
  • fix: [pyupgrade] Skip fix when a defaulted TypeVar precedes a non-defaulted one (UP040, UP046, UP047) (#27133)
  • fix: [refurb] Mark fixes that remove unknown separators as unsafe (FURB105) (#27200)
  • fix: [ruff] Fix false positive with unpacked arguments (RUF065) (#26959)
  • fix: [ruff] Fix missing check on unrecognized early bound (RUF016) (#26986)
  • fix: [ty] Fix Just[float] protocol matching (#27053)
  • fix: [ty] Fix ParamSpec declaration hover and type navigation (#27183)
  • fix: [ty] Fix Self binding for classmethod new constructors (#27030)
  • fix: [ty] Fix missing-override-decorator suggestion before Python 3.12 (#27166)
  • fix: [ty] Fix double specialization of generic type aliases (#27058)
  • fix: [ty] Fix gradual class assignability with generic receivers (#27223)
  • fix: [ty] Fix identity narrowing for NewTypes (#26439)
  • fix: [ty] Fix nested short-circuit flow snapshots (#26956)
  • fix: [ty] Fix type and TypeForm intersections (#27099)
  • …and 191 more

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

Survey your own repository

astral-sh/ruff was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.

About this page

  • The score is its most recent published measurement, taken on 29 July 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
  • Measured at commit 7de420ecd242fdecf859c65b8ffdaaae339c9a54 — the exact code this score is about.
  • Scored under rubric-2026.08.18 — the same rubric and the same method as every other entry in this index.
  • Measured by watchdog.canine.dev using codehealth-analyzer latest.