kodu 2.1.2 → 2.2.0

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.
Files changed (122) hide show
  1. package/AGENTS.md +23 -1
  2. package/__tests__/core/registry/registry.service.test.ts +82 -0
  3. package/__tests__/shared/runbook/runbook.service.test.ts +104 -0
  4. package/dist/package.json +1 -1
  5. package/dist/src/app.module.js +6 -0
  6. package/dist/src/app.module.js.map +1 -1
  7. package/dist/src/commands/init/init.command.d.ts +1 -0
  8. package/dist/src/commands/init/init.command.js +34 -1
  9. package/dist/src/commands/init/init.command.js.map +1 -1
  10. package/dist/src/commands/ops/ops-add.command.d.ts +18 -0
  11. package/dist/src/commands/ops/ops-add.command.js +102 -0
  12. package/dist/src/commands/ops/ops-add.command.js.map +1 -0
  13. package/dist/src/commands/ops/ops-init.command.d.ts +22 -0
  14. package/dist/src/commands/ops/ops-init.command.js +130 -0
  15. package/dist/src/commands/ops/ops-init.command.js.map +1 -0
  16. package/dist/src/commands/ops/ops-list.command.d.ts +12 -0
  17. package/dist/src/commands/ops/ops-list.command.js +73 -0
  18. package/dist/src/commands/ops/ops-list.command.js.map +1 -0
  19. package/dist/src/commands/ops/ops-path.command.d.ts +9 -0
  20. package/dist/src/commands/ops/ops-path.command.js +52 -0
  21. package/dist/src/commands/ops/ops-path.command.js.map +1 -0
  22. package/dist/src/commands/ops/ops-runbook.command.d.ts +12 -0
  23. package/dist/src/commands/ops/ops-runbook.command.js +81 -0
  24. package/dist/src/commands/ops/ops-runbook.command.js.map +1 -0
  25. package/dist/src/commands/ops/ops-status.command.d.ts +11 -0
  26. package/dist/src/commands/ops/ops-status.command.js +62 -0
  27. package/dist/src/commands/ops/ops-status.command.js.map +1 -0
  28. package/dist/src/commands/ops/ops-use.command.d.ts +12 -0
  29. package/dist/src/commands/ops/ops-use.command.js +76 -0
  30. package/dist/src/commands/ops/ops-use.command.js.map +1 -0
  31. package/dist/src/commands/ops/ops.command.d.ts +7 -0
  32. package/dist/src/commands/ops/ops.command.js +56 -0
  33. package/dist/src/commands/ops/ops.command.js.map +1 -0
  34. package/dist/src/commands/ops/ops.helpers.d.ts +2 -0
  35. package/dist/src/commands/ops/ops.helpers.js +11 -0
  36. package/dist/src/commands/ops/ops.helpers.js.map +1 -0
  37. package/dist/src/commands/ops/ops.module.d.ts +2 -0
  38. package/dist/src/commands/ops/ops.module.js +36 -0
  39. package/dist/src/commands/ops/ops.module.js.map +1 -0
  40. package/dist/src/core/registry/registry.module.d.ts +2 -0
  41. package/dist/src/core/registry/registry.module.js +22 -0
  42. package/dist/src/core/registry/registry.module.js.map +1 -0
  43. package/dist/src/core/registry/registry.schema.d.ts +24 -0
  44. package/dist/src/core/registry/registry.schema.js +21 -0
  45. package/dist/src/core/registry/registry.schema.js.map +1 -0
  46. package/dist/src/core/registry/registry.service.d.ts +16 -0
  47. package/dist/src/core/registry/registry.service.js +91 -0
  48. package/dist/src/core/registry/registry.service.js.map +1 -0
  49. package/dist/src/shared/runbook/runbook.module.d.ts +2 -0
  50. package/dist/src/shared/runbook/runbook.module.js +22 -0
  51. package/dist/src/shared/runbook/runbook.module.js.map +1 -0
  52. package/dist/src/shared/runbook/runbook.service.d.ts +20 -0
  53. package/dist/src/shared/runbook/runbook.service.js +118 -0
  54. package/dist/src/shared/runbook/runbook.service.js.map +1 -0
  55. package/dist/src/shared/runbook/runbook.templates.d.ts +6 -0
  56. package/dist/src/shared/runbook/runbook.templates.js +49 -0
  57. package/dist/src/shared/runbook/runbook.templates.js.map +1 -0
  58. package/dist/tsconfig.build.tsbuildinfo +1 -1
  59. package/package.json +1 -1
  60. package/registry.schema.json +39 -0
  61. package/scripts/generate-json-schema.ts +14 -5
  62. package/skills/ac/SKILL.md +239 -0
  63. package/skills/al/SKILL.md +98 -0
  64. package/skills/audit/SKILL.md +205 -0
  65. package/skills/audit/audit-baseline-template.yml +188 -0
  66. package/skills/audit/runtime-detect.md +64 -0
  67. package/skills/audit/stacks/_generic.md +41 -0
  68. package/skills/audit/stacks/_registry.md +47 -0
  69. package/skills/audit/stacks/go.md +66 -0
  70. package/skills/audit/stacks/java.md +44 -0
  71. package/skills/audit/stacks/node.md +57 -0
  72. package/skills/audit/stacks/python.md +45 -0
  73. package/skills/audit/stacks/rust.md +44 -0
  74. package/skills/audit-api-contracts/SKILL.md +201 -0
  75. package/skills/audit-architecture/SKILL.md +200 -0
  76. package/skills/audit-bugs/SKILL.md +226 -0
  77. package/skills/audit-concurrency/SKILL.md +197 -0
  78. package/skills/audit-deployment/SKILL.md +218 -0
  79. package/skills/audit-docs/SKILL.md +209 -0
  80. package/skills/audit-errors/SKILL.md +216 -0
  81. package/skills/audit-logging/SKILL.md +197 -0
  82. package/skills/audit-matrix/SKILL.md +245 -0
  83. package/skills/audit-meta/SKILL.md +120 -0
  84. package/skills/audit-naming/SKILL.md +200 -0
  85. package/skills/audit-owasp/SKILL.md +223 -0
  86. package/skills/audit-performance/SKILL.md +199 -0
  87. package/skills/audit-reinvention/SKILL.md +214 -0
  88. package/skills/audit-secrets/SKILL.md +198 -0
  89. package/skills/audit-tests/SKILL.md +210 -0
  90. package/skills/audit-validation/SKILL.md +206 -0
  91. package/skills/audit-verify/SKILL.md +139 -0
  92. package/skills/audit-yagni/SKILL.md +188 -0
  93. package/skills/doc-gen/SKILL.md +490 -0
  94. package/skills/doc-gen/scripts/doc_gen.py +911 -0
  95. package/skills/generate-project-docs/SKILL.md +380 -0
  96. package/skills/implement-project/SKILL.md +409 -0
  97. package/skills/litefront-prototype/SKILL.md +484 -0
  98. package/skills/ops/SKILL.md +94 -0
  99. package/skills/post-call-task-builder/SKILL.md +419 -0
  100. package/skills/skills-best-practices/SKILL.md +415 -0
  101. package/skills/start/SKILL.md +319 -0
  102. package/skills/tech-blueprint/SKILL.md +890 -0
  103. package/skills/tech-blueprint/scripts/blueprint_validator.py +417 -0
  104. package/src/app.module.ts +6 -0
  105. package/src/commands/init/init.command.ts +43 -1
  106. package/src/commands/ops/ops-add.command.ts +83 -0
  107. package/src/commands/ops/ops-init.command.ts +125 -0
  108. package/src/commands/ops/ops-list.command.ts +57 -0
  109. package/src/commands/ops/ops-path.command.ts +38 -0
  110. package/src/commands/ops/ops-runbook.command.ts +74 -0
  111. package/src/commands/ops/ops-status.command.ts +47 -0
  112. package/src/commands/ops/ops-use.command.ts +76 -0
  113. package/src/commands/ops/ops.command.ts +42 -0
  114. package/src/commands/ops/ops.helpers.ts +20 -0
  115. package/src/commands/ops/ops.module.ts +23 -0
  116. package/src/core/registry/registry.module.ts +9 -0
  117. package/src/core/registry/registry.schema.ts +46 -0
  118. package/src/core/registry/registry.service.ts +128 -0
  119. package/src/shared/runbook/runbook.module.ts +9 -0
  120. package/src/shared/runbook/runbook.service.ts +164 -0
  121. package/src/shared/runbook/runbook.templates.ts +66 -0
  122. package/dist/tsconfig.tsbuildinfo +0 -1
