Skip to main content

inspect-evals-lint

Static checks for Inspect AI evaluations: file structure, test coverage conventions, best practices and sandbox image pinning.

These checks began life as the autolint tool inside inspect_evals. They are packaged here so any repository of Inspect evaluations can run the same checks, including standalone repos built from the inspect-evals-template and submitted to the inspect_evals register.

Nothing is imported or executed from the evaluation being checked. Every check is static analysis over Python source (via ast), eval.yaml, compose files and pyproject.toml.

Install

uv add --dev inspect-evals-lint
# or
pip install inspect-evals-lint

Usage

inspect-evals-lint <eval_name>            # one evaluation (or helper package, e.g. utils)
inspect-evals-lint --all-evals            # every evaluation and helper package in the repo
inspect-evals-lint --all-evals --summary-only
inspect-evals-lint --check-summary        # per-check compliance across evals
inspect-evals-lint <eval_name> --check registry
inspect-evals-lint --all-evals --json > lint.json
inspect-evals-lint --list-checks

--json writes one document to stdout and sends progress to stderr, so the output can be piped straight into other tooling. It carries passed, run-wide summary counts and, per package, its kind (eval or helper) and every check's status, category (the CHECKS.md section: file_structure, code_quality, tests or best_practices), message, file (relative to the repository root when possible) and line. Evaluations are listed under evaluations (counted by evaluations_total / evaluations_passed) and helper packages under helpers (helpers_total / helpers_passed), so a consumer that only knows evaluations keeps reading the same list. The set of categories is stable: a new check always joins one of the four, because badge and dashboard tooling keys on them.

The repository root is the nearest pyproject.toml carrying a [tool.inspect-evals-lint] table (falling back to the nearest pyproject.toml, then the current directory). Pass --root to override.

Exit codes: 0 all checks passed (warnings, skips and suppressions count as passing), 1 at least one check failed, 2 usage or configuration error.

Configuration

Configuration lives in pyproject.toml. Pick a layout preset and override any field:

[tool.inspect-evals-lint]
preset = "template"   # or "monorepo" / "register"
Key template preset monorepo preset register preset Meaning
source-root src src/inspect_evals src Directory with one sub-directory per evaluation
tests-root tests tests tests Directory holding <tests-root>/<eval>/
tests-layout per-eval per-eval flat flat also accepts test files directly under tests-root when <tests-root>/<eval>/ is absent
readme-location eval-dir eval-dir repo-root repo-root also accepts the repository's top-level README.md
eval-yaml-required true true false Whether a missing eval.yaml fails (a present one is always validated)
import-prefix "" inspect_evals "" Dotted prefix evaluations import under
registry entry-points module entry-points entry-points reads [project.entry-points.inspect_ai]; module greps a registry module; none skips
registry-module unset src/inspect_evals/_registry.py unset Required when registry = "module"
helper-dirs ["utils"] ["utils"] same as template Shared-code packages under source-root, linted with the helper scope (see below)
ignore-dirs ["examples"] [] same as template Sub-directories of source-root that are never linted
eval-yaml-required-fields title, description, group, contributors, tasks same same Keys every eval.yaml must define
isolated-packages-dir unset packages unset Per-eval pyproject.toml directory for isolated dependency sets
disabled-checks [] [] [] Checks that never run
sandbox-image-allowlist {} {} {} { eval = ["image/ref"] } pairs allowed to stay unpinned (warn, not fail)
model-role-allowlist {} {} {} { eval = ["role"] } pairs whose get_model(role=...) may lack a deliberate resolution (warn, not fail)

Without a [tool.inspect-evals-lint] table the template preset is used. --preset overrides the table for one run.

Only Python packages are linted: a sub-directory of source-root without an __init__.py (a README left behind after a move, a data directory) is skipped by --all-evals and reported as a skip when named directly, so it needs no ignore-dirs entry. ignore-dirs is for packages you really do not want checked.

Helper packages

