- Replace pylint with ruff (backend/ruff.toml) - line-length=300, max-complexity=10, per-file-ignores for tests - Exclude D (docstrings replaced by contracts) and ANN - Add eslint flat config for frontend (eslint-plugin-svelte) - Allow console.info/warn/error (belief-state protocol) - Remove .pylintrc (references non-existent plugin) - Update agent docs: ruff check . + npm run lint - Add ruff>=0.11.0 to backend/requirements.txt - Add eslint + plugins to frontend devDependencies
138 lines
4.9 KiB
Markdown
138 lines
4.9 KiB
Markdown
# План: Линтер (Ruff + ESLint) для агентской разработки
|
||
|
||
## Мотивация
|
||
|
||
Привести тулинг проекта в соответствие с GRACE-Poly протоколом:
|
||
|
||
- **Pylint** — мёртвый груз (плагин `pylint_ai_checker.checker` не существует, никто не использует)
|
||
- **Ruff** — уже де-факто стандарт (все агенты ссылаются на `ruff check`), но нет конфига
|
||
- **ESLint** — есть `.eslintignore`, но нет ни конфига, ни зависимостей, ни npm-скрипта
|
||
- **semantics-contracts** `@REJECTED`: linter НЕ должен проверять GRACE-Poly контракты — это агентский протокол
|
||
|
||
---
|
||
|
||
### 1. Создать `backend/ruff.toml`
|
||
|
||
```toml
|
||
target-version = "py313"
|
||
line-length = 300 # перенос из .pylintrc (символов в строке, не LOC)
|
||
|
||
[lint]
|
||
select = [
|
||
"F", # pyflakes — неиспользуемые импорты/переменные (антислэш)
|
||
"E", "W", # pycodestyle — PEP8
|
||
"I", # isort — порядок импортов
|
||
"N", # pep8-naming — snake_case
|
||
"UP", # pyupgrade — современный Python 3.13
|
||
"B", # flake8-bugbear — баги
|
||
"SIM", # flake8-simplify — упрощение
|
||
"C4", # flake8-comprehensions
|
||
"C90", # mccabe — cyclomatic complexity (INV_7 из semantics-core)
|
||
"ARG", # flake8-unused-arguments — мёртвые аргументы
|
||
"T20", # flake8-print — запрет print (должен быть log())
|
||
"RUF", # ruff-specific
|
||
]
|
||
ignore = [
|
||
"E501", # line-length — своё через глобальный параметр
|
||
"D", # pydocstyle — контракты заменяют docstring (per .pylintrc)
|
||
"ANN", # аннотации — слишком педантично
|
||
]
|
||
|
||
[lint.mccabe]
|
||
max-complexity = 10 # INV_7 из semantics-core
|
||
|
||
[lint.per-file-ignores]
|
||
"tests/*" = ["T20"] # в тестах print разрешён
|
||
```
|
||
|
||
### 2. Удалить `.pylintrc` из корня проекта
|
||
|
||
- Плагин `pylint_ai_checker.checker` не существует
|
||
- Ruff покрывает всё (и быстрее, и с автофиксом)
|
||
- Ни один агент/скилл не ссылается на pylint
|
||
|
||
### 3. Добавить ruff в `backend/requirements.txt`
|
||
|
||
```
|
||
ruff>=0.11.0
|
||
```
|
||
|
||
### 4. Создать `frontend/eslint.config.js` (flat config)
|
||
|
||
```js
|
||
import svelte from "eslint-plugin-svelte";
|
||
import js from "@eslint/js";
|
||
import globals from "globals";
|
||
|
||
export default [
|
||
js.configs.recommended,
|
||
...svelte.configs["flat/recommended"],
|
||
{
|
||
languageOptions: {
|
||
globals: { ...globals.browser, ...globals.node },
|
||
},
|
||
rules: {
|
||
"no-unused-vars": ["error", { argsIgnorePattern: "^_" }],
|
||
"no-console": ["warn", { allow: ["warn", "error"] }],
|
||
},
|
||
},
|
||
{
|
||
ignores: [
|
||
"node_modules/", "dist/", "build/",
|
||
".svelte-kit/", ".vite/", "coverage/",
|
||
],
|
||
},
|
||
];
|
||
```
|
||
|
||
### 5. Обновить `frontend/package.json`
|
||
|
||
**devDependencies** (добавить):
|
||
```json
|
||
"eslint": "^9.0.0",
|
||
"@eslint/js": "^9.0.0",
|
||
"eslint-plugin-svelte": "^3.0.0",
|
||
"globals": "^16.0.0"
|
||
```
|
||
|
||
**scripts** (добавить):
|
||
```json
|
||
"lint": "eslint .",
|
||
"lint:fix": "eslint . --fix"
|
||
```
|
||
|
||
`.eslintignore` уже существует — его содержимое корректно.
|
||
|
||
### 6. Обновить агентские инструкции
|
||
|
||
| Файл | Изменение |
|
||
|---|---|
|
||
| `.opencode/agents/python-coder.md` | `ruff check src/ tests/` → `ruff check .` |
|
||
| `.opencode/agents/qa-tester.md` | `ruff check src/ tests/` → `ruff check .` |
|
||
| `.opencode/agents/fullstack-coder.md` | `ruff check src/ tests/` → `ruff check .` |
|
||
| `.opencode/agents/speckit.md` | Добавить `npm run lint` в verification |
|
||
| `.opencode/skills/semantics-python/SKILL.md` | `ruff check src/ tests/` → `ruff check .` |
|
||
| `.opencode/skills/semantics-contracts/SKILL.md` | `ruff check .` |
|
||
| `.opencode/command/speckit.*.md` | `ruff check backend/src/ backend/tests/` → `ruff check .` |
|
||
|
||
### 7. Верификация
|
||
|
||
```bash
|
||
# Python
|
||
cd backend && source .venv/bin/activate
|
||
pip install -r requirements.txt # установка ruff
|
||
python -m ruff check .
|
||
|
||
# Frontend
|
||
cd frontend && npm install # установка eslint + плагинов
|
||
npm run lint
|
||
```
|
||
|
||
---
|
||
|
||
## Что НЕ проверяет linter (сознательно)
|
||
|
||
- GRACE-Poly анкоры (`@BRIEF`, `@RELATION`, `@PRE`/`@POST`, `#region`) — rejected контрактами
|
||
- Наличие/отсутствие контрактных тегов C1-C5 — агентский протокол
|
||
- Длину модуля (< 400 LOC) и контракта (< 150 LOC) — сложно автоматизировать в linter, мониторится через code review
|