git:20261014.68e5a91 to git:20261016.295b5a0

7 added, 4 removed. Audit A to A.

---
name: dd-code-review
- description: Ревью локальных изменений, открытого PR/MR или diff ветки на баги, проблемы безопасности и нарушения гайдлайнов проекта — через набор ревью-линз инлайн (маленький diff) или параллельными агентами (большой diff). Стиль и то, что ловит линтер, — вне скоупа. Read-only: правки и комментарии в PR/MR только по явному одобрению пользователя.
+ description: Ревью локальных изменений, открытого PR/MR или diff ветки на баги, проблемы безопасности и нарушения гайдлайнов проекта и актуальных спецификаций (docs/specs/) — через набор ревью-линз инлайн (маленький diff) или параллельными агентами (большой diff). Стиль и то, что ловит линтер, — вне скоупа. Read-only: правки и комментарии в PR/MR только по явному одобрению пользователя.
trigger_phrases:
- "code review"
- "код ревью"
- "ревью изменений"
- "ревью PR"
- "проверь diff"
- "проверь изменения"
- "review PR"
- "dd code review"
related_skills:
- dd-discovery
- dd-delivery
- git-commit
---
# dd-code-review
- Анализ локальных git-изменений (или PR/MR) на соответствие гайдлайнам проекта через ревью-линзы из [Шага 4](#шаг-4-ревью-по-линзам) — инлайн на маленьком diff, параллельными агентами на большом. Вне скоупа: стиль, субъективные предпочтения и всё, что уже ловит линтер.
+ Анализ локальных git-изменений (или PR/MR) на соответствие гайдлайнам проекта и актуальным спецификациям через ревью-линзы из [Шага 4](#шаг-4-ревью-по-линзам) — инлайн на маленьком diff, параллельными агентами на большом. Вне скоупа: стиль, субъективные предпочтения и всё, что уже ловит линтер.
+ Скилл — часть пакета DD-SDD: опирается на те же источники, что и треки. `docs/specs/` здесь первичный источник — тот, что читает `dd-discovery` перед постановкой задачи и обновляет `dd-delivery` по факту реализации: в спеках зафиксированы актуальное поведение системы и проектные нюансы логики и конвенций. Изменение, отходящее от спеки без её обновления, — находка ревью.
+
Адаптировано из [optimus-claude/skills/code-review](https://github.com/oprogramadorreal/optimus-claude/tree/master/skills/code-review). Промпты агентов и общие ограничения — в `references/` рядом с этим файлом.
Аргументы: `[--pr N | --branch | путь]` — всё остальное трактуется как естественно-языковой скоуп/фокус (пути, номера PR, рефы: «ревью src/auth», «ревью PR #42», «изменения против main»).
## Шаг 1: Разбор аргументов и пререквизиты
- `--branch` → принудительно diff ветки в Шаге 2, без авто-маршрутизации на PR. Не действует, если есть локальные изменения или PR запрошен явно (`--pr N`, `#N`, URL PR).
- **Multi-repo / вне git**: если `git rev-parse --is-inside-work-tree` не вернул `true`, проверь, не workspace ли это с несколькими репозиториями (например, мета-репозиторий с подпроектами в подкаталогах). Тогда git-команды Шага 2 выполняются внутри каждого дочернего репо, а для PR/MR-режима пользователь обязан назвать репозиторий. Корень репо — `git rev-parse --show-toplevel` (работает и в worktree, и в подкаталоге).
- - **Пререквизиты**: если в проекте нет `AGENTS.md`/`CLAUDE.md` или гайдлайнов (`docs/coding-guidelines.md`, `docs/specs/`), предложи сначала сформировать их. Если пользователь решает продолжить — ревьюй против общих best practices для обнаруженного стека и отметь в отчёте, что находки общие, а не проектно-специфичные.
+ - **Пререквизиты**: если в проекте нет `AGENTS.md`/`CLAUDE.md`, гайдлайнов (`docs/coding-guidelines.md`) или спецификаций (`docs/specs/`), предложи сначала сформировать их — в DD-SDD спеки заводятся треками `dd-discovery`/`dd-delivery`. Если пользователь решает продолжить — ревьюй против общих best practices для обнаруженного стека и отметь в отчёте, что находки общие, а не проектно-специфичные.
## Шаг 2: Определение скоупа ревью
**Локальные изменения (по умолчанию)**: собери staged + unstaged + untracked через `git diff --cached`, `git diff` и `git status --short`. Если есть — ревьюим их.
**Локальных изменений нет → авто-маршрутизация** (без вопросов пользователю):
1. Определи платформу по `git remote get-url origin`: содержит `github.com` → GitHub (`gh`); `gitlab` → GitLab (`glab`). Неизвестно — попробуй оба CLI, бери первый подтверждённый открытый PR/MR.
2. Проверь открытый PR/MR текущей ветки: GitHub — `gh pr view --json number,state,baseRefName` (учитывать только `state` = `"OPEN"`); GitLab — `glab mr view --output json` (только `state` = `"opened"`; падение команды = нет MR, если только это не похоже на ошибку авторизации/сети — тогда скажи пользователю до фолбэка).
3. База = target-ветка PR/MR; если PR/MR или CLI нет — определи default-ветку: `git symbolic-ref --quiet refs/remotes/origin/HEAD` (обрезать `refs/remotes/origin/`), фолбэк — `git rev-parse --verify origin/main`, затем `origin/master`. Не удалось — спроси у пользователя базовый реф, **никогда не угадывай**; если рефа нет — ревьюить нечего.
4. Выполни `git log --oneline origin/<base>..HEAD`; если коммиты есть, маршрутизируй:
- `--branch` → diff ветки.
- Открытый PR/MR найден И HEAD полностью запушен (`git rev-list origin/<current-branch>..HEAD` пуст) → PR-режим без переспрашивания. Одной строкой: *«Ревьюю PR #N — описание PR использую как контекст намерения автора. Передай `--branch`, чтобы ревьюить diff ветки.»*
- PR/MR найден, НО HEAD не запушен полностью или статус пуша не определить → diff ветки. Одной строкой: *«Ревьюю diff ветки — PR #N существует, но HEAD запушен не полностью. Передай `--pr N`, чтобы ревьюить только запушенное состояние PR.»*
- PR/MR нет (или CLI недоступен) → diff ветки.
**Совсем ничего нет** → сообщи, что ревьюить нечего; предложи застейджить изменения или указать PR.
### PR-режим
Вход по явному запросу или авто-маршрутом.
| | GitHub | GitLab |
|---|---|---|
| Метаданные | `gh pr view <N> --json state,isDraft,title,body,baseRefName,headRefName,headRefOid` | `glab mr view <N> --output json` |
| Поля `pr-description` | `title` + `body` | `title` + `description` |
| Diff | `gh pr diff <N>` | `glab mr diff <N>` |
| Head SHA | `headRefOid` | `sha` |
| Checkout | `gh pr checkout <N>` | `glab mr checkout <N>` |
- Сначала проверь CLI (`gh --version` / `glab --version`); недоступен → скажи, что для PR/MR-режима он нужен, и предложи diff ветки.
- Сохрани title + body как `pr-description` для Шагов 4–5 (контекст намерения автора).
- PR/MR закрыт или влит → предупреди и остановись.
- **Расхождение head**: если head SHA отличается от `git rev-parse HEAD`, предложи checkout до продолжения — агенты Шага 4 и валидация Шага 5 читают локальное дерево, и при расхождении молча ревьюится не тот контент. При отказе — продолжай с предупреждением, что валидация идёт по локальному дереву, а не по head PR.
**Режим ветки/рефа**: diff — `git diff <ref>...HEAD`; список файлов — `git diff --name-only <ref>...HEAD`.
**Фильтр по пути**: при скоупе на путь фильтруй diff (`git diff -- <path>`, `git diff --cached -- <path>`).
### Сводка скоупа
Перед продолжением покажи короткую `## Review Scope`: режим (локальные изменения / PR #N / diff ветки с `<ref>`), файлов изменено, строк +/-. В PR/MR-режиме, если `pr-description` пусто или в нём нет заполненной секции `## Intent` (Problem / Scope / Non-goals / Key decisions), добавь одну заметку, какой из случаев: проверки intent-vs-implementation пропускаются. Мягкое предупреждение — ревью продолжается в любом случае.
**Предупреждение о большом diff**: больше 50 файлов или 3000 строк — предупреди и предложи сузить скоуп (путь, каталог).
## Шаг 3: Загрузка контекста проекта
Загрузи документы-ограничения проекта — они определяют критерии ревью:
+ - `docs/specs/*` — актуальные спецификации: зафиксированное поведение системы и проектные нюансы логики и конвенций. Первичный источник для проверки: изменение, противоречащее спеке, — находка, если только спека не обновляется в том же diff (это нормальный выход `dd-delivery`);
- `AGENTS.md` / `CLAUDE.md` (карта кодбазы, правила);
- - `docs/coding-guidelines.md`, `docs/architecture.md`, `docs/testing.md`, `docs/specs/*` — что есть;
+ - `docs/coding-guidelines.md`, `docs/architecture.md`, `docs/testing.md` — что есть;
- в монорепо/workspace — для каждого затронутого подпроекта свои документы, применяются к файлам только этого подпроекта;
- исключи vendored/submodule-каталоги (`vendor/`, `node_modules/`, сабмодули) — их код не ревьюим.
Каждая находка по гайдлайнам должна обосновываться тем, что установлено этими документами; внешние предпочтения не навязывать.
Покажи короткую сводку контекста (какие доки загружены, каких нет и какой фолбэк, тип проекта) и сразу переходи к Шагу 4 — без ожидания подтверждения.
## Шаг 4: Ревью по линзам
Таблица ниже — линзы, которые ревью обязано покрыть. В скольких контекстах их покрывать — решаешь по размеру diff.
**На маленьком diff — примерно до 3 файлов и 150 изменённых строк — применяй линзы сам за один проход.** Пять сабагентов над пятистрочным изменением перечитают одни и те же доки и diff, чтобы выдать то, до чего ты дойдёшь напрямую; прочитай файлы промптов ради критериев и пройдись по ним. Разветвляйся, когда diff велик настолько, что один контекст не вмещает его вместе с доками, когда линзам нужны genuinely разные части дерева.
При разветвлении запускай всех применимых агентов **одним сообщением** параллельно — разные сообщения сериализуют их без выгоды. Каждый агент покрывает линзу, которой нет у других; выкинуть агента = оставить категорию без ревью. Дождись завершения всех запущенных агентов до Шага 5.
| Агент | Роль | Файл промпта |
|-------|------|--------------|
| 1 — Bug Detector | Null-доступ, off-by-one, гонки, утечки ресурсов, несовпадение типов | `references/bug-detector.md` |
| 2 — Security & Logic | Инъекции, XSS, секреты, отсутствующая авторизация, security-релевантные нарушения API | `references/security-reviewer.md` |
| 3 — Guideline Compliance | Явные нарушения документов проекта, каждое со ссылкой на правило | `references/guideline-reviewer.md` |
| 4 — Architecture & Boundaries | Слоистость и направление зависимостей, ответственность модулей, дрейф структурных паттернов, размещение | `references/architecture-reviewer.md` |
| 5 — Code Simplifier | Лишняя сложность, мёртвый код, упрощения только удалением | `references/code-simplifier.md` |
| 6 — Test Guardian | Пробелы в покрытии тестами, структурные барьеры тестируемости | `references/test-guardian.md` |
| 7 — Contracts Reviewer | Обратная совместимость, типобезопасность, версионирование, инкапсуляция | `references/contracts-reviewer.md` |
Линзы 1–5 применяются всегда, инлайн или агентами. Линза 6 — когда обнаружена тестовая инфраструктура (`docs/testing.md`, каталог `tests/`, конфиг phpunit/jest/vitest/pest). Линза 7 — когда хоть один изменённый файл матчит контракт-паттерн: каталоги `api/`, `routes/`, `controllers/`, `endpoints/`, `handlers/`, `graphql/`, `proto/`, `grpc/`; файлы `*.dto.*`, `*.schema.*`, `*.contract.*`, `openapi.*`, `swagger.*`, `*.proto`, `*.graphql`, `*.gql`. Нет совпадения — пропускай целиком.
**Сборка промпта**: прочитай файл промпта из `references/` + `references/shared-constraints.md` (общая планка качества и формат вывода; он же тянет `references/shared-agent-constraints.md`). Промпт агента = общие ограничения + файл линзы + список изменённых файлов + hunks diff'а. Для агента 3 замени строку `<!-- dispatcher: ... -->` в `guideline-reviewer.md` на конкретные пути документов, разрешённые в Шаге 3.
Заверши каждый собранный промпт списком изменённых файлов (из Шага 2), за которым идут hunks diff'а — как минимум диапазоны изменённых строк по файлам, если diff целиком не влезает. У агентов нет санкционированного способа вычислить diff самим; никогда не отправляй одни только пути файлов.
### Инъекция PR/MR-контекста (только PR/MR-режим)
Если `pr-description` из Шага 2 непустое, добавь в начало каждого промпта агента, прямо перед списком файлов, блок:
```
## PR/MR Context
Title: <title>
Description: <body, обрезать до 2000 символов с пометкой об усечении>
Это заявленное намерение автора. Источник правды — код и git-история:
при противоречии доверяй коду, а не описанию.
```
## Шаг 5: Валидация находок
Прочитай `references/finding-validation.md` и примени к каждой находке. Дополнения code review:
- **Перекрёстная корроборация** — два агента независимо флагают одно место → уверенность растёт, даже если категории разные.
- **Санкционированные pre-existing находки** — проверка Pre-existing не отбрасывает security/bug-находки непосредственно рядом с изменёнными строками и consistency-находки по структурным соседям (`references/shared-constraints.md` разрешает оба); остальные проверки применяются.
### Описание PR/MR как сигнал намерения
Если захвачено `pr-description`, используй его как дополнительный мягкий сигнал: явное объяснение *почему* сделано флагаемое изменение, подтверждённое git-историей → −1 уверенность; противоречит истории или не подтверждено ею → доверяй истории (код важнее заявлений); молчит о находке → без корректировки. Никогда не фильтруй находку жёстко только по описанию.
**Уверенность после валидации**: High и Medium идут в Шаг 6; число отброшенных укажи в сводке отчёта.
## Шаг 6: Консолидация и отчёт
- **Дедупликация**: тот же файл + диапазон строк + категория → оставь более детальную версию. Если два агента дошли независимо — слей в одну с пометкой «подтверждено независимым ревью».
- **Противоречия**: находки на один регион с противоположными рекомендациями («добавь валидацию» vs «упрости валидацию») → оставь более высокую серьёзность; при ничьей — security/correctness-находку (требования безопасности оправдывают соразмерную сложность).
- **Серьёзность**: **Critical** — баги, уязвимости, падения рантайма, Intent Mismatch в противоречии с заявленным non-goal. **Warning** — нарушения гайдлайнов, отсутствующая обработка ошибок, пробелы покрытия на критических путях, обратно-несовместимые изменения контрактов, Intent Mismatch по неподтверждённым scope-заявлениям. **Suggestion** — улучшения качества, мелкий дрейф, Intent Mismatch по частичным совпадениям.
- **Лимит находок**: максимум **15 доменных находок**, по серьёзности, затем по уверенности. `Intent Mismatch` — сверх 15, до 5, дедуплицированные между агентами, после доменных. Если проблем больше — укажи число и предложи более узкий скоуп.
### Формат вывода
```
## Code Review
### Summary
- Scope: [локальные изменения / PR #N / diff ветки с X]
- Files reviewed: [N]
- Lines changed: +[A] / -[R]
- Findings: [N] (Critical: [N], Warning: [N], Suggestion: [N])
- Unconfirmed findings dropped: [N]
- Docs used: [список]
- Agents: [список запущенных]
- Verdict: CHANGES LOOK GOOD / ISSUES FOUND
### Change Summary
[2–4 фактических предложения о том, что делают изменения]
### Findings
**[N]. [Заголовок находки]** (Critical/Warning/Suggestion — [Category])
- **File:** `file:line`
- **Category:** [категория по файлу промпта линзы]
- **Guideline:** [правило проекта, "General: ...", или для Intent Mismatch литерально "Intent (see Intent claim)"]
- **Intent claim:** [только Intent Mismatch — цитата из `## Intent`]
- **Issue:** [конкретное описание]
- **Current:** [сниппет — макс 5 строк]
- **Suggested:** [фикс или рекомендация — макс 5 строк]
[Порядок: Critical → Warning → Suggestion, внутри — по пути файла. Если находок нет: «Изменения соответствуют гайдлайнам проекта. Багов, проблем безопасности и нарушений не обнаружено.»]
```
В PR-режиме добавляй ссылки на код с полным SHA:
- GitHub: `https://github.com/owner/repo/blob/[full-sha]/path#L[start]-L[end]`
- GitLab: URL инстанса из `git remote get-url origin`, затем `https://[gitlab-host]/owner/repo/-/blob/[full-sha]/path#L[start]-L[end]`
## Шаг 7: Предложение действий
Вердикт **CHANGES LOOK GOOD** → пропусти шаг целиком, сразу к финальной рекомендации.
Вердикт **ISSUES FOUND** → спроси (вопрос «Как поступим с находками ревью?»):
- **Исправить** — примени предложенные фиксы напрямую, затем прогони тесты и доложи результат; отмена фикса — только обратными правками, никогда не `git checkout`/`git restore`/`git stash` — они снесут незакоммиченные изменения, которые ревьюились.
- **Комментарий в PR** (только PR/MR-режим) — запости сводку ревью комментарием.
- **Пропустить** — оставить отчёт как справку.
**Постинг комментария**: выполни `mktemp ./review-summary-XXXXXX` — относительный путь, не `/tmp` (на Windows Git Bash монт `/tmp` не разрешается нативными `gh.exe`/`glab.exe`, и комментарий молча уйдёт пустым). Запиши сводку в напечатанный путь и подставь его литерально вместо `<summary-file>` (shell-переменные между вызовами не живут). Всегда `rm -f <summary-file>` после попытки постинга, независимо от результата.
- GitHub: `gh pr comment <N> --body-file <summary-file>`
- GitLab: `glab api -X POST "projects/:id/merge_requests/<N>/notes" -F body=@<summary-file>` — избегает поломки на shell-метасимволах, которая ждёт `glab mr note --message "$(cat ...)"` со сниппетами кода в сводке
## Важно
Скилл read-only: никогда не изменяй файлы, не коммить, не пушь и не пости комментарии без явного одобрения пользователя; одобренные фиксы остаются локальными изменениями, которые пользователь проверяет через `git diff` до коммита.
В финале порекомендуй следующий шаг: находки исправлены → коммит (скилл `git-commit`); чисто или фиксы пропущены → оформление PR/MR (если ревьюился не сам PR). Оставайся в этом разговоре — контекст реализации здесь.