chore: configure ruff + eslint linters for agentic workflow

- 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
This commit is contained in:
2026-05-14 10:28:30 +03:00
parent 4074506114
commit 9b8c485562
13 changed files with 1337 additions and 25 deletions

View File

@@ -62,7 +62,8 @@ You own:
# Backend
cd backend && source .venv/bin/activate
python -m pytest -v
python -m ruff check src/ tests/
python -m ruff check .
npm run lint # from frontend/
# Frontend
cd frontend

View File

@@ -71,7 +71,7 @@ cd backend && source .venv/bin/activate && python -m pytest -v
python -m pytest --cov=src --cov-report=term-missing
# Ruff linting
python -m ruff check src/ tests/
python -m ruff check .
# Specific test file
python -m pytest tests/test_auth.py -v

View File

@@ -47,7 +47,8 @@ For each production contract, verify:
## Execution
- **Python tests:** `cd backend && source .venv/bin/activate && python -m pytest -v`
- **Python coverage:** `python -m pytest --cov=src --cov-report=term-missing`
- **Python lint:** `python -m ruff check src/ tests/`
- **Python lint:** `python -m ruff check .`
- **Frontend lint:** `cd frontend && npm run lint`
- **Svelte tests:** `cd frontend && npm run test`
- **Svelte build check:** `cd frontend && npm run build`

View File

@@ -96,7 +96,8 @@ You are Kilo Code, acting as a Speckit Workflow Specialist. MANDATORY USE `skill
6. After each phase, run verification:
- Backend: `cd backend && source .venv/bin/activate && python -m pytest -v`
- Frontend: `cd frontend && npm run test`
- Lint: `python -m ruff check` (backend)
- Lint: `python -m ruff check .` (backend)
- Frontend lint: `cd frontend && npm run lint`
7. If a phase fails verification, stop and fix before proceeding.
8. Never bypass semantic debt to make code appear working.
9. Never strip `@RATIONALE` or `@REJECTED` to silence semantic debt.

View File

@@ -42,7 +42,8 @@ You **MUST** consider the user input before proceeding (if not empty).
- Active feature docs always live under `specs/<feature>/...` and are discovered via the `.specify/scripts/bash/*` helpers.
- Default verification stack:
- Backend: `cd backend && source .venv/bin/activate && python -m pytest -v`
- Backend lint: `python -m ruff check backend/src/ backend/tests/`
- Backend lint: `cd backend && python -m ruff check .`
- Frontend lint: `cd frontend && npm run lint`
- Frontend: `cd frontend && npm run test`
- Frontend build: `cd frontend && npm run build`
- Do not fall back to Rust `cargo`/`src/server/` conventions — this is a Python/Svelte project.

View File

@@ -246,7 +246,7 @@ cd backend && source .venv/bin/activate && python -m pytest -v
python -m pytest --cov=src --cov-report=term-missing
# Ruff linting
python -m ruff check src/ tests/
python -m ruff check .
# Type checking (if mypy is configured)
python -m mypy src/

View File

@@ -1,18 +0,0 @@
[MAIN]
# Загружаем наш кастомный плагин с проверками для ИИ
load-plugins=pylint_ai_checker.checker
[MESSAGES CONTROL]
# Отключаем правила, которые мешают AI-friendly подходу.
# R0801: duplicate-code - Мы разрешаем дублирование на начальных фазах.
# C0116: missing-function-docstring - У нас свой, более правильный стандарт "ДО-контрактов".
disable=duplicate-code, missing-function-docstring
[DESIGN]
# Увеличиваем лимиты, чтобы не наказывать за явность и линейность кода.
max-args=10
max-locals=25
[FORMAT]
# Увеличиваем максимальную длину строки для наших подробных контрактов и якорей.
max-line-length=300

View File

@@ -55,3 +55,4 @@ openai
playwright
tenacity
Pillow
ruff>=0.11.0

29
backend/ruff.toml Normal file
View File

@@ -0,0 +1,29 @@
target-version = "py313"
line-length = 300
[lint]
select = [
"F", # pyflakes
"E", "W", # pycodestyle
"I", # isort
"N", # pep8-naming
"UP", # pyupgrade
"B", # flake8-bugbear
"SIM", # flake8-simplify
"C4", # flake8-comprehensions
"C90", # mccabe
"ARG", # flake8-unused-arguments
"T20", # flake8-print
"RUF", # ruff-specific
]
ignore = [
"E501",
"D",
"ANN",
]
[lint.mccabe]
max-complexity = 10
[lint.per-file-ignores]
"tests/*" = ["T20"]

23
frontend/eslint.config.js Normal file
View File

@@ -0,0 +1,23 @@
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: ["info", "warn", "error"] }],
},
},
{
ignores: [
"node_modules/", "dist/", "build/",
".svelte-kit/", ".vite/", "coverage/",
],
},
];

File diff suppressed because it is too large Load Diff

View File

@@ -8,15 +8,21 @@
"build": "vite build",
"preview": "vite preview",
"test": "vitest run",
"test:watch": "vitest"
"test:watch": "vitest",
"lint": "eslint .",
"lint:fix": "eslint . --fix"
},
"devDependencies": {
"@eslint/js": "^9.0.0",
"@sveltejs/adapter-static": "^3.0.10",
"@sveltejs/kit": "^2.49.2",
"@sveltejs/vite-plugin-svelte": "^6.2.1",
"@testing-library/jest-dom": "^6.9.1",
"@testing-library/svelte": "^5.3.1",
"autoprefixer": "^10.4.0",
"eslint": "^9.0.0",
"eslint-plugin-svelte": "^3.0.0",
"globals": "^16.0.0",
"jsdom": "^28.1.0",
"postcss": "^8.4.0",
"svelte": "^5.43.8",

137
lint-plan.md Normal file
View File

@@ -0,0 +1,137 @@
# План: Линтер (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