Lint¶
botica lint runs the rules of its catalog and of the catalogs of the project.
The design is in
ADR 0003.
The catalog under catalog/rules/ is the only documentation of the rules: each rule has a README,
the rules of this site show it, and botica rules lists them.
Commands¶
botica lint # the current directory
botica lint src tests/a.py # directories to walk, or files (as prek passes them)
botica lint --select file-size-guard,no-utils
botica lint --output-format json # text (default), json, sarif, github or markdown; json and sarif carry the
# code and the standard of the rule of each finding
botica lint --judged judge.sarif # the findings of a judge, filtered by the configuration and comments;
# the file is SARIF or the report of `abide check --json`
botica lint --diff origin/main # the files changed since the merge base, and only the findings on
# the lines the change adds (ADR 0009); no result cache
botica lint --staged # the same for the changes staged against HEAD, read from the index
botica lint --diff-file pr.diff # the same for the changes of a unified diff
botica lint --commit-msg "$1" # the rules of scope commit over a commit message, and no file
botica lint --commits origin/main..HEAD # over each commit of the range (ADR 0010)
botica lint --pr-title="$PR_TITLE" # over the title of a pull request
botica rules # which rules are active, and why (--all adds the inactive ones), the
# programs that `botica lint` runs and the tools that enforce rules
# outside it; --json adds the kind of each implementation
botica explain no-notebooks # what a rule is, how it is built and how it is configured here
botica rules eval no-utils src # what one rule finds in real code, on or off in the configuration,
# for a review of its false positives; the findings do not fail it
botica rules export --format markdown --output site # one page per rule of the catalog, and an index;
# the catalogs of .botica/rules get a folder and an index section each
botica rules export --format json --output out # the whole catalog in out/catalog.json
botica rules export --format agents-md --output AGENTS.md [--check]
# the active judgment rules, between <!-- botica:rules --> and <!-- /botica:rules -->;
# a judgment rule whose covered-by names an active rule is left out
botica rules export --format abide [--check] # the rubric of abide, .abide/rubric.json, with the
# judgment rules of the block of AGENTS.md (--agents-md names another file)
Editor has botica server, Recipes has botica recipe,
References has botica refs, and Write a rule has botica rules
new, conform and test.
Exit code: 0 clean (a warning does not fail the run), 1 a finding of severity error, 2
the run itself failed (it wins over 1). --fail-on warning (or info, hint) lowers the
severity that exits with 1. --exit-zero forgives only the findings.
Rules¶
botica rules --all lists the rules of the catalog, with their code and whether each is active and
why; botica explain <slug> shows one, with its standard and its status. A rule with the status
preview is off by default: it runs only with preview = true and when you select it. A rule of
kind external is enforced by another tool through its configuration
(External rules).
Which files¶
The walk honours .gitignore and enters hidden directories (.github/…) except the directories
of tools, caches and agent configuration (.git, .venv, .mypy_cache, .botica, .agents,
.claude…; the list is TOOL_DIRS in crates/botica-core/src/walk/mod.rs). A path named on the
command line is linted even if it is on that list or excluded, unless you pass --force-exclude,
which leaves out what extend-exclude names and what sits in a directory of a tool (unless
extend-include asks for it). The botica hook of the mirror passes it, because prek names every
file.
extend-exclude = ["vendor/"]skips more (gitignore globs); it wins over everything.extend-include = ["generated/api.py"]brings back what.gitignoreorTOOL_DIRSleave out.
Result cache¶
--cache keeps per-file results in .botica/cache under the project root; --cache-dir <dir>
chooses another place. It is off by default and meant for CI and --all-files. The key is the file
path and bytes; the whole cache is discarded when the version, the configuration or the rules
change. A directory botica creates ignores itself in git; one that already existed is left alone,
so add it to your .gitignore. A cache that cannot be written (a read-only checkout) is a warning
on stderr, not a failure: the findings and the exit code are the same, only the next run is slower.