agent-quality-kit 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +155 -0
- package/kit/docs/ai/agent-harness-playbook.md +596 -0
- package/kit/docs/ai/ai-native-development.md +371 -0
- package/kit/docs/ai/ai-sdlc.md +221 -0
- package/kit/docs/ai/anthropic-ai-native-sdlc-2026-08.md +294 -0
- package/kit/docs/ai/app-owner-strategy.md +921 -0
- package/kit/docs/ai/deep-research-2026-07.md +161 -0
- package/kit/docs/ai/harness-best-practices.md +385 -0
- package/kit/docs/ai/index.md +64 -0
- package/kit/docs/ai/project-baseline.md +261 -0
- package/kit/docs/ai/quality-gates-checklist.md +322 -0
- package/kit/docs/ai/sources-building-with-agents.md +111 -0
- package/kit/docs/ai/stream-2026-08-ai-coding-panel.md +304 -0
- package/kit/docs/ready-made-rules.md +170 -0
- package/kit/gates/README.md +231 -0
- package/kit/gates/_skip.sh +75 -0
- package/kit/gates/commit-explains-itself/README.md +45 -0
- package/kit/gates/commit-explains-itself/check.sh +63 -0
- package/kit/gates/commit-explains-itself/gate.yml +10 -0
- package/kit/gates/commit-explains-itself/green/COMMIT_MSG +6 -0
- package/kit/gates/commit-explains-itself/red/COMMIT_MSG +3 -0
- package/kit/gates/complexity-limit/README.md +37 -0
- package/kit/gates/complexity-limit/check.sh +44 -0
- package/kit/gates/complexity-limit/gate.yml +13 -0
- package/kit/gates/complexity-limit/green/flat.py +10 -0
- package/kit/gates/complexity-limit/red/deep.py +9 -0
- package/kit/gates/dead-code/README.md +30 -0
- package/kit/gates/dead-code/gate.yml +23 -0
- package/kit/gates/dead-code/green/mod.py +9 -0
- package/kit/gates/dead-code/red/mod.py +9 -0
- package/kit/gates/deps-are-pinned/README.md +29 -0
- package/kit/gates/deps-are-pinned/check.sh +49 -0
- package/kit/gates/deps-are-pinned/gate.yml +9 -0
- package/kit/gates/deps-are-pinned/green/nodep-go/go.mod +3 -0
- package/kit/gates/deps-are-pinned/green/package-lock.json +3 -0
- package/kit/gates/deps-are-pinned/green/package.json +4 -0
- package/kit/gates/deps-are-pinned/green/requirements.txt +2 -0
- package/kit/gates/deps-are-pinned/red/package.json +4 -0
- package/kit/gates/deps-are-pinned/red/requirements.txt +2 -0
- package/kit/gates/deps-are-pinned/red/withdep-go/go.mod +5 -0
- package/kit/gates/duplicate-code/README.md +40 -0
- package/kit/gates/duplicate-code/check.sh +58 -0
- package/kit/gates/duplicate-code/gate.yml +12 -0
- package/kit/gates/duplicate-code/green/common.py +9 -0
- package/kit/gates/duplicate-code/green/use.py +9 -0
- package/kit/gates/duplicate-code/red/a.py +12 -0
- package/kit/gates/duplicate-code/red/b.py +12 -0
- package/kit/gates/entry-links-exist/README.md +22 -0
- package/kit/gates/entry-links-exist/check.sh +24 -0
- package/kit/gates/entry-links-exist/gate.yml +16 -0
- package/kit/gates/entry-links-exist/green/AGENTS.md +5 -0
- package/kit/gates/entry-links-exist/green/rules/general.md +3 -0
- package/kit/gates/entry-links-exist/red/AGENTS.md +3 -0
- package/kit/gates/file-size-limit/README.md +22 -0
- package/kit/gates/file-size-limit/check.sh +34 -0
- package/kit/gates/file-size-limit/gate.yml +9 -0
- package/kit/gates/file-size-limit/green/a.py +251 -0
- package/kit/gates/file-size-limit/green/b.py +251 -0
- package/kit/gates/file-size-limit/red/big.py +601 -0
- package/kit/gates/gate-has-samples/README.md +29 -0
- package/kit/gates/gate-has-samples/check.sh +48 -0
- package/kit/gates/gate-has-samples/gate.yml +9 -0
- package/kit/gates/gate-has-samples/green/.aqk.yml +10 -0
- package/kit/gates/gate-has-samples/green/gates/no-print-in-prod/check.sh +2 -0
- package/kit/gates/gate-has-samples/green/gates/no-print-in-prod/green/good.py +2 -0
- package/kit/gates/gate-has-samples/green/gates/no-print-in-prod/red/bad.py +1 -0
- package/kit/gates/gate-has-samples/red/.aqk.yml +10 -0
- package/kit/gates/gate-has-samples/red/gates/no-print-in-prod/check.sh +2 -0
- package/kit/gates/gates-are-runnable/README.md +23 -0
- package/kit/gates/gates-are-runnable/check.sh +35 -0
- package/kit/gates/gates-are-runnable/gate.yml +9 -0
- package/kit/gates/gates-are-runnable/green/.aqk.yml +9 -0
- package/kit/gates/gates-are-runnable/green/checks/lint.sh +2 -0
- package/kit/gates/gates-are-runnable/red/.aqk.yml +6 -0
- package/kit/gates/gates-run-in-ci/README.md +29 -0
- package/kit/gates/gates-run-in-ci/check.sh +42 -0
- package/kit/gates/gates-run-in-ci/gate.yml +12 -0
- package/kit/gates/gates-run-in-ci/green/.aqk.yml +6 -0
- package/kit/gates/gates-run-in-ci/green/.github/workflows/ci.yml +7 -0
- package/kit/gates/gates-run-in-ci/green/checks/lint.sh +2 -0
- package/kit/gates/gates-run-in-ci/red/.aqk.yml +6 -0
- package/kit/gates/gates-run-in-ci/red/.github/workflows/ci.yml +7 -0
- package/kit/gates/gates-run-in-ci/red/checks/lint.sh +2 -0
- package/kit/gates/lesson-has-outcome/README.md +37 -0
- package/kit/gates/lesson-has-outcome/check.sh +50 -0
- package/kit/gates/lesson-has-outcome/gate.yml +11 -0
- package/kit/gates/lesson-has-outcome/green/.aqk.yml +2 -0
- package/kit/gates/lesson-has-outcome/green/incidents/README.md +32 -0
- package/kit/gates/lesson-has-outcome/red/.aqk.yml +2 -0
- package/kit/gates/lesson-has-outcome/red/incidents/README.md +13 -0
- package/kit/gates/no-print-in-prod/README.md +44 -0
- package/kit/gates/no-print-in-prod/check.sh +36 -0
- package/kit/gates/no-print-in-prod/gate.yml +15 -0
- package/kit/gates/no-print-in-prod/green/docs.ts +15 -0
- package/kit/gates/no-print-in-prod/green/legacy.py +9 -0
- package/kit/gates/no-print-in-prod/green/main.go +8 -0
- package/kit/gates/no-print-in-prod/green/main.rs +4 -0
- package/kit/gates/no-print-in-prod/green/service.py +8 -0
- package/kit/gates/no-print-in-prod/red/main.go +8 -0
- package/kit/gates/no-print-in-prod/red/main.rs +4 -0
- package/kit/gates/no-print-in-prod/red/service.py +3 -0
- package/kit/gates/secrets-not-in-code/README.md +29 -0
- package/kit/gates/secrets-not-in-code/check.sh +18 -0
- package/kit/gates/secrets-not-in-code/gate.yml +9 -0
- package/kit/gates/secrets-not-in-code/green/settings.py +4 -0
- package/kit/gates/secrets-not-in-code/red/settings.py +2 -0
- package/kit/gates/swallowed-error/README.md +26 -0
- package/kit/gates/swallowed-error/check.sh +54 -0
- package/kit/gates/swallowed-error/gate.yml +12 -0
- package/kit/gates/swallowed-error/green/loader.py +11 -0
- package/kit/gates/swallowed-error/green/run.js +8 -0
- package/kit/gates/swallowed-error/red/loader.py +5 -0
- package/kit/gates/swallowed-error/red/run.js +3 -0
- package/kit/gates/todo-without-task/README.md +26 -0
- package/kit/gates/todo-without-task/check.sh +19 -0
- package/kit/gates/todo-without-task/gate.yml +12 -0
- package/kit/gates/todo-without-task/green/order.py +9 -0
- package/kit/gates/todo-without-task/red/order.py +8 -0
- package/kit/ratchet/ratchet.sh +62 -0
- package/kit/rules/general.md +55 -0
- package/kit/rules/security.md +33 -0
- package/kit/rules/testing.md +46 -0
- package/package.json +41 -0
- package/tool/commands/doctor.mjs +230 -0
- package/tool/commands/gates.mjs +445 -0
- package/tool/commands/project.mjs +316 -0
- package/tool/lib/core.mjs +98 -0
- package/tool/lib/manifest.mjs +140 -0
- package/tool/lib/repo.mjs +270 -0
- package/tool/lib/templates.mjs +187 -0
- package/tool/program.mjs +81 -0
- package/tool/selfcheck/conditional.sh +24 -0
- package/tool/selfcheck/gates.sh +127 -0
- package/tool/selfcheck/smoke.sh +539 -0
- package/tool/selfcheck/syntax.sh +23 -0
- package/tool/selfcheck/units.mjs +105 -0
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
<!-- источник: audit_project/docs/ai/stream-2026-08-ai-coding-panel.md -->
|
|
2
|
+
# Разбор стрима «Инструментарий AI-кодинга» (2026-08-24)
|
|
3
|
+
|
|
4
|
+
> **Что это.** Конспект панельного стрима + **сверка каждого тезиса с нашим проектом**: что у нас
|
|
5
|
+
> уже есть, чего нет, что стоит взять, а что — маркетинг. Плюс словарь терминов, прозвучавших в
|
|
6
|
+
> эфире, с переводом на язык этого проекта.
|
|
7
|
+
>
|
|
8
|
+
> **Участники:** Андрей Бреслав (один из создателей Kotlin, делает инструмент CodeSpec —
|
|
9
|
+
> «вечно живая спека» поверх агента) · Валера Ковальский (Neural Deep; инфраструктура, флот
|
|
10
|
+
> агентов, консультирует enterprise по внедрению) · Максим Ключников (техлид, работа с агентами в
|
|
11
|
+
> корпоративной среде) · ведущий.
|
|
12
|
+
>
|
|
13
|
+
> **Как читать пометки:**
|
|
14
|
+
> 🎙 — тезис из стрима: это **мнение практика, а не измерение**. Верификация — на нас.
|
|
15
|
+
> 📏 — измерено/проверено на нашем проекте (дата рядом).
|
|
16
|
+
> ⚖️ — место, где мнения спикеров расходятся или где тезис спорный.
|
|
17
|
+
>
|
|
18
|
+
> **Чем отличается от соседей по корпусу:** [`agent-harness-playbook.md` §18](agent-harness-playbook.md) — наша дисциплина
|
|
19
|
+
> (правило = свой инцидент) · [`harness-best-practices.md`](harness-best-practices.md) — каталог
|
|
20
|
+
> приёмов из чужих харнесов.
|
|
21
|
+
> **Здесь — срез практики индустрии на август 2026 и то, что из него применимо нам.**
|
|
22
|
+
>
|
|
23
|
+
> Дата разбора: **2026-08-24**.
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## 0. Главный вывод в одну фразу
|
|
28
|
+
|
|
29
|
+
**Никто из трёх практиков не строит сложный харнес. Все трое строят одно и то же: способ понижать
|
|
30
|
+
размерность — чтобы человек и агент смотрели не на код, а на компактное правдивое представление
|
|
31
|
+
системы — и способ доказывать корректность внешним арбитром, который нельзя подогнать.**
|
|
32
|
+
|
|
33
|
+
Всё остальное (скиллы, MCP, память, тесты, ревью) — инструменты этих двух целей. Если приём не
|
|
34
|
+
служит ни одной из них — он украшение.
|
|
35
|
+
|
|
36
|
+
> **📐 Понижение размерности (dimensionality reduction)**
|
|
37
|
+
> **Простыми словами:** заменить 200 000 строк кода на 2 000 строк описания, по которым можно
|
|
38
|
+
> ориентироваться и принимать решения, не открывая код.
|
|
39
|
+
> **Зачем тебе:** кода уже больше, чем человек способен прочитать. Не понизив размерность, ты
|
|
40
|
+
> обязан либо верить агенту на слово, либо не спать.
|
|
41
|
+
> **В твоём проекте:** это `specs/memory/project-map.md` (карта «что где лежит»), `structure.md`,
|
|
42
|
+
> `specs/decisions/` (ADR) и скиллы. Свежесть карты стережёт `scripts/check-map.sh` в pre-commit.
|
|
43
|
+
> **Как проверить:** «могу ли я по карте назвать место правки, ни разу не открыв код?»
|
|
44
|
+
|
|
45
|
+
Ключевое уточнение Андрея, которое легко пропустить: **сжатое представление тоже нельзя делать
|
|
46
|
+
спагетти**. Модули, границы, SOLID/DRY нужны не только в коде — они нужны в документах и спеках,
|
|
47
|
+
потому что теперь именно документы читает человек.
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## 1. Словарь: 30 терминов из эфира
|
|
52
|
+
|
|
53
|
+
### 1.1 Про обвязку агента
|
|
54
|
+
|
|
55
|
+
| Термин | Простыми словами | У нас |
|
|
56
|
+
|---|---|---|
|
|
57
|
+
| **Харнес (harness)** | вся обвязка вокруг модели: правила, скиллы, хуки, гейты, пайплайн агентов | `.claude/` целиком |
|
|
58
|
+
| **Скилл (skill)** | пакет «инструкция + инструменты + данные» по одной теме, грузится по решению агента | 📏 26 скиллов в `.claude/skills/` |
|
|
59
|
+
| **MCP-сервер** | стандартный способ дать агенту доступ к внешней системе (протокол) | codegraph, codebase_memory, Playwright, ag-mcp |
|
|
60
|
+
| **CLI-инструмент** | то же самое, но обычной консольной командой (`gh`, `aws`, свой скрипт) | 🎙 Андрей: **предпочитает CLI, а не MCP** — дешевле по контексту |
|
|
61
|
+
| **Хук (hook)** | скрипт, который харнес запускает сам при событии; агент не может его обойти | `.claude/hooks/`, pre-commit гейты |
|
|
62
|
+
| **Гейт (gate)** | автоматическая проверка, блокирующая плохое | `scripts/arch-lint.sh`, `check-map.sh`, `test-lock.sh` |
|
|
63
|
+
| **Статуслайн** | строка состояния: модель, остаток лимита, заполнение контекста | 🎙 Валера: минимальный обязательный сетап |
|
|
64
|
+
| **Компакшн (compaction)** | автосжатие переписки, когда контекст переполнен; часть деталей теряется | наблюдается в длинных сессиях |
|
|
65
|
+
| **Контекстное окно** | сколько текста модель держит одновременно | ⚖️ Валера: «жить можно на 256k; миллион — неконтролируемо» |
|
|
66
|
+
|
|
67
|
+
### 1.2 Про знание и память
|
|
68
|
+
|
|
69
|
+
| Термин | Простыми словами | У нас |
|
|
70
|
+
|---|---|---|
|
|
71
|
+
| **Memory bank / банк памяти** | структурированное хранилище знаний о проекте в маркдауне | `specs/memory/`, `.claude/agent-memory/`, скиллы |
|
|
72
|
+
| **Слой знаний** | то же самое, но включая «почему так решили» | `specs/decisions/` (ADR) + `docs/` |
|
|
73
|
+
| **Дрифт контекста** | расхождение между тем, что в головах/документах, и тем, что в коде | 📏 наше правило: код — источник истины, статусы task-файлов врут |
|
|
74
|
+
| **Проекция кодовой базы** | компактное представление кода для навигации | `project-map.md`, `structure.md`, `feature-map.md` |
|
|
75
|
+
| **Индексирование / семантический поиск** | быстрый поиск по смыслу, а не по grep | codegraph + codebase_memory (MCP) |
|
|
76
|
+
| **Локализация** | найти место, которое надо править | 🎙 Валера: **90–95% времени агента уходит именно на это** |
|
|
77
|
+
|
|
78
|
+
### 1.3 Про доказательство корректности
|
|
79
|
+
|
|
80
|
+
> **📐 Арбитр корректности**
|
|
81
|
+
> **Простыми словами:** то, что говорит «правильно/неправильно» вместо тебя. Тест, сверка с 1С,
|
|
82
|
+
> живой прогон, реальный пользователь.
|
|
83
|
+
> **Зачем тебе:** сила арбитра решает, можно ли доверять «зелёному». Слабый арбитр = зелёный ничего
|
|
84
|
+
> не значит.
|
|
85
|
+
> **В твоём проекте:** сверка отчётов с 1С до копейки — сильный внешний арбитр, поэтому DirectPG
|
|
86
|
+
> идёт по lightweight-треку. Бизнес-логика без такого арбитра — full track с ревью и человеком.
|
|
87
|
+
> **Как проверить:** «может ли агент сделать это зелёным, не сделав работу?» Может → арбитр слабый.
|
|
88
|
+
|
|
89
|
+
| Термин | Простыми словами | У нас |
|
|
90
|
+
|---|---|---|
|
|
91
|
+
| **Mutation testing** | инструмент портит код специально; если тесты не покраснели — тесты бесполезны | `scripts/mutation-test.sh` (advisory, DirectPG casts) |
|
|
92
|
+
| **Архитектурные тесты** | тест не на поведение, а на структуру: «слой A не смеет импортировать B» | eslint `boundaries` (FSD), `arch-lint.sh`, `check-app-gate-coverage.py` |
|
|
93
|
+
| **Holdout-тесты** | тесты, которых Builder не видит — проверка, что он не подогнал результат | агент `auditor` есть, 📏 по умолчанию **отключён** |
|
|
94
|
+
| **Anti-gaming / reward hacking** | агент добивается «зелёного», не делая работу: правит тест, мокает, удаляет проверку | `scripts/test-lock.sh` — снимок тестов до/после Builder |
|
|
95
|
+
| **Golden-тест** | эталон от авторитетного источника, с которым сверяется вывод | сверка отчётов 1С 1-в-1 |
|
|
96
|
+
| **Eval (эвал)** | проверка **промпта/скилла** на датасете: срабатывает ли, когда надо, и не срабатывает ли, когда не надо | 📏 17 датасетов в `.claude/skills/trigger-evals/`, **прогонщика нет** |
|
|
97
|
+
| **Целевая функция** | формальный критерий «результат хороший» | 🎙 Андрей: автономность работает **только** там, где она есть |
|
|
98
|
+
|
|
99
|
+
### 1.4 Про людей и процессы
|
|
100
|
+
|
|
101
|
+
| Термин | Простыми словами | Замечание |
|
|
102
|
+
|---|---|---|
|
|
103
|
+
| **Human-in-the-loop / HumanOp** | человек обязателен в точке решения | ⚖️ все трое: **полностью автономный SDLC — маркетинг** |
|
|
104
|
+
| **Cognitive surrender** | когнитивная капитуляция: человек перестаёт думать и отдаёт решения модели | самый опасный эффект по мнению Максима |
|
|
105
|
+
| **Decision fatigue** | усталость от плотного потока решений: агент пишет быстро, решения нужны часто | 🎙 Андрей: главный источник выгорания в новой работе |
|
|
106
|
+
| **Sycophancy / податливость** | агент соглашается вместо спора; не приходит сказать «твоя идея плоха» | лечится только явным промптом «спорь» |
|
|
107
|
+
| **Размывание ответственности** | «это агент сделал» вместо «я сделал» | 🎙 Максим: командная проблема №1 |
|
|
108
|
+
| **Zero-shot удача** | сложная задача разово удалась с первого раза → человек расслабляется | ловушка: не повторяется |
|
|
109
|
+
| **AI-readiness кодовой базы** | готовность проекта к работе агента: контракты, типы, границы, воспроизводимый прогон | ниже §4 — наш чек-лист |
|
|
110
|
+
| **Explainability** | объяснимость системы человеку: схема, диаграмма, отчёт вместо чтения кода | у нас частично: карты + ADR |
|
|
111
|
+
|
|
112
|
+
### 1.5 Про инфраструктуру моделей (контекст, а не работа)
|
|
113
|
+
|
|
114
|
+
**SLM** — маленькие модели для узких задач (классификация, поиск, суммаризация); внутри больших
|
|
115
|
+
агентов они делают львиную долю служебной работы. **Квантование** — сжатие модели ради скорости и
|
|
116
|
+
цены (побочный эффект — падение качества). **MoE (mixture of experts)** — архитектура, где на
|
|
117
|
+
запрос работает часть модели. **Cerebras / Groq** — железо ради очень быстрого инференса.
|
|
118
|
+
🎙 Валера: ближайшие два года прогресса — это цена и скорость инференса, а не «ещё умнее».
|
|
119
|
+
⚖️ «Модели тупеют перед выкаткой новой» — сетевая молва, не измерение; относиться как к гипотезе.
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## 2. Тезисы, ради которых стоило смотреть
|
|
124
|
+
|
|
125
|
+
### 2.1 Что говорят все трое (сходятся)
|
|
126
|
+
|
|
127
|
+
1. **Автономная «фабрика софта» не работает.** Работает только там, где ты умеешь формально
|
|
128
|
+
отличить хороший результат от плохого. Не умеешь — человек в петле обязателен.
|
|
129
|
+
2. **Архитектура стала важнее, а не менее важна.** Она переезжает из кода в документы и в
|
|
130
|
+
архитектурные тесты — но никуда не девается.
|
|
131
|
+
3. **Тесты, написанные агентом, — слабый сигнал.** Нужен внешний арбитр либо мутационное
|
|
132
|
+
тестирование, иначе «зелёное» ничего не доказывает.
|
|
133
|
+
4. **Главная проблема больших репозиториев — не контекст, а навигация.** Агенту нужно за что
|
|
134
|
+
зацепиться: контракты, типы, границы, карта.
|
|
135
|
+
5. **Скорость (латентность) — главный раздражитель.** Ожидание ломает поток; переключение контекста
|
|
136
|
+
выжигает больше, чем сама работа.
|
|
137
|
+
|
|
138
|
+
### 2.2 Где расходятся
|
|
139
|
+
|
|
140
|
+
| Вопрос | Андрей | Валера | Максим |
|
|
141
|
+
|---|---|---|---|
|
|
142
|
+
| Сложность харнеса | минимальный: голый Claude Code + мало скиллов | средний: флот агентов, скиллы под роль, свой memory-подход | блоки прозы + **детерминированные скрипты** между ними |
|
|
143
|
+
| MCP | не любит, предпочитает CLI | использует | «в enterprise приходится — это стандарт поставки» |
|
|
144
|
+
| Куда вкладываться | новый «язык» выше кода (спеки как инженерный артефакт) | инфраструктура и стоимость инференса | эвалы, трейсы, аналитика по трейсам |
|
|
145
|
+
|
|
146
|
+
### 2.3 Отдельно ценное
|
|
147
|
+
|
|
148
|
+
- 🎙 **Андрей:** «Заголовок скилла — это тоже промпт, и его надо эвалить. Самое сложное в скилле —
|
|
149
|
+
не тело, а описание: чтобы он вызывался, когда надо». Ровно наша боль: автоподхвата нет.
|
|
150
|
+
- 🎙 **Андрей:** «Я написал промпт, он сработал два раза, значит работает» — так рассуждают даже
|
|
151
|
+
ML-инженеры. Система недетерминированная: два прогона — не проверка.
|
|
152
|
+
- 🎙 **Максим:** агенты **не удаляют код**. Пост-тренинг награждает за написанное, не за удалённое.
|
|
153
|
+
Отсюда мёртвые области, которые не ловит даже статический анализ (код задублирован).
|
|
154
|
+
- 🎙 **Максим:** «Понижайте размерность того, что передаёте другому человеку». Пять экранов
|
|
155
|
+
сгенерированного текста коллеге — это перекладывание работы, а не коммуникация.
|
|
156
|
+
- 🎙 **Андрей:** «В интернете все врут: у кого «всё автоматизировано» — не автоматизировано».
|
|
157
|
+
Поезд не ушёл; время есть, тратить его на инструменты.
|
|
158
|
+
- 🎙 **Валера:** учиться надо базе (как работает сеть, процессор, сервис, сборка) — она и есть то,
|
|
159
|
+
что позволяет проверять агента.
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## 3. Сверка с нашим проектом (что уже есть)
|
|
164
|
+
|
|
165
|
+
Значки строгие: ✅ — сделано **и доказано**; ⬜ — решено, не сделано; ❌ — отсутствует/сломано.
|
|
166
|
+
|
|
167
|
+
| Тезис стрима | У нас | Доказательство |
|
|
168
|
+
|---|---|---|
|
|
169
|
+
| Понижение размерности: карта проекта | ✅ | `specs/memory/project-map.md` + гейт `scripts/check-map.sh` в pre-commit |
|
|
170
|
+
| Индексаторы вместо grep | ✅ | MCP codegraph + codebase_memory, скиллы `codegraph-mcp`, `codebase-memory-mcp`, правило в `CLAUDE.md` |
|
|
171
|
+
| Архитектура зафиксирована решениями | ✅ | `specs/decisions/` + правило «отступление от ADR — вопрос владельцу» |
|
|
172
|
+
| Архитектурные гейты | ✅ | `arch-lint.sh` (антипаттерны тестов, размер файлов), eslint `boundaries` на error, `check-queue-consumers.py` |
|
|
173
|
+
| Внешний неподгоняемый арбитр | ✅ | сверка отчётов с 1С до копейки; live-stack e2e; Playwright MCP по живому UI |
|
|
174
|
+
| Защита от подгонки тестов | ✅ | `scripts/test-lock.sh` (snapshot/verify вокруг Builder) |
|
|
175
|
+
| Тесты пишет не тот, кто пишет код | ✅ | Tester ≠ Builder — железно |
|
|
176
|
+
| Мутационное тестирование | ⬜ | `scripts/mutation-test.sh` есть, но **advisory и только DirectPG casts** — не гейт |
|
|
177
|
+
| Централизованные логи | ✅ | Loki + Alloy (task-221) |
|
|
178
|
+
| Error tracking (Sentry-класс) | ❌ | нет — числится P0 в `docs/rebuild/10-open-work-register.md` |
|
|
179
|
+
| Эвалы скиллов (срабатывание) | ❌ | 📏 17 датасетов лежат с 2026-06-16, **прогонщика нет**; 9 скиллов вообще без датасета |
|
|
180
|
+
| Трейсы прогонов + метрики агентов | ❌ | 📏 `specs/memory/metrics.json`, `learnings/`, `evolution-archive.jsonl` **отсутствуют**, хотя `CLAUDE.md` и агенты `analyzer`/`evolver` на них ссылаются |
|
|
181
|
+
| Holdout / anti-gaming тесты | ⬜ | агент `auditor` есть, по умолчанию отключён (осознанно) |
|
|
182
|
+
| Изоляция Builder'а (контракты) | ❌ | отключена: `scripts/extract-contracts.py` ломает файлы (📏 воспроизведено 2026-08-03) |
|
|
183
|
+
| Общая среда «люди + агенты» (чат) | ❌ | нет; работа one-to-one с агентом |
|
|
184
|
+
| Учёт стоимости / FinOps токенов | ❌ | не измеряется |
|
|
185
|
+
| Поиск мёртвого кода | ⬜ | `/sentinel` и `arch-audit.sh` есть, запуск ручной и нерегулярный |
|
|
186
|
+
|
|
187
|
+
**Честный итог сверки:** по «арбитрам корректности» мы сильнее среднего из услышанного — сверка с 1С
|
|
188
|
+
и live-stack e2e жёстче, чем у большинства. По «наблюдаемости самого харнеса» (эвалы, трейсы,
|
|
189
|
+
метрики, стоимость) у нас **дыра, описанная в правилах как работающая система**. Это ровно тот
|
|
190
|
+
случай из [`agent-harness-playbook.md` §18](agent-harness-playbook.md) §3 — документация врёт по умолчанию.
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
## 4. Что взять (кандидаты, по цене/пользе)
|
|
195
|
+
|
|
196
|
+
Ни один пункт не выполняется без отдельной задачи и апрува — `.claude/**` вне scope продуктовых
|
|
197
|
+
задач. Здесь — обоснование, а очередь работ живёт в
|
|
198
|
+
`../rebuild/10-open-work-register.md`.
|
|
199
|
+
|
|
200
|
+
### Дёшево и сразу полезно
|
|
201
|
+
|
|
202
|
+
1. **Прогонщик эвалов скиллов.** Датасеты уже лежат. Нужен скрипт: даёт формулировку → смотрит,
|
|
203
|
+
загрузился ли скилл → считает точность срабатывания и ложные срабатывания. Закрывает тезис
|
|
204
|
+
Андрея «заголовок скилла — это промпт, его надо эвалить» и наш собственный инцидент 2026-07-29
|
|
205
|
+
(скилл не загрузился, решение переоткрыли заново). *Уже стоит в реестре как P3 — поднять.*
|
|
206
|
+
2. **Маркерные слова агента как гейт.** Из эфира: агент отклоняется от курса, называя это `fallback`
|
|
207
|
+
/ `MVP` / «пока замокаем» / «упростим». Дешёвый grep по диффу и по рассуждению → предупреждение
|
|
208
|
+
в ревью. Это перенос мягкого в жёсткое (`agent-harness-playbook.md` §18 §0).
|
|
209
|
+
3. **Правило «понижай размерность отчёта человеку».** Итоги — таблицей и галочками, а не пятью
|
|
210
|
+
экранами. У нас это уже формализовано в скилле `engineering-literacy`; распространить требование
|
|
211
|
+
на отчёты Reviewer/Analyzer.
|
|
212
|
+
|
|
213
|
+
### Средняя цена, большая отдача
|
|
214
|
+
|
|
215
|
+
4. **Мутационное тестирование как периодический гейт на расчётных модулях.** Сейчас advisory и
|
|
216
|
+
только для DirectPG casts. Кандидаты: расчёт прогресса задач (`tracker/progress.py`), кастинг и
|
|
217
|
+
маппинг DirectPG, денежные расчёты зарплатных отчётов. Медленно — значит по расписанию, не в
|
|
218
|
+
pre-commit.
|
|
219
|
+
5. **Регулярный охотник за мёртвым кодом.** Тезис Максима: агенты пишут и не удаляют, мёртвые
|
|
220
|
+
области не ловятся статическим анализом, потому что задублированы. У нас есть `codebase_memory`
|
|
221
|
+
с детектором дублей (`SIMILAR_TO`) — это ровно тот инструмент. Нужен ритм, а не разовый запуск.
|
|
222
|
+
6. **Сбор трейсов и стоимости прогонов.** Без него `analyzer`/`evolver` — фикция: они читают файлы,
|
|
223
|
+
которых нет. Либо поднять сбор, либо честно вычеркнуть эволюционную петлю из `CLAUDE.md`.
|
|
224
|
+
**Одно из двух — обязательно.**
|
|
225
|
+
|
|
226
|
+
### Дорого / отложить
|
|
227
|
+
|
|
228
|
+
7. Общая среда «люди + агенты» в одном чате — интересно, но у нас команда из одного человека;
|
|
229
|
+
выгоды нет.
|
|
230
|
+
8. Своя «вечно живая спека» уровня CodeSpec — большая инженерия; ждать, пока это станет продуктом.
|
|
231
|
+
|
|
232
|
+
---
|
|
233
|
+
|
|
234
|
+
## 5. Что НЕ брать (и почему)
|
|
235
|
+
|
|
236
|
+
- **Оркестрация десятков агентов.** ⚖️ Валера прямо: «в оркестрацию не верю, она не работает».
|
|
237
|
+
Наш опыт того же класса: укороченный пайплайн работает лучше полного (память
|
|
238
|
+
`shortened-pipeline-preference`).
|
|
239
|
+
- **Гнаться за миллионным контекстом.** Чем больше окно, тем меньше контроль над тем, что в нём.
|
|
240
|
+
Наша ставка — компактная правдивая карта, а не «загрузить весь проект».
|
|
241
|
+
- **Плодить скиллы.** 📏 26 скиллов уже съедают около 80% бюджета листинга описаний. Новый скилл —
|
|
242
|
+
только вместо старого либо с укорачиванием чужих описаний.
|
|
243
|
+
- **Верить «всё автоматизировано» из интернета.** По прямому свидетельству участников — врут.
|
|
244
|
+
- **Оценивать промпт по паре удачных прогонов.** Система недетерминированная; два прогона — анекдот.
|
|
245
|
+
|
|
246
|
+
---
|
|
247
|
+
|
|
248
|
+
## 6. Правила-кандидаты (мягкое) и гейты-кандидаты (жёсткое)
|
|
249
|
+
|
|
250
|
+
По принципу `agent-harness-playbook.md` §18 §0: повторилось нарушение → переносим из мягкого в жёсткое.
|
|
251
|
+
|
|
252
|
+
**Мягкое (в правила/скиллы):**
|
|
253
|
+
- Промпт, скилл и описание скилла — это код без тестов, пока не прогнаны на датасете.
|
|
254
|
+
- Отчёт другому человеку понижает размерность, а не перекладывает чтение.
|
|
255
|
+
- «Сработало два раза» — не доказательство работоспособности недетерминированной системы.
|
|
256
|
+
- Агент не приходит сам сказать «твоя идея плоха» — спрашивать возражения явно.
|
|
257
|
+
|
|
258
|
+
**Жёсткое (кандидаты в гейты):**
|
|
259
|
+
- grep по маркерам ухода от курса в диффе (`fallback`, `MVP`, `mock`, `упростим`, `пока что`).
|
|
260
|
+
- порог mutation score на списке критичных модулей (по расписанию).
|
|
261
|
+
- проверка «датасет эвала существует для каждого скилла» при добавлении нового скилла.
|
|
262
|
+
- проверка «файлы, на которые ссылается `CLAUDE.md`, существуют» — она бы поймала отсутствующие
|
|
263
|
+
`metrics.json` и `learnings/` в тот же день.
|
|
264
|
+
|
|
265
|
+
---
|
|
266
|
+
|
|
267
|
+
## 7. Учебный план (для владельца проекта)
|
|
268
|
+
|
|
269
|
+
Совет из эфира, дословно по смыслу: **качать инженерию высокого уровня, а не синтаксис.**
|
|
270
|
+
Для аудитора, который управляет агентами, это конкретно:
|
|
271
|
+
|
|
272
|
+
1. **System design крупными блоками:** что такое сервис, очередь, кэш, база, воркер, и как они
|
|
273
|
+
отказывают. Без этого нельзя оценить «что сломается».
|
|
274
|
+
2. **Границы и контракты:** где у системы швы, кто с кем говорит и по какому соглашению.
|
|
275
|
+
Это язык, на котором ставится задача агенту.
|
|
276
|
+
3. **Арбитры:** для каждой части системы уметь назвать, чем доказывается её корректность — и честно
|
|
277
|
+
помечать места, где арбитра нет. Это и есть карта реальной слепоты.
|
|
278
|
+
4. **Критическое мышление как процедура:** любое утверждение агента → «чем проверено?».
|
|
279
|
+
Три источника (официальная дока × наши правила и интернет × живая система) — уже наше правило.
|
|
280
|
+
5. **Понятия отказов:** идемпотентность, транзакция, гонка, таймаут, ретрай, блокировка.
|
|
281
|
+
Их разбор с привязкой к проекту — скилл `engineering-literacy` и его `references/concepts.md`.
|
|
282
|
+
|
|
283
|
+
Проверка усвоения — не «понятно?», а ситуация с выбором. Пример из эфира, годный как упражнение:
|
|
284
|
+
*агент предлагает захардкодить фолбэк, потому что «это же MVP». Что здесь может пойти не так и чем
|
|
285
|
+
это ловится?*
|
|
286
|
+
|
|
287
|
+
---
|
|
288
|
+
|
|
289
|
+
## 8. Статус этого документа
|
|
290
|
+
|
|
291
|
+
Это **конспект мнений практиков**, а не исследование. Тезисы с 🎙 не измерены ни ими, ни нами —
|
|
292
|
+
проверять по мере применения. Сверка с нашим проектом (§3) — 📏 проверена по файлам 2026-08-24:
|
|
293
|
+
наличие скриптов, скиллов, датасетов и отсутствие `metrics.json` / `learnings/` подтверждены
|
|
294
|
+
непосредственно, а не по документации.
|
|
295
|
+
|
|
296
|
+
---
|
|
297
|
+
|
|
298
|
+
## Связанное
|
|
299
|
+
|
|
300
|
+
- Наша дисциплина — [`agent-harness-playbook.md` §18](agent-harness-playbook.md)
|
|
301
|
+
- Каталог приёмов харнесов — [`harness-best-practices.md`](harness-best-practices.md)
|
|
302
|
+
- Процесс по этапам — [`ai-sdlc.md`](ai-sdlc.md)
|
|
303
|
+
- Научная база по анти-геймингу и оценке — [`deep-research-2026-07.md`](deep-research-2026-07.md)
|
|
304
|
+
- Очередь работ проекта
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
# Готовые правила: где искать, прежде чем писать свой гейт
|
|
2
|
+
|
|
3
|
+
> **Зачем этот файл.** У AQK есть правило «сперва ищи готовое, потом пиши своё». Без карты
|
|
4
|
+
> «где искать» оно неисполнимо. Здесь карта.
|
|
5
|
+
>
|
|
6
|
+
> **Данные не по памяти.** Разбивка по группам получена из самого инструмента:
|
|
7
|
+
> `ruff rule --all --output-format json` (версия 0.15.20) — **964 правила в 61 группе**.
|
|
8
|
+
> Проверить у себя: та же команда.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Правило целиком, обеими половинами
|
|
13
|
+
|
|
14
|
+
**Сперва ищи готовое.** Готовое лучше не потому, что чужое, а потому что его поддерживают без
|
|
15
|
+
вас, оно подробнее и его знают в лицо в чужих проектах.
|
|
16
|
+
|
|
17
|
+
📏 Цена пропуска измерена: разбор синтаксического дерева по всему проекту искал час места, где
|
|
18
|
+
ошибку пишут в лог без трейса, — 80 находок. Правило `TRY400` находит их одной строкой конфига,
|
|
19
|
+
нашло 47 и не дало ложных.
|
|
20
|
+
|
|
21
|
+
**Свой гейт законен, когда он про решение конкретного проекта.** Паритет очередей между средами,
|
|
22
|
+
свежесть карты проекта, неизменяемость применённой миграции, реестр долга — этого в библиотеках
|
|
23
|
+
нет и быть не может: они не знают, как устроен ваш проект.
|
|
24
|
+
|
|
25
|
+
📏 Проверять надо оба направления: неразрывный пробел не ловит **ни одно** из 964 правил — там
|
|
26
|
+
свой гейт единственный способ.
|
|
27
|
+
|
|
28
|
+
**«Не искал» и «нет» — разные утверждения.** В `README` записи каталога это отдельный раздел.
|
|
29
|
+
|
|
30
|
+
## Как проверить за минуту
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
ruff rule --all | grep -i «что ищете» # есть ли такое правило вообще
|
|
34
|
+
ruff rule TRY400 # что именно оно делает и как чинить
|
|
35
|
+
ruff check --select TRY400 --statistics . # сколько находок У ВАС
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Третья команда — главная. Она превращает «наверное, полезно» в число, и по этому числу решают:
|
|
39
|
+
ноль находок — включать бесплатно прямо сейчас; десятки — заход на один вечер; тысячи — сначала
|
|
40
|
+
храповик, потом разбор.
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## Ruff: 61 группа
|
|
45
|
+
|
|
46
|
+
### Ядро — включать всегда
|
|
47
|
+
|
|
48
|
+
| Группа | Правил | Что ловит |
|
|
49
|
+
|---|---|---|
|
|
50
|
+
| `F` | 43 | Pyflakes: неиспользуемые импорты и переменные, обращение к несуществующему |
|
|
51
|
+
| `E` `W` | 67 | pycodestyle. ⚠️ подгруппы `E1xx–E3xx` спорят с форматтером — их отключают |
|
|
52
|
+
| `B` | 43 | bugbear: мутабельные значения по умолчанию и прочие классические ловушки |
|
|
53
|
+
| `SIM` | 30 | упрощения: код, который делает лишнее |
|
|
54
|
+
| `UP` | 47 | устаревший синтаксис — агент тянет его из старых данных |
|
|
55
|
+
| `RUF` | 76 | правила самого ruff, включая опознание похожих юникод-символов |
|
|
56
|
+
| `C4` | 20 | лишние преобразования списков и словарей |
|
|
57
|
+
| `PERF` `FURB` | 42 | производительность и современные идиомы |
|
|
58
|
+
|
|
59
|
+
### Ошибки и отказы — самая ценная группа для кода, который пишет агент
|
|
60
|
+
|
|
61
|
+
| Группа | Правил | Что ловит |
|
|
62
|
+
|---|---|---|
|
|
63
|
+
| `BLE` | 1 | ловля голого исключения |
|
|
64
|
+
| `TRY` | 10 | tryceratops. **`TRY400`** — запись в лог без трейса. ⚠️ `TRY003` спорное, отключают отдельно |
|
|
65
|
+
| `LOG` `G` | 15 | корректность записи в лог: потерянный трейс, форматирование внутри вызова |
|
|
66
|
+
| `SIM105` | — | перехват ради тишины (замена на подавление явное) |
|
|
67
|
+
| `EM` | 3 | сообщение исключения строкой прямо в конструкторе |
|
|
68
|
+
| `RET` `RSE` | 9 | лишнее перед возвратом, лишние скобки при возбуждении |
|
|
69
|
+
|
|
70
|
+
### Долг и мусор
|
|
71
|
+
|
|
72
|
+
| Группа | Правил | Что ловит |
|
|
73
|
+
|---|---|---|
|
|
74
|
+
| `ERA` | 1 | закомментированный код |
|
|
75
|
+
| `FIX` `TD` | 11 | маркеры «доделать потом» и требования к их оформлению |
|
|
76
|
+
| `ARG` | 5 | неиспользуемые аргументы. ⚠️ обычно тысячи находок, нужен храповик |
|
|
77
|
+
| `T` | 3 | отладочная печать (`T201`) и забытая точка останова (`T100`) |
|
|
78
|
+
|
|
79
|
+
### Размер и сложность
|
|
80
|
+
|
|
81
|
+
| Правило | Что ловит |
|
|
82
|
+
|---|---|
|
|
83
|
+
| `C901` | цикломатическая сложность функции, порог настраивается |
|
|
84
|
+
| `PLR0912` | слишком много ветвлений |
|
|
85
|
+
| `PLR0913` | слишком много аргументов |
|
|
86
|
+
| `PLR0915` | слишком много инструкций |
|
|
87
|
+
|
|
88
|
+
**Предела на размер файла среди 964 правил нет.** Это тот случай, где нужен свой гейт.
|
|
89
|
+
|
|
90
|
+
### Безопасность
|
|
91
|
+
|
|
92
|
+
| Группа | Правил | Замечание |
|
|
93
|
+
|---|---|---|
|
|
94
|
+
| `S` | 73 | flake8-bandit. **Полностью перекрывает отдельный `bandit`** — держать оба незачем |
|
|
95
|
+
| `PGH` | 5 | в том числе запрет подавления без указания правила |
|
|
96
|
+
| `SLF` | 1 | обращение к приватному снаружи |
|
|
97
|
+
|
|
98
|
+
### Пути, время, типы
|
|
99
|
+
|
|
100
|
+
| Группа | Правил | Что ловит |
|
|
101
|
+
|---|---|---|
|
|
102
|
+
| `PTH` | 35 | старая работа с путями вместо `pathlib` |
|
|
103
|
+
| `DTZ` | 10 | время без часового пояса — бомба в любом дат-домене |
|
|
104
|
+
| `TC` | 9 | импорты, нужные только для типов |
|
|
105
|
+
| `ANN` | 11 | отсутствующие аннотации. ⚠️ если стоит `mypy`, это дубль |
|
|
106
|
+
|
|
107
|
+
### Тесты и стек
|
|
108
|
+
|
|
109
|
+
`PT` (31) — стиль pytest · `DJ` (7) Django · `FAST` (3) FastAPI · `PD` (13) pandas ·
|
|
110
|
+
`NPY` (4) NumPy · `AIR` (13) Airflow · `PYI` (55) файлы типов · `ASYNC` (16) асинхронность.
|
|
111
|
+
|
|
112
|
+
Берутся только под свой стек. Остальные — мёртвые правила.
|
|
113
|
+
|
|
114
|
+
### Спорные — решать осознанно
|
|
115
|
+
|
|
116
|
+
| Группа | Почему спорная |
|
|
117
|
+
|---|---|
|
|
118
|
+
| `D` (48) | докстринги по формату. Если они содержательные, а не форматные — шум |
|
|
119
|
+
| `Q` `COM` `ISC` | кавычки, запятые, склейка строк — спорят с форматтером |
|
|
120
|
+
| `FBT` (3) | булев аргумент как ловушка. Полезно, но ломает много чужих сигнатур |
|
|
121
|
+
| `CPY` (1) | требование заголовка об авторских правах |
|
|
122
|
+
|
|
123
|
+
### Мелкие, но дешёвые
|
|
124
|
+
|
|
125
|
+
`A` (6) имя затеняет встроенное · `PIE` (8) мелкие бессмыслицы · `N` (16) именование ·
|
|
126
|
+
`ICN` (3) общепринятые сокращения импортов · `TID` (5) порядок импортов ·
|
|
127
|
+
`SLOT` (3) · `FLY` (1) · `YTT` (10) · `INP` (1) · `EXE` (5) · `INT` (3) · `FA` (2) · `DOC` (7).
|
|
128
|
+
|
|
129
|
+
---
|
|
130
|
+
|
|
131
|
+
## Другие стеки: где искать
|
|
132
|
+
|
|
133
|
+
| Язык | Инструмент | Как посмотреть список |
|
|
134
|
+
|---|---|---|
|
|
135
|
+
| JavaScript, TypeScript | eslint | `npx eslint --print-config file.js`; правила — на сайте eslint |
|
|
136
|
+
| TypeScript | typescript-eslint | отдельный набор поверх eslint |
|
|
137
|
+
| Go | `go vet`, staticcheck | `staticcheck -list-checks` |
|
|
138
|
+
| Rust | clippy | `cargo clippy -- -W help` |
|
|
139
|
+
| Ruby | rubocop | `rubocop --show-cops` |
|
|
140
|
+
| Java, Kotlin | detekt, SpotBugs | `detekt --generate-config` |
|
|
141
|
+
| PHP | PHPStan, Psalm | уровни строгости вместо групп |
|
|
142
|
+
| Shell | shellcheck | `shellcheck --list-optional` |
|
|
143
|
+
| SQL | sqlfluff | `sqlfluff rules` |
|
|
144
|
+
| Dockerfile | hadolint | список в документации |
|
|
145
|
+
| Любой | semgrep | реестр чужих правил: `semgrep --config auto` |
|
|
146
|
+
|
|
147
|
+
**Кроссязыковое:** `gitleaks` — секреты · `trivy` — уязвимости образов ·
|
|
148
|
+
`jscpd` — дубли и Python, и TypeScript одним прогоном.
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## А если проект не на Python?
|
|
153
|
+
|
|
154
|
+
Ничего не меняется. Запись каталога держит **одно намерение и несколько исполнителей**, и
|
|
155
|
+
программа выбирает в три ступени: готовый инструмент под ваш язык → переносимая проверка без
|
|
156
|
+
зависимостей → честно скрыть запись, если нечем.
|
|
157
|
+
|
|
158
|
+
Так что проект на Rust, Go или C++ получает сторожа сразу — переносимого. А когда кто-то принесёт
|
|
159
|
+
строку `rust: cargo clippy …`, он уступит место более точному.
|
|
160
|
+
|
|
161
|
+
**Одна строка в существующей записи — самый дешёвый и самый ценный вклад.** Намерение уже
|
|
162
|
+
доказано отказом, образцы уже лежат, проверять нечего кроме самой команды.
|
|
163
|
+
|
|
164
|
+
## Если готового нет
|
|
165
|
+
|
|
166
|
+
Тогда свой гейт — и в его `README.md` пишется, **что именно проверено**: какой инструмент
|
|
167
|
+
смотрели и какой командой. Это не бюрократия: через год кто-то захочет выкинуть самописное как
|
|
168
|
+
дубль, и разница между «не искал» и «нет» решает, выкинуть или оставить.
|
|
169
|
+
|
|
170
|
+
Норма записи — `kit/gates/README.md`.
|