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,188 @@
|
|
|
1
|
+
# audit-baseline.yml
|
|
2
|
+
# Принятые/отложенные риски. Совпадение по check_id → статус ⏸ ACCEPTED в отчёте.
|
|
3
|
+
# Скопируй в корень проекта: docs/audit-baseline.yml
|
|
4
|
+
#
|
|
5
|
+
# check_id стек-нейтральны: один и тот же идентификатор применяется к любому
|
|
6
|
+
# рантайму (Node/TS, Go, Python, Rust, Java). Конкретика стека берётся из
|
|
7
|
+
# профилей skills/audit/stacks/<runtime>.md и не влияет на матчинг по check_id.
|
|
8
|
+
|
|
9
|
+
accepted:
|
|
10
|
+
# Пример:
|
|
11
|
+
# - check_id: OWA-06
|
|
12
|
+
# file: src/app.ts # Опционально: ограничить конкретным файлом
|
|
13
|
+
# reason: "Rate limiting на nginx уровне"
|
|
14
|
+
# type: accepted-risk # accepted-risk | false-positive | intentional-design
|
|
15
|
+
# accepted_by: username
|
|
16
|
+
# accepted_date: 2026-01-01
|
|
17
|
+
# expires: 2026-12-31 # Опционально: когда пересмотреть
|
|
18
|
+
|
|
19
|
+
# ─────────────────────────────────────────
|
|
20
|
+
# Ложные срабатывания (инструмент ошибся, нарушения нет)
|
|
21
|
+
false_positives:
|
|
22
|
+
# - check_id: ARC-03
|
|
23
|
+
# reason: "import cycle from prisma-generated client, not real cycle"
|
|
24
|
+
# type: false-positive
|
|
25
|
+
|
|
26
|
+
# Намеренные архитектурные решения (не баги, обоснованный выбор)
|
|
27
|
+
intentional:
|
|
28
|
+
# - check_id: NAM-06
|
|
29
|
+
# reason: "utils.ts contains 3 tightly related helpers, intentional"
|
|
30
|
+
# type: intentional-design
|
|
31
|
+
|
|
32
|
+
# ─────────────────────────────────────────
|
|
33
|
+
# ПОЛНЫЙ СПИСОК check_id
|
|
34
|
+
# ─────────────────────────────────────────
|
|
35
|
+
#
|
|
36
|
+
# audit-secrets:
|
|
37
|
+
# SEC-01 Нет hardcoded credentials в коде (пароли, токены, API-ключи, приватные ключи)
|
|
38
|
+
# SEC-02 Файлы с секретами исключены из VCS (.env* в .gitignore)
|
|
39
|
+
# SEC-03 Секреты не передаются через URL (query params, Basic Auth в URL)
|
|
40
|
+
# SEC-04 .env.example содержит только placeholder-значения без реальных данных
|
|
41
|
+
# SEC-05 Dockerfile не содержит секретов в ENV-директивах
|
|
42
|
+
# SEC-06 Комментарии в коде не содержат credentials
|
|
43
|
+
# SEC-07 Автоматическое сканирование секретов настроено (pre-commit или CI)
|
|
44
|
+
#
|
|
45
|
+
# audit-owasp:
|
|
46
|
+
# OWA-01 A03: Все запросы к БД/OS/LDAP параметризованы, нет injection
|
|
47
|
+
# OWA-02 A01: Все защищённые маршруты имеют auth-middleware
|
|
48
|
+
# OWA-03 A01: Resource ownership проверяется, нет IDOR
|
|
49
|
+
# OWA-04 A02: Пароли хранятся безопасно (bcrypt/argon2/scrypt)
|
|
50
|
+
# OWA-05 A05: Безопасная конфигурация сервера (CORS, security headers, body limits)
|
|
51
|
+
# OWA-06 A07: Защита от перебора (rate limiting на auth и чувствительных эндпоинтах)
|
|
52
|
+
# OWA-07 A09: Техническая информация не утекает в ответы (stack trace, внутренние пути)
|
|
53
|
+
# OWA-08 A10: URL из user input не передаётся в HTTP-клиент без whitelist (SSRF)
|
|
54
|
+
# OWA-09 A05: CSRF-защита реализована (SameSite cookies или CSRF-токены на state-changing запросах)
|
|
55
|
+
#
|
|
56
|
+
# audit-validation:
|
|
57
|
+
# VAL-01 Все входящие данные (body, params, query) проходят schema-валидацию
|
|
58
|
+
# VAL-02 Строки имеют maxLength, числа — диапазон, enum-значения — whitelist
|
|
59
|
+
# VAL-03 JSON.parse обёрнут в try/catch с последующей валидацией структуры
|
|
60
|
+
# VAL-04 Identity данные берутся из аутентифицированного контекста (не из user input)
|
|
61
|
+
# VAL-05 Вложенные структуры и массивы ограничены (глубина, minItems/maxItems)
|
|
62
|
+
# VAL-06 Валидатор не выполняет неявный coercion
|
|
63
|
+
# VAL-07 Prototype pollution: merge/assign с user input фильтрует __proto__, constructor, prototype
|
|
64
|
+
# VAL-08 Загрузка файлов: MIME тип проверяется по содержимому, имя файла санитизировано, размер ограничен
|
|
65
|
+
#
|
|
66
|
+
# audit-errors:
|
|
67
|
+
# ERR-01 Ошибки не проглатываются — catch-блоки обрабатывают или пробрасывают
|
|
68
|
+
# ERR-02 Внутренние детали (stack trace, пути, версии) не попадают в ответы
|
|
69
|
+
# ERR-03 Async handlers корректно пробрасывают исключения в error middleware
|
|
70
|
+
# ERR-04 Unhandled rejections и uncaught exceptions имеют process-level обработчики
|
|
71
|
+
# ERR-05 Внешние вызовы (HTTP-клиенты, DB) имеют явные таймауты
|
|
72
|
+
# ERR-06 Graceful shutdown реализован — SIGTERM обрабатывается
|
|
73
|
+
# ERR-07 Error responses консистентны по структуре во всём приложении
|
|
74
|
+
# ERR-08 Retry-стратегии используют exponential backoff с jitter
|
|
75
|
+
# ERR-09 AbortSignal/CancellationToken пробрасывается во внешние вызовы
|
|
76
|
+
#
|
|
77
|
+
# audit-logging:
|
|
78
|
+
# LOG-01 Production-код не использует console.log/console.error напрямую
|
|
79
|
+
# LOG-02 PII не логируется (email, телефон, имена, адреса, финансовые данные)
|
|
80
|
+
# LOG-03 Секреты и токены не попадают в логи
|
|
81
|
+
# LOG-04 Запросы трассируются (Request ID или correlation ID сквозной)
|
|
82
|
+
# LOG-05 Формат логов структурирован (JSON) в production
|
|
83
|
+
# LOG-06 Критические операции логируются (auth, create, update, delete)
|
|
84
|
+
# LOG-07 User input санитизируется перед логированием (защита от log injection)
|
|
85
|
+
# LOG-08 Критические события безопасности логируются: вход, выход, изменение прав, массовая выгрузка данных
|
|
86
|
+
#
|
|
87
|
+
# audit-performance:
|
|
88
|
+
# PER-01 Нет N+1: DB-запросы не выполняются внутри циклов
|
|
89
|
+
# PER-02 Выборки из БД ограничены (LIMIT, пагинация)
|
|
90
|
+
# PER-03 Обработчики запросов не содержат блокирующего I/O
|
|
91
|
+
# PER-04 CPU-интенсивные операции вынесены из main thread
|
|
92
|
+
# PER-05 Независимые async-операции выполняются параллельно
|
|
93
|
+
# PER-06 Кэши ограничены по размеру и времени жизни (TTL + size limit)
|
|
94
|
+
# PER-07 Event listeners и subscriptions очищаются при завершении
|
|
95
|
+
# PER-08 Нет утечек памяти: timers и closures не удерживают большие объекты в долгоживущем scope
|
|
96
|
+
#
|
|
97
|
+
# audit-architecture:
|
|
98
|
+
# ARC-01 Бизнес-логика вынесена из route handlers в service/domain слой
|
|
99
|
+
# ARC-02 Presentation layer не взаимодействует с БД напрямую
|
|
100
|
+
# ARC-03 Нет circular dependencies между модулями
|
|
101
|
+
# ARC-04 Нет god-объектов: файлы и классы имеют единственную ответственность
|
|
102
|
+
# ARC-05 Конфигурация и env-переменные изолированы в config-модуле
|
|
103
|
+
# ARC-06 Внешние зависимости инжектируются (DI), не импортируются напрямую
|
|
104
|
+
# ARC-07 Доменный слой не импортирует инфраструктурные модули
|
|
105
|
+
#
|
|
106
|
+
# audit-concurrency:
|
|
107
|
+
# CON-01 async/await не используется в неасинхронных итераторах (forEach, map)
|
|
108
|
+
# CON-02 Read-modify-write операции выполняются в транзакциях
|
|
109
|
+
# CON-03 Нет shared mutable state на уровне модуля (синглтоны, кэши без locks)
|
|
110
|
+
# CON-04 Module-level кэш имеет механизм инвалидации
|
|
111
|
+
# CON-05 Обработчики событий и webhook-handlers идемпотентны
|
|
112
|
+
# CON-06 Background async операции имеют механизм отмены (AbortController/signal) и не блокируют graceful shutdown
|
|
113
|
+
#
|
|
114
|
+
# audit-naming:
|
|
115
|
+
# NAM-01 Соглашение об именовании соблюдается консистентно (camelCase/snake_case)
|
|
116
|
+
# NAM-02 Имена переменных, функций и классов описывают назначение, не реализацию
|
|
117
|
+
# NAM-03 Boolean-переменные имеют предикативные имена (is/has/can/should)
|
|
118
|
+
# NAM-04 Функции-читатели (get*/find*) не имеют side effects
|
|
119
|
+
# NAM-05 Magic numbers и magic strings заменены именованными константами
|
|
120
|
+
# NAM-06 Утилитные модули не являются свалкой несвязанного кода
|
|
121
|
+
# NAM-07 Ключевые сущности названы в соответствии с доменным глоссарием
|
|
122
|
+
#
|
|
123
|
+
# audit-yagni:
|
|
124
|
+
# YAGNI-01 Нет закомментированного кода
|
|
125
|
+
# YAGNI-02 Нет dead code — неиспользуемых экспортов, функций, переменных
|
|
126
|
+
# YAGNI-03 Абстракции оправданы: интерфейс/фабрика имеет >1 реализации или требуется тестами
|
|
127
|
+
# YAGNI-04 Feature flags не зафиксированы в одном значении
|
|
128
|
+
# YAGNI-05 Технический долг актуален — нет заброшенных TODO/FIXME без даты или прогресса
|
|
129
|
+
#
|
|
130
|
+
# audit-reinvention:
|
|
131
|
+
# REINV-01 Нет ручной реализации того, что есть в stdlib/языке/рантайме
|
|
132
|
+
# REINV-02 Нет ручной реализации того, что уже умеет установленная зависимость
|
|
133
|
+
# REINV-03 Нет смыслового дублирования логики (одинаковый код в ≥2 местах вместо общей утилиты)
|
|
134
|
+
# REINV-04 Крупные механизмы (ORM, DI, scheduler, logger, job queue) не написаны с нуля при наличии зрелого решения
|
|
135
|
+
#
|
|
136
|
+
# audit-docs:
|
|
137
|
+
# DOC-01 README/онбординг документирует install/run/test/build, команды совпадают с package.json scripts
|
|
138
|
+
# DOC-02 Env-переменные синхронизированы: используемые в коде задокументированы, нет задокументированных но неиспользуемых
|
|
139
|
+
# DOC-03 Внутренние ссылки и пути в Markdown-документации ведут на существующие файлы и секции
|
|
140
|
+
# DOC-04 Комментарии и JSDoc/docstring не противоречат коду (сигнатура, параметры, типы, поведение)
|
|
141
|
+
# DOC-05 Публичная поверхность (экспортируемое API библиотеки/пакета) имеет doc-комментарий
|
|
142
|
+
# DOC-06 Проектная/архитектурная документация не ссылается на удалённые/переименованные сущности
|
|
143
|
+
#
|
|
144
|
+
# audit-bugs:
|
|
145
|
+
# BUG-01 Преобразования типов безопасны (NaN, radix, coercion)
|
|
146
|
+
# BUG-02 async/await используется корректно (нет await в forEach, нет if(asyncFn()))
|
|
147
|
+
# BUG-03 Null-safety соблюдается — обращения к свойствам защищены от undefined/null
|
|
148
|
+
# BUG-04 Функции не мутируют входные аргументы (sort, splice, object spread)
|
|
149
|
+
# BUG-05 Exhaustive handling — все enum/union-ветки обработаны
|
|
150
|
+
# BUG-06 Математические guard-условия (деление на ноль, граничные значения)
|
|
151
|
+
# BUG-07 Off-by-one: границы диапазонов корректны (< vs <=, индексы массивов, slice)
|
|
152
|
+
# BUG-08 Float comparison не использует === для проверки равенства
|
|
153
|
+
# BUG-09 Дата/время хранятся и обрабатываются в UTC, не локальном времени
|
|
154
|
+
# BUG-10 RegExp с user input не содержит катастрофического backtracking (ReDoS)
|
|
155
|
+
#
|
|
156
|
+
# audit-tests:
|
|
157
|
+
# TST-01 TypeScript strict mode включён
|
|
158
|
+
# TST-02 Coverage thresholds настроены и применяются в CI
|
|
159
|
+
# TST-03 Pre-commit/pre-push хуки запускают проверки (tests, lint, typecheck)
|
|
160
|
+
# TST-04 Критические пути покрыты тестами (auth, validation, error handling)
|
|
161
|
+
# TST-05 Тесты изолированы — нет shared mutable state между тестами
|
|
162
|
+
# TST-06 Нет пропущенных или зафиксированных тестов (.only/.skip без обоснования)
|
|
163
|
+
# TST-07 Тесты проверяют поведение, а не детали реализации
|
|
164
|
+
# TST-08 Нет нестабильных тестов (Math.random, Date.now без mock, sleep)
|
|
165
|
+
# TST-09 Snapshot-тесты охватывают значимые изменения, не весь DOM
|
|
166
|
+
#
|
|
167
|
+
# audit-deployment:
|
|
168
|
+
# DEP-01 Docker images используют pinned versions (нет :latest)
|
|
169
|
+
# DEP-02 Контейнеры запускаются от непривилегированного пользователя (USER nonroot)
|
|
170
|
+
# DEP-03 Multi-stage build разделяет dev и prod зависимости
|
|
171
|
+
# DEP-04 .dockerignore исключает node_modules, .git, .env
|
|
172
|
+
# DEP-05 HEALTHCHECK определён в Dockerfile
|
|
173
|
+
# DEP-06 Секреты не hardcoded в Dockerfile (нет в ENV)
|
|
174
|
+
# DEP-07 .env исключён из VCS
|
|
175
|
+
# DEP-08 .env.example документирует все переменные окружения
|
|
176
|
+
# DEP-09 NODE_ENV корректно устанавливается для production
|
|
177
|
+
# DEP-10 npm ci используется вместо npm install в Docker
|
|
178
|
+
# DEP-11 Ограничения ресурсов контейнера определены (CPU limits, Memory limits)
|
|
179
|
+
# DEP-12 Возможность запуска с read-only root filesystem проверена
|
|
180
|
+
#
|
|
181
|
+
# audit-api-contracts:
|
|
182
|
+
# API-01 Форма ответов консистентна — единый envelope или его отсутствие по всему API
|
|
183
|
+
# API-02 HTTP статус-коды семантически корректны (201 при создании, 4xx для client errors)
|
|
184
|
+
# API-03 Error responses машиночитаемы и консистентны по структуре
|
|
185
|
+
# API-04 Именование полей консистентно (camelCase или snake_case, не смешано)
|
|
186
|
+
# API-05 Stack trace и внутренние детали не попадают в error responses
|
|
187
|
+
# API-06 Пагинация включает метаданные (total/hasNext) где применима
|
|
188
|
+
# API-07 Публичный API имеет стратегию версионирования
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# Runtime Detection & Stack Profile (общий канон)
|
|
2
|
+
|
|
3
|
+
Этот файл — единый источник правды для того, как аудит-скилл определяет рантайм
|
|
4
|
+
проекта и подгружает соответствующий **профиль стека** из `./skills/audit/stacks/`.
|
|
5
|
+
|
|
6
|
+
Каждый кодовый аудит-скилл содержит инлайн-копию блока ниже (раздел
|
|
7
|
+
«Runtime Detection & Stack Profile»). Инлайн-копия обязательна — она гарантирует,
|
|
8
|
+
что скилл работает автономно (`/audit-<name>`), даже если оркестратор `/audit`
|
|
9
|
+
не запускался. Этот файл — справочник и место для синхронной правки канона.
|
|
10
|
+
|
|
11
|
+
## Принцип
|
|
12
|
+
|
|
13
|
+
Один запуск аудита = **ровно один рантайм**. Скилл:
|
|
14
|
+
1. принимает рантайм, инъектированный оркестратором, ЕСЛИ он передан; иначе
|
|
15
|
+
2. определяет ровно один рантайм текущего каталога; затем
|
|
16
|
+
3. читает профиль и использует его инструменты/идиомы/анти-паттерны.
|
|
17
|
+
|
|
18
|
+
Полиглот-репозитории (например Go-бэкенд + Node-фронтенд в одном дереве)
|
|
19
|
+
аудитятся по подпроектам: запусти аудит отдельно внутри каждого подкаталога.
|
|
20
|
+
|
|
21
|
+
## Канонический блок (вставляется в каждый кодовый скилл)
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
## Runtime Detection & Stack Profile
|
|
25
|
+
|
|
26
|
+
Этот аудит стек-агностичен: проверки сформулированы нейтрально, а конкретика
|
|
27
|
+
(инструменты, идиомы, анти-паттерны, примеры) берётся из профиля стека.
|
|
28
|
+
|
|
29
|
+
1. **Профиль передан контекстом?** Если оркестратор `/audit` передал
|
|
30
|
+
`runtime=<id>` и/или содержимое профиля — используй его, шаги 2–3 пропусти.
|
|
31
|
+
|
|
32
|
+
2. **Иначе определи РОВНО ОДИН рантайм** этого каталога:
|
|
33
|
+
```bash
|
|
34
|
+
if [ -f package.json ]; then echo "runtime=node"
|
|
35
|
+
elif [ -f go.mod ]; then echo "runtime=go"
|
|
36
|
+
elif [ -f pyproject.toml ] || [ -f requirements.txt ] || [ -f setup.py ]; then echo "runtime=python"
|
|
37
|
+
elif [ -f Cargo.toml ]; then echo "runtime=rust"
|
|
38
|
+
elif [ -f pom.xml ] || ls build.gradle* settings.gradle* >/dev/null 2>&1; then echo "runtime=java"
|
|
39
|
+
else echo "runtime=generic"; fi
|
|
40
|
+
```
|
|
41
|
+
Один запуск = один рантайм; не миксуй backend и frontend. Если найдено
|
|
42
|
+
несколько маркеров (монорепо) — выбери соответствующий текущему scope/анализируемым
|
|
43
|
+
файлам и зафиксируй выбор в разделе Audit Coverage.
|
|
44
|
+
|
|
45
|
+
3. **Загрузи профиль** через Read: `./skills/audit/stacks/<runtime>.md`
|
|
46
|
+
(fallback `./skills/audit/stacks/_generic.md`, если файл не найден).
|
|
47
|
+
|
|
48
|
+
Дальше используй профиль:
|
|
49
|
+
- **Инструменты** — из секции «Tooling by category» профиля (раздел
|
|
50
|
+
«Инструментальная поддержка» ниже ссылается на категории, а не на команды).
|
|
51
|
+
- **Ожидания PASS** — из «Idioms»; **формулировки FAIL** — из «Anti-patterns».
|
|
52
|
+
- **Точечные подсказки** — из «Check-ID hints» по префиксу этого аудита.
|
|
53
|
+
- Если профиль `tier: general` или `runtime=generic` → стек-специфичные находки
|
|
54
|
+
без однозначного evidence помечай `🔍 UNVERIFIED`, а не `❌ FAIL`. Проверки,
|
|
55
|
+
чей механизм в рантайме отсутствует, помечай `N/A`.
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Инъекция из оркестратора
|
|
59
|
+
|
|
60
|
+
Мастер-скилл `audit/SKILL.md` определяет рантайм один раз (Шаг 0), читает профиль
|
|
61
|
+
один раз и передаёт `runtime=<id>` + содержимое профиля каждому `Skill()` тем же
|
|
62
|
+
каналом, что и baseline. Саб-скиллы видят это в шаге 1 и пропускают собственный
|
|
63
|
+
детект. Автономность при этом не теряется: инлайн-блок отрабатывает сам, если
|
|
64
|
+
инъекции нет.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Stack Profile: Generic (fallback) (id: generic)
|
|
2
|
+
Tier: fallback
|
|
3
|
+
|
|
4
|
+
Используется, когда рантайм не определён (нет известного маркер-файла) или нужный
|
|
5
|
+
профиль не найден. Инструментов нет; работают только **стек-нейтральные** проверки.
|
|
6
|
+
|
|
7
|
+
## 1. Detection signals
|
|
8
|
+
- ничего из известных маркеров (`package.json`, `go.mod`, `pyproject.toml`/`requirements.txt`, `Cargo.toml`, `pom.xml`/`build.gradle`)
|
|
9
|
+
|
|
10
|
+
## 2. Tooling by category
|
|
11
|
+
| Категория | Команда | Как читать вывод |
|
|
12
|
+
|-----------|---------|------------------|
|
|
13
|
+
| unused-code | — | нет инструмента → ручной скан ссылок на символы → `🔍 UNVERIFIED` |
|
|
14
|
+
| clone-detection | — | grep повторяющихся блоков вручную → `🔍 UNVERIFIED` |
|
|
15
|
+
| dep-audit | — | нет → пометить «аудит зависимостей недоступен» |
|
|
16
|
+
| env-extraction | `grep -rEoh '[A-Z][A-Z0-9_]{2,}' . 2>/dev/null \| sort -u` (грубо) | кандидаты в env-переменные, верифицируй вручную |
|
|
17
|
+
| arch-lint | — | ручной разбор слоёв → `🔍 UNVERIFIED` |
|
|
18
|
+
| lint/format | — | — |
|
|
19
|
+
| type-check | — | — |
|
|
20
|
+
| test-run | — | — |
|
|
21
|
+
| secret-scan | `gitleaks detect --no-banner 2>/dev/null \|\| trufflehog filesystem . 2>/dev/null \|\| true` | стек-нейтрально, работает всегда |
|
|
22
|
+
|
|
23
|
+
## 3. Idioms
|
|
24
|
+
Стек-нейтральные ожидания (применимы к любому языку):
|
|
25
|
+
- Ошибки обрабатываются или явно пробрасываются, не подавляются молча.
|
|
26
|
+
- Внешние вызовы имеют таймауты и механизм отмены.
|
|
27
|
+
- Секреты не захардкожены; конфигурация изолирована.
|
|
28
|
+
- Логи структурированы, без PII и секретов.
|
|
29
|
+
- Имена описывают назначение; нет дублирования логики.
|
|
30
|
+
- Документация (README, ссылки, env) синхронизирована с кодом.
|
|
31
|
+
|
|
32
|
+
## 4. Anti-patterns
|
|
33
|
+
- Подавление ошибок без обработки.
|
|
34
|
+
- Захардкоженные секреты, разбросанная конфигурация.
|
|
35
|
+
- Дублирование логики, мёртвый код.
|
|
36
|
+
|
|
37
|
+
## 5. Check-ID hints
|
|
38
|
+
Для всех стек-специфичных Check ID без однозначного evidence ставь `🔍 UNVERIFIED`.
|
|
39
|
+
Реальные `✅ PASS`/`❌ FAIL` допустимы только для стек-нейтральных направлений:
|
|
40
|
+
secrets (SEC-*), docs (DOC-*), naming-читаемость (NAM-02/03/05), bugs-логика
|
|
41
|
+
(BUG-06/07/09), api-contracts (API-*) при наличии явного evidence.
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Stack Profiles — реестр
|
|
2
|
+
|
|
3
|
+
Таблица соответствия «маркер-файл → id профиля». Используется блоком
|
|
4
|
+
Runtime Detection (см. `../runtime-detect.md`). Порядок проверки — сверху вниз,
|
|
5
|
+
выбирается первый совпавший рантайм (один запуск = один рантайм).
|
|
6
|
+
|
|
7
|
+
| Приоритет | Маркер-файл(ы) | runtime id | Профиль | Tier |
|
|
8
|
+
|-----------|----------------|------------|---------|------|
|
|
9
|
+
| 1 | `package.json` | `node` | `node.md` | first-class |
|
|
10
|
+
| 2 | `go.mod` | `go` | `go.md` | first-class |
|
|
11
|
+
| 3 | `pyproject.toml` / `requirements.txt` / `setup.py` | `python` | `python.md` | general |
|
|
12
|
+
| 4 | `Cargo.toml` | `rust` | `rust.md` | general |
|
|
13
|
+
| 5 | `pom.xml` / `build.gradle*` / `settings.gradle*` | `java` | `java.md` | general |
|
|
14
|
+
| — | ничего из перечисленного | `generic` | `_generic.md` | fallback |
|
|
15
|
+
|
|
16
|
+
## Tier — что означает
|
|
17
|
+
|
|
18
|
+
- **first-class** — профиль содержит конкретные инструменты и идиомы; находки
|
|
19
|
+
могут быть `❌ FAIL` с точным evidence.
|
|
20
|
+
- **general** — профиль даёт нейтральные формулировки и общие идиомы, но без
|
|
21
|
+
гарантированных инструментов; стек-специфичные находки без однозначного
|
|
22
|
+
evidence помечай `🔍 UNVERIFIED`.
|
|
23
|
+
- **fallback** (`generic`) — инструментов нет; работают только стек-нейтральные
|
|
24
|
+
проверки (docs-ссылки, secrets, naming-читаемость), остальное → `🔍 UNVERIFIED`.
|
|
25
|
+
|
|
26
|
+
## Категории инструментов (общие для всех профилей)
|
|
27
|
+
|
|
28
|
+
Секция «Tooling by category» в каждом профиле использует один и тот же набор
|
|
29
|
+
ключей, чтобы скиллы ссылались на категорию, а не на команду:
|
|
30
|
+
|
|
31
|
+
`unused-code`, `clone-detection`, `dep-audit`, `env-extraction`, `arch-lint`,
|
|
32
|
+
`lint/format`, `type-check`, `test-run`, `secret-scan`.
|
|
33
|
+
|
|
34
|
+
## Структура профиля
|
|
35
|
+
|
|
36
|
+
Каждый `stacks/<id>.md` имеет одинаковые секции:
|
|
37
|
+
1. **Detection signals** — маркер-файлы.
|
|
38
|
+
2. **Tooling by category** — таблица по категориям выше.
|
|
39
|
+
3. **Idioms** — как выглядит «правильно» (ожидания PASS).
|
|
40
|
+
4. **Anti-patterns** — как выглядит FAIL (1 строка кода на пункт).
|
|
41
|
+
5. **Check-ID hints** — точечные подсказки по префиксу Check ID.
|
|
42
|
+
|
|
43
|
+
## Добавление нового стека
|
|
44
|
+
|
|
45
|
+
1. Создай `stacks/<id>.md` по структуре выше.
|
|
46
|
+
2. Добавь строку в таблицу реестра.
|
|
47
|
+
3. Добавь ветку в bash-детект в `../runtime-detect.md` и в инлайн-блоках скиллов.
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# Stack Profile: Go (id: go)
|
|
2
|
+
Tier: first-class
|
|
3
|
+
|
|
4
|
+
Профиль рантайма Go. Конкретные библиотеки (chi, gqlgen, sqlc, pgx, asynq, slog,
|
|
5
|
+
go-oidc) упоминаются лишь как примеры идиом, а не как требования.
|
|
6
|
+
|
|
7
|
+
## 1. Detection signals
|
|
8
|
+
- `go.mod` (основной маркер)
|
|
9
|
+
- доп.: `go.sum`, `Taskfile.yml`/`Makefile`, `.golangci.yml`, `.go-arch-lint.yml`
|
|
10
|
+
|
|
11
|
+
## 2. Tooling by category
|
|
12
|
+
| Категория | Команда | Как читать вывод |
|
|
13
|
+
|-----------|---------|------------------|
|
|
14
|
+
| unused-code | `deadcode ./... 2>/dev/null \|\| true` (golang.org/x/tools/cmd/deadcode) | недостижимые функции → YAGNI-02; верифицируй перед FAIL |
|
|
15
|
+
| clone-detection | `dupl -threshold 50 ./... 2>/dev/null \|\| true` | дубли токенов → REINV-03 |
|
|
16
|
+
| dep-audit | `govulncheck ./... 2>/dev/null \|\| true` | CVE в модулях (вне чеклиста — справочно) |
|
|
17
|
+
| env-extraction | `grep -rEoh 'os\.Getenv\("[A-Z0-9_]+"\)' . 2>/dev/null \| sed -E 's/.*"(.*)".*/\1/' \| sort -u` | имена env из кода → DOC-02 (учти теги `env:"..."` для caarlos0/env) |
|
|
18
|
+
| arch-lint | `go vet ./... 2>/dev/null`; слои: `go-arch-lint check 2>/dev/null \|\| true` | циклы импортов запрещены компилятором → ARC-03 на уровне пакетов авто-PASS |
|
|
19
|
+
| lint/format | `golangci-lint run 2>/dev/null \|\| true`; `gofmt -l . 2>/dev/null` | включает `errcheck`, `gosec`, `nilness`, `staticcheck` |
|
|
20
|
+
| type-check | `go build ./... 2>/dev/null \|\| true` | компиляция = проверка типов |
|
|
21
|
+
| test-run | `go test ./... 2>/dev/null \|\| true`; гонки: `go test -race ./...` | `-race` обнаруживает data race → CON-03 |
|
|
22
|
+
| secret-scan | `gitleaks detect --no-banner 2>/dev/null \|\| trufflehog filesystem . 2>/dev/null \|\| true` | стек-нейтрально |
|
|
23
|
+
|
|
24
|
+
Всегда верифицируй вывод инструмента вручную (`file:line`) перед `❌ FAIL`.
|
|
25
|
+
|
|
26
|
+
## 3. Idioms (как выглядит «правильно» → PASS)
|
|
27
|
+
- **Error handling:** явная проверка `if err != nil`; оборачивание `fmt.Errorf("...: %w", err)`; sentinel-ошибки + `errors.Is`/`errors.As`. Возвращаемая ошибка не игнорируется.
|
|
28
|
+
- **Concurrency:** отмена через `context.Context` (не сигналы); shared state под `sync.Mutex`/каналами; fan-out через `errgroup`/`sync.WaitGroup`; каждая goroutine имеет путь завершения по `ctx.Done()`.
|
|
29
|
+
- **Graceful shutdown:** `signal.NotifyContext(ctx, syscall.SIGTERM, os.Interrupt)`; `server.Shutdown(ctx)`; закрытие пулов (pgx), воркеров (asynq), redis.
|
|
30
|
+
- **Panic safety:** `defer recover()` в HTTP-хендлерах (chi `middleware.Recoverer`), в gqlgen (`RecoverFunc`), в каждой фоновой goroutine и в обёртке job (asynq).
|
|
31
|
+
- **Env/config:** централизованная config-структура (например caarlos0/env), загружается при старте; нет `os.Getenv` вразброс.
|
|
32
|
+
- **Logging:** структурный `log/slog` (JSON в prod) с request/correlation ID через `context`; нет `fmt.Print*`/`log.Print*` в request-путях.
|
|
33
|
+
- **Null-safety:** проверка nil-указателей/интерфейсов перед разыменованием; запись в nil-map не допускается; map-доступ через `v, ok := m[k]`.
|
|
34
|
+
- **Type coercion:** `strconv.Atoi`/`ParseInt` с проверкой ошибки; type assertion через `v, ok := x.(T)` (comma-ok).
|
|
35
|
+
- **Deps / reinvention:** stdlib `slices`/`maps`/`sync`; `database/sql`/sqlc вместо самописного query builder.
|
|
36
|
+
- **Build/deploy:** multi-stage (builder → distroless/`nonroot`); `go.mod`+`go.sum` закоммичены; `GOFLAGS=-mod=readonly`; `CGO_ENABLED=0` для статической линковки; нет `go get` в Dockerfile; нет `net/http/pprof`/debug-роутов в prod.
|
|
37
|
+
|
|
38
|
+
## 4. Anti-patterns (как выглядит FAIL)
|
|
39
|
+
- **Errors:** игнор ошибки через `_ = f()` или `v, _ := f()`; `panic` для обычного потока управления; потеря wrap-цепочки.
|
|
40
|
+
- **Concurrency:** goroutine без `WaitGroup`/`errgroup`/`ctx` (результат теряется / процесс не ждёт / leak); запись в map из >1 goroutine без lock (data race, ловит `go test -race`); `for ... { go f(loopVar) }` — захват переменной цикла (до Go 1.22); незакрытый канал блокирует получателей.
|
|
41
|
+
- **Panic:** паника в goroutine без `recover()` роняет весь процесс.
|
|
42
|
+
- **Logging:** `fmt.Print*`/`log.Print*`/`println` в production-путях вместо `slog`.
|
|
43
|
+
- **Resources:** `defer` внутри цикла (ресурс держится до конца функции, не итерации).
|
|
44
|
+
- **Build/deploy:** `go get` в Dockerfile; отсутствие `go.sum`; компилятор/тесты в финальном образе.
|
|
45
|
+
|
|
46
|
+
## 5. Check-ID hints
|
|
47
|
+
- `LOG-01` → `fmt.Print*`, `log.Print*`, `println` вне обёртки `slog`.
|
|
48
|
+
- `BUG-01` → **N/A**, если нет парсинга строк; иначе — type assertion `x.(T)` без comma-ok, проигнорированная ошибка `strconv`.
|
|
49
|
+
- `BUG-02` → **N/A** (нет синтаксиса промисов/forEach); риск переезжает в `CON-01`.
|
|
50
|
+
- `BUG-03` → nil-deref указателя/интерфейса/map; запись в nil-map (паника).
|
|
51
|
+
- `BUG-08` → сравнение float через `==`; деньги — в `int64` (центы) или `shopspring/decimal`.
|
|
52
|
+
- `BUG-10` → **N/A или Low**: `regexp` (RE2) не имеет backtracking, ReDoS практически невозможен.
|
|
53
|
+
- `CON-01` → goroutine без механизма завершения (WaitGroup/errgroup/ctx) → goroutine leak.
|
|
54
|
+
- `CON-03` → конкурентный доступ к map/переменной пакета без `sync.Mutex`/atomic (data race).
|
|
55
|
+
- `CON-06` → фоновая goroutine не слушает `ctx.Done()` → не завершается при shutdown.
|
|
56
|
+
- `ERR-01` → ошибка проигнорирована через `_`.
|
|
57
|
+
- `ERR-03` → нет recover-middleware (паника в хендлере роняет соединение/процесс).
|
|
58
|
+
- `ERR-04` → нет `defer recover()` в фоновых goroutine/asynq-handler.
|
|
59
|
+
- `ERR-06` → нет `signal.NotifyContext`/`server.Shutdown` (graceful shutdown).
|
|
60
|
+
- `ERR-09` → `context.Context` не пробрасывается во внешние вызовы (pgx/HTTP/asynq).
|
|
61
|
+
- `PER-08` → `defer` в цикле/долгой функции держит ресурсы (rows/файлы/locks).
|
|
62
|
+
- `ARC-03` → **N/A на уровне пакетов** (циклы импортов запрещены компилятором); проверять только логические слои через go-arch-lint.
|
|
63
|
+
- `ARC-05` → `os.Getenv` разбросан вместо config-структуры.
|
|
64
|
+
- `DEP-09` → нет переключения в production-режим (debug-роуты/pprof/verbose в prod-образе).
|
|
65
|
+
- `DEP-10` → `go get` в сборке вместо `go mod download` по закоммиченному `go.sum`; нет `-mod=readonly`.
|
|
66
|
+
- `TST-01` → `go vet`/`staticcheck`/`golangci-lint` не включены/не обязательны.
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Stack Profile: Java / JVM (id: java)
|
|
2
|
+
Tier: general
|
|
3
|
+
|
|
4
|
+
Профиль уровня general: нейтральные идиомы + ориентиры по инструментам без
|
|
5
|
+
гарантий их наличия. Стек-специфичные находки без однозначного evidence
|
|
6
|
+
помечай `🔍 UNVERIFIED`.
|
|
7
|
+
|
|
8
|
+
## 1. Detection signals
|
|
9
|
+
- `pom.xml` (Maven) / `build.gradle*` / `settings.gradle*` (Gradle)
|
|
10
|
+
|
|
11
|
+
## 2. Tooling by category
|
|
12
|
+
| Категория | Команда | Как читать вывод |
|
|
13
|
+
|-----------|---------|------------------|
|
|
14
|
+
| unused-code | SpotBugs / IDE-инспекции | неиспользуемое → YAGNI-02 (часто `🔍 UNVERIFIED` без инструмента) |
|
|
15
|
+
| clone-detection | `pmd cpd --minimum-tokens 50 --dir . 2>/dev/null \|\| true` | дубли → REINV-03 |
|
|
16
|
+
| dep-audit | `mvn org.owasp:dependency-check-maven:check 2>/dev/null \|\| true` | CVE в зависимостях |
|
|
17
|
+
| env-extraction | `grep -rEoh 'System\.getenv\("[A-Z0-9_]+"\)' . 2>/dev/null \| sort -u` | env из кода → DOC-02 (учти `@Value`/`application.yml`) |
|
|
18
|
+
| arch-lint | ArchUnit-тесты | слои/зависимости |
|
|
19
|
+
| lint/format | `mvn checkstyle:check 2>/dev/null \|\| true`; SpotBugs | — |
|
|
20
|
+
| type-check | `mvn compile 2>/dev/null \|\| ./gradlew compileJava 2>/dev/null \|\| true` | компиляция |
|
|
21
|
+
| test-run | `mvn test 2>/dev/null \|\| ./gradlew test 2>/dev/null \|\| true` | — |
|
|
22
|
+
| secret-scan | `gitleaks detect --no-banner 2>/dev/null \|\| true` | стек-нейтрально |
|
|
23
|
+
|
|
24
|
+
## 3. Idioms
|
|
25
|
+
- **Errors:** конкретные исключения; try-with-resources для ресурсов; нет пустых `catch`.
|
|
26
|
+
- **Concurrency:** `ExecutorService`/`CompletableFuture`; отмена через `Future.cancel`/interruption; иммутабельность или `synchronized`/`java.util.concurrent`.
|
|
27
|
+
- **Env/config:** Spring `@Value`/`application.yml` или `System.getenv`, централизованно.
|
|
28
|
+
- **Logging:** SLF4J/Logback со структурой; нет `System.out.println` в production.
|
|
29
|
+
- **Null-safety:** `Optional<T>`; аннотации `@Nullable`/`@NonNull`; проверки null.
|
|
30
|
+
- **Lifecycle:** `@Transactional` для read-modify-write; graceful shutdown через lifecycle-хуки.
|
|
31
|
+
- **Deps:** проверенные библиотеки экосистемы вместо самописного.
|
|
32
|
+
|
|
33
|
+
## 4. Anti-patterns
|
|
34
|
+
- Пустой `catch (Exception e) {}`.
|
|
35
|
+
- `System.out.println`/`printStackTrace` в production.
|
|
36
|
+
- Shared mutable state без синхронизации.
|
|
37
|
+
- Разбросанный `System.getenv` без централизации.
|
|
38
|
+
|
|
39
|
+
## 5. Check-ID hints
|
|
40
|
+
- `LOG-01` → `System.out.println`/`printStackTrace` вместо SLF4J.
|
|
41
|
+
- `ERR-01` → пустой `catch`.
|
|
42
|
+
- `CON-02` → read-modify-write без `@Transactional`.
|
|
43
|
+
- `ARC-05` → `System.getenv` вразброс.
|
|
44
|
+
- Прочие стек-специфичные → при нехватке evidence `🔍 UNVERIFIED`.
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Stack Profile: Node / TypeScript (id: node)
|
|
2
|
+
Tier: first-class
|
|
3
|
+
|
|
4
|
+
Покрывает и бэкенд (Node), и фронтенд (браузер/Vite). Это профиль рантайма, а не
|
|
5
|
+
фреймворка — конкретные фреймворки (Express/Fastify/NestJS, React/Vite) упоминаются
|
|
6
|
+
лишь как примеры идиом.
|
|
7
|
+
|
|
8
|
+
## 1. Detection signals
|
|
9
|
+
- `package.json` (основной маркер)
|
|
10
|
+
- доп.: `tsconfig.json`, `package-lock.json` / `pnpm-lock.yaml` / `yarn.lock`
|
|
11
|
+
|
|
12
|
+
## 2. Tooling by category
|
|
13
|
+
| Категория | Команда | Как читать вывод |
|
|
14
|
+
|-----------|---------|------------------|
|
|
15
|
+
| unused-code | `npx knip --reporter json 2>/dev/null \| head -200 \|\| true` | неиспользуемые экспорты/зависимости/файлы → YAGNI-02, NAM-06 |
|
|
16
|
+
| clone-detection | `npx jscpd --min-lines 8 --min-tokens 50 --reporters json --silent --output ./.jscpd ./src 2>/dev/null \|\| true` | дубли блоков → REINV-03 |
|
|
17
|
+
| dep-audit | `npm audit --json 2>/dev/null \| head -100 \|\| pnpm audit --json 2>/dev/null \|\| true` | CVE в зависимостях (вне чеклиста — справочно) |
|
|
18
|
+
| env-extraction | `grep -rEoh 'process\.env\.[A-Z0-9_]+\|import\.meta\.env\.[A-Z0-9_]+' ./src 2>/dev/null \| sed -E 's/.*env\.//' \| sort -u` | имена env-переменных из кода → DOC-02 |
|
|
19
|
+
| arch-lint | `npx dependency-cruiser --validate 2>/dev/null \|\| true`; FSD: `npx steiger ./src 2>/dev/null \|\| true` | circular deps → ARC-03; нарушения слоёв FSD |
|
|
20
|
+
| lint/format | `npx biome check 2>/dev/null \|\| npx eslint . 2>/dev/null \|\| true` | — |
|
|
21
|
+
| type-check | `npx tsc --noEmit 2>/dev/null \|\| true` | — |
|
|
22
|
+
| test-run | `npm test 2>/dev/null \|\| true` | — |
|
|
23
|
+
| secret-scan | `gitleaks detect --no-banner 2>/dev/null \|\| trufflehog filesystem . 2>/dev/null \|\| true` | стек-нейтрально |
|
|
24
|
+
|
|
25
|
+
Всегда верифицируй вывод инструмента вручную (`file:line`) перед `❌ FAIL`.
|
|
26
|
+
|
|
27
|
+
## 3. Idioms (как выглядит «правильно» → PASS)
|
|
28
|
+
- **Error handling:** `try/catch` вокруг `await`; типизированные ошибки; промисы либо `await`-ятся, либо явно `.catch`. Express 5 / `asyncHandler` пробрасывает rejection в error-middleware.
|
|
29
|
+
- **Concurrency:** `Promise.all`/`allSettled` для независимых задач; `AbortController`/`AbortSignal` для отмены и таймаутов; `process.on('SIGTERM')` для graceful shutdown.
|
|
30
|
+
- **Env/config:** `process.env` (бэкенд) / `import.meta.env` (Vite-фронтенд), валидируется при старте (zod/envalid) и изолируется в config-модуле.
|
|
31
|
+
- **Logging:** структурный логгер (pino/winston) с request/correlation ID; в production нет `console.*`.
|
|
32
|
+
- **Null-safety:** optional chaining `?.`, nullish coalescing `??`; строгие проверки `undefined`/`null`.
|
|
33
|
+
- **Type coercion:** `parseInt(x, 10)` с radix; строгое `===`; явные `Number()`/`String()`.
|
|
34
|
+
- **DI / абстракции:** зависимости инжектируются (конструктор/параметры), не создаются внутри функций; интерфейс оправдан >1 реализацией или тестами.
|
|
35
|
+
- **Deps / reinvention:** предпочитать stdlib (`structuredClone`, `crypto.randomUUID`, `[...new Set()]`, `Array.flat`) и уже установленные библиотеки самописным аналогам.
|
|
36
|
+
- **Build/deploy:** multi-stage Dockerfile; `npm ci` по `package-lock.json`; `NODE_ENV=production`; `USER node`/nonroot; `.dockerignore` исключает `node_modules`/`.git`/`.env`.
|
|
37
|
+
|
|
38
|
+
## 4. Anti-patterns (как выглядит FAIL)
|
|
39
|
+
- **Errors:** пустой `catch (e) {}`; промис без `await`/`.catch`; `if (asyncFn())` (всегда truthy).
|
|
40
|
+
- **Concurrency:** `async` callback в `Array.forEach`/`map` (потерянные промисы); `await` в последовательном цикле для независимых задач; module-level mutable singleton без инвалидации.
|
|
41
|
+
- **Logging:** `console.log`/`console.error` в production-коде; `[object Object]` в логах.
|
|
42
|
+
- **Type coercion:** `parseInt(x)` без radix; `==` вместо `===`; сравнение float через `===`.
|
|
43
|
+
- **Build/deploy:** `npm install` вместо `npm ci`; нет `NODE_ENV=production`; `node_modules` в build-контексте Docker.
|
|
44
|
+
|
|
45
|
+
## 5. Check-ID hints
|
|
46
|
+
- `LOG-01` → `console.log`/`console.error`/`console.*` в production.
|
|
47
|
+
- `BUG-01` → `parseInt` без radix, `NaN`-проверки, `==`-coercion.
|
|
48
|
+
- `BUG-02` / `CON-01` → `async` в `forEach`/`map`, потерянные промисы.
|
|
49
|
+
- `BUG-10` → катастрофический backtracking в `RegExp` на user input (ReDoS реален).
|
|
50
|
+
- `DEP-04` → `node_modules`/`.git`/`.env` в build-контексте.
|
|
51
|
+
- `DEP-09` → `NODE_ENV` не выставлен в `production`.
|
|
52
|
+
- `DEP-10` → `npm install` вместо `npm ci`; нет `package-lock.json`.
|
|
53
|
+
- `ERR-04` → нет `process.on('unhandledRejection')`/`uncaughtException`.
|
|
54
|
+
- `ERR-06` → нет `process.on('SIGTERM')` для graceful shutdown.
|
|
55
|
+
- `ERR-09` → `AbortSignal` не пробрасывается во внешние вызовы.
|
|
56
|
+
- `ARC-05` → `process.env.X` разбросан вместо config-модуля.
|
|
57
|
+
- `TST-01` → `tsconfig.json` без `strict: true`.
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Stack Profile: Python (id: python)
|
|
2
|
+
Tier: general
|
|
3
|
+
|
|
4
|
+
Профиль уровня general: даёт нейтральные идиомы и ориентиры по инструментам, но
|
|
5
|
+
без гарантий их наличия. Стек-специфичные находки без однозначного evidence
|
|
6
|
+
помечай `🔍 UNVERIFIED`.
|
|
7
|
+
|
|
8
|
+
## 1. Detection signals
|
|
9
|
+
- `pyproject.toml` / `requirements.txt` / `setup.py`
|
|
10
|
+
- доп.: `Pipfile`, `poetry.lock`, `tox.ini`
|
|
11
|
+
|
|
12
|
+
## 2. Tooling by category
|
|
13
|
+
| Категория | Команда | Как читать вывод |
|
|
14
|
+
|-----------|---------|------------------|
|
|
15
|
+
| unused-code | `vulture . 2>/dev/null \|\| true` | мёртвый код → YAGNI-02 |
|
|
16
|
+
| clone-detection | `pylint --disable=all --enable=duplicate-code . 2>/dev/null \|\| true` | дубли → REINV-03 |
|
|
17
|
+
| dep-audit | `pip-audit 2>/dev/null \|\| safety check 2>/dev/null \|\| true` | CVE в зависимостях |
|
|
18
|
+
| env-extraction | `grep -rEoh 'os\.environ(\.get)?\(?\["'\'']?[A-Z0-9_]+' . 2>/dev/null \| sort -u` | env из кода → DOC-02 |
|
|
19
|
+
| arch-lint | `import-linter 2>/dev/null \|\| true` | слои/циклы |
|
|
20
|
+
| lint/format | `ruff check . 2>/dev/null \|\| flake8 2>/dev/null \|\| true` | — |
|
|
21
|
+
| type-check | `mypy . 2>/dev/null \|\| pyright 2>/dev/null \|\| true` | — |
|
|
22
|
+
| test-run | `pytest 2>/dev/null \|\| true` | — |
|
|
23
|
+
| secret-scan | `gitleaks detect --no-banner 2>/dev/null \|\| true` | стек-нейтрально |
|
|
24
|
+
|
|
25
|
+
## 3. Idioms
|
|
26
|
+
- **Errors:** конкретные исключения, не голый `except:`; `finally`/context managers (`with`) для ресурсов.
|
|
27
|
+
- **Concurrency:** `asyncio` с `async/await`; отмена через `asyncio.CancelledError`/`asyncio.timeout`; `concurrent.futures` для CPU.
|
|
28
|
+
- **Env/config:** `os.environ`/pydantic-settings, валидация при старте; изоляция в config-модуле.
|
|
29
|
+
- **Logging:** модуль `logging` со структурой; нет `print()` в production.
|
|
30
|
+
- **Null-safety:** явные проверки `is None`; `Optional[...]`.
|
|
31
|
+
- **Type coercion:** явные `int()`/`str()` с обработкой `ValueError`.
|
|
32
|
+
- **Deps:** stdlib (`itertools`, `functools`, `collections`, `datetime`, `secrets`); `pydantic` для валидации.
|
|
33
|
+
|
|
34
|
+
## 4. Anti-patterns
|
|
35
|
+
- Голый `except:` / `except Exception: pass`.
|
|
36
|
+
- `print()` для логирования в production.
|
|
37
|
+
- Изменяемые аргументы по умолчанию (`def f(x=[])`).
|
|
38
|
+
- Разбросанный `os.environ[...]` без централизации.
|
|
39
|
+
|
|
40
|
+
## 5. Check-ID hints
|
|
41
|
+
- `LOG-01` → `print()` вместо `logging`.
|
|
42
|
+
- `ERR-01` → `except: pass` (проглатывание).
|
|
43
|
+
- `BUG-04` → mutable default argument.
|
|
44
|
+
- `ARC-05` → `os.environ` вразброс.
|
|
45
|
+
- Прочие стек-специфичные → при нехватке evidence `🔍 UNVERIFIED`.
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Stack Profile: Rust (id: rust)
|
|
2
|
+
Tier: general
|
|
3
|
+
|
|
4
|
+
Профиль уровня general: нейтральные идиомы + ориентиры по инструментам без
|
|
5
|
+
гарантий их наличия. Стек-специфичные находки без однозначного evidence
|
|
6
|
+
помечай `🔍 UNVERIFIED`.
|
|
7
|
+
|
|
8
|
+
## 1. Detection signals
|
|
9
|
+
- `Cargo.toml`
|
|
10
|
+
- доп.: `Cargo.lock`, `rust-toolchain.toml`
|
|
11
|
+
|
|
12
|
+
## 2. Tooling by category
|
|
13
|
+
| Категория | Команда | Как читать вывод |
|
|
14
|
+
|-----------|---------|------------------|
|
|
15
|
+
| unused-code | `cargo +nightly udeps 2>/dev/null \|\| true`; warnings `cargo build` | неиспользуемое → YAGNI-02 |
|
|
16
|
+
| clone-detection | — (нет стандартного инструмента) | grep повторов → `🔍 UNVERIFIED` |
|
|
17
|
+
| dep-audit | `cargo audit 2>/dev/null \|\| true` | CVE в crates |
|
|
18
|
+
| env-extraction | `grep -rEoh '(std::)?env::var\(?"[A-Z0-9_]+"' . 2>/dev/null \| sort -u` | env из кода → DOC-02 |
|
|
19
|
+
| arch-lint | — | ручной разбор слоёв → `🔍 UNVERIFIED` |
|
|
20
|
+
| lint/format | `cargo clippy 2>/dev/null \|\| true`; `cargo fmt --check 2>/dev/null` | — |
|
|
21
|
+
| type-check | `cargo check 2>/dev/null \|\| true` | компиляция = проверка типов |
|
|
22
|
+
| test-run | `cargo test 2>/dev/null \|\| true` | — |
|
|
23
|
+
| secret-scan | `gitleaks detect --no-banner 2>/dev/null \|\| true` | стек-нейтрально |
|
|
24
|
+
|
|
25
|
+
## 3. Idioms
|
|
26
|
+
- **Errors:** `Result<T, E>` + `?`; `thiserror`/`anyhow`; нет `.unwrap()`/`.expect()` в production-путях.
|
|
27
|
+
- **Concurrency:** `tokio`/`async`; отмена через drop/`CancellationToken`; shared state через `Arc<Mutex<...>>`/каналы.
|
|
28
|
+
- **Env/config:** `std::env::var` с обработкой `Result`; централизованный config (`serde`/`config`).
|
|
29
|
+
- **Logging:** `tracing`/`log` со структурой; нет `println!` в production.
|
|
30
|
+
- **Null-safety:** `Option<T>` + сопоставление с образцом; компилятор гарантирует отсутствие null.
|
|
31
|
+
- **Deps:** crates экосистемы (`serde`, `itertools`, `tokio`); stdlib-итераторы.
|
|
32
|
+
|
|
33
|
+
## 4. Anti-patterns
|
|
34
|
+
- `.unwrap()`/`.expect()` на пути, где ошибка возможна.
|
|
35
|
+
- `println!`/`eprintln!` для логирования в production.
|
|
36
|
+
- `unsafe` без обоснования.
|
|
37
|
+
- Игнор `Result` (`let _ = ...`) там, где ошибку нужно обработать.
|
|
38
|
+
|
|
39
|
+
## 5. Check-ID hints
|
|
40
|
+
- `LOG-01` → `println!`/`eprintln!` вместо `tracing`/`log`.
|
|
41
|
+
- `ERR-01` → `.unwrap()`/`.expect()`/проигнорированный `Result`.
|
|
42
|
+
- `BUG-03` → в основном **N/A** (нет null; `Option` проверяется компилятором).
|
|
43
|
+
- `BUG-10` → ReDoS обычно **N/A** (crate `regex` без catastrophic backtracking).
|
|
44
|
+
- Прочие стек-специфичные → при нехватке evidence `🔍 UNVERIFIED`.
|