---
# ansible-lint для HomeLab infras.
#
# Profile: moderate.
#   - `production` / `safety` дали бы сотни нарушений на текущем коде (fqcn,
#     jinja[spacing], no-handler, key-order, галактические метаданные ролей) —
#     линтер стал бы шумом, который все игнорируют.
#   - Фактическая проверка: на этом репозитории `basic` и `moderate` дают
#     ровно один и тот же набор нарушений (все сработавшие правила помечены
#     profile:basic). То есть `moderate` сегодня ничего не стоит, но держит
#     планку выше для нового кода. Отсюда выбор.
#   - Правила корректности и безопасности (syntax-check, risky-file-permissions,
#     risky-shell-pipe, risky-octal, no-changed-when, no-free-form, deprecated-*,
#     jinja[invalid], sanity) НЕ отключены — они остаются fatal.

profile: moderate

exclude_paths:
  - archive/            # исторические NixOS/docker-compose/ansible конфиги, read-only
  - ansible/.venv/      # gitignored, локальное venv
  - ansible/collections/  # gitignored, установленные galaxy-коллекции
  - ansible/generated/  # gitignored артефакты
  - .opencode/          # конфиги агентов + node_modules
  - tools/              # tools/grimmory-mcp — JS, не ansible
  - node_modules/
  - .direnv/
  - .git/
  # Зашифрованный ansible-vault: линтер не может его расшифровать и шумит
  # предупреждениями о Decryption failed.
  - ansible/inventory/host_vars/gyro/vault.yml

# Явно указываем, что считать плейбуками/тасками — иначе ansible-lint
# принимает inventory/*.yml и roles/*/files/*.yml за плейбуки.
kinds:
  - playbook: 'ansible/playbooks/*.yml'
  - tasks: 'ansible/tasks/*.yml'

# ------------------------------------------------------------------
# warn_list — правила, которые СЕЙЧАС массово срабатывают на легаси-коде.
# Они видны в выводе как warning, но не роняют CI. Это осознанный
# «нулевой baseline»: CI зелёный, долг виден.
# По каждому пункту — почему и стоит ли возвращать в fatal.
# ------------------------------------------------------------------
warn_list:
  # 40 срабатываний. Роли используют осмысленные кросс-ролевые префиксы
  # (openvpn_*, monitoring_*, emergency_*), а не имя роли. Переименование
  # затронет inventory, host_vars и все плейбуки разом.
  # ВЕРНУТЬ В FATAL: после разового переименования переменных ролей.
  - var-naming[no-role-prefix]

  # 19 срабатываний. Имена задач в нижнем регистре ("restart gitea lxc").
  # Чисто косметика, на поведение не влияет.
  # ВЕРНУТЬ В FATAL: после массового причёсывания имён (дешёвый разовый PR).
  - name[casing]

  # 18 срабатываний. Часть файлов без "---" в начале.
  # ВЕРНУТЬ В FATAL: тривиально чинится, но затрагивает 18 файлов.
  - yaml[document-start]

  # 6 срабатываний. Все — верификационные команды с changed_when: false
  # (curl для проверки HTTPS-эндпоинта, systemctl is-active, git config
  # внутри чужого чекаута, docker exec caddy validate). Замена на
  # uri/systemd/git-модули здесь не улучшает код, а иногда невозможна
  # (команда исполняется внутри pct/docker exec).
  # ВЕРНУТЬ В FATAL: вряд ли — правило по сути false-positive для этого стиля.
  - command-instead-of-module

  # 5 срабатываний: безымянные `- import_playbook:` записи в *-update.yml.
  # 1 срабатывание: безымянный `- block:` в ru-vps-mihomo-harden.yml.
  # Влияет только на читаемость вывода ansible-playbook.
  # ВЕРНУТЬ В FATAL: да, после того как проставят name (мелкий PR).
  - name[play]
  - name[missing]

  # 1 срабатывание: emergency_access/tasks/client.yml:46 — become_user без
  # become. Это, вероятно, НАСТОЯЩИЙ баг (ключ создаётся не тем пользователем),
  # но чинить его — задача не линтера. Держим в warn_list, чтобы CI не был
  # красным с первого дня; ВЕРНУТЬ В FATAL сразу после фикса.
  - partial-become

# skip_list пуст намеренно: ничего не отключаем полностью, всё либо fatal,
# либо видимый warning.
skip_list: []

use_default_rules: true