@@ -0,0 +1,197 @@
1
+ ---
2
+ name: audit-concurrency
3
+ description: >
4
+ Аудит управления состоянием и конкурентности: race conditions, deadlocks, shared mutable state,
5
+ неатомарные операции. Запускай при /audit-concurrency.
6
+ ---
7
+
8
+ ## Правило применимости (Relevance Rule)
9
+
10
+ Применим к коду с параллельными операциями, shared state, кэшированием, транзакциями БД, очередями, WebSocket. Для однопоточных скриптов без параллелизма — верни пустой ответ.
11
+
12
+ ## Runtime Detection & Stack Profile
13
+
14
+ Этот аудит стек-агностичен: проверки сформулированы нейтрально, а конкретика
15
+ (инструменты, идиомы, анти-паттерны, примеры) берётся из профиля стека.
16
+
17
+ 1. **Профиль передан контекстом?** Если оркестратор `/audit` передал
18
+ `runtime=<id>` и/или содержимое профиля — используй его, шаги 2–3 пропусти.
19
+
20
+ 2. **Иначе определи РОВНО ОДИН рантайм** этого каталога:
21
+ ```bash
22
+ if [ -f package.json ]; then echo "runtime=node"
23
+ elif [ -f go.mod ]; then echo "runtime=go"
24
+ elif [ -f pyproject.toml ] || [ -f requirements.txt ] || [ -f setup.py ]; then echo "runtime=python"
25
+ elif [ -f Cargo.toml ]; then echo "runtime=rust"
26
+ elif [ -f pom.xml ] || ls build.gradle* settings.gradle* >/dev/null 2>&1; then echo "runtime=java"
27
+ else echo "runtime=generic"; fi
28
+ ```
29
+ Один запуск = один рантайм; не миксуй backend и frontend. Если найдено
30
+ несколько маркеров (монорепо) — выбери соответствующий текущему scope/анализируемым
31
+ файлам и зафиксируй выбор в разделе Audit Coverage.
32
+
33
+ 3. **Загрузи профиль** через Read: `./skills/audit/stacks/<runtime>.md`
34
+ (fallback `./skills/audit/stacks/_generic.md`, если файл не найден).
35
+
36
+ Дальше используй профиль:
37
+ - **Инструменты** — из секции «Tooling by category» профиля (раздел
38
+ «Инструментальная поддержка» ниже ссылается на категории, а не на команды).
39
+ - **Ожидания PASS** — из «Idioms»; **формулировки FAIL** — из «Anti-patterns».
40
+ - **Точечные подсказки** — из «Check-ID hints» по префиксу `CON-`.
41
+ - Если профиль `tier: general` или `runtime=generic` → стек-специфичные находки
42
+ без однозначного evidence помечай `🔍 UNVERIFIED`, а не `❌ FAIL`. Проверки,
43
+ чей механизм в рантайме отсутствует, помечай `N/A`.
44
+
45
+ ## Severity Guide
46
+
47
+ | Severity | Критерий назначения |
48
+ |----------|---------------------|
49
+ | 🔴 Critical | RCE, auth bypass, data corruption, необратимый финансовый риск |
50
+ | 🟠 High | Падение production, privilege escalation, утечка данных |
51
+ | 🟡 Medium | Деградация производительности или поддерживаемости без immediate outage |
52
+ | 🟢 Low | Стиль, читаемость, слабое нарушение конвенции |
53
+
54
+ Правило: severity = impact × exploitability × blast radius. Одинаковый паттерн → одинаковый severity между аудитами.
55
+
56
+ ## Чеклист
57
+
58
+ | Check ID | Проверка |
59
+ |----------|----------|
60
+ | CON-01 | Параллельные операции запускаются и синхронизируются корректно; результаты дожидаются, фоновые задачи не утекают |
61
+ | CON-02 | Read-modify-write операции выполняются в транзакциях [⚡ dynamic] |
62
+ | CON-03 | Разделяемое изменяемое состояние защищено синхронизацией (синглтоны, кэши, переменные уровня модуля) |
63
+ | CON-04 | Module-level кэш имеет механизм инвалидации |
64
+ | CON-05 | Обработчики событий и webhook-handlers идемпотентны [⚡ dynamic] |
65
+ | CON-06 | Фоновые операции имеют механизм отмены и не блокируют graceful shutdown |
66
+
67
+ ## Правила верификации
68
+
69
+ 1. **Только чеклист**: оценивай ТОЛЬКО проверки выше. Не добавляй новые.
70
+ 2. **Явная верификация = PASS**: ставь `✅ PASS` только если явно проверил механизм (нашёл схему, конфиг, guard) и подтвердил отсутствие нарушения — укажи что именно проверено.
71
+ 3. **Нет доказательства = UNVERIFIED**: не можешь указать `файл:строка` ни для нарушения, ни для подтверждения — ставь `🔍 UNVERIFIED`.
72
+ - Проверки с `[⚡ dynamic]` нельзя статически подтвердить — только `🔍 UNVERIFIED` или `❌ FAIL` (при явном evidence), но не `✅ PASS`
73
+ 4. **Baseline приоритетен**: check_id есть в `docs/audit-baseline.yml` → `⏸ ACCEPTED`.
74
+ 5. **Только 🔴/🟠 FAIL требуют решения**: 🟡/🟢 — решение необязательно.
75
+
76
+ ## Evidence Quality Rules
77
+
78
+ Любой `❌ FAIL` обязан содержать:
79
+ - Точный `file:line`
80
+ - Минимальный код-фрагмент (1–3 строки)
81
+ - Causal chain: почему именно это нарушение → какой риск возникает
82
+
83
+ Запрещено:
84
+ - Предполагать runtime behavior без evidence в коде
85
+ - Предполагать prod-конфигурацию по dev-конфигу
86
+ - Предполагать отсутствие middleware без проверки всей router chain
87
+ - Если вывод основан на предположении — только `🔍 UNVERIFIED`
88
+
89
+ ## Language Rule
90
+
91
+ Результаты аудита должны быть написаны простым и понятным языком. Избегай сложных терминов, жаргона и абстрактных понятий без необходимости. Общепринятые технические термины (Docker, HTTP, API, JSON, URL) допустимы. Описывай проблемы так, чтобы они были понятны разработчику любого уровня, а не только узкому специалисту в данной области.
92
+
93
+ ## Baseline
94
+
95
+ До анализа:
96
+ ```bash
97
+ if [ ! -f ./docs/audit-baseline.yml ]; then
98
+ mkdir -p ./docs
99
+ cp ./skills/audit/audit-baseline-template.yml ./docs/audit-baseline.yml 2>/dev/null || \
100
+ printf "accepted: []\n" > ./docs/audit-baseline.yml
101
+ fi
102
+ cat ./docs/audit-baseline.yml
103
+ ```
104
+
105
+ ## Контекст анализа
106
+
107
+ > Примеры ниже — иллюстративные (Node/TS). Конкретику текущего рантайма бери из
108
+ > загруженного профиля (`stacks/<runtime>.md`, секции Idioms/Anti-patterns/Check-ID hints).
109
+
110
+ **CON-01 — Параллельные операции запускаются и синхронизируются корректно:**
111
+ - Параллельная операция запущена, но её результат не дожидается (теряется)
112
+ - Фоновая задача утекает — нет пути её завершения
113
+ - Shared state между параллельными операциями без синхронизации
114
+ - В Node: `await` внутри `forEach` (итерация не ждёт промисов); `async` в `Array.map` без `Promise.all` (промисы не ожидаются)
115
+ - В Go: goroutine без `WaitGroup`/`errgroup`/`ctx` → потеря результата или goroutine leak; захват loop-переменной в `for { go f(loopVar) }` (до Go 1.22); незакрытый канал блокирует получателей
116
+
117
+ **CON-02 — Read-modify-write в транзакциях:**
118
+ - SELECT + UPDATE без транзакции (TOCTOU — time-of-check to time-of-use)
119
+ - Двойное списание/начисление без транзакции с блокировкой
120
+ - Check-then-act без атомарности (читаем → проверяем → пишем без lock)
121
+ - Optimistic locking без retry при конфликте версий
122
+ - Кэш-инвалидация между чтением и записью
123
+
124
+ **CON-03 — Разделяемое изменяемое состояние защищено синхронизацией:**
125
+ - Глобальные переменные, изменяемые из нескольких мест без синхронизации
126
+ - Синглтоны с mutable state без синхронизации
127
+ - Closure над изменяемой переменной в async callback
128
+ - Конкурентная запись в один файл/ресурс без координации
129
+ - В Go: map/переменная уровня пакета без `sync.Mutex`/atomic при конкурентном доступе → data race; ловится `go test -race`
130
+
131
+ **CON-04 — Module-level кэш инвалидируется:**
132
+ - Module-level кэш без механизма инвалидации при обновлении данных
133
+ - Кэш без TTL (stale data не обновляется никогда)
134
+ - Нет стратегии обновления кэша при изменении исходных данных
135
+
136
+ **CON-05 — Идемпотентность обработчиков:**
137
+ - Обработчики событий/сообщений без идемпотентности (повторная доставка не безопасна)
138
+ - Нет защиты от дублирующихся webhook-вызовов (нет проверки event_id)
139
+ - Финансовые или критические операции без идемпотентного ключа
140
+
141
+ **CON-06 — Фоновые операции с механизмом отмены:**
142
+ - Фоновая операция запущена без механизма отмены — при shutdown процесс не завершается чисто
143
+ - Background job без timeout и без механизма принудительной остановки
144
+ - Graceful shutdown не ожидает завершения фоновых задач
145
+ - В Node: Promise-цепочка в фоне без `AbortController`/`signal`; `setInterval`/`setImmediate` в request handler без очистки; `Promise.all` с неотменяемыми задачами
146
+ - В Go: фоновая goroutine не слушает `ctx.Done()` → не завершается при shutdown; нужен `context.Context` с проверкой отмены
147
+
148
+ ## Граница с другими аудитами
149
+
150
+ - **Идемпотентность** — этот скилл первичный (CON-05). `audit-errors` ссылается сюда.
151
+ - **async/await в forEach** — первичный: `audit-bugs` (BUG-02). `audit-concurrency` (CON-01) фокусируется на параллелизме, а не на синтаксической ошибке.
152
+
153
+ ## Формат вывода
154
+
155
+ | Check ID | Проверка | Статус | Уверенность | Доказательство | Решение | Исправлено |
156
+ |----------|----------|--------|-------------|----------------|---------|------------|
157
+ | CON-01 | Параллельные операции запускаются и синхронизируются корректно; результаты дожидаются, фоновые задачи не утекают | ✅ PASS | High | `src/` — async forEach не найден | — | — |
158
+ | CON-02 | Read-modify-write операции выполняются в транзакциях | ❌ FAIL 🔴 | High | `services/wallet.ts:67` | **1. Обернуть в db.transaction() с SELECT FOR UPDATE** \\ 2. Использовать optimistic locking с retry \\ 3. Добавить уникальное ограничение на уровне БД [⚡ dynamic] | Нет |
159
+ | CON-05 | Обработчики событий и webhook-handlers идемпотентны | ⏸ ACCEPTED | Medium | `handlers/stripe.ts:12` | В baseline: идемпотентность обеспечена через event_id [⚡ dynamic] | — |
160
+
161
+ Статусы: `✅ PASS` / `❌ FAIL 🔴` / `❌ FAIL 🟠` / `❌ FAIL 🟡` / `❌ FAIL 🟢` / `⏸ ACCEPTED` / `🔍 UNVERIFIED`
162
+
163
+ Уверенность: `High` — проверил несколько ключевых файлов, паттерн очевиден / `Medium` — проверил выборочно, паттерн вероятен / `Low` — ограниченный контекст, полная уверенность невозможна
164
+
165
+ Для `❌ FAIL`: ровно 3 варианта решения, разделитель `\\`, вариант 1 жирным.
166
+
167
+ `Исправлено`: FAIL → `Нет` (разработчик меняет на `✅ Да` вручную после фикса). PASS / ACCEPTED / UNVERIFIED → `—`.
168
+
169
+ Требования к решениям:
170
+ - Взаимно исключающие (не перефразировки одного и того же)
171
+ - Соответствуют текущему стеку проекта (не предлагать смену фреймворка)
172
+ - Не требуют переписать всю систему — realistic migration cost
173
+ - Вариант 3 может быть «оставить, задокументировать причину» при наличии обоснования
174
+
175
+ В конце отчёта добавь раздел покрытия:
176
+ ```
177
+ ## Audit Coverage
178
+ Проверено: src/module1/**, src/module2/**
179
+ Пропущено: scripts/**, migrations/**, tests/**
180
+ Файлов проверено: N | Пропущено: N
181
+ ```
182
+
183
+ Если все PASS — выведи: `✅ Проблем с конкурентностью не обнаружено.`
184
+
185
+ ## Сохранение результатов
186
+
187
+ 1. Найди папку сессии:
188
+ ```bash
189
+ ls -dt ./docs/audits/[0-9]*/ 2>/dev/null | head -1 | sed 's|/$||'
190
+ ```
191
+ Если пусто — создай: `mkdir -p ./docs/audits/$(date +"%Y-%m-%d_%H-%M")`
192
+ 2. Сохрани через Write: `<AUDIT_DIR>/audit-concurrency.md`
193
+
194
+ ```
195
+ # Audit Report: State & Concurrency — <YYYY-MM-DD HH:MM>
196
+ <таблица>
197
+ ```
@@ -0,0 +1,218 @@
1
+ ---
2
+ name: audit-deployment
3
+ description: >
4
+ Аудит сборки и деплоя: оптимизация Dockerfile, переменные окружения, CI/CD конфигурации,
5
+ secrets в конфигах, non-root пользователи. Запускай при /audit-deployment.
6
+ ---
7
+
8
+ ## Правило применимости (Relevance Rule)
9
+
10
+ Применим при наличии Dockerfile, docker-compose.yml, CI/CD конфигов (`.github/workflows`, `gitlab-ci.yml`, `Jenkinsfile`), `.env` файлов, Kubernetes манифестов. Для проектов без deployment конфигурации — верни пустой ответ.
11
+
12
+ ## Runtime Detection & Stack Profile
13
+
14
+ Этот аудит стек-агностичен: проверки сформулированы нейтрально, а конкретика
15
+ (инструменты, идиомы, анти-паттерны, примеры) берётся из профиля стека.
16
+
17
+ 1. **Профиль передан контекстом?** Если оркестратор `/audit` передал
18
+ `runtime=<id>` и/или содержимое профиля — используй его, шаги 2–3 пропусти.
19
+
20
+ 2. **Иначе определи РОВНО ОДИН рантайм** этого каталога:
21
+ ```bash
22
+ if [ -f package.json ]; then echo "runtime=node"
23
+ elif [ -f go.mod ]; then echo "runtime=go"
24
+ elif [ -f pyproject.toml ] || [ -f requirements.txt ] || [ -f setup.py ]; then echo "runtime=python"
25
+ elif [ -f Cargo.toml ]; then echo "runtime=rust"
26
+ elif [ -f pom.xml ] || ls build.gradle* settings.gradle* >/dev/null 2>&1; then echo "runtime=java"
27
+ else echo "runtime=generic"; fi
28
+ ```
29
+ Один запуск = один рантайм; не миксуй backend и frontend. Если найдено
30
+ несколько маркеров (монорепо) — выбери соответствующий текущему scope/анализируемым
31
+ файлам и зафиксируй выбор в разделе Audit Coverage.
32
+
33
+ 3. **Загрузи профиль** через Read: `./skills/audit/stacks/<runtime>.md`
34
+ (fallback `./skills/audit/stacks/_generic.md`, если файл не найден).
35
+
36
+ Дальше используй профиль:
37
+ - **Инструменты** — из секции «Tooling by category» профиля (раздел
38
+ «Инструментальная поддержка» ниже ссылается на категории, а не на команды).
39
+ - **Ожидания PASS** — из «Idioms»; **формулировки FAIL** — из «Anti-patterns».
40
+ - **Точечные подсказки** — из «Check-ID hints» по префиксу `DEP-`.
41
+ - Если профиль `tier: general` или `runtime=generic` → стек-специфичные находки
42
+ без однозначного evidence помечай `🔍 UNVERIFIED`, а не `❌ FAIL`. Проверки,
43
+ чей механизм в рантайме отсутствует, помечай `N/A`.
44
+
45
+ ## Severity Guide
46
+
47
+ | Severity | Критерий назначения |
48
+ |----------|---------------------|
49
+ | 🔴 Critical | RCE, auth bypass, data corruption, необратимый финансовый риск |
50
+ | 🟠 High | Падение production, privilege escalation, утечка данных |
51
+ | 🟡 Medium | Деградация производительности или поддерживаемости без immediate outage |
52
+ | 🟢 Low | Стиль, читаемость, слабое нарушение конвенции |
53
+
54
+ Правило: severity = impact × exploitability × blast radius. Одинаковый паттерн → одинаковый severity между аудитами.
55
+
56
+ ## Чеклист
57
+
58
+ | Check ID | Проверка |
59
+ |----------|----------|
60
+ | DEP-01 | Docker images используют pinned versions (нет :latest) |
61
+ | DEP-02 | Контейнеры запускаются от непривилегированного пользователя (USER nonroot) |
62
+ | DEP-03 | Multi-stage build: финальный образ без инструментов сборки и dev-артефактов |
63
+ | DEP-04 | .dockerignore исключает артефакты сборки/зависимости, VCS-каталог и секреты |
64
+ | DEP-05 | HEALTHCHECK определён в Dockerfile |
65
+ | DEP-06 | Секреты не hardcoded в Dockerfile (нет в ENV) |
66
+ | DEP-07 | .env исключён из VCS |
67
+ | DEP-08 | .env.example документирует все переменные окружения |
68
+ | DEP-09 | Окружение переключено в production-режим: dev-артефакты выключены в проде |
69
+ | DEP-10 | Детерминированная установка по локфайлу с проверкой целостности |
70
+ | DEP-11 | Ограничения ресурсов контейнера определены (CPU limits, Memory limits) |
71
+ | DEP-12 | Возможность запуска с read-only root filesystem проверена |
72
+
73
+ ## Правила верификации
74
+
75
+ 1. **Только чеклист**: оценивай ТОЛЬКО проверки выше. Не добавляй новые.
76
+ 2. **Явная верификация = PASS**: ставь `✅ PASS` только если явно проверил механизм (нашёл схему, конфиг, guard) и подтвердил отсутствие нарушения — укажи что именно проверено.
77
+ 3. **Нет доказательства = UNVERIFIED**: не можешь указать `файл:строка` ни для нарушения, ни для подтверждения — ставь `🔍 UNVERIFIED`.
78
+ 4. **Baseline приоритетен**: check_id есть в `docs/audit-baseline.yml` → `⏸ ACCEPTED`.
79
+ 5. **Только 🔴/🟠 FAIL требуют решения**: 🟡/🟢 — решение необязательно.
80
+
81
+ ## Evidence Quality Rules
82
+
83
+ Любой `❌ FAIL` обязан содержать:
84
+ - Точный `file:line`
85
+ - Минимальный код-фрагмент (1–3 строки)
86
+ - Causal chain: почему именно это нарушение → какой риск возникает
87
+
88
+ Запрещено:
89
+ - Предполагать runtime behavior без evidence в коде
90
+ - Предполагать prod-конфигурацию по dev-конфигу
91
+ - Предполагать отсутствие middleware без проверки всей router chain
92
+ - Если вывод основан на предположении — только `🔍 UNVERIFIED`
93
+
94
+ ## Language Rule
95
+
96
+ Результаты аудита должны быть написаны простым и понятным языком. Избегай сложных терминов, жаргона и абстрактных понятий без необходимости. Общепринятые технические термины (Docker, HTTP, API, JSON, URL) допустимы. Описывай проблемы так, чтобы они были понятны разработчику любого уровня, а не только узкому специалисту в данной области.
97
+
98
+ ## Baseline
99
+
100
+ До анализа:
101
+ ```bash
102
+ if [ ! -f ./docs/audit-baseline.yml ]; then
103
+ mkdir -p ./docs
104
+ cp ./skills/audit/audit-baseline-template.yml ./docs/audit-baseline.yml 2>/dev/null || \
105
+ printf "accepted: []\n" > ./docs/audit-baseline.yml
106
+ fi
107
+ cat ./docs/audit-baseline.yml
108
+ ```
109
+
110
+ ## Контекст анализа
111
+
112
+ > Примеры ниже — иллюстративные. Конкретные инструменты, идиомы и анти-паттерны
113
+ > сборки/деплоя для текущего рантайма бери из загруженного профиля
114
+ > (`stacks/<runtime>.md`, секции Idioms/Anti-patterns/Check-ID hints по префиксу
115
+ > `DEP-`). Node: `npm ci`/`package-lock.json`, `NODE_ENV`, `node_modules`.
116
+ > Go: builder→distroless, `go.mod`+`go.sum`, `CGO_ENABLED=0`, нет `net/http/pprof`.
117
+
118
+ **DEP-01 — Pinned versions:**
119
+ - Базовый образ `:latest` без pinning версии (непредсказуемые обновления)
120
+ - Тег `:alpine` без конкретной версии
121
+ - Digest-based pinning отсутствует для критичных образов
122
+
123
+ **DEP-02 — Непривилегированный пользователь:**
124
+ - Запуск контейнера как root без переключения на non-root (Node: `USER node`; Go: distroless `nonroot`)
125
+ - Отсутствие создания non-root пользователя перед переключением (или образа со встроенным nonroot)
126
+
127
+ **DEP-03 — Multi-stage build: финальный образ без инструментов сборки и dev-артефактов:**
128
+ - Отсутствие multi-stage build (инструменты сборки/dev-зависимости в финальном образе)
129
+ - Node: `devDependencies` устанавливаются в production stage
130
+ - Go: компилятор/тесты в финальном образе вместо `builder → distroless`
131
+ - Build artifacts не копируются из builder stage
132
+
133
+ **DEP-04 — .dockerignore:**
134
+ - Нет `.dockerignore` или он не исключает зависимости/артефакты сборки (Node: `node_modules`; Go: локальный `vendor/`, build-кэш) и VCS-каталог `.git`
135
+ - `.env` и прочие секреты не исключены из Docker build context
136
+ - Тесты и документация попадают в production образ
137
+
138
+ **DEP-05 — HEALTHCHECK:**
139
+ - HEALTHCHECK отсутствует в Dockerfile
140
+ - Health check endpoint не существует в приложении
141
+
142
+ **DEP-06 — Секреты не в Dockerfile ENV:**
143
+ - Secrets в `ENV` директивах Dockerfile (видны в docker inspect и слоях образа)
144
+ - Credentials в `ARG` без использования build secrets (`--secret`)
145
+
146
+ **DEP-07 — .env исключён из VCS:**
147
+ - `.env` файл с реальными credentials закоммичен в репозиторий
148
+ - Отсутствие `.env*` в `.gitignore`
149
+
150
+ **DEP-08 — .env.example документирует переменные:**
151
+ - `.env.example` отсутствует
152
+ - `.env.example` содержит реальные credentials
153
+ - Не все обязательные переменные задокументированы
154
+
155
+ **DEP-09 — Окружение переключено в production-режим:**
156
+ - Dev-артефакты не выключены в проде: debug-эндпоинты, verbose-логи, dev-зависимости
157
+ - Node: `NODE_ENV` не выставлен или `development` в prod образе (ведёт к загрузке devDependencies в runtime)
158
+ - Go: нет признаков prod-режима (нет `APP_ENV`/собственного флага), `net/http/pprof` и debug-роуты доступны в проде, нет `-ldflags "-s -w"`, нет `CGO_ENABLED=0`
159
+
160
+ **DEP-10 — Детерминированная установка по локфайлу с проверкой целостности:**
161
+ - Node: `npm install` вместо `npm ci` (не детерминированная, медленнее); отсутствие `package-lock.json`
162
+ - Go: `go.mod`/`go.sum` не закоммичены; в Dockerfile `go get` вместо `go mod download` по локфайлу; нет `GOFLAGS=-mod=readonly` / `go mod verify`
163
+
164
+ **Ограничения ресурсов:**
165
+ - `docker-compose.yml` без `deploy.resources.limits.memory` и `cpus`
166
+ - Kubernetes Deployment без `resources.limits` в контейнере
167
+ - Нет ограничений → один контейнер с memory leak роняет весь хост
168
+ - Go-доп.: при memory-лимите контейнера выставить `GOMEMLIMIT`/`GOMAXPROCS` под cgroup-квоты (иначе GC видит память/CPU хоста)
169
+
170
+ **Read-only filesystem:**
171
+ - Контейнер без `read_only: true` (docker-compose) или `readOnlyRootFilesystem: true` (K8s)
172
+ - Если приложение пишет во временные файлы — проверить наличие tmpfs mount для `/tmp`
173
+
174
+ ## Формат вывода
175
+
176
+ | Check ID | Проверка | Статус | Уверенность | Доказательство | Решение | Исправлено |
177
+ |----------|----------|--------|-------------|----------------|---------|------------|
178
+ | DEP-01 | Docker images используют pinned versions (нет :latest) | ✅ PASS | High | `Dockerfile:1` — pinned version указана | — | — |
179
+ | DEP-02 | Контейнеры запускаются от непривилегированного пользователя (USER nonroot) | ❌ FAIL 🟠 | High | `Dockerfile:12` | **1. Добавить `RUN addgroup -S app && adduser -S app -G app` и `USER app`** \\ 2. Использовать образ со встроенным nonroot (Node: node:alpine; Go: distroless nonroot) \\ 3. Добавить `USER node` если базовый образ node | Нет |
180
+ | DEP-05 | HEALTHCHECK определён в Dockerfile | ⏸ ACCEPTED | Medium | — | В baseline: health check управляется Kubernetes liveness probe | — |
181
+
182
+ Статусы: `✅ PASS` / `❌ FAIL 🔴` / `❌ FAIL 🟠` / `❌ FAIL 🟡` / `❌ FAIL 🟢` / `⏸ ACCEPTED` / `🔍 UNVERIFIED`
183
+
184
+ Уверенность: `High` — проверил несколько ключевых файлов, паттерн очевиден / `Medium` — проверил выборочно, паттерн вероятен / `Low` — ограниченный контекст, полная уверенность невозможна
185
+
186
+ Для `❌ FAIL`: ровно 3 варианта решения, разделитель `\\`, вариант 1 жирным.
187
+
188
+ `Исправлено`: FAIL → `Нет` (разработчик меняет на `✅ Да` вручную после фикса). PASS / ACCEPTED / UNVERIFIED → `—`.
189
+
190
+ Требования к решениям:
191
+ - Взаимно исключающие (не перефразировки одного и того же)
192
+ - Соответствуют текущему стеку проекта (не предлагать смену фреймворка)
193
+ - Не требуют переписать всю систему — realistic migration cost
194
+ - Вариант 3 может быть «оставить, задокументировать причину» при наличии обоснования
195
+
196
+ В конце отчёта добавь раздел покрытия:
197
+ ```
198
+ ## Audit Coverage
199
+ Проверено: src/module1/**, src/module2/**
200
+ Пропущено: scripts/**, migrations/**, tests/**
201
+ Файлов проверено: N | Пропущено: N
202
+ ```
203
+
204
+ Если все PASS — выведи: `✅ Конфигурация сборки и деплоя в порядке.`
205
+
206
+ ## Сохранение результатов
207
+
208
+ 1. Найди папку сессии:
209
+ ```bash
210
+ ls -dt ./docs/audits/[0-9]*/ 2>/dev/null | head -1 | sed 's|/$||'
211
+ ```
212
+ Если пусто — создай: `mkdir -p ./docs/audits/$(date +"%Y-%m-%d_%H-%M")`
213
+ 2. Сохрани через Write: `<AUDIT_DIR>/audit-deployment.md`
214
+
215
+ ```
216
+ # Audit Report: Build & Deployment Configuration — <YYYY-MM-DD HH:MM>
217
+ <таблица>
218
+ ```
@@ -0,0 +1,209 @@
1
+ ---
2
+ name: audit-docs
3
+ description: >
4
+ Аудит документации: расхождение README/инструкций с реальным кодом, битые ссылки,
5
+ рассинхрон env-переменных, комментарии и JSDoc, противоречащие сигнатурам, устаревшие
6
+ упоминания удалённых сущностей. Запускай при /audit-docs или запросе проверить документацию.
7
+ ---
8
+
9
+ ## Правило применимости (Relevance Rule)
10
+
11
+ Применим к любому проекту, где есть документация (README, `docs/**`, JSDoc, инструкции запуска) или комментарии в коде. Для проектов без документации вообще — проверяй только DOC-01 (минимум для онбординга) и DOC-04 (комментарии).
12
+
13
+ **Фокус — только верифицируемые расхождения.** Этот аудит НЕ оценивает «достаточно ли документации» субъективно. `❌ FAIL` ставится только когда документация **противоречит** коду или ссылается на то, чего нет — и это доказуемо `file:line`. «Хорошо бы добавить описание» без конкретного противоречия — не находка.
14
+
15
+ **Граница с соседними аудитами** (чтобы не дублировать находки):
16
+ - `audit-api-contracts` — владеет «документация API vs реализация» (эндпоинты, формы ответов, OpenAPI/GraphQL-схема). REST/GraphQL-контракты отдавай туда.
17
+ - `audit-yagni` (YAGNI-05) — владеет устаревшими TODO/FIXME без прогресса. Здесь TODO не проверяем.
18
+ - `audit-naming` — владеет самодокументирующимися именами. Здесь не оцениваем «понятность имён».
19
+ - `audit-deployment` (DEP-08) — владеет полнотой `.env.example`. DOC-02 фокусируется на **рассинхроне** «код ↔ документация», а не на наличии файла.
20
+
21
+ ## Runtime Detection & Stack Profile
22
+
23
+ Этот аудит стек-агностичен: проверки сформулированы нейтрально, а конкретика
24
+ (инструменты, идиомы, анти-паттерны, примеры) берётся из профиля стека.
25
+
26
+ 1. **Профиль передан контекстом?** Если оркестратор `/audit` передал
27
+ `runtime=<id>` и/или содержимое профиля — используй его, шаги 2–3 пропусти.
28
+
29
+ 2. **Иначе определи РОВНО ОДИН рантайм** этого каталога:
30
+ ```bash
31
+ if [ -f package.json ]; then echo "runtime=node"
32
+ elif [ -f go.mod ]; then echo "runtime=go"
33
+ elif [ -f pyproject.toml ] || [ -f requirements.txt ] || [ -f setup.py ]; then echo "runtime=python"
34
+ elif [ -f Cargo.toml ]; then echo "runtime=rust"
35
+ elif [ -f pom.xml ] || ls build.gradle* settings.gradle* >/dev/null 2>&1; then echo "runtime=java"
36
+ else echo "runtime=generic"; fi
37
+ ```
38
+ Один запуск = один рантайм; не миксуй backend и frontend. Если найдено
39
+ несколько маркеров (монорепо) — выбери соответствующий текущему scope/анализируемым
40
+ файлам и зафиксируй выбор в разделе Audit Coverage.
41
+
42
+ 3. **Загрузи профиль** через Read: `./skills/audit/stacks/<runtime>.md`
43
+ (fallback `./skills/audit/stacks/_generic.md`, если файл не найден).
44
+
45
+ Дальше используй профиль:
46
+ - **Инструменты** — из секции «Tooling by category» профиля (раздел
47
+ «Инструментальная поддержка» ниже ссылается на категории, а не на команды).
48
+ - **Ожидания PASS** — из «Idioms»; **формулировки FAIL** — из «Anti-patterns».
49
+ - **Точечные подсказки** — из «Check-ID hints» по префиксу `DOC-`.
50
+ - Если профиль `tier: general` или `runtime=generic` → стек-специфичные находки
51
+ без однозначного evidence помечай `🔍 UNVERIFIED`, а не `❌ FAIL`. Проверки,
52
+ чей механизм в рантайме отсутствует, помечай `N/A`.
53
+
54
+ ## Severity Guide
55
+
56
+ | Severity | Критерий назначения |
57
+ |----------|---------------------|
58
+ | 🔴 Critical | Документация направляет на небезопасное действие: инструкция отключить security-механизм, опубликованный реальный секрет «для примера», команда с разрушительным побочным эффектом без предупреждения |
59
+ | 🟠 High | Инструкция, ломающая онбординг/деплой: неверная команда установки/запуска, отсутствующая обязательная env-переменная, из-за которой прод падает или конфигурируется неверно |
60
+ | 🟡 Medium | Дрейф: README/комментарий/JSDoc противоречит текущему коду, битые внутренние ссылки, упоминание удалённых сущностей |
61
+ | 🟢 Low | Незначительная нехватка: публичный экспорт без doc-комментария, мелкая неактуальность без риска |
62
+
63
+ Правило: severity = impact × вероятность ввести разработчика/оператора в заблуждение × blast radius. Одинаковый паттерн → одинаковый severity между аудитами.
64
+
65
+ ## Чеклист
66
+
67
+ | Check ID | Проверка |
68
+ |----------|----------|
69
+ | DOC-01 | README/онбординг документирует установку, запуск, тесты, сборку; команды совпадают с манифестом задач проекта (package.json scripts / Makefile / Taskfile) |
70
+ | DOC-02 | Env-переменные синхронизированы: каждая используемая в коде переменная задокументирована, нет задокументированных, но неиспользуемых |
71
+ | DOC-03 | Внутренние ссылки и пути в Markdown-документации ведут на существующие файлы и секции |
72
+ | DOC-04 | Комментарии и JSDoc/docstring не противоречат коду (сигнатура, имена параметров, типы, описанное поведение) |
73
+ | DOC-05 | Публичная поверхность (экспортируемое API библиотеки/пакета) имеет doc-комментарий назначения и параметров |
74
+ | DOC-06 | Проектная/архитектурная документация не ссылается на удалённые или переименованные сущности и неактуальные факты |
75
+
76
+ ## Правила верификации
77
+
78
+ 1. **Только чеклист**: оценивай ТОЛЬКО проверки выше. Не добавляй новые.
79
+ 2. **Расхождение, не отсутствие**: `❌ FAIL` валиден только при доказуемом противоречии «документация ↔ код» или ссылке на несуществующее. Субъективное «мало документации» — не FAIL.
80
+ 3. **Два якоря на находку**: каждый FAIL обязан указывать И место в документации (`file:line`), И место в коде, которое его опровергает (`file:line`).
81
+ 4. **Явная верификация = PASS**: ставь `✅ PASS`, только если сверил документ с кодом и подтвердил соответствие — укажи что именно сверено.
82
+ 5. **Нет доказательства = UNVERIFIED**: не можешь указать оба якоря — ставь `🔍 UNVERIFIED`.
83
+ 6. **Baseline приоритетен**: check_id есть в `docs/audit-baseline.yml` → `⏸ ACCEPTED`.
84
+ 7. **Только 🔴/🟠 FAIL требуют решения**: 🟡/🟢 — решение необязательно.
85
+
86
+ ## Evidence Quality Rules
87
+
88
+ Любой `❌ FAIL` обязан содержать:
89
+ - Якорь в документации: `file:line` + цитата утверждения (1–2 строки)
90
+ - Якорь в коде: `file:line`, опровергающий утверждение
91
+ - Causal chain: почему расхождение → кого и как введёт в заблуждение (разработчик при онбординге / оператор при деплое / читатель API)
92
+
93
+ Запрещено:
94
+ - Считать FAIL отсутствие комментария там, где код самоочевиден (это не противоречие)
95
+ - Проверять внешние URL на доступность (сеть нестабильна) — только внутренние ссылки/пути и якоря внутри репозитория
96
+ - Предполагать, что команда/переменная «вероятно устарела» без сверки с кодом — только `🔍 UNVERIFIED`
97
+ - Дублировать находки, принадлежащие `audit-api-contracts`/`audit-yagni`/`audit-naming` (см. границы выше)
98
+
99
+ ## Language Rule
100
+
101
+ Результаты аудита должны быть написаны простым и понятным языком. Избегай сложных терминов, жаргона и абстрактных понятий без необходимости. Общепринятые технические термины (Docker, HTTP, API, JSON, URL) допустимы. Описывай проблемы так, чтобы они были понятны разработчику любого уровня, а не только узкому специалисту в данной области.
102
+
103
+ ## Baseline
104
+
105
+ До анализа:
106
+ ```bash
107
+ if [ ! -f ./docs/audit-baseline.yml ]; then
108
+ mkdir -p ./docs
109
+ cp ./skills/audit/audit-baseline-template.yml ./docs/audit-baseline.yml 2>/dev/null || \
110
+ printf "accepted: []\n" > ./docs/audit-baseline.yml
111
+ fi
112
+ cat ./docs/audit-baseline.yml
113
+ ```
114
+
115
+ ## Контекст анализа
116
+
117
+ **DOC-01 — Инструкции совпадают с реальностью:**
118
+ - README ссылается на скрипт/команду, которой нет в манифесте задач проекта (package.json scripts / Makefile / Taskfile)
119
+ - Документированы шаги установки с неверным менеджером пакетов или версией рантайма (несовпадение с `engines`/lock-файлом)
120
+ - Отсутствует базовый онбординг (как установить / запустить / прогнать тесты) при наличии этих скриптов в проекте
121
+
122
+ **DOC-02 — Синхронизация env-переменных:**
123
+ - Переменная используется в коде, но отсутствует в `.env.example`/README — оператор не узнает о ней
124
+ - Переменная задокументирована, но больше нигде не читается (устаревшая инструкция)
125
+ - Описание переменной противоречит коду (дефолт, формат, обязательность)
126
+ - Синтаксис извлечения env-переменных из кода бери из профиля стека (`process.env` / `import.meta.env` / `os.Getenv`)
127
+
128
+ **DOC-03 — Валидные ссылки и пути:**
129
+ - Относительная ссылка в Markdown ведёт на несуществующий файл
130
+ - Якорь (`#section`) указывает на отсутствующий заголовок
131
+ - Путь к файлу/папке в инструкции не существует в репозитории
132
+
133
+ **DOC-04 — Комментарии не лгут:**
134
+ - JSDoc/TSDoc `@param`/`@returns` не совпадает с фактической сигнатурой (имя, число, тип параметров)
135
+ - Комментарий описывает поведение, противоположное коду («возвращает null, если...» — а код кидает исключение)
136
+ - Docstring/комментарий ссылается на параметр/шаг, которого в функции уже нет
137
+
138
+ **DOC-05 — Документация публичной поверхности:**
139
+ - Применять ТОЛЬКО если проект является публикуемой библиотекой/пакетом (по манифесту проекта)
140
+ - Экспортируемая публичная функция/класс/тип без doc-комментария назначения
141
+ - Для приложений (не публикуемая библиотека) — DOC-05 = `N/A`, не FAIL
142
+
143
+ **DOC-06 — Актуальность проектной документации:**
144
+ - Архитектурный документ описывает модуль/сервис/эндпоинт, удалённый или переименованный в коде
145
+ - Диаграмма/схема упоминает технологию, которой больше нет в зависимостях
146
+ - Версия в документации расходится с `package.json`/тегом (если документация декларирует версию)
147
+
148
+ ## Инструментальная поддержка
149
+
150
+ Env-переменные — код vs документация (DOC-02): извлеки имена env-переменных из кода
151
+ инструментом категории **env-extraction** из профиля стека (секция «Tooling by
152
+ category»; синтаксис зависит от рантайма — Node: `process.env`/`import.meta.env`;
153
+ Go: `os.Getenv`). Сравни полученный список с задокументированными переменными
154
+ (`.env.example`/README); разница между списками — кандидаты в DOC-02. Верифицируй
155
+ каждую вручную (бывают переменные из CI/инфраструктуры, не из `.env`).
156
+
157
+ Команды README vs манифест задач (DOC-01): возьми список задач/скриптов из
158
+ **манифеста задач проекта** (по профилю стека: `package.json` scripts / `Makefile` /
159
+ `Taskfile`). Команды, упомянутые в README, сверь с этим манифестом — команда из
160
+ README, которой нет в манифесте, → кандидат в DOC-01.
161
+
162
+ Внутренние ссылки в Markdown (DOC-03): извлеки относительные ссылки `[...](./path)` и проверь существование путей через `Read`/`ls`. Внешние `http(s)://`-ссылки НЕ проверяй на доступность.
163
+
164
+ ## Формат вывода
165
+
166
+ | Check ID | Проверка | Статус | Уверенность | Доказательство | Решение | Исправлено |
167
+ |----------|----------|--------|-------------|----------------|---------|------------|
168
+ | DOC-01 | README документирует установку/запуск/тесты, команды совпадают со scripts | ❌ FAIL 🟠 | High | `README.md:24` — `npm run start:dev`; в `package.json` есть только `dev` | **1. Исправить README на `npm run dev`** \\ 2. Добавить алиас `start:dev` в scripts \\ 3. Сгенерировать раздел команд из scripts автоматически | Нет |
169
+ | DOC-02 | Env-переменные синхронизированы | ❌ FAIL 🟠 | High | `src/config.ts:9` читает `REDIS_URL`; нет в `.env.example` | **1. Добавить `REDIS_URL` в `.env.example` с описанием** \\ 2. Валидировать env при старте (zod/envalid) \\ 3. Удалить чтение переменной, если она не нужна | Нет |
170
+ | DOC-04 | Комментарии и JSDoc не противоречат коду | ❌ FAIL 🟡 | Medium | `src/user.ts:40` JSDoc `@returns User`; функция возвращает `User | null` | **1. Поправить `@returns` на `User \| null`** \\ 2. Удалить устаревший JSDoc \\ 3. Включить `eslint-plugin-jsdoc` для авто-проверки | Нет |
171
+ | DOC-05 | Публичная поверхность задокументирована | ✅ PASS | Medium | по манифесту — приложение, не публикуемая библиотека → N/A | — | — |
172
+
173
+ Статусы: `✅ PASS` / `❌ FAIL 🔴` / `❌ FAIL 🟠` / `❌ FAIL 🟡` / `❌ FAIL 🟢` / `⏸ ACCEPTED` / `🔍 UNVERIFIED` / `N/A`
174
+
175
+ Уверенность: `High` — сверил утверждение документации с кодом, расхождение однозначно / `Medium` — расхождение вероятно, контекст проверен выборочно / `Low` — ограниченный контекст, полная уверенность невозможна
176
+
177
+ Для `❌ FAIL`: ровно 3 варианта решения, разделитель `\\`, вариант 1 жирным.
178
+
179
+ `Исправлено`: FAIL → `Нет` (разработчик меняет на `✅ Да` вручную после фикса). PASS / ACCEPTED / UNVERIFIED / N/A → `—`.
180
+
181
+ Требования к решениям:
182
+ - Взаимно исключающие (не перефразировки одного и того же)
183
+ - Минимум один вариант — «исправить документ», минимум один — «исправить/удалить код или автоматизировать сверку»
184
+ - Реалистичная стоимость, без «переписать всю документацию»
185
+ - Вариант 3 может быть «удалить устаревший раздел/комментарий», если он больше не нужен
186
+
187
+ В конце отчёта добавь раздел покрытия:
188
+ ```
189
+ ## Audit Coverage
190
+ Проверено: README.md, docs/**, src/**/*.ts (JSDoc), .env.example
191
+ Пропущено: CHANGELOG.md (auto-generated), node_modules/**
192
+ Файлов проверено: N | Пропущено: N
193
+ ```
194
+
195
+ Если все PASS — выведи: `✅ Расхождений документации с кодом не обнаружено.`
196
+
197
+ ## Сохранение результатов
198
+
199
+ 1. Найди папку сессии:
200
+ ```bash
201
+ ls -dt ./docs/audits/[0-9]*/ 2>/dev/null | head -1 | sed 's|/$||'
202
+ ```
203
+ Если пусто — создай: `mkdir -p ./docs/audits/$(date +"%Y-%m-%d_%H-%M")`
204
+ 2. Сохрани через Write: `<AUDIT_DIR>/audit-docs.md`
205
+
206
+ ```
207
+ # Audit Report: Documentation — <YYYY-MM-DD HH:MM>
208
+ <таблица>
209
+ ```