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.
- package/AGENTS.md +23 -1
- package/__tests__/core/registry/registry.service.test.ts +82 -0
- package/__tests__/shared/runbook/runbook.service.test.ts +104 -0
- package/dist/package.json +1 -1
- package/dist/src/app.module.js +6 -0
- package/dist/src/app.module.js.map +1 -1
- package/dist/src/commands/init/init.command.d.ts +1 -0
- package/dist/src/commands/init/init.command.js +34 -1
- package/dist/src/commands/init/init.command.js.map +1 -1
- package/dist/src/commands/ops/ops-add.command.d.ts +18 -0
- package/dist/src/commands/ops/ops-add.command.js +102 -0
- package/dist/src/commands/ops/ops-add.command.js.map +1 -0
- package/dist/src/commands/ops/ops-init.command.d.ts +22 -0
- package/dist/src/commands/ops/ops-init.command.js +130 -0
- package/dist/src/commands/ops/ops-init.command.js.map +1 -0
- package/dist/src/commands/ops/ops-list.command.d.ts +12 -0
- package/dist/src/commands/ops/ops-list.command.js +73 -0
- package/dist/src/commands/ops/ops-list.command.js.map +1 -0
- package/dist/src/commands/ops/ops-path.command.d.ts +9 -0
- package/dist/src/commands/ops/ops-path.command.js +52 -0
- package/dist/src/commands/ops/ops-path.command.js.map +1 -0
- package/dist/src/commands/ops/ops-runbook.command.d.ts +12 -0
- package/dist/src/commands/ops/ops-runbook.command.js +81 -0
- package/dist/src/commands/ops/ops-runbook.command.js.map +1 -0
- package/dist/src/commands/ops/ops-status.command.d.ts +11 -0
- package/dist/src/commands/ops/ops-status.command.js +62 -0
- package/dist/src/commands/ops/ops-status.command.js.map +1 -0
- package/dist/src/commands/ops/ops-use.command.d.ts +12 -0
- package/dist/src/commands/ops/ops-use.command.js +76 -0
- package/dist/src/commands/ops/ops-use.command.js.map +1 -0
- package/dist/src/commands/ops/ops.command.d.ts +7 -0
- package/dist/src/commands/ops/ops.command.js +56 -0
- package/dist/src/commands/ops/ops.command.js.map +1 -0
- package/dist/src/commands/ops/ops.helpers.d.ts +2 -0
- package/dist/src/commands/ops/ops.helpers.js +11 -0
- package/dist/src/commands/ops/ops.helpers.js.map +1 -0
- package/dist/src/commands/ops/ops.module.d.ts +2 -0
- package/dist/src/commands/ops/ops.module.js +36 -0
- package/dist/src/commands/ops/ops.module.js.map +1 -0
- package/dist/src/core/registry/registry.module.d.ts +2 -0
- package/dist/src/core/registry/registry.module.js +22 -0
- package/dist/src/core/registry/registry.module.js.map +1 -0
- package/dist/src/core/registry/registry.schema.d.ts +24 -0
- package/dist/src/core/registry/registry.schema.js +21 -0
- package/dist/src/core/registry/registry.schema.js.map +1 -0
- package/dist/src/core/registry/registry.service.d.ts +16 -0
- package/dist/src/core/registry/registry.service.js +91 -0
- package/dist/src/core/registry/registry.service.js.map +1 -0
- package/dist/src/shared/runbook/runbook.module.d.ts +2 -0
- package/dist/src/shared/runbook/runbook.module.js +22 -0
- package/dist/src/shared/runbook/runbook.module.js.map +1 -0
- package/dist/src/shared/runbook/runbook.service.d.ts +20 -0
- package/dist/src/shared/runbook/runbook.service.js +118 -0
- package/dist/src/shared/runbook/runbook.service.js.map +1 -0
- package/dist/src/shared/runbook/runbook.templates.d.ts +6 -0
- package/dist/src/shared/runbook/runbook.templates.js +49 -0
- package/dist/src/shared/runbook/runbook.templates.js.map +1 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/registry.schema.json +39 -0
- package/scripts/generate-json-schema.ts +14 -5
- package/skills/ac/SKILL.md +239 -0
- package/skills/al/SKILL.md +98 -0
- package/skills/audit/SKILL.md +205 -0
- package/skills/audit/audit-baseline-template.yml +188 -0
- package/skills/audit/runtime-detect.md +64 -0
- package/skills/audit/stacks/_generic.md +41 -0
- package/skills/audit/stacks/_registry.md +47 -0
- package/skills/audit/stacks/go.md +66 -0
- package/skills/audit/stacks/java.md +44 -0
- package/skills/audit/stacks/node.md +57 -0
- package/skills/audit/stacks/python.md +45 -0
- package/skills/audit/stacks/rust.md +44 -0
- package/skills/audit-api-contracts/SKILL.md +201 -0
- package/skills/audit-architecture/SKILL.md +200 -0
- package/skills/audit-bugs/SKILL.md +226 -0
- package/skills/audit-concurrency/SKILL.md +197 -0
- package/skills/audit-deployment/SKILL.md +218 -0
- package/skills/audit-docs/SKILL.md +209 -0
- package/skills/audit-errors/SKILL.md +216 -0
- package/skills/audit-logging/SKILL.md +197 -0
- package/skills/audit-matrix/SKILL.md +245 -0
- package/skills/audit-meta/SKILL.md +120 -0
- package/skills/audit-naming/SKILL.md +200 -0
- package/skills/audit-owasp/SKILL.md +223 -0
- package/skills/audit-performance/SKILL.md +199 -0
- package/skills/audit-reinvention/SKILL.md +214 -0
- package/skills/audit-secrets/SKILL.md +198 -0
- package/skills/audit-tests/SKILL.md +210 -0
- package/skills/audit-validation/SKILL.md +206 -0
- package/skills/audit-verify/SKILL.md +139 -0
- package/skills/audit-yagni/SKILL.md +188 -0
- package/skills/doc-gen/SKILL.md +490 -0
- package/skills/doc-gen/scripts/doc_gen.py +911 -0
- package/skills/generate-project-docs/SKILL.md +380 -0
- package/skills/implement-project/SKILL.md +409 -0
- package/skills/litefront-prototype/SKILL.md +484 -0
- package/skills/ops/SKILL.md +94 -0
- package/skills/post-call-task-builder/SKILL.md +419 -0
- package/skills/skills-best-practices/SKILL.md +415 -0
- package/skills/start/SKILL.md +319 -0
- package/skills/tech-blueprint/SKILL.md +890 -0
- package/skills/tech-blueprint/scripts/blueprint_validator.py +417 -0
- package/src/app.module.ts +6 -0
- package/src/commands/init/init.command.ts +43 -1
- package/src/commands/ops/ops-add.command.ts +83 -0
- package/src/commands/ops/ops-init.command.ts +125 -0
- package/src/commands/ops/ops-list.command.ts +57 -0
- package/src/commands/ops/ops-path.command.ts +38 -0
- package/src/commands/ops/ops-runbook.command.ts +74 -0
- package/src/commands/ops/ops-status.command.ts +47 -0
- package/src/commands/ops/ops-use.command.ts +76 -0
- package/src/commands/ops/ops.command.ts +42 -0
- package/src/commands/ops/ops.helpers.ts +20 -0
- package/src/commands/ops/ops.module.ts +23 -0
- package/src/core/registry/registry.module.ts +9 -0
- package/src/core/registry/registry.schema.ts +46 -0
- package/src/core/registry/registry.service.ts +128 -0
- package/src/shared/runbook/runbook.module.ts +9 -0
- package/src/shared/runbook/runbook.service.ts +164 -0
- package/src/shared/runbook/runbook.templates.ts +66 -0
- package/dist/tsconfig.tsbuildinfo +0 -1
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: audit-api-contracts
|
|
3
|
+
description: >
|
|
4
|
+
Аудит API-контрактов: консистентность форм ответов, HTTP-коды, версионирование,
|
|
5
|
+
документация vs реализация, GraphQL/REST конвенции. Запускай при /audit-api-contracts.
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Правило применимости (Relevance Rule)
|
|
9
|
+
|
|
10
|
+
Применим к коду с HTTP-роутингом, REST/GraphQL API, контроллерами, схемами запросов/ответов, OpenAPI/Swagger спецификациями. Для CLI-инструментов и internal-only функций без HTTP-интерфейса — верни пустой ответ.
|
|
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» по префиксу `API-`.
|
|
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
|
+
| API-01 | Форма ответов консистентна — единый envelope или его отсутствие по всему API |
|
|
61
|
+
| API-02 | HTTP статус-коды семантически корректны (201 при создании, 4xx для client errors) |
|
|
62
|
+
| API-03 | Error responses машиночитаемы и консистентны по структуре |
|
|
63
|
+
| API-04 | Именование полей консистентно (camelCase или snake_case, не смешано) |
|
|
64
|
+
| API-05 | Stack trace и внутренние детали не попадают в error responses |
|
|
65
|
+
| API-06 | Пагинация включает метаданные (total/hasNext) где применима |
|
|
66
|
+
| API-07 | Публичный API имеет стратегию версионирования |
|
|
67
|
+
|
|
68
|
+
## Правила верификации
|
|
69
|
+
|
|
70
|
+
1. **Только чеклист**: оценивай ТОЛЬКО проверки выше. Не добавляй новые.
|
|
71
|
+
2. **Явная верификация = PASS**: ставь `✅ PASS` только если явно проверил механизм (нашёл схему, конфиг, guard) и подтвердил отсутствие нарушения — укажи что именно проверено.
|
|
72
|
+
3. **Нет доказательства = UNVERIFIED**: не можешь указать `файл:строка` ни для нарушения, ни для подтверждения — ставь `🔍 UNVERIFIED`.
|
|
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
|
+
> Примеры в этом разделе и в таблице вывода (Express-style middleware, `HttpException`)
|
|
108
|
+
> иллюстративны. Контракт может быть REST (Node: Express/Fastify; Go: chi-роуты)
|
|
109
|
+
> или GraphQL (Node: Apollo/Yoga; Go: gqlgen-резолверы). Check ID и их смысл
|
|
110
|
+
> одинаковы для любого транспорта — конкретику бери из загруженного профиля.
|
|
111
|
+
|
|
112
|
+
**API-01 — Консистентная форма ответов:**
|
|
113
|
+
- Одна сущность возвращается с разными наборами полей в разных endpoint'ах
|
|
114
|
+
- Envelope-паттерн применяется непоследовательно (`{ data: ... }` в одних, прямой объект в других)
|
|
115
|
+
- Разная структура success-ответов для схожих операций
|
|
116
|
+
|
|
117
|
+
**API-02 — Семантически корректные HTTP-коды:**
|
|
118
|
+
- 200 возвращается при ошибке (тело содержит `{ error: "..." }` но статус 200)
|
|
119
|
+
- 500 возвращается для пользовательских ошибок (должен быть 4xx)
|
|
120
|
+
- 201 не используется при создании ресурса (POST → 200 вместо 201)
|
|
121
|
+
- 204 возвращается с телом ответа (No Content не должен иметь body)
|
|
122
|
+
- GET-запрос с побочными эффектами (изменение состояния)
|
|
123
|
+
|
|
124
|
+
**API-03 — Machine-readable и консистентные error responses:**
|
|
125
|
+
- Разный формат ошибок в разных endpoint'ах
|
|
126
|
+
- Отсутствие machine-readable error code (только human-readable message)
|
|
127
|
+
- Разная структура ошибок для validation vs auth vs server errors
|
|
128
|
+
|
|
129
|
+
**API-04 — Консистентное именование полей:**
|
|
130
|
+
- Разные имена для одного поля (`userId` vs `user_id` vs `id`)
|
|
131
|
+
- Смешение camelCase и snake_case в одном API
|
|
132
|
+
- Непоследовательные аббревиатуры (`orgId` vs `organisationId`)
|
|
133
|
+
|
|
134
|
+
**API-05 — Нет технических деталей в responses:**
|
|
135
|
+
- Stack trace в ответе в production
|
|
136
|
+
- Внутренние пути файловой системы в error messages
|
|
137
|
+
- SQL-ошибки или DB-специфичные сообщения в API responses
|
|
138
|
+
- Версии библиотек/фреймворка в заголовках или телах ответов
|
|
139
|
+
|
|
140
|
+
**API-06 — Пагинация с метаданными:**
|
|
141
|
+
- Разные паттерны пагинации в одном API (offset + cursor смешаны)
|
|
142
|
+
- Отсутствие метаданных пагинации (total, hasNext) при наличии пагинации
|
|
143
|
+
- Нет максимального лимита страницы (клиент может запросить всё)
|
|
144
|
+
|
|
145
|
+
**API-07 — Стратегия версионирования:**
|
|
146
|
+
- Поле удалено или переименовано без версионирования API
|
|
147
|
+
- Тип поля изменён (string → number) без версионирования
|
|
148
|
+
- Нет стратегии версионирования при наличии публичного API (URL versioning, header versioning)
|
|
149
|
+
|
|
150
|
+
## Граница с другими аудитами
|
|
151
|
+
|
|
152
|
+
- **Stack trace в ответах** (API-05) — первичный: `audit-errors` (ERR-02). Если обнаружено здесь — добавь cross-ref «*см. ERR-02*» в доказательство, не создавай дублирующий `❌ FAIL`.
|
|
153
|
+
- **Валидация входных данных** (отсутствие проверки полей) → `audit-validation`
|
|
154
|
+
- **OWASP-уязвимости** (injection, auth) → `audit-owasp`
|
|
155
|
+
- **Производительность** (N+1 без DataLoader) → `audit-performance`
|
|
156
|
+
|
|
157
|
+
## Формат вывода
|
|
158
|
+
|
|
159
|
+
| Check ID | Проверка | Статус | Уверенность | Доказательство | Решение | Исправлено |
|
|
160
|
+
|----------|----------|--------|-------------|----------------|---------|------------|
|
|
161
|
+
| API-01 | Форма ответов консистентна — единый envelope или его отсутствие по всему API | ✅ PASS | High | `routes/` — все ответы используют единый `{ data, error }` envelope | — | — |
|
|
162
|
+
| API-02 | HTTP статус-коды семантически корректны (201 при создании, 4xx для client errors) | ❌ FAIL 🟠 | High | `routes/auth.ts:78` | **1. Заменить res.status(200) на res.status(400) для ошибок валидации** \\ 2. Добавить централизованный error middleware \\ 3. Использовать HTTP Exception классы (HttpException) | Нет |
|
|
163
|
+
| API-07 | Публичный API имеет стратегию версионирования | ⏸ ACCEPTED | Medium | — | В baseline: внутренний API без внешних клиентов | — |
|
|
164
|
+
|
|
165
|
+
Статусы: `✅ PASS` / `❌ FAIL 🔴` / `❌ FAIL 🟠` / `❌ FAIL 🟡` / `❌ FAIL 🟢` / `⏸ ACCEPTED` / `🔍 UNVERIFIED`
|
|
166
|
+
|
|
167
|
+
Уверенность: `High` — проверил несколько ключевых файлов, паттерн очевиден / `Medium` — проверил выборочно, паттерн вероятен / `Low` — ограниченный контекст, полная уверенность невозможна
|
|
168
|
+
|
|
169
|
+
Для `❌ FAIL`: ровно 3 варианта решения, разделитель `\\`, вариант 1 жирным.
|
|
170
|
+
|
|
171
|
+
`Исправлено`: FAIL → `Нет` (разработчик меняет на `✅ Да` вручную после фикса). PASS / ACCEPTED / UNVERIFIED → `—`.
|
|
172
|
+
|
|
173
|
+
Требования к решениям:
|
|
174
|
+
- Взаимно исключающие (не перефразировки одного и того же)
|
|
175
|
+
- Соответствуют текущему стеку проекта (не предлагать смену фреймворка)
|
|
176
|
+
- Не требуют переписать всю систему — realistic migration cost
|
|
177
|
+
- Вариант 3 может быть «оставить, задокументировать причину» при наличии обоснования
|
|
178
|
+
|
|
179
|
+
В конце отчёта добавь раздел покрытия:
|
|
180
|
+
```
|
|
181
|
+
## Audit Coverage
|
|
182
|
+
Проверено: src/module1/**, src/module2/**
|
|
183
|
+
Пропущено: scripts/**, migrations/**, tests/**
|
|
184
|
+
Файлов проверено: N | Пропущено: N
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
Если все PASS — выведи: `✅ API-контракты консистентны.`
|
|
188
|
+
|
|
189
|
+
## Сохранение результатов
|
|
190
|
+
|
|
191
|
+
1. Найди папку сессии:
|
|
192
|
+
```bash
|
|
193
|
+
ls -dt ./docs/audits/[0-9]*/ 2>/dev/null | head -1 | sed 's|/$||'
|
|
194
|
+
```
|
|
195
|
+
Если пусто — создай: `mkdir -p ./docs/audits/$(date +"%Y-%m-%d_%H-%M")`
|
|
196
|
+
2. Сохрани через Write: `<AUDIT_DIR>/audit-api-contracts.md`
|
|
197
|
+
|
|
198
|
+
```
|
|
199
|
+
# Audit Report: API Contracts — <YYYY-MM-DD HH:MM>
|
|
200
|
+
<таблица>
|
|
201
|
+
```
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: audit-architecture
|
|
3
|
+
description: >
|
|
4
|
+
Аудит архитектуры и файловой структуры: корректность связей между слоями, нарушения
|
|
5
|
+
dependency rules, структура папок, circular dependencies. Запускай при /audit-architecture.
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Правило применимости (Relevance Rule)
|
|
9
|
+
|
|
10
|
+
Применим к проектам с выраженной слоистой архитектурой (MVC, Clean Architecture, DDD, Hexagonal). Для single-file скриптов или утилит без архитектурного деления — верни пустой ответ.
|
|
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» по префиксу `ARC-`.
|
|
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
|
+
| ARC-01 | Бизнес-логика вынесена из route handlers в service/domain слой |
|
|
61
|
+
| ARC-02 | Presentation layer не взаимодействует с БД напрямую |
|
|
62
|
+
| ARC-03 | Нет circular dependencies между модулями |
|
|
63
|
+
| ARC-04 | Нет god-объектов: файлы и классы имеют единственную ответственность |
|
|
64
|
+
| ARC-05 | Конфигурация и env-переменные изолированы в config-модуле |
|
|
65
|
+
| ARC-06 | Внешние зависимости инжектируются (DI), не импортируются напрямую |
|
|
66
|
+
| ARC-07 | Доменный слой не импортирует инфраструктурные модули |
|
|
67
|
+
|
|
68
|
+
## Правила верификации
|
|
69
|
+
|
|
70
|
+
1. **Только чеклист**: оценивай ТОЛЬКО проверки выше. Не добавляй новые.
|
|
71
|
+
2. **Явная верификация = PASS**: ставь `✅ PASS` только если явно проверил механизм (нашёл схему, конфиг, guard) и подтвердил отсутствие нарушения — укажи что именно проверено.
|
|
72
|
+
3. **Нет доказательства = UNVERIFIED**: не можешь указать `файл:строка` ни для нарушения, ни для подтверждения — ставь `🔍 UNVERIFIED`.
|
|
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
|
+
**ARC-01 — Бизнес-логика в service/domain слое:**
|
|
108
|
+
- Бизнес-правила и вычисления прямо в route handler / controller
|
|
109
|
+
- Сложные условия и трансформации данных в middleware вместо сервиса
|
|
110
|
+
- Операции с несколькими сущностями выполняются в handler без сервиса
|
|
111
|
+
|
|
112
|
+
**ARC-02 — Presentation layer без прямых DB-вызовов:**
|
|
113
|
+
- Прямые обращения к ORM/query builder из роутеров/контроллеров
|
|
114
|
+
- Импорт репозиториев или DB-клиента непосредственно в слой представления
|
|
115
|
+
- SQL / Prisma / Mongoose вызовы в middleware (примеры иллюстративны — Node; конкретные ORM/драйверы текущего рантайма см. в профиле, секции Idioms/Anti-patterns)
|
|
116
|
+
|
|
117
|
+
**ARC-03 — Нет circular dependencies:**
|
|
118
|
+
- Модуль A импортирует модуль B, который импортирует модуль A
|
|
119
|
+
- Circular deps через несколько уровней (A→B→C→A)
|
|
120
|
+
- Прямые импорты между feature-модулями (должны идти через shared)
|
|
121
|
+
|
|
122
|
+
**ARC-04 — Нет god-объектов:**
|
|
123
|
+
- Файлы >500 строк с несвязанной логикой (несколько разных ответственностей)
|
|
124
|
+
- Классы с методами из разных доменных областей
|
|
125
|
+
- Модуль делает несвязанные вещи (low cohesion)
|
|
126
|
+
|
|
127
|
+
**ARC-05 — Конфигурация изолирована:**
|
|
128
|
+
- Доступ к конфигурации/env централизован в одном модуле; чтение env вразброс вне config-модуля — нарушение (профиль уточняет механизм: `process.env` в Node / `os.Getenv` в Go / `caarlos0/env`-теги и т.п.)
|
|
129
|
+
- Магические строки с именами env-переменных разбросаны по коду
|
|
130
|
+
- Нет единой точки валидации конфигурации при старте приложения
|
|
131
|
+
|
|
132
|
+
**ARC-06 — Внешние зависимости инжектируются:**
|
|
133
|
+
- HTTP-клиенты, email-сервисы, БД-клиенты создаются внутри функций (не инжектируются)
|
|
134
|
+
- Зависимость от конкретных реализаций вместо интерфейсов/абстракций
|
|
135
|
+
- Отсутствие dependency injection делает код нетестируемым (нельзя подменить в тестах)
|
|
136
|
+
|
|
137
|
+
**Направление зависимостей (Dependency Rule):**
|
|
138
|
+
> Примеры ниже иллюстративны (Node); конкретные ORM/типы инфраструктуры текущего рантайма см. в профиле (секции Idioms/Anti-patterns/Check-ID hints, ARC-07).
|
|
139
|
+
- Domain/service слой импортирует типы Prisma напрямую (должен через repository interface)
|
|
140
|
+
- Бизнес-логика зависит от Express Request/Response типов
|
|
141
|
+
- Domain entity содержит ORM-декораторы (TypeORM @Entity в domain классе)
|
|
142
|
+
- Нарушение: `domain/ → infrastructure/` (правильно: `infrastructure/ → domain/`)
|
|
143
|
+
|
|
144
|
+
## Инструментальная поддержка
|
|
145
|
+
|
|
146
|
+
Для ARC-03 (circular dependencies) и нарушений слоёв используй инструмент
|
|
147
|
+
категории **arch-lint** из профиля стека (секция «Tooling by category»). Используй
|
|
148
|
+
вывод как подсказку и верифицируй каждую находку вручную (`file:line`) перед
|
|
149
|
+
занесением в FAIL. Если ячейка пустая (tier general/generic) — проверяй вручную и
|
|
150
|
+
помечай находки `🔍 UNVERIFIED`.
|
|
151
|
+
|
|
152
|
+
Примечание: в Go циклы импортов запрещены компилятором, поэтому ARC-03 на уровне
|
|
153
|
+
пакетов — авто-PASS / N/A; проверять нужно только логические слои (см. Check-ID
|
|
154
|
+
hints профиля go).
|
|
155
|
+
|
|
156
|
+
## Формат вывода
|
|
157
|
+
|
|
158
|
+
| Check ID | Проверка | Статус | Уверенность | Доказательство | Решение | Исправлено |
|
|
159
|
+
|----------|----------|--------|-------------|----------------|---------|------------|
|
|
160
|
+
| ARC-01 | Бизнес-логика вынесена из route handlers в service/domain слой | ✅ PASS | High | `routes/` — handlers делегируют в services | — | — |
|
|
161
|
+
| ARC-03 | Нет circular dependencies между модулями | ❌ FAIL 🟠 | High | `modules/order/index.ts:3` | **1. Вынести общий код в shared модуль** \\ 2. Применить dependency inversion \\ 3. Разбить модуль на независимые части | Нет |
|
|
162
|
+
| ARC-06 | Внешние зависимости инжектируются (DI), не импортируются напрямую | ⏸ ACCEPTED | Medium | `services/payment.ts:1` | В baseline: refactor запланирован в Q3 | — |
|
|
163
|
+
|
|
164
|
+
Статусы: `✅ PASS` / `❌ FAIL 🔴` / `❌ FAIL 🟠` / `❌ FAIL 🟡` / `❌ FAIL 🟢` / `⏸ ACCEPTED` / `🔍 UNVERIFIED`
|
|
165
|
+
|
|
166
|
+
Уверенность: `High` — проверил несколько ключевых файлов, паттерн очевиден / `Medium` — проверил выборочно, паттерн вероятен / `Low` — ограниченный контекст, полная уверенность невозможна
|
|
167
|
+
|
|
168
|
+
Для `❌ FAIL`: ровно 3 варианта решения, разделитель `\\`, вариант 1 жирным.
|
|
169
|
+
|
|
170
|
+
`Исправлено`: FAIL → `Нет` (разработчик меняет на `✅ Да` вручную после фикса). PASS / ACCEPTED / UNVERIFIED → `—`.
|
|
171
|
+
|
|
172
|
+
Требования к решениям:
|
|
173
|
+
- Взаимно исключающие (не перефразировки одного и того же)
|
|
174
|
+
- Соответствуют текущему стеку проекта (не предлагать смену фреймворка)
|
|
175
|
+
- Не требуют переписать всю систему — realistic migration cost
|
|
176
|
+
- Вариант 3 может быть «оставить, задокументировать причину» при наличии обоснования
|
|
177
|
+
|
|
178
|
+
В конце отчёта добавь раздел покрытия:
|
|
179
|
+
```
|
|
180
|
+
## Audit Coverage
|
|
181
|
+
Проверено: src/module1/**, src/module2/**
|
|
182
|
+
Пропущено: scripts/**, migrations/**, tests/**
|
|
183
|
+
Файлов проверено: N | Пропущено: N
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
Если все PASS — выведи: `✅ Архитектурные принципы соблюдены.`
|
|
187
|
+
|
|
188
|
+
## Сохранение результатов
|
|
189
|
+
|
|
190
|
+
1. Найди папку сессии:
|
|
191
|
+
```bash
|
|
192
|
+
ls -dt ./docs/audits/[0-9]*/ 2>/dev/null | head -1 | sed 's|/$||'
|
|
193
|
+
```
|
|
194
|
+
Если пусто — создай: `mkdir -p ./docs/audits/$(date +"%Y-%m-%d_%H-%M")`
|
|
195
|
+
2. Сохрани через Write: `<AUDIT_DIR>/audit-architecture.md`
|
|
196
|
+
|
|
197
|
+
```
|
|
198
|
+
# Audit Report: Architecture & File Structure — <YYYY-MM-DD HH:MM>
|
|
199
|
+
<таблица>
|
|
200
|
+
```
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: audit-bugs
|
|
3
|
+
description: >
|
|
4
|
+
Аудит прямых багов и логических ошибок: неверные условия, off-by-one, null dereference,
|
|
5
|
+
забытый await, unreachable code, type coercion, мутация аргументов. Запускай при /audit-bugs.
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Правило применимости (Relevance Rule)
|
|
9
|
+
|
|
10
|
+
Применим к любому коду с бизнес-логикой. Пропускай только автогенерированные файлы (миграции, protobuf-generated, build output) и чисто декларативные конфиги (JSON, YAML без логики).
|
|
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» по префиксу `BUG-`.
|
|
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
|
+
| BUG-01 | Преобразования типов безопасны: ошибки парсинга обрабатываются, нет небезопасного приведения |
|
|
61
|
+
| BUG-02 | Асинхронные/конкурентные вызовы ожидаются корректно, результат не теряется |
|
|
62
|
+
| BUG-03 | Null-safety соблюдается — обращения к свойствам защищены от undefined/null |
|
|
63
|
+
| BUG-04 | Функции не мутируют входные аргументы (sort, splice, object spread) |
|
|
64
|
+
| BUG-05 | Exhaustive handling — все enum/union-ветки обработаны |
|
|
65
|
+
| BUG-06 | Математические guard-условия (деление на ноль, граничные значения) |
|
|
66
|
+
| BUG-07 | Off-by-one: границы диапазонов корректны (`<` vs `<=`, индексы массивов, slice) |
|
|
67
|
+
| BUG-08 | Float comparison не использует `===` для проверки равенства (используется epsilon или toFixed) |
|
|
68
|
+
| BUG-09 | Дата/время хранятся и обрабатываются в UTC, не локальном времени |
|
|
69
|
+
| BUG-10 | RegExp с user input не содержит катастрофического backtracking (ReDoS) |
|
|
70
|
+
|
|
71
|
+
## Правила верификации
|
|
72
|
+
|
|
73
|
+
1. **Только чеклист**: оценивай ТОЛЬКО проверки выше. Не добавляй новые.
|
|
74
|
+
2. **Явная верификация = PASS**: ставь `✅ PASS` только если явно проверил механизм (нашёл схему, конфиг, guard) и подтвердил отсутствие нарушения — укажи что именно проверено.
|
|
75
|
+
3. **Нет доказательства = UNVERIFIED**: не можешь указать `файл:строка` ни для нарушения, ни для подтверждения — ставь `🔍 UNVERIFIED`.
|
|
76
|
+
4. **Baseline приоритетен**: check_id есть в `docs/audit-baseline.yml` → `⏸ ACCEPTED`.
|
|
77
|
+
5. **Только 🔴/🟠 FAIL требуют решения**: 🟡/🟢 — решение необязательно.
|
|
78
|
+
|
|
79
|
+
## Evidence Quality Rules
|
|
80
|
+
|
|
81
|
+
Любой `❌ FAIL` обязан содержать:
|
|
82
|
+
- Точный `file:line`
|
|
83
|
+
- Минимальный код-фрагмент (1–3 строки)
|
|
84
|
+
- Causal chain: почему именно это нарушение → какой риск возникает
|
|
85
|
+
|
|
86
|
+
Запрещено:
|
|
87
|
+
- Предполагать runtime behavior без evidence в коде
|
|
88
|
+
- Предполагать prod-конфигурацию по dev-конфигу
|
|
89
|
+
- Предполагать отсутствие middleware без проверки всей router chain
|
|
90
|
+
- Если вывод основан на предположении — только `🔍 UNVERIFIED`
|
|
91
|
+
|
|
92
|
+
## Language Rule
|
|
93
|
+
|
|
94
|
+
Результаты аудита должны быть написаны простым и понятным языком. Избегай сложных терминов, жаргона и абстрактных понятий без необходимости. Общепринятые технические термины (Docker, HTTP, API, JSON, URL) допустимы. Описывай проблемы так, чтобы они были понятны разработчику любого уровня, а не только узкому специалисту в данной области.
|
|
95
|
+
|
|
96
|
+
## Baseline
|
|
97
|
+
|
|
98
|
+
До анализа:
|
|
99
|
+
```bash
|
|
100
|
+
if [ ! -f ./docs/audit-baseline.yml ]; then
|
|
101
|
+
mkdir -p ./docs
|
|
102
|
+
cp ./skills/audit/audit-baseline-template.yml ./docs/audit-baseline.yml 2>/dev/null || \
|
|
103
|
+
printf "accepted: []\n" > ./docs/audit-baseline.yml
|
|
104
|
+
fi
|
|
105
|
+
cat ./docs/audit-baseline.yml
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Контекст анализа
|
|
109
|
+
|
|
110
|
+
> Примеры ниже — иллюстративные (Node/TS). Конкретику текущего рантайма бери из
|
|
111
|
+
> загруженного профиля (`stacks/<runtime>.md`, секции Idioms/Anti-patterns/Check-ID hints).
|
|
112
|
+
|
|
113
|
+
**BUG-01 — Преобразования типов безопасны:**
|
|
114
|
+
- Парсинг строки в число без обработки ошибки/результата
|
|
115
|
+
- Небезопасное приведение типа без проверки успешности
|
|
116
|
+
- Неявное приведение типов с неожиданным результатом
|
|
117
|
+
- Сравнение значений разных типов с неявным coercion
|
|
118
|
+
- В Go это проигнорированная ошибка `strconv` (`v, _ := strconv.Atoi(...)`) или type assertion `x.(T)` без comma-ok; radix/`==`-coercion — **N/A** при отсутствии парсинга строк (см. Check-ID hints профиля).
|
|
119
|
+
|
|
120
|
+
**BUG-02 — Асинхронные/конкурентные вызовы ожидаются корректно:**
|
|
121
|
+
- Асинхронный вызов запущен, но его результат/ошибка не дожидается
|
|
122
|
+
- Условие на необёрнутом отложенном результате (всегда truthy)
|
|
123
|
+
- Параллельный вызов теряется, потому что не синхронизирован
|
|
124
|
+
- В Node: `await` внутри `forEach` (итерация не ждёт промисов), `if (asyncFn())` вместо `if (await asyncFn())`, async-вызов без `await`, `Promise` без обработки ошибки. В Go синтаксис forEach отсутствует (**N/A**), аналогичный риск — в CON-01.
|
|
125
|
+
|
|
126
|
+
**BUG-03 — Null-safety соблюдается:**
|
|
127
|
+
- Обращение к свойству без проверки на null/undefined
|
|
128
|
+
- Опциональная цепочка пропущена (`obj.a.b` там где `obj.a` может быть undefined)
|
|
129
|
+
- Деструктуризация без дефолтного значения при возможном undefined
|
|
130
|
+
- В Go: разыменование nil-указателя/интерфейса; обращение к nil-map; запись в nil-map = паника; map-доступ без `v, ok := m[k]`
|
|
131
|
+
|
|
132
|
+
**BUG-04 — Функции не мутируют входные аргументы:**
|
|
133
|
+
- `Array.sort()` на переданном массиве без предварительного `.slice()`
|
|
134
|
+
- `Array.splice()` изменяет оригинальный массив-аргумент
|
|
135
|
+
- Прямое присваивание свойств объекта-аргумента вместо создания копии через spread
|
|
136
|
+
- В Go: `sort.Slice` мутирует переданный слайс на месте; запись в slice/map-аргумент видна вызывающему
|
|
137
|
+
|
|
138
|
+
**BUG-05 — Exhaustive handling:**
|
|
139
|
+
- `switch` без `default` на enum-значении — новое значение enum пройдёт незамеченным
|
|
140
|
+
- Union type без обработки всех вариантов в if/else цепочке
|
|
141
|
+
- Отсутствие never-проверки для исчерпывающего TypeScript switch
|
|
142
|
+
- В Go: `switch` по значению без ветки `default`
|
|
143
|
+
|
|
144
|
+
**BUG-06 — Математические guard-условия:**
|
|
145
|
+
- Деление на ноль без guard-проверки знаменателя
|
|
146
|
+
- `Number()` / `parseInt()` без проверки результата на NaN перед использованием
|
|
147
|
+
- Граничные значения не проверяются (отрицательный индекс, пустой массив)
|
|
148
|
+
|
|
149
|
+
**BUG-07 — Off-by-one:**
|
|
150
|
+
- `for (i = 0; i <= arr.length; i++)` — выход за границы массива
|
|
151
|
+
- `slice(0, n)` / `slice(0, n-1)` — потеря или дублирование последнего элемента
|
|
152
|
+
- Сравнение `index < arr.length - 1` там где нужно `index < arr.length`
|
|
153
|
+
- Пагинация: `offset * limit` vs `(offset - 1) * limit` при 1-based страницах
|
|
154
|
+
|
|
155
|
+
**BUG-08 — Float comparison:**
|
|
156
|
+
- `a === b` где a и b — результаты float-арифметики (0.1 + 0.2 !== 0.3)
|
|
157
|
+
- Сравнение денежных сумм через float вместо integer cents / BigDecimal
|
|
158
|
+
- Условие `if (parseFloat(x) === 1.0)` вместо `Math.abs(x - 1.0) < epsilon`
|
|
159
|
+
- В Go: сравнение `float64` через `==`; деньги — в `int64` (центы) или `shopspring/decimal`
|
|
160
|
+
|
|
161
|
+
**BUG-09 — Дата/время в UTC:**
|
|
162
|
+
- `new Date()` без явной UTC-обработки — результат зависит от timezone сервера
|
|
163
|
+
- Сравнение дат через `toLocaleDateString()` — зависит от локали
|
|
164
|
+
- Хранение timestamp как local datetime строки вместо ISO 8601 с `Z`
|
|
165
|
+
- `new Date('2024-01-01')` парсится как UTC, `new Date('2024-01-01 00:00')` — как local
|
|
166
|
+
- В Go: `time.Now()` вместо `time.Now().UTC()` — результат зависит от часового пояса сервера
|
|
167
|
+
|
|
168
|
+
**BUG-10 — ReDoS:**
|
|
169
|
+
- `new RegExp(userInput)` — пользователь контролирует регулярное выражение
|
|
170
|
+
- Вложенные quantifiers на перекрывающихся классах: `(a+)+`, `(a*)*`, `([a-zA-Z]+\s?)+`
|
|
171
|
+
- Проверка: `'a'.repeat(50000) + 'x'` на подозрительном regex вешает event loop
|
|
172
|
+
- Особо опасно в middleware (auth, routing), где regex применяется к каждому запросу
|
|
173
|
+
- В Go движок `regexp` (RE2) не имеет backtracking → ReDoS практически невозможен; помечай `N/A` или `Low` (см. профиль)
|
|
174
|
+
|
|
175
|
+
## Граница с другими аудитами
|
|
176
|
+
|
|
177
|
+
- **Обработка ошибок** (timeout, retry, circuit breaker) → `audit-errors`
|
|
178
|
+
- **Race conditions, транзакции** → `audit-concurrency`
|
|
179
|
+
- **Валидация входных данных** → `audit-validation`
|
|
180
|
+
- **Безопасность (injection, XSS)** → `audit-owasp`
|
|
181
|
+
|
|
182
|
+
## Формат вывода
|
|
183
|
+
|
|
184
|
+
| Check ID | Проверка | Статус | Уверенность | Доказательство | Решение | Исправлено |
|
|
185
|
+
|----------|----------|--------|-------------|----------------|---------|------------|
|
|
186
|
+
| BUG-01 | Преобразования типов безопасны: ошибки парсинга обрабатываются, нет небезопасного приведения | ✅ PASS | High | `src/` — parseInt всегда с radix | — | — |
|
|
187
|
+
| BUG-03 | Null-safety соблюдается — обращения к свойствам защищены от undefined/null | ❌ FAIL 🟠 | High | `services/order.ts:55` | **1. Добавить опциональную цепочку: `user?.address?.city`** \\ 2. Добавить guard-проверку перед обращением \\ 3. Использовать nullish coalescing с дефолтом | Нет |
|
|
188
|
+
| BUG-05 | Exhaustive handling — все enum/union-ветки обработаны | ⏸ ACCEPTED | Medium | `handlers/event.ts:23` | В baseline: exhaustive check через TypeScript never | — |
|
|
189
|
+
|
|
190
|
+
Статусы: `✅ PASS` / `❌ FAIL 🔴` / `❌ FAIL 🟠` / `❌ FAIL 🟡` / `❌ FAIL 🟢` / `⏸ ACCEPTED` / `🔍 UNVERIFIED`
|
|
191
|
+
|
|
192
|
+
Уверенность: `High` — проверил несколько ключевых файлов, паттерн очевиден / `Medium` — проверил выборочно, паттерн вероятен / `Low` — ограниченный контекст, полная уверенность невозможна
|
|
193
|
+
|
|
194
|
+
Для `❌ FAIL`: ровно 3 варианта решения, разделитель `\\`, вариант 1 жирным.
|
|
195
|
+
|
|
196
|
+
`Исправлено`: FAIL → `Нет` (разработчик меняет на `✅ Да` вручную после фикса). PASS / ACCEPTED / UNVERIFIED → `—`.
|
|
197
|
+
|
|
198
|
+
Требования к решениям:
|
|
199
|
+
- Взаимно исключающие (не перефразировки одного и того же)
|
|
200
|
+
- Соответствуют текущему стеку проекта (не предлагать смену фреймворка)
|
|
201
|
+
- Не требуют переписать всю систему — realistic migration cost
|
|
202
|
+
- Вариант 3 может быть «оставить, задокументировать причину» при наличии обоснования
|
|
203
|
+
|
|
204
|
+
В конце отчёта добавь раздел покрытия:
|
|
205
|
+
```
|
|
206
|
+
## Audit Coverage
|
|
207
|
+
Проверено: src/module1/**, src/module2/**
|
|
208
|
+
Пропущено: scripts/**, migrations/**, tests/**
|
|
209
|
+
Файлов проверено: N | Пропущено: N
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
Если все PASS — выведи: `✅ Явных логических ошибок не обнаружено.`
|
|
213
|
+
|
|
214
|
+
## Сохранение результатов
|
|
215
|
+
|
|
216
|
+
1. Найди папку сессии:
|
|
217
|
+
```bash
|
|
218
|
+
ls -dt ./docs/audits/[0-9]*/ 2>/dev/null | head -1 | sed 's|/$||'
|
|
219
|
+
```
|
|
220
|
+
Если пусто — создай: `mkdir -p ./docs/audits/$(date +"%Y-%m-%d_%H-%M")`
|
|
221
|
+
2. Сохрани через Write: `<AUDIT_DIR>/audit-bugs.md`
|
|
222
|
+
|
|
223
|
+
```
|
|
224
|
+
# Audit Report: Bugs & Logic Errors — <YYYY-MM-DD HH:MM>
|
|
225
|
+
<таблица>
|
|
226
|
+
```
|