# llmlint configuration. Docs: https://github.com/nickderobertis/llmlint
#
# llmlint uses an LLM as a judge for checks deterministic linters can't express.
# Phrase each rule as a positive invariant: holds=true means the code complies;
# holds=false is a violation. Keep using deterministic linters for everything
# they can already check.
#
# `version` is this config's published version. It matters when the config is
# consumed elsewhere as a plugin: that consumer pins a desired version with an
# `@` suffix on the URL (see `plugins` below).
version: 1

# Files linted when none are passed explicitly on the CLI. Omit this block (or
# leave `include` empty) to lint every file in the tree from the current
# directory; `exclude` and `.gitignore` still narrow the set.
files:
  include:
    - "src/**"
  exclude:
    - "**/target/**"

# Whether judges must justify each verdict with a short `rationale` (default
# true). Rationales improve auditability (a record of *why* each verdict landed),
# debugging (you see the judge's reasoning, not just pass/fail), and reliability
# (the judge reasons before concluding) — but they cost extra output tokens on
# every request. Turn off to save tokens (`rationales: false`, or
# `--no-rationales`); override per rule with a rule-level `rationale:`.
rationales: true

# Plugins / shared rule sets, merged in one line each. An entry is a config
# file: a local path or a URL (`http(s)://`, `file://`). Pin a URL to a version
# with `@` (e.g. `…/rules.yml@1.2.3`); a pinned URL is fetched and cached once
# and only refetched when you change the pin. The bundled config-lint plugin
# below lints this file's own rules for clear names and descriptions — it ships
# inside llmlint and resolves offline, so keep it on.
plugins:
  - "https://raw.githubusercontent.com/nickderobertis/llmlint/main/assets/config_lint.yml@1"

# Agents group rules and add reviewer context. Rules with no `agent` use the
# `default` agent. `harness` is any id from `oneharness list`; omit it to let
# oneharness pick its own configured default. Use YAML anchors to share prompt
# text across agents.
agents:
  default:
    harness: claude-code

rules:
  # Example rule — edit or replace. `judges: 3` would run three independent
  # judges and take the majority vote for higher-stakes checks.
  - name: public_items_are_documented
    description: |
      Every public function, struct, enum, and module has a doc comment
      explaining its purpose.
    judges: 1

  # `relevance` scopes a rule to the changes it applies to, so you don't have to
  # bolt "or not applicable" onto every description. It is `true` by default
  # (always evaluated); set `false` to disable a rule (reported "not relevant"
  # with no judge call), or give a condition the judge decides first — it reports
  # "not relevant" (no pass/fail) when the condition does not hold.
  #
  # - name: errors_are_contextualized
  #   description: |
  #     TRUE when every returned error adds context about the operation that
  #     failed. FALSE when an error is propagated with no added context.
  #   relevance: the change adds or modifies error handling

  # `require_line_attribution: true` makes every violation of a rule cite a
  # concrete file + line (the schema requires it, so the judge localizes the
  # whole batch in one turn; an unlocalized violation is then a hard error). Use
  # it for rules whose findings should always point at an exact source location.
  #
  # - name: no_todo_comments
  #   description: No TODO or FIXME comments remain in the code.
  #   require_line_attribution: true
