Skip to content
Back to skills

Bug Report

ASecurity

Баг-репорт на русском в два слоя: суть для аналитика бизнес-языком, затем полный репорт для разработчика — предусловия, шаги, ожидаемый и фактический результат, причина, место в коде, трейс и логи, масштаб находки. Используй всегда, когда просят «оформи баг», «напиши баг-репорт», «заведи дефект», «опиши находку», «что написать разработчику», и перед отправкой любой находки в трекер или чат. English: bug report, defect report, steps to reproduce.

  • 2 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added October 16, 2026
ai-agentspythonreacttestinggitapi

Works with

  • api

Security analysis

A100/100

Pro scans all 6 files and shows the line behind each finding

Scanned October 16, 2026

npx -y skills add KonstantinVCH/QA-agent-skills --skill bug-report --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Bug Report?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Bug Report
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/konstantinvch-bug-report/badge)](https://www.skillsdirectory.com/skills/konstantinvch-bug-report)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: bug-report
description: "Баг-репорт на русском в два слоя: суть для аналитика бизнес-языком, затем полный репорт для разработчика — предусловия, шаги, ожидаемый и фактический результат, причина, место в коде, трейс и логи, масштаб находки. Используй всегда, когда просят «оформи баг», «напиши баг-репорт», «заведи дефект», «опиши находку», «что написать разработчику», и перед отправкой любой находки в трекер или чат. English: bug report, defect report, steps to reproduce."
license: MIT
compatibility: "Ничего обязательного: скилл формирует текст. Опционально python3 и доступ к API Jaeger для разбора WARN/ERROR трейса (scripts/trace_warnings.py), curl для проверки ссылок на git."
metadata:
  author: KonstantinVCH
  version: "1.1.0"
  language: ru
---

# Баг-репорт в два слоя

Репорт читают два разных человека. Аналитику и менеджеру нужно за десять секунд понять, что
сломано, чем это плохо и почему должно быть иначе, — без классов, трейсов и номеров строк.
Разработчику нужно воспроизвести дефект и найти место в коде. Если смешать оба слоя, первый
читатель тонет в коде, а второй не находит шагов. Поэтому репорт пишется сверху вниз: сначала
слой для человека без кода, под ним — слой для разработчика.

Формат сложился из итераций с живыми читателями: каждая отвергнутая версия превратилась в
правило ниже, реальные случаи приведены рядом.

## Настройка под проект

Шаблоны ссылок на git, трейсинг и логи, адреса стендов, название системы спецификаций и чата
команды собраны в `references/project-config.md`. Заполни один раз; до этого используй
плейсхолдеры `{BITBUCKET_URL}`, `{JAEGER_URL}`, `{OPENSEARCH_URL}`, `{STAND}`.

---

## Когда какой формат

| Ситуация | Формат |
|---|---|
| Баг / дефект реализации | **Слой 1 + слой 2** (ниже) |
| Вопрос аналитику, расхождение документации и кода | Короткий: что вижу → как в документации → что предлагаю. Без шагов, бизнес-языком |
| Ответ в чате «что нашёл» | Только слой 1 |
| Находка, у которой нет корня или контрольного позитива | Наблюдение: что вижу / чем плохо / что предлагаю, с явной пометкой HYPOTHESIS. Баг не заводить |

Если спека декларирует поведение, которого система не умеет, — это не баг кода, а
несогласованный контракт. Адресат — аналитик, а не разработчик.

---

## Слой 1 — для аналитика и менеджера

4–6 строк. Бизнес-язык, без кода, трейсов, номеров строк и кодов ошибок. Термины — из задачи,
спеки и речи команды, а не из имён классов.

```
**<ЧТО ломается — при каком условии>**

Что вижу: <наблюдаемое поведение словами пользователя или бизнеса>
Чем плохо: <последствие: кто страдает, что теряется>
Как должно быть: <ожидаемое> — по <спека, раздел>
Масштаб и что делать: <сколько случаев сейчас; фикс / бэклог / вопрос аналитику>
```

Проверка слоя 1: поймёт ли человек, не видевший твоей сессии, суть по заголовку и первым трём
строкам? Нет — переписать.

---

## Слой 2 — для разработчика

```
**BUG. <ЧТО именно ломается> — <ГДЕ: сервис/метод> — <при каком условии>**

**Предусловия**
- <стенд, ветки задачи>
- <моки/флаги/состояние, без которых не воспроизвести>

**Шаги воспроизведения**
1. <действие с конкретным URL и ключевым полем тела>
2. <проверка промежуточного состояния — БД/очередь>
3. <действие, вызывающее дефект>
4. <где смотреть результат>

**ОР** — <ожидаемое, дословно/кодом>
Основание: <ссылка на спеку + раздел>, <ссылка на эталонный метод>, <схема/контракт>.

**ФР** — <фактическое, дословные значения>

**Причина:** <одна строка, человеческим языком>
**Fix:** <одна строка, с git-ссылкой на место>

<кликабельный трейс> · не тест-данные: <чем доказано>
```

Развёрнутая форма «Что вижу / Когда / Как должно быть / Похоже, причина / Чем кончается / Fix»,
формат комментария разработчику в Jira и разбор заголовков — в `references/developer-formats.md`.

---

## Жёсткие правила

1. **ОР всегда со ссылкой на источник.** «Должно быть с часовым поясом» — недостаточно. Нужно
   «по [спеке], раздел П_09_02» или «в эталонном методе для партнёра A так-то». Без основания
   разработчик не понимает, почему вообще должно быть иначе. *(Реальная претензия читателя:
   «непонятно, почему должно быть иначе, нет ссылок на доку».)*

2. **Ссылок на документацию минимум две, лучше три:** спека самой задачи, эталонный или
   аналогичный метод, формальный контракт (JSON-схема, XSD, OpenAPI).

3. **Каждый упомянутый файл, класс, метод и строка — кликабельная ссылка на git, а не путь
   текстом.** Это касается и «Причины», и «Fix», и ФР. `src/main/resources/application.yml` —
   плохо; `[application.yml:137](<ссылка на файл в ветке, строка 137>)` — хорошо. Шаблоны для
   Bitbucket Server, GitLab и GitHub — в `references/project-config.md`. Ветку указывай всегда:
   без неё открывается основная ветка, и разработчик увидит не тот код. Перед отправкой проверь,
   что ссылка отдаёт 200:
   `curl -o /dev/null -w "%{http_code}" -H "Authorization: Bearer $BITBUCKET_TOKEN" "<url>"`.
   *(Реальная претензия: путь в Fix был написан текстом — «почему нет реальной ссылки на гит?
   исправь навсегда».)*

4. **ОР и ФР — дословные значения**, а не пересказ. Копируй реальные строки из тела запроса или
   лога.

5. **Первый экран — без кода.** Классы, методы и аннотации маппинга уходят в «Причину»/«Fix»
   одной строкой либо под спойлер. Заголовок и первые строки должны читаться человеком, не
   знающим код. Именно поэтому слой 1 идёт первым.

6. **Кратко.** Слой 2 помещается на один экран. Не помещается — техдетали под `<details>`.
   *(Претензия на развёрнутую версию: «теперь кратко!!!!».)*

7. **Строка про тест-данные обязательна.** Одной фразой: чем доказано, что значение
   сгенерировано системой, а не подставлено тестировщиком.

8. **Трейс кликабельный**, и перед отправкой проверь, что в нём видно именно утверждаемое
   (Jaeger: `{JAEGER_URL}/trace/<traceId>?uiFind=<spanId>` — сразу на нужный спан). **То же для
   логов: упомянул лог — дай ссылку на лог, всегда.** Две ссылки: на саму запись (Kibana/OpenSearch
   Dashboards: `.../app/discover#/doc/<index-pattern-id>/<index>?id=<_id>`, `_id` и `_index` — из
   ответа поиска) и на выборку (discover с фильтрами namespace + pod/container, запрос
   `level:"ERROR"`, **абсолютное** время `time:(from:'…Z',to:'…Z')` — относительное `now-24h`
   протухает через сутки). Перечислить фильтры текстом вместо ссылки нельзя. Перед отправкой
   открой ссылку и убедись, что цитируемая запись видна.

9. **Заголовок = ЧТО — ГДЕ — при каких условиях.** Без причины, кода ошибки и fix одновременно.
   Разбор атомарности полей заголовка — в `references/developer-formats.md`.

10. **Разбери ВСЕ WARN и ERROR трейса и назови их в репорте.** Формулировка «ошибок нет»
    допустима, только если реально просмотрены логи всех спанов. Каждый WARN классифицируй одной
    строкой: относится к дефекту / нормальное поведение при этих условиях / отдельная находка.
    Молчание про WARN читается как «не смотрел» и обнуляет доверие ко всему репорту.

    Формат строки:
    ```
    Трейс <ссылка> — 12 спанов, ERROR нет; 2 WARN не по теме
    («Product for complete … not found» — первая загрузка товара;
     «Schema is not found for ProductPublishedEvent»).
    ```
    Снять WARN/ERROR всех спанов: `python3 scripts/trace_warnings.py <traceId>` (берёт трейс из
    `JAEGER_URL`) или `python3 scripts/trace_warnings.py --file trace.json`.

    *(Реальный случай: написал «12 спанов, ошибок нет», пропустив два WARN. Читатель открыл лог
    сам: «я тебе не верю, перепроверь себя». Один из WARN выглядел так, будто флоу отработал не
    полностью, — пришлось объясняться постфактум.)*

11. **Перед отправкой ответь себе: этот дефект в скоупе задачи?** Найденное в ходе тестирования
    задачи — ещё не дефект этой задачи. Проверка в три шага:

    1. **Менялся ли этот код в PR задачи?** Открой diff всех PR. Файла там нет — поведение
       унаследованное.
    2. **Специфично ли оно для нашего партнёра/флоу?** Если тот же код обслуживает других
       партнёров и они получают то же самое — проблема платформенная.
    3. **Требовала ли постановка это изменить?** Прямой пункт скоупа или «сделать по аналогии с
       эталоном» — в скоупе. Ничего не требовала — вне.

    Вывод пиши с обоснованием, а не ярлыком:
    ```
    В скоупе: задача требовала «аналогично интеграции с партнёром A»; у эталона преобразование
              даты есть (DateMapper.setTimezone(3 * 60)), в новом адаптере его не написали.
    Вне скоупа: PR задачи этот маппер не трогали; статус формируется общим кодом, остальные
              партнёры получают то же самое — поведение существует до задачи.
    ```

    Зачем: дефект вне скоупа, поданный как дефект задачи, блокирует приёмку из-за древнего
    поведения платформы и подставляет разработчика, который к нему не причастен. Такие находки
    оформляются отдельно — вопросом аналитику или в бэклог.

    *(Реальный случай: статус обработки никогда не принимал одно из значений — доказано живьём,
    но маппер общий, PR задачи его не касались: «вне скоупа, запомни и идём дальше». А отсутствие
    конвертации дат — в скоупе: постановка требовала копию эталона.)*

12. **Утверждение о последствиях проверяй так же, как утверждение о дефекте.** Правило «факты
    важнее гипотез» обычно применяют к самой находке, а мимо проходят фразы вокруг неё: «это
    сломает X», «будет конфликт», «эталон требует Y», «метод не реализован». Они читаются как
    факт, по ним принимают решения — проверять их надо до отправки, а не после вопроса «ты
    уверен?». **Утверждение проверяется одной командой — проверь.**

    | Утверждение | Чем проверяется |
    |---|---|
    | «будет конфликт при слиянии» | `git merge-tree --write-tree A B` — код возврата и дерево |
    | «файлы в двух ветках разные» | `git rev-parse A:путь` против `B:путь` — сравнение blob |
    | «эталон требует такой формат» | открыть страницу спеки и прочитать раздел, а не помнить |
    | «метод не реализован на той стороне» | это чужое утверждение — замерить или назвать источник |
    | «сообщение потеряется» | счётчики очереди до/после: `publish`, `ack`, `redeliver` |
    | «переменную можно переопределить» | найти её в шаблоне конфига, а не предполагать |

    Проверить нельзя — пиши не «сломается», а «не проверял, риск такой-то». «Скорее всего» в
    тексте для разработчика или аналитика недопустимо: либо факт с доказательством, либо явная
    пометка HYPOTHESIS.

    **Механика находки — ещё не её значимость.** Доказанный механизм без масштаба превращается в
    ложную тревогу. Находка подаётся связкой из трёх частей, третья обязательна:

    1. **механизм** — что сломано, доказано кодом и прогоном;
    2. **масштаб** — на скольких реальных данных срабатывает **сейчас** и может сработать позже;
       данных нет — так и пиши;
    3. **что делать** — фикс, бэклог или ничего.

    Признаки раздувания: «любой X даст Y», хотя таких X в данных нет; технический долг вынесен в
    находки; масштаб выясняет не автор, а вопросы читателя; тревожный тон при нуле случаев.
    Правильная формулировка при нулевом масштабе: «дефект есть, ущерба нет и не предвидится — в
    бэклог, задачу не блокирует».

    *(Реальные случаи. Первый: защита от дублей не срабатывала для записей со старым написанием
    названия — механика подтверждена кодом, миграцией и прогоном, подано как «любая активная
    запись даст дубль». По факту: 54 записи, все закрытые, ноль дублей сейчас и в перспективе;
    масштаб читатель вытаскивал двумя вопросами. Второй: формат дат подан дефектом со ссылкой на
    маппинг другой ветки контракта — по репорту сделали фикс, развернувший уже закрытое решение
    партнёра. Третий: «второй PR получит конфликт по всем десяти файлам» — симуляция слияния
    вернула код 0, файлы побайтово совпали. Каждая проверка занимала одну команду.)*

13. **Строку лога привязывай к вызову, только если в ней есть его traceId или точное время.**
    Строка без traceId и времени доказывает одно: такая запись в логе была. Чья она — из неё не
    следует, особенно когда несколько вызовов трогали один и тот же объект. Поставленная в ФР под
    конкретным вызовом, она читается как его след, и разработчик ищет причину не там.

    - В строке есть traceId вызова или время, которое попадает только в окно этого вызова, — ставь
      её в ФР рядом с ним.
    - Нет ни того, ни другого — найди запись по traceId вызова в логах (скилл чтения логов) или подай
      её отдельно: «в логах payment-service есть запись …; к какому вызову она относится, не
      установлено».

    *(Случай из прогона скилла на тестовом запросе: заказ отменили дважды, оба вызова создали
    возврат. Строка «creating refund for order 1042» без traceId и времени встала в ФР сразу под
    вторым вызовом, хотя могла прийти и от первого.)*

---

## Эталонный пример (принят читателями дословно; домен заменён на вымышленный)

```
**Даты публикации товара уходят партнёру без часового пояса**

Что вижу: при публикации товара партнёр X получает даты без часового пояса и в двух разных форматах.
Чем плохо: партнёр трактует время как своё локальное — расхождение до нескольких часов в витрине.
Как должно быть: дата с поясом +03:00, единый формат — по спеке партнёра X, пример П_09_02.
Масштаб и что делать: каждая публикация через новый адаптер; фикс в рамках задачи.

---

**BUG. Колбэк о публикации: даты уходят партнёру без часового пояса и в разных форматах**

**Предусловия**
- Стенд {STAND}, ветки `PROJ-123`: `catalog-service`, `partner-x-adapter`
- Адаптер задеплоен в режиме мока (колбэк идёт на WireMock, т.к. партнёр метод ещё не реализовал)
- На моке стаб `POST /catalog/response` → 200

**Шаги воспроизведения**
1. Загрузить каталог: `POST {GATEWAY_URL}/partner-x-adapter/openapi/catalog/upload`,
   в теле `"creation": "2026-08-18T14:30:00"` → в ответе `batchId`
2. Проверить БД: `catalog.preactivation_product` → строка с `source=PARTNER_X`, `status=CREATED`
3. Активировать товар: `POST {CATALOG_SERVICE_URL}/openapi/pre-activation/product/activate`
   с `externalProductCode`, `batchId`, `publicationStatus=PUBLISHED`
4. Посмотреть тело запроса, ушедшего партнёру, — журнал WireMock или лог HTTP-клиента в трейсе

**ОР** — дата с часовым поясом, единый формат обоих полей, без долей секунды:
    "creation": "2026-08-18T14:53:34+03:00"
    "received": "2026-08-18T14:53:05+03:00"
Основание: эталонная интеграция с партнёром A (спека, раздел М_09_01, «мск +03:00»), пример
П_09_02 в спеке партнёра X (с `Z`), схема `DateTime` (доли секунды запрещены).

**ФР** — зоны нет ни у одного поля, форматы разные:
    "creation": "2026-08-18T14:53:34.866238"
    "received": "2026-08-18T14:53:05"

**Причина:** у партнёра A дата пересобирается по пути к партнёру, у партнёра X копируется как есть.
**Fix:** конвертировать `creation` и `received` так же, как в `autoupdate-service` [ссылка на метод].

<трейс> · не тест-данные: слал `14:30:00`, ушло `14:53:34.866238`.
```

Почему пример хорош: слой 1 читается без кода; заголовок слоя 2 тоже; шаги воспроизводимы
дословно; ОР подкреплён тремя источниками; ФР — реальные строки; причина объяснена контрастом с
работающим аналогом; одна строка снимает подозрение в артефакте тест-данных.

---

## Внутренний критик (обязательный отдельный проход)

Черновик написан — работа не закончена. Перечитай репорт ещё раз как придирчивый читатель и
вычисти нейропаттерны: антитезы «не X, а Y», оценочные анонсы («важный нюанс»), дежурные связки
(«стоит отметить»), хеджирование («может приводить»), канцелярит («является», «данный»),
формульный финал, правило трёх, декор из эмодзи. Найденное переписывай, а не смягчай.

Полный список паттернов, запрещённые обороты, процедуру и то, чего критик НЕ трогает (числа,
тексты ошибок, имена полей, фактические отрицания), — в `references/neuro-critic.md`. Прочитай
его перед первым репортом в сессии.

---

## Чеклист перед отправкой

- [ ] Слой 1 есть, без кода и трейсов; суть понятна по заголовку и трём строкам
- [ ] Заголовок слоя 2: ЧТО — ГДЕ — условие. Без причины и fix внутри
- [ ] Шаги воспроизводимы человеком, который не видел мою сессию (реальные URL, ключевые поля)
- [ ] ОР со **ссылками** (≥2 источника)
- [ ] **Каждый файл/класс/строка — кликабельная git-ссылка с веткой и строкой, проверенная на 200** (включая Fix)
- [ ] ФР — дословные значения
- [ ] Причина отделена от симптома, fix — отдельной строкой
- [ ] Трейс приложен и проверен
- [ ] **Каждый упомянутый лог — ссылка на запись и на выборку с абсолютным временем, открыта и проверена**
- [ ] Строка лога стоит под вызовом, только если в ней его traceId или время (правило 13)
- [ ] **Все WARN/ERROR трейса просмотрены и классифицированы** — «ошибок нет» без просмотра запрещено
- [ ] Строка «не тест-данные»
- [ ] **Определён скоуп** — дефект задачи или унаследованное поведение; вывод с обоснованием
- [ ] **У находки назван масштаб**; нулевой масштаб пишется прямо
- [ ] **Каждое утверждение о последствиях проверено или помечено как непроверенное**
- [ ] Слой 2 помещается на экран
- [ ] **Пройден внутренний критик** — отдельным проходом, после написания текста
- [ ] Состояние стенда исходное, есть контрольный позитив или контраст с работающим аналогом

---

## Антипаттерны (все — реальные отказы читателей)

| Что сделал | Реакция | Правило |
|---|---|---|
| Начал репорт с аннотаций маппинга и имён классов | «человеконечитаемо» | Первый экран без кода, слой 1 первым |
| Написал «ожидается дата со смещением» без ссылок | «непонятно, почему должно быть иначе» | ОР всегда с основанием |
| Развернул на две страницы с таблицами и спойлерами | «теперь кратко!!!!» | Один экран |
| Дал 8 репортов списком, когда просили один | «дай конкретный, краткий» | Один репорт = одна находка |
| Утверждал дефект по значению, которое сам же прислал | — | Строка «не тест-данные» обязательна |
| Написал «12 спанов, ошибок нет», не открыв WARN | «я тебе не верю, перепроверь себя» | Разобрать и назвать все WARN/ERROR |
| Подал платформенное поведение как дефект задачи | «это проблема в рамках нашей задачи?» | Скоуп с обоснованием до отправки |
| Обосновал дефект маппингом другой ветки контракта | по репорту сделали фикс, развернувший закрытое решение партнёра | Проверять источник требования, а не помнить |
| Заявил «будет конфликт по всем файлам» без симуляции слияния | «перепроверь себя» — конфликтов не было | Утверждение о последствиях — командой |
| В Fix написал путь к файлу текстом | «почему нет реальной ссылки на гит?» | Каждый файл — git-ссылка с веткой |

Ложные баги из-за тест-данных и грязного стенда разобраны в `references/developer-formats.md`.

---

## Границы скилла

Скилл описывает **только текст репорта**. Готовый текст выдаётся в чат; куда его девать — в
Jira, в мессенджер или обсудить устно — решает пользователь. Ничего не публиковать, задачи и
комментарии не создавать и не редактировать без явной просьбы.

Связанные скиллы: `test-session-report` — итог всей сессии тестирования (после прогона);
этот скилл — одна находка (по ходу). `qa-task-testing` — полный QA-протокол задачи.

## Справка

- `references/developer-formats.md` — развёрнутая форма, комментарий разработчику, заголовки, ложные баги
- `references/neuro-critic.md` — внутренний критик: нейропаттерны
- `references/project-config.md` — шаблоны ссылок и настройки проекта
- `scripts/trace_warnings.py` — все WARN/ERROR трейса Jaeger по спанам

Files in this skill

  • SKILL.md31.1 KB
  • evals/evals.json3 KB
  • references/developer-formats.md9.7 KB
  • references/neuro-critic.md5.7 KB
  • references/project-config.md2.7 KB
  • scripts/trace_warnings.py3.6 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.