Shared code that evaluations import, such as inspect_evals' utils package, is not an evaluation but does most of the same things: it grades, it resolves models, it imports third-party packages. Directories listed in helper-dirs are linted with the checks that guard that behaviour (private_api_imports, score_constants, unscored_reason, get_model_location, model_role_resolution, sample_ids, task_overridable_defaults, sandbox_image_pinning, external_dependencies, tests_init and the custom_*_tests checks) and not with the ones about an evaluation's structure and registration (main_file, init_exports, readme, registry, eval_yaml, tests_exist, e2e_test, record_to_sample_test). Two checks adapt: external_dependencies requires a helper's module-level third-party imports to be in [project].dependencies, since every evaluation that imports the helper loads them, while imports inside a function, a try block or an if TYPE_CHECKING: block only need declaring in some group or isolated package; and the custom_*_tests checks look for a helper's tests anywhere under tests-root, not only in tests/<name>/. Allowlists are keyed by directory name, so utils = ["grader"] under model-role-allowlist works for a helper too. A failing helper check fails the run like any other.

The register preset is for an upstream repository listed in the inspect_evals register: one evaluation, tests directly under tests/, the README at the repository root, and metadata held by the register entry rather than an eval.yaml in the repo. Run it from outside the repo with inspect-evals-lint --root <clone> --preset register --all-evals --json.

Suppressing a check

  • Line: # noautolint: <check_name> on the offending line (checks that report per-site results: private_api_imports, get_model_location).
  • File: # noautolint-file: <check_name> within the first ten lines of a file.
  • Directory: a .noautolint file in a sub-directory listing check names, one per line. Files under that directory are also excluded from AST-based checks.
  • Evaluation: a .noautolint file in the evaluation directory listing check names.

Checks

See docs/CHECKS.md for the full list with the reasoning behind each check.

Python API

from pathlib import Path
from inspect_evals_lint import (
    get_all_eval_names,
    get_all_helper_names,
    lint_evaluation,
    load_config,
)

root = Path(".")
config = load_config(root)
for name in (*get_all_eval_names(root, config), *get_all_helper_names(root, config)):
    report = lint_evaluation(root, name, config)
    print(name, report.kind, report.passed(), report.summary())

Development

uv sync
uv run pre-commit install   # optional: run the lint stack on every commit
uv run pytest
uv run basedpyright src

Linting (ruff, zizmor, mdformat) runs via pre-commit; CI runs the same stack plus basedpyright and pytest via the shared python-ci reusable workflow.

Releasing

See RELEASING.md.

Release files for inspect-evals-lint 0.2.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for inspect-evals-lint 0.2.1
File Size Uploaded
inspect_evals_lint-0.2.1.tar.gz 92.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for inspect-evals-lint 0.2.1
File Interpreter ABI Platform
inspect_evals_lint-0.2.1-py3-none-any.whl Python 3 none any Details

Total release size: 134.5 kB

Release files / inspect_evals_lint-0.2.1.tar.gz

Download URL inspect_evals_lint-0.2.1.tar.gz
Size 92.2 kB
Tags Source
SHA-256 checksum
How to use checksums
28d8fb8d1893470f1d609e74f97eff91c91ffd025704ccd55955222e41859fed
BLAKE2b-256 checksum
How to use checksums
30d3dac9de96475f2c5c2c6782ea1619396935a44df11af48fd7a1d8765e7044
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 18, 2026.

Transparency log

Release files / inspect_evals_lint-0.2.1-py3-none-any.whl

Download URL inspect_evals_lint-0.2.1-py3-none-any.whl
Size 42.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
4bfa099d4b67d19ce4b2b5c41760a24db531e46323af8b36f916e10328601d38
BLAKE2b-256 checksum
How to use checksums
a8476095713c5dd67511d58a4e50c8f98d59450986e67bef567442cf1aa98be6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 18, 2026.

Transparency log

Release history Release notifications | RSS feed

0.7.0

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.4.3

2 release files

0.4.2

2 release files

0.4.1

2 release files

0.4.0

2 release files

0.3.1

2 release files

0.3.0

2 release files

This release

0.2.1 This release

2 release files

0.2.0

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page