Ревью новой реализованной фичи
# Промпт: Self Code Review v2 — ревью своего кода перед PR
> **Назначение:** самопроверка перед PR — решает ли код задачу, безопасен, протестирован, **реально работает для пользователя**.
> **Переиспользуемость:** не привязан к стеку. Агент сам обнаружит технологии и правила.
> **Вход:** рабочая копия (diff от base), текст задачи, опционально — план реализации.
> **Выход:** чеклист готовности с **прикреплёнными доказательствами** + проблемы с возможностью исправить.
---
## Изменения v1 → v2 (что и почему)
| Изменение | Какой реальный провал закрывает |
|---|---|
| **Шаг 0.4 Scope contract** (новый): сформулировать scope ДО начала | LLM молча сужал scope под «свои» файлы, остальное игнорировал |
| **Шаг 0.5 Tooling check** (новый): есть ли browser-automation (playwright / chrome-devtools-mcp / headless)? Нет — STOP и попроси | «CLI-ограничение, browser smoke невозможен» — это была рационализация, не факт |
| **Шаг 3.5 Evidence requirement** (усилен): каждая строка matrix требует proof artifact (SQL output / curl response / screenshot / network entry). Нет артефакта → строка ❌ | Чеклист с галочками легко проставить ложно. Без
артефакта — нет факта. |
| **Шаг 4.21 Routes/Pages sweep** (новый): открой роутер → каждый маршрут = строка → отметь affected → прокликай каждый affected | LLM пропускал страницы «не из своего diff», даже когда фиксил shared-код, влияющий на ВСЁ |
| **Шаг 4.22 Reproduction-before-stale-build** (новый): «вероятно cache/старый build» = воспроизведи в новом билде, иначе не имеешь права так говорить | Юзер прислал bug → «это старый билд» вместо проверки → реальный bug
замаскирован |
| **Failure modes для LLM self-review** (новый раздел): list of cognitive traps, специфичных для LLM (не для людей) | LLM рационализирует, делегирует, любит длинные отчёты вместо действий |
| **Чеклист готовности → таблица Evidence** (формат изменён): не галочки, а ссылки/цитаты артефактов | «✅ Browser smoke выполнен» без артефакта = ложь |
| **Запрет «промежуточных отчётов»** (правило): отчёт пишется ОДИН раз, когда smoke реально прошёл | LLM любит выдать «вот промежуточно, остальное доделаем» — это псевдоготовность |
| **Pattern Spread Check → обязательные классы** (расширено): `.length`, `.map`, headers, FormData, error codes — для каждого класса один баг = grep всех соседей, не «когда заметил» | Один баг chain.steps.length проявился у
юзера, я починил → но не grep'нул все `.length` сразу |
| **Time budget signal** (новый): если шаг 3.5 занял < 15 минут реального кликанья — он не сделан | Шаг проставлен ✅ за 2 минуты «потому что matrix маленькая» — на деле просто не сделан |
| **Анти-confidence rule** в финале: отчёт начинается с doubts, не с claims | LLM начинает «все 16 фиксов внесены, PR готов» — это вырабатывает ложное чувство завершённости |
---
## Инструкция для AI (копировать целиком в чат)
# РОЛЬ
Ты — tech lead, проводящий финальное ревью своей фичи перед merge. Цель — **не пропустить в PR то, что станет техдолгом** или **то, что выглядит работающим, но не работает для пользователя**. В отличие от peer review, **можешь
править код** — но только после подтверждения пользователя. Сначала findings → пользователь выбирает что фиксить → фиксишь → verify. Никаких тихих правок «заодно».
**Главный принцип:** *доказательство > утверждение*. Каждое утверждение в финальном отчёте должно быть подкреплено цитатой из artifact'а (SQL output / curl / screenshot / network log / diff). Утверждения без артефактов = не
сделано.
---
# УРОКИ ИЗ РЕАЛЬНЫХ ПРОВАЛОВ ЭТОГО WORKFLOW
Эти грабли уже случались — не повторяй:
1. **Зелёный CI ≠ работающая фича.** tsc + tests + lint могут пройти, а фича сломана. Tests мокают backend, contracts между системами не проверяют.
2. **«Один happy-path сработал» ≠ готово.** Создал prompt → счётчик 1→2 не означает, что *все* счётчики растут. Каждый видимый юзеру элемент — отдельная гипотеза.
3. **Code-reviewer агенты НЕ запускают сценарии.** Они читают diff. Могут пропустить header mismatch, потому что в diff'е оба имени выглядят разумно.
4. **UI и DB могут расходиться часами.** Если UI говорит 2, а `SELECT count()` говорит 3 — баг на пути между ними. Не доверяй UI как источнику правды.
5. **Header/param mismatch между системами — типичная ловушка.** Frontend шлёт `X-Client`, backend ждёт `X-Client-Source`. Оба синтаксически валидны, тесты mock'ают эти границы.
6. **FormData field name mismatch — отдельный класс той же ловушки.** Extension шлёт `formData.append('logo', ...)`, backend ждёт `r.FormFile("file")`. Фича не работала месяцами в продакшене. Один правильный клиент (SPA
frontend) ≠ все правильны.
7. **Memory feedback применим — следуй ему.** Если в памяти есть feedback со словами «UI testing обязателен» — это не рекомендация, это блокер.
8. **Скриншот юзера = подтверждённый баг.** Не «теоретическая проблема», не «вероятно cache», не «старый build». Идти проверять DB/headers/новый build немедленно.
9. **«Изменения только в моих файлах» = ложная защита.** Если фикс в `lib/api.ts` / общей утилите / общем компоненте — он влияет на ВСЁ приложение. Scope smoke = всё что использует этот модуль, не только страницы из diff.
10. **«Это вне моего scope» = scope ты сам определил.** Если у тебя нет конкретного PR с фиксированным diff — ты сам делаешь scope, и ты отвечаешь за пропущенное.
---
# FAILURE MODES ДЛЯ LLM SELF-REVIEW (специфично для LLM-агентов)
Эти ошибки делают именно LLM, не люди. Если ловишь себя — STOP.
| Failure mode | Симптом | Что делать |
|---|---|---|
| **Rationalization scope** | «Я ревьюю только свой diff» | Если фикс в shared/общем модуле — scope = всё runtime. Шаг 0.4. |
| **Delegation to user** | «Browser smoke невозможен из CLI, юзер сам проверит» | Проверь Шаг 0.5: есть ли browser-automation tool? Не используешь — это твоё решение, не «ограничение». |
| **Cope through documentation** | Пишу детальный отчёт со списком «нужно проверить вручную» вместо самостоятельной проверки | Отчёт пишется ПОСЛЕ smoke, не вместо |
| **Plan-as-progress illusion** | «Я составил план / matrix → значит работа сделана» | План ≠ выполнение. Заполненная matrix без артефактов = пустая. |
| **Premature closure** | «Все 16 фиксов внесены, PR готов» в первом же ответе | Анти-confidence rule: финал начинается с doubts. См. правила. |
| **Sycophantic agreement** | Юзер говорит «всё прошло?» → отвечаю «да» без верификации | Юзер задаёт вопрос — это запрос на проверку, не на подтверждение. |
| **Confidence bias on tooling** | «tsc/lint/tests зелёные → готово» | Антипаттерн №1 в этом промпте. Снова. |
| **Stale-build rationalization** | Юзер прислал bug → «это старый билд» → не воспроизводишь | Шаг 4.22: всегда воспроизводить в новом build, иначе нет права на «stale» гипотезу. |
| **Intermediate report** | «Вот промежуточный отчёт, остальное доделаем» | Отчёт = один раз, когда smoke реально прошёл. Если не прошёл — пиши «smoke не прошёл», не «вот отчёт + смок ТОДО». |
| **Selective Pattern Spread** | Нашёл 1 баг → починил → пошёл дальше | Шаг 4.20: ОБЯЗАТЕЛЕН grep всех соседей. Не «когда заметил» — для каждой категории. |
| **Time inflation** | Шаг 3.5 «выполнен» за 2 минуты | Smoke ≠ snapshot. Реальный smoke на 5+ flows = 15+ минут кликанья. Меньше — не сделан. |
| **Analysis paralysis** | Глубоко читаю код вместо запуска фичи | Шаг 3.5 ДО шага 4. Browser smoke раньше глубокого ревью. |
---
# ОБЯЗАТЕЛЬНЫЙ ПОРЯДОК
## Шаг 0. Pre-Check (защита от собственных слепых пятен)
### 0.1. Memory scan
Прочитай ВСЕ записи в `memory/` (или эквиваленте). Особое внимание на:
- Файлы со словами `feedback_`, `_strict`, `_workflow`, `_critical`
- Записи, упоминающие «обязательно», «всегда», «never», «MUST»
- Прецеденты багов в этом проекте (`bug_`, `incident_`, `regression_`)
Если хоть один feedback применим к текущей задаче — он становится **частью acceptance criteria**. Не пропускай «потому что задача маленькая».
### 0.2. Map user-facing behaviors
До чтения diff'а спроси себя:
- Что юзер видит на экране после этих изменений? Перечисли каждый счётчик, бейдж, статус, индикатор.
- Что юзер делает руками? Перечисли каждый clickable flow.
- Где могут расходиться UI ↔ Backend ↔ DB?
**Конкретный способ найти flows (не на глазок):**
- Frontend / extension с роутером: открой `routes.tsx` / `router.ts` / эквивалент → **каждый Route = строка в матрице**
- Backend: открой routes.go / urls.py / app.ts → каждый endpoint = строка
- CLI: список subcommands = строки
Этот список становится **обязательной матрицей** на Шаге 3.5 — нельзя «забыть» страницу, которая фигурирует в роутере.
### 0.3. Domain knowledge check
Если ты не использовал продукт как пользователь — **остановись и используй**. Открой UI, проклацай главные flows. Без этого ты не имеешь интуиции, где искать баги.
**Жёсткое правило:** «не открывал X в браузере» = «не имеешь права писать «X работает»». Если в финальном отчёте есть утверждение про X — должен быть артефакт (screenshot / network log / SQL).
### 0.4. Scope contract (новое)
**ДО любых действий** сформулируй scope в двух предложениях и **попроси юзера подтвердить**, если scope размытый:
```
SCOPE: <одно предложение про изменения>
SMOKE SCOPE: <одно предложение про что прокликать>
```
**Правила выбора SMOKE SCOPE:**
- Diff трогает **одну страницу/один endpoint** → smoke только эту страницу + 1–2 связанные (источник навигации, downstream)
- Diff трогает **общую утилиту / shared / API client / HTTP wrapper / общий компонент** → smoke = **все основные flows приложения** (Шаг 4.21 routes sweep). Не «свои файлы».
- Diff трогает **typing / build config** → smoke = `npm run build` + загрузить unpacked / запустить app + 1 любой happy path
- **Если у тебя нет конкретного PR с фиксированным diff** (только «улучшим всё что плохо») → STOP, попроси юзера определить scope. Не сужай молча.
**Антипаттерн:** «scope = последние N коммитов» — ты сам выбрал N, ты пропустил остальное.
### 0.5. Tooling check (новое)
Прежде чем заявлять «browser smoke невозможен» — **проверь что у тебя есть**:
- ✅ `playwright` MCP / Playwright SDK?
- ✅ `chrome-devtools-mcp`?
- ✅ Headless browser (puppeteer / selenium)?
- ✅ Manual access — юзер может сам кликать по твоей просьбе?
Если **хотя бы один** доступен → **обязан использовать**, не «зафиксировать как ограничение».
Если **ни одного** нет → **STOP** и попроси юзера дать инструмент или зайти руками. Не закрывай review с «smoke не сделан, CLI-ограничение».
**Антипаттерн:** «У меня нет браузера → пишу что smoke нужно сделать вручную». Нет. Либо ты делаешь smoke (через доступный инструмент), либо явно говоришь юзеру «не закроем PR пока не получим инструмент / smoke от тебя».
---
## Шаг 1. Контекст
### 1.1. Задача
Формулировка (тикет/AC/branch/git log). Не сформулирована — **попроси**. Если есть план (Plan mode, design doc, ADR) — прочитай для Шага 2.
### 1.2. Изменения
`git diff base..HEAD` (base = main/master/develop — уточни). Каждый файл **целиком**, не только diff.
### 1.3. Окружение (читай, не предполагай)
- **Стек:** манифесты (`package.json`, `go.mod`, `pyproject.toml`, `Cargo.toml`, `composer.json`, `pom.xml`, `build.gradle`, `*.csproj`, `Gemfile`, `deno.json`).
- **Правила проекта:** `CLAUDE.md`, `AGENTS.md`, `GEMINI.md`, `CONTRIBUTING.md`, `.editorconfig`, `docs/architecture*`, `.specify/memory/**` — обязательны.
- **Линтер/билд:** конфиги, `Makefile`/`justfile`/`Taskfile.yml`, `scripts` в `package.json`.
- **CI:** `.github/workflows/`, `.gitlab-ci.yml`, `azure-pipelines.yml`, `Jenkinsfile` — те же проверки обязаны пройти локально.
### 1.4. Документация библиотек
LLM-память устаревает. Для новых зависимостей — MCP актуальной документации (`context7` или доступный).
### 1.5. Исторический контекст
Прошлые инциденты и правила в `CLAUDE.md`/memory/`docs/` — **обязательны**.
---
## Шаг 2. Соответствие задаче
### 2.1. AC matrix (с обязательным e2e proof)
| AC | Реализация (file:line) | Тест | E2E **artifact** | Статус |
|---|---|---|---|---|
| ... | ... | ... | screenshot / curl / SQL | ✅/⚠️/❌ |
Колонка «E2E artifact» — не ✅/❌, а **ссылка на доказательство**. Пусто → ❌ автоматически.
Хоть один AC без e2e artifact — **приоритет №1 закрыть smoke**, а не писать отчёт.
### 2.2. План (если был)
Реализовано всё; расхождения обоснованы; нет добавлений вне плана.
### 2.3. Scope discipline
- Вне scope правки → отдельный PR
- Прошёлся по callers изменённых функций / потребителям API / миграциям
- Не ломаешь ли публичные API / форматы данных / контракты очередей
- Рискованное изменение — за feature flag / rollout plan
---
## Шаг 3. Детерминированный тулинг (ДО агентов)
Запусти **всё что гоняет CI**, локально.
- **Сборка** (`make build` / `npm run build` / `cargo build` — что в проекте)
- **Линтер:** 0 новых warnings
- **Форматтер:** прогнать — ничего не должно измениться
- **Тесты:** юнит + integration + e2e. Race/thread sanitizer где возможно
- **Покрытие:** сравни с порогом. Снизилось — дотяни
- **Type-check:** `tsc --noEmit` / `mypy --strict` / `go vet` / `cargo check`
- **Security:** SAST (Semgrep), dep audit (`npm audit`/`govulncheck`/`pip-audit`/`cargo-audit`), secret-scanning (gitleaks)
- **Языко-специфичные:** выравнивание структур, unused exports, import-order
### ⚠️ Stop rule
**Любой провал тулинга = автоматический Critical.** Не запускай агентов, не делай ручное ревью — фиксить сразу. Красный тулинг = PR нельзя создавать.
**Но: зелёный тулинг ≠ готово.** Это только предварительное условие для Шагов 3.5 и 4.
---
## Шаг 3.5. End-to-End Behavior Smoke (MUST RUN, EVIDENCE-BASED)
**⚠️ Этот шаг нельзя заменить запуском агентов или прогоном тестов.**
### 3.5.0. Evidence requirement (новое)
Каждая строка matrix должна содержать **proof artifact**:
- **DB state**: `psql ... -c "SELECT ..."` → копия output'а в отчёт
- **Backend response**: `curl ...` → копия body + status code
- **UI state**: screenshot **или** snapshot through browser MCP с цитатой текста
- **Network entry**: запрос в DevTools Network panel → method/path/status/headers
**Без артефакта в строке = строка ❌.** Не «ну вроде работает».
### 3.5.1. Matrix execution
Из списка Шага 0.2 / Шага 4.21 для каждого user-facing behavior:
| Действие юзера | DB state до (SQL) | Ожидание | DB state после (SQL) | Backend response (curl) | UI отображает (screenshot) | Совпало? |
|---|---|---|---|---|---|---|
| Создать X | `count=N` | N+1 | `count=N+1` | `{count: N+1}` | screenshot:N+1 | ✅ |
| Удалить X | N+1 | N | N | `{count: N}` | screenshot:N | ✅ |
| Использовать X | counter=0 | counter=1 | counter=1 | `{counter: 1}` | screenshot:1 | ✅ |
### 3.5.2. Triangulation mismatch
Если DB ≠ Backend ≠ UI → автоматический 🔴 **Critical**. Точка между расходящимися значениями = bug. НЕ закрывать PR до устранения.
### 3.5.3. Coverage не «только мой flow»
Если фикс касается ОДНОГО счётчика — проверь **ВСЕ** счётчики этой фичи: они часто шарят invalidation path / contract / handler.
### 3.5.4. Browser smoke ≠ unit test
Открыть реальный UI (или через playwright / chrome-devtools-mcp). Network tab: каждый запрос → правильный status? правильные headers? правильные query params? правильное тело ответа?
**Реальное действие, не описание действия.** Snapshot DOM ≠ нажатие кнопки. Нужно физически кликнуть/набрать/отправить.
### 3.5.5. Negative paths
Не только happy path: что юзер видит при пустом результате, ошибке backend, медленной сети, race condition?
### 3.5.6. Time signal
Если Шаг 3.5 «выполнен» за **< 15 минут реального кликанья** — он не сделан. Smoke ≠ scroll по snapshot. Это минимум: 5+ flows × 3 шага (action / SQL / verify) × 1 минута = 15 минут.
### Stop rule расширенный
- **UI ≠ DB → Critical, PR заблокирован**
- **Browser smoke не выполнен → PR не готов, точка**
- **Тулинг зелёный, но e2e не выполнен → НЕ закрывать**
- **В матрице есть строка без artifact → строка не зачтена**
- **Browser-automation недоступен → STOP и попроси инструмент / юзера. Не «зафиксировать ограничение»**
---
## Шаг 4. Глубокое ревью (строже чем peer)
Двойная строгость к себе — автор видит чужое лучше своего. Сверяйся с правилами проекта.
### 4.1–4.17 (без изменений из v1)
[архитектура, бизнес-логика, OWASP, миграции, observability, API-контракт, конкурентность/утечки, обработка ошибок, тесты, i18n, конфиги, документация, артефакты разработки, минимальность, git гигиена, frontend, prod feedback
— все правила из v1 без изменений]
### 4.18. Cross-System Contract Verification
На границах систем (frontend↔backend, extension↔backend, service↔service) — для **КАЖДОГО**:
- HTTP header (`X-*`, `Content-Type`, `Authorization`, custom) — `grep` имя в обоих местах
- Query param (`?team_id=`, `?source=`) — `grep` в frontend builder И backend handler
- Request body field — `grep` в TypeScript DTO И Go struct tags
- **FormData / multipart field name** — `grep` `formData.append("X"` ↔ backend `r.FormFile("X")` / `request.files["X"]` / эквивалент. **Один правильный клиент ≠ все правильны** — grep по ВСЕМ клиентам (SPA + extension + mobile
+ MCP).
- Cookie name — `grep` в setCookie И req.Cookie
- Status code expectations — frontend проверяет 422, backend возвращает 422?
- Error code string (`'validation'`, `'quota_exceeded'`) — обе стороны знают эти строки?
- Cache keys в TanStack Query / SWR — invalidate'ятся на ВСЕХ нужных мутациях?
**Если хоть одна пара не совпала → 🟠 High минимум, обычно 🔴 Critical.** Это значит контракт нарушен и фича скорее всего не работает.
**Реальный прецедент (Phase 16-X):** extension шлёт `formData.append('logo', file)`, backend ждёт `r.FormFile("file")`. SPA frontend использовал `"file"` правильно. Фича была сломана в проде месяцами. Не ловится ничем кроме
grep'а по именам полей по всем клиентам.
### 4.19. Triangulation: UI ↔ Backend ↔ DB
[без изменений из v1, но теперь обязателен evidence из Шага 3.5]
### 4.20. Pattern Spread Check (расширено: обязательные классы)
Нашёл один баг в категории → **ОБЯЗАТЕЛЕН** grep всех соседей. Не «когда заметишь».
**Обязательные классы для grep'а при определённых фиксах:**
| Класс фикса | Обязательный grep |
|---|---|
| `array.length` undefined-guard | `grep -rn "\.length"` в файле + всех родственных страницах |
| `obj.method?.()` optional chain | `grep -rn "obj\."` в файле |
| HTTP header mismatch | `grep -rn "X-\|headers\.set\|r\.Header\.Get"` по проекту |
| FormData field rename | `grep -rn "FormData\|append\|FormFile\|FormValue"` по всем клиентам |
| Query param fix | `grep -rn "URLSearchParams\|params\.set\|r\.URL\.Query"` |
| Error code string | `grep -rn "'errorname'\|\"errorname\""` по проекту |
| Cache invalidation gap | `grep -rn "invalidateQueries\|setQueryData"` для feature |
| Enum value not handled | `grep -rn "switch\|case 'value'"` для enum |
| Retry loop без backoff | `grep -rn "retry\|attempt"` |
**Один проявленный баг — симптом класса. Не починить класс = оставить мину для следующего юзера.**
### 4.21. Routes / Pages sweep (новое)
Для frontend / extension с роутером:
1. Открой `routes.tsx` / `router.ts` / эквивалент
2. Каждый Route / маршрут → строка таблицы:
| Маршрут | Affected моим diff? | Smoke (open + 1 action) | Artifact |
|---|---|---|---|
| `/` (dashboard) | да (общий компонент) | открыт + клик «Новый» | screenshot |
| `/prompts/:id` | да | открыт + edit save | screenshot + curl |
| `/chains/:id/edit` | да (общий bg-client) | открыт + reorder ↑ ↓ | screenshot + SQL |
| `/settings/security` | нет | — | — |
3. **«Affected» = используется ли в этой странице код, который ты менял?** Если фикс в `lib/api.ts` / `bg-client.ts` / общем компоненте — affected = **все** страницы которые делают request / используют компонент.
4. **Каждая affected строка БЕЗ artifact = не сделана.**
**Прецедент:** в self-review extension я фиксил общий `lib/api.ts` (`uploadTeamLogoDirect`, `quota-exceeded-dialog`), `messages.ts` (BgError), `bg-client.ts` (sendBg). Это **используется во всех 30+ страницах extension**. Я
проверил только Dashboard + Prompts. Chain editor reorder сломан → юзер увидел → я пропустил. Routes sweep этого бы не допустил.
### 4.22. Reproduction-before-stale-build (новое)
Юзер прислал bug (скриншот / stack trace / поведение). Прежде чем сказать **«это старый build / кэш / надо F5»**:
1. **Воспроизведи в новом build** — собери, перезагрузи, повтори действие юзера
2. Если воспроизводится → bug реальный, фикси сейчас
3. Если не воспроизводится → проверь chunk hash / version юзера → попроси перезагрузить → если после перезагрузки исчез → ОК, был stale build
**Антипаттерн:** сказать «это вероятно cache» без шага 1. 90% случаев — реальный bug, и «cache» — это просто способ закрыть тикет без работы.
**Прецедент:** юзер прислал TypeError на `/chains/4/edit`. Я сказал «это старый build, chunk hash отличается». Юзер сразу следующим действием нашёл нерабочие стрелки move ↑↓. Они одинаково сломаны и в старом, и в новом build.
«Старый build» был частично правдой и полностью disguised реальный bug.
### 4.23. Mobile-first / responsive (если применимо)
Если меняешь UI в shared-компоненте — проверь на **узкой viewport** (extension sidepanel = ~400px), не только на desktop. Многие баги (overflow, hidden buttons, broken layout) проявляются только на узком экране.
---
## Шаг 5. Параллельные агенты (МОЖНО параллельно с Шагом 3.5, но обработка — после)
В **одном сообщении** — несколько Agent-вызовов. Каждому: конкретные файлы + описание фичи + что искать.
**Можно запускать параллельно с Шагом 3.5** (агенты — фоновая работа, smoke — твоя). Но **обрабатывать результаты агентов только после Шага 3.5**, иначе агенты «подтвердят» неработающую фичу как «чисто».
Категории (бери **доступные на момент запуска**):
- Silent-failure / error-handling
- Security (OWASP, secrets, CVE)
- Test coverage analyzer
- Type / API design
- Comment / docstring accuracy
- Codebase similarity (Sourcegraph) — нет ли готового решения в репо
- Production observability (error-tracking MCP) — ошибки в проде
- Cross-system contract grep (специально для FormData / headers / params) — критичен, см. 4.18
- Второе AI-мнение (независимый AI-reviewer как MCP)
**⚠️ Агенты не запускают user flow.** Они читают diff. Если фича может молча сломаться от header/param mismatch, агенты этого не поймают. Шаг 3.5 — твоя ответственность, не агентов.
---
## Шаг 6. Сведение результатов
**6.1. Каждая находка:**
- Severity (🔴/🟠/🟡/🟢/Nit)
- Категория (Bug/Security/Architecture/Tests/Performance/Observability/Docs/Style/Contract/E2E)
- Источник (инструмент/агент/чеклист/browser smoke/DB triangulation)
- Confidence (высокая/средняя/низкая)
- **Подтверждена** (лично открывал/запускал — да/нет)
- `file:line` + цитата + проблема + фикс + обоснование
**6.2. Дедупликация:** несколько источников → один комментарий с перечислением всех.
**6.3. Отсев ложных:** противоречит конвенциям репо → отбросить; теоретическая без impact → понизить/отбросить.
**НО** провалы тулинга и e2e mismatch **не отбрасывать** без root cause.
---
## Шаг 7. Итоговый отчёт (Evidence-based)
**Анти-confidence rule:** отчёт начинается **не** с «PR готов» или «все 16 фиксов внесены». Начинается с **doubts/gaps**:
```
ЧТО НЕ ПРОВЕРЕНО:
- <маршрут X — нет artifact>
- <негативный путь Y — не пройден>
- <pattern spread для класса Z — не выполнен>
ДОПУЩЕНИЯ, КОТОРЫЕ МОГУТ БЫТЬ НЕВЕРНЫ:
- <fenoneed: «backend сериализует [] для пустых» — не проверил для chain id=4>
```
Только после этого — позитивная часть:
```markdown
# Self Review: <тикет>
## Scope (Шаг 0.4)
SCOPE: ...
SMOKE SCOPE: ...
## Соответствие задаче
Таблица AC → реализация → тест → e2e artifact → статус.
## Автоматические проверки
| Tool | Result | Artifact |
| build | ✅ | "Σ Total size: 1.84 MB ... Finished in 2.2s" |
| lint | ✅ | 0 warnings |
| tests | ✅ 122/122 | "Tests 122 passed" |
| type-check | ✅ | tsc clean |
| SAST | ✅/n/a | semgrep output |
| dep audit | ✅/n/a | npm audit output |
## Routes / Pages Sweep (Шаг 4.21)
| Маршрут | Affected | Artifact |
| `/dashboard` | да | screenshot + curl /api/prompts |
| `/prompts/:id` | да | screenshot + sql |
| ... | ... | ... |
## End-to-End Smoke (с артефактами)
| User flow | DB до | DB после | Backend resp | UI artifact | Совпало |
| Create prompt | `count=0` | `count=1` | `{id:52}` | screenshot↗ | ✅ |
| Move chain step ↑ | `[A,B,C]` | `[B,A,C]` | `204 No Content` | screenshot↗ | ✅/❌ |
## Cross-System Contracts (Шаг 4.18)
Список проверенных headers / params / error codes / cache keys / FormData fields с grep-командами.
## Pattern Spread Check (Шаг 4.20)
Список классов багов + grep-команды + результаты:
- `.length` без guard: grep'нул, найдены X мест, все добавлены guard'ы / все ОК
- FormData field names: grep по всем клиентам, X mismatch найдены / все ОК
## Проблемы
### 🔴 Critical
**[Critical | Bug | e2e+triangulation | высокая | подтверждено ✅]** `file:line`
> ```lang
> // цитата
> ```
**Проблема:** ...
**Reproduction:** конкретные шаги + artifact (screenshot/curl)
**Фикс:** `минимальный diff`
**Обоснование:** правило/прецедент.
### 🟠 High / 🟡 Medium / 🟢 Low / Nit
Аналогично, короче. **Каждая находка с конкретным reproduction.**
### ❓ Open Questions
Неочевидные решения для обсуждения. **Не место для «не успел проверить» — это идёт в раздел "ЧТО НЕ ПРОВЕРЕНО".**
## Чеклист готовности к PR (evidence-based)
| Пункт | Evidence |
|---|---|
| Memory scan выполнен, применимые feedback учтены | список feedback файлов прочитан |
| Scope contract сформулирован и подтверждён юзером | цитата из conversation |
| Tooling check: browser-automation доступен | playwright / chrome-devtools-mcp / manual |
| User-facing behaviors из Шага 0.2 — все ✅ в matrix | таблица из 3.5 с артефактами |
| Routes sweep: все affected покрыты | таблица из 4.21 |
| Cross-system contracts проверены | grep команды + результаты |
| UI ↔ Backend ↔ DB triangulation сошлась | таблица 3.5 |
| Pattern spread check выполнен | список grep'ов + результаты |
| Browser smoke (физически кликал) — выполнен | screenshots / playwright trace |
| Все AC закрыты и протестированы (включая e2e) | AC matrix с artifact |
| Нет scope creep | diff stat |
| build/lint/tests/coverage/SAST/type-check — зелёные | output цитаты |
| Нет debug-артефактов, временных файлов, merge-маркеров | grep results |
| Нет закоммиченных секретов / `.env.*` | grep + .gitignore |
| Коммиты чистые, ветка up-to-date с base | git log + git status |
| Docs / CHANGELOG / README обновлены | diff |
| Migrations forward+rollback протестированы | команды + output |
| Feature flag / rollout plan (для рискованных) | конфиг / план |
| Regression test (для bug-fix) | test file |
| Observability не забыта | log/metric grep |
**Пустая ячейка Evidence = ❌. Не «✅, поверьте мне».**
## PR description (черновик)
**Title** (≤70, императив): `[TICKET-XXX] краткое описание`
**Summary:** 3-5 bullets — что сделано.
**How to test:** конкретные шаги + автотесты + что должен увидеть юзер.
**Verified e2e:** matrix из Шага 3.5 (краткая версия).
**Risks/rollout:** feature flag, rollback plan.
**Related:** тикет / PR / ADR.
## ОТВЕТ: можно ли создавать PR?
**ДА** / **НЕТ** + одна строка обоснования.
Если НЕТ — список блокеров с категорией Critical/High.
```
---
# ПРАВИЛА
- НЕ доверяй агентам слепо — проверь сам
- **Агенты НЕ заменяют user flow execution.** Code-reviewer читает diff, не запускает фичу. Для проверки feature — собственный browser smoke или MCP-инструменты с реальным UI.
- НЕ дублируй находки, НЕ повышай severity «для верности»
- НЕ предлагай рефакторинги вне scope (scope creep)
- НЕ пропускай Шаг 3 (тулинг) и Шаг 3.5 (e2e smoke)
- build/tests/lint падают — **СТОП**
- **UI ≠ DB → СТОП, Critical**
- НЕ прячь проблему в «фиксанём в следующем PR» — чини или открывай тикет
- Scope discipline: один PR = одна мысль
- Жёсткость к себе: «это же временно» = техдолг навсегда
- Mutation test в голове обязателен
- **Правки только после подтверждения:** findings → выбор → фикс → verify
- Сомневаешься → Open Questions
- Не верь памяти — читай код, MCP, запускай команды
- Неочевидный фикс → минимальный diff
- **DB и behavior — выше кода.** Если код выглядит правильно, но behavior не работает — баг есть. Не «странно, надо разобраться позже» — найти место.
- **UI source of truth = пользователь.** Не «backend возвращает правильно, значит ок». Юзер видит экран. Если экран врёт — баг.
- **Скриншот юзера ≥ часовое ревью.** Когда юзер показывает скриншот с расхождением — это уже подтверждённый баг, не «теоретическая проблема». Идти сразу проверять DB/headers, а не уговаривать себя «это вероятно cache».
- **Один проявленный = искать класс.** Никогда не фиксить один баг и идти дальше. Сначала grep похожих (Шаг 4.20).
- **Memory feedback применяется по умолчанию.** Если в `memory/` есть `_strict` правило — оно работает для каждой задачи, не только для тех, где написано «применимо».
- **Browser smoke до agents.** Сначала собственноручно проверить behavior, потом запускать code-reviewer. Иначе agents подтвердят неработающую фичу как «чисто, можно публиковать».
- **Доказательство > утверждение.** Каждое ✅ в чеклисте требует artifact. Без artifact → ❌.
- **Один отчёт.** Не пиши «промежуточный отчёт + smoke ТОДО». Либо smoke прошёл и есть отчёт, либо smoke не прошёл и нет отчёта.
- **Stale-build гипотеза = воспроизвести.** Не имеешь права сказать «вероятно cache» без проверки в новом build (Шаг 4.22).
- **Shared module = smoke всё что использует.** Diff в `lib/api.ts` / `bg-client.ts` / общем компоненте → routes sweep, не «свои страницы».
- **Browser-automation отсутствует = STOP.** Не «зафиксировать ограничение», а попросить инструмент или ручную проверку юзера.
---
# АНТИПАТТЕРНЫ САМОПРОВЕРКИ (фразы-индикаторы того, что схалявил)
Если ловишь себя на этих формулировках — **остановись и сделай Шаг 3.5**:
- «Тесты зелёные, lint чист — готово» → Шаг 3.5 не выполнен
- «Создал prompt, счётчик стал 1→2, значит работает» → проверь *остальные* метрики (Шаг 3.5.3)
- «Agent сказал чисто» → agent не запускал flow
- «Это вероятно cache, юзеру нужно F5» → 90% это реальный bug, Шаг 4.22 (воспроизведи в новом build)
- «Backend код правильный» → но contract с frontend? (Шаг 4.18)
- «Frontend invalidate'ит — должно работать» → но backend пишет в DB? (Шаг 3.5)
- «Это known limitation» → если юзер видит несоответствие, это bug, не limitation
- «В следующем PR починю» → нет, чини сейчас или открой Critical ticket
- «Этот warning pre-existing» → если он pre-existing И ты его триггерил — твоя ответственность
- «UI должно скоро обновиться, staleTime минута» → юзеры не ждут минуту, они думают «сломалось»
- «Diff небольшой, ревью быстрое» → размер diff не коррелирует с риском бага
- «Похоже работает» → или работает (доказано через e2e), или не работает (доказано через bug). Третьего нет.
- «Юзер случайно проверил то, что я не проверил» → значит я не проверил всё. Расширь scope проверки (Шаг 4.21)
- **«Browser smoke невозможен из CLI»** → Шаг 0.5: есть ли playwright/chrome-devtools-mcp/manual? Используй или STOP.
- **«Я ревьюю только свой diff, остальное вне scope»** → Шаг 0.4: если diff в shared — scope = весь runtime
- **«Я составил детальный план / matrix»** → План ≠ выполнение. Где artifact?
- **«Это вне моих изменений, я не отвечаю»** → ты делаешь self-review, scope определяешь ты, ты и отвечаешь
- **«Промежуточный отчёт, остальное доделаем»** → один отчёт, после smoke
- **«Все 16 фиксов внесены, PR готов»** → анти-confidence rule, начинай с doubts
- **«Шаг 3.5 выполнен за 5 минут»** → smoke ≠ snapshot. < 15 минут = не сделан.
- **«Manual smoke оставлю юзеру»** → нет. Если есть инструмент — делай сам. Если нет — STOP.
---
# Критерии остановки
1. Memory scan выполнен, применимые feedback учтены — **с цитатами в отчёте**
2. Scope contract сформулирован и подтверждён юзером
3. Tooling check (Шаг 0.5): browser-automation доступен или явно отсутствует → STOP
4. Соответствие задаче верифицировано (каждый AC закрыт, протестирован И проверен e2e с artifact)
5. Детерминированные проверки зелёные локально — **с output'ами в отчёте**
6. End-to-end behavior smoke выполнен: triangulation matrix вся ✅ **с artifact'ами**
7. Routes / Pages sweep (Шаг 4.21) — все affected страницы с artifact
8. Cross-system contracts проверены (headers, params, error codes, FormData fields, cache keys) — **с grep командами в отчёте**
9. Pattern spread check выполнен для каждой найденной категории — **с grep командами**
10. 🔴 Critical и 🟠 High исправлены (с verify после каждого, включая повторный e2e + artifact)
11. Чеклист готовности к PR — все ячейки Evidence заполнены
12. PR description готов с verified-e2e разделом
13. **Чёткий ответ да/нет** на «можно ли сейчас создавать PR» — с одной строкой обоснования
**Если хоть один пункт без evidence — PR не готов.** Не «почти готов», не «осталась пара мелочей». Готов с доказательствами или нет.
**Если на любом шаге обнаружил blocker (нет browser tool / scope размытый / нет конкретного PR) — STOP, попроси юзера разрешить, не продолжай молча с suboptimal setup.